From 8db90ba449f4ca178518ca1e1504c9c58ec98d13 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Mon, 22 Aug 2022 09:25:08 +0530 Subject: [PATCH 1/2] Use SparseArrayCompat for thumbnails. --- .../fragments/list/search/SearchFragment.java | 14 +-- .../SeekbarPreviewThumbnailHolder.java | 97 +++++++------------ .../giga/service/DownloadManagerService.java | 31 +++--- 3 files changed, 57 insertions(+), 85 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index 5175e0096..26a283229 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -33,6 +33,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.TooltipCompat; +import androidx.collection.SparseArrayCompat; import androidx.core.text.HtmlCompat; import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.ItemTouchHelper; @@ -70,9 +71,7 @@ import org.schabi.newpipe.util.ServiceHelper; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Queue; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -141,7 +140,7 @@ public class SearchFragment extends BaseListFragment menuItemToFilterName = null; + private final SparseArrayCompat menuItemToFilterName = new SparseArrayCompat<>(); private StreamingService service; private Page nextPage; private boolean showLocalSuggestions = true; @@ -426,8 +425,6 @@ public class SearchFragment extends BaseListFragment(); - int itemId = 0; boolean isFirstItem = true; final Context c = getContext(); @@ -468,11 +465,8 @@ public class SearchFragment extends BaseListFragment cf = new ArrayList<>(1); - cf.add(menuItemToFilterName.get(item.getItemId())); - changeContentFilter(item, cf); - } + final var filter = Collections.singletonList(menuItemToFilterName.get(item.getItemId())); + changeContentFilter(item, filter); return true; } diff --git a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java index 08c6366c8..50ffa2f2a 100644 --- a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHolder.java @@ -1,6 +1,7 @@ package org.schabi.newpipe.player.seekbarpreview; import static org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper.SeekbarPreviewThumbnailType; +import static org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper.getSeekbarPreviewThumbnailType; import android.content.Context; import android.graphics.Bitmap; @@ -8,6 +9,7 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.collection.SparseArrayCompat; import com.google.common.base.Stopwatch; @@ -15,12 +17,9 @@ import org.schabi.newpipe.extractor.stream.Frameset; import org.schabi.newpipe.util.PicassoHelper; import java.util.Comparator; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Supplier; @@ -34,18 +33,15 @@ public class SeekbarPreviewThumbnailHolder { // Key = Position of the picture in milliseconds // Supplier = Supplies the bitmap for that position - private final Map> seekbarPreviewData = new ConcurrentHashMap<>(); + private final SparseArrayCompat> seekbarPreviewData = + new SparseArrayCompat<>(); // This ensures that if the reset is still undergoing // and another reset starts, only the last reset is processed private UUID currentUpdateRequestIdentifier = UUID.randomUUID(); - public synchronized void resetFrom( - @NonNull final Context context, - final List framesets) { - - final int seekbarPreviewType = - SeekbarPreviewThumbnailHelper.getSeekbarPreviewThumbnailType(context); + public void resetFrom(@NonNull final Context context, final List framesets) { + final int seekbarPreviewType = getSeekbarPreviewThumbnailType(context); final UUID updateRequestIdentifier = UUID.randomUUID(); this.currentUpdateRequestIdentifier = updateRequestIdentifier; @@ -63,13 +59,12 @@ public class SeekbarPreviewThumbnailHolder { executorService.shutdown(); } - private void resetFromAsync( - final int seekbarPreviewType, - final List framesets, - final UUID updateRequestIdentifier) { - + private void resetFromAsync(final int seekbarPreviewType, final List framesets, + final UUID updateRequestIdentifier) { Log.d(TAG, "Clearing seekbarPreviewData"); - seekbarPreviewData.clear(); + synchronized (seekbarPreviewData) { + seekbarPreviewData.clear(); + } if (seekbarPreviewType == SeekbarPreviewThumbnailType.NONE) { Log.d(TAG, "Not processing seekbarPreviewData due to settings"); @@ -94,10 +89,8 @@ public class SeekbarPreviewThumbnailHolder { generateDataFrom(frameset, updateRequestIdentifier); } - private Frameset getFrameSetForType( - final List framesets, - final int seekbarPreviewType) { - + private Frameset getFrameSetForType(final List framesets, + final int seekbarPreviewType) { if (seekbarPreviewType == SeekbarPreviewThumbnailType.HIGH_QUALITY) { Log.d(TAG, "Strategy for seekbarPreviewData: high quality"); return framesets.stream() @@ -111,17 +104,14 @@ public class SeekbarPreviewThumbnailHolder { } } - private void generateDataFrom( - final Frameset frameset, - final UUID updateRequestIdentifier) { - + private void generateDataFrom(final Frameset frameset, final UUID updateRequestIdentifier) { Log.d(TAG, "Starting generation of seekbarPreviewData"); final Stopwatch sw = Log.isLoggable(TAG, Log.DEBUG) ? Stopwatch.createStarted() : null; int currentPosMs = 0; int pos = 1; - final int frameCountPerUrl = frameset.getFramesPerPageX() * frameset.getFramesPerPageY(); + final int urlFrameCount = frameset.getFramesPerPageX() * frameset.getFramesPerPageY(); // Process each url in the frameset for (final String url : frameset.getUrls()) { @@ -130,11 +120,11 @@ public class SeekbarPreviewThumbnailHolder { // The data is not added directly to "seekbarPreviewData" due to // concurrency and checks for "updateRequestIdentifier" - final Map> generatedDataForUrl = new HashMap<>(); + final var generatedDataForUrl = new SparseArrayCompat>(urlFrameCount); // The bitmap consists of several images, which we process here // foreach frame in the returned bitmap - for (int i = 0; i < frameCountPerUrl; i++) { + for (int i = 0; i < urlFrameCount; i++) { // Frames outside the video length are skipped if (pos > frameset.getTotalCount()) { break; @@ -161,7 +151,9 @@ public class SeekbarPreviewThumbnailHolder { // Check if we are still the latest request // If not abort method execution if (isRequestIdentifierCurrent(updateRequestIdentifier)) { - seekbarPreviewData.putAll(generatedDataForUrl); + synchronized (seekbarPreviewData) { + seekbarPreviewData.putAll(generatedDataForUrl); + } } else { Log.d(TAG, "Aborted of generation of seekbarPreviewData"); break; @@ -169,7 +161,7 @@ public class SeekbarPreviewThumbnailHolder { } if (sw != null) { - Log.d(TAG, "Generation of seekbarPreviewData took " + sw.stop().toString()); + Log.d(TAG, "Generation of seekbarPreviewData took " + sw.stop()); } } @@ -189,17 +181,14 @@ public class SeekbarPreviewThumbnailHolder { final Bitmap bitmap = PicassoHelper.loadSeekbarThumbnailPreview(url).get(); if (sw != null) { - Log.d(TAG, - "Download of bitmap for seekbarPreview from '" + url - + "' took " + sw.stop().toString()); + Log.d(TAG, "Download of bitmap for seekbarPreview from '" + url + "' took " + + sw.stop()); } return bitmap; } catch (final Exception ex) { - Log.w(TAG, - "Failed to get bitmap for seekbarPreview from url='" + url - + "' in time", - ex); + Log.w(TAG, "Failed to get bitmap for seekbarPreview from url='" + url + + "' in time", ex); return null; } } @@ -208,32 +197,20 @@ public class SeekbarPreviewThumbnailHolder { return this.currentUpdateRequestIdentifier.equals(requestIdentifier); } - public Optional getBitmapAt(final int positionInMs) { - // Check if the BitmapData is empty - if (seekbarPreviewData.isEmpty()) { - return Optional.empty(); + // Get the frame supplier closest to the requested position + Supplier closestFrame = () -> null; + synchronized (seekbarPreviewData) { + int min = Integer.MAX_VALUE; + for (int i = 0; i < seekbarPreviewData.size(); i++) { + final int pos = Math.abs(seekbarPreviewData.keyAt(i) - positionInMs); + if (pos < min) { + closestFrame = seekbarPreviewData.valueAt(i); + min = pos; + } + } } - // Get the closest frame to the requested position - final int closestIndexPosition = - seekbarPreviewData.keySet().stream() - .min(Comparator.comparingInt(i -> Math.abs(i - positionInMs))) - .orElse(-1); - - // this should never happen, because - // it indicates that "seekbarPreviewData" is empty which was already checked - if (closestIndexPosition == -1) { - return Optional.empty(); - } - - try { - // Get the bitmap for the position (executes the supplier) - return Optional.ofNullable(seekbarPreviewData.get(closestIndexPosition).get()); - } catch (final Exception ex) { - // If there is an error, log it and return Optional.empty - Log.w(TAG, "Unable to get seekbar preview", ex); - return Optional.empty(); - } + return Optional.ofNullable(closestFrame.get()); } } diff --git a/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java b/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java index 25ec87f80..dc56ee205 100755 --- a/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java +++ b/app/src/main/java/us/shandian/giga/service/DownloadManagerService.java @@ -1,5 +1,8 @@ package us.shandian.giga.service; +import static org.schabi.newpipe.BuildConfig.APPLICATION_ID; +import static org.schabi.newpipe.BuildConfig.DEBUG; + import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -22,12 +25,12 @@ import android.os.IBinder; import android.os.Message; import android.os.Parcelable; import android.util.Log; -import android.util.SparseArray; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; +import androidx.collection.SparseArrayCompat; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat.Builder; import androidx.core.app.ServiceCompat; @@ -37,24 +40,21 @@ import androidx.preference.PreferenceManager; import org.schabi.newpipe.R; import org.schabi.newpipe.download.DownloadActivity; import org.schabi.newpipe.player.helper.LockManager; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; - -import us.shandian.giga.get.DownloadMission; -import us.shandian.giga.get.MissionRecoveryInfo; import org.schabi.newpipe.streams.io.StoredDirectoryHelper; import org.schabi.newpipe.streams.io.StoredFileHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.PendingIntentCompat; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import us.shandian.giga.get.DownloadMission; +import us.shandian.giga.get.MissionRecoveryInfo; import us.shandian.giga.postprocessing.Postprocessing; import us.shandian.giga.service.DownloadManager.NetworkState; -import static org.schabi.newpipe.BuildConfig.APPLICATION_ID; -import static org.schabi.newpipe.BuildConfig.DEBUG; - public class DownloadManagerService extends Service { private static final String TAG = "DownloadManagerService"; @@ -95,7 +95,7 @@ public class DownloadManagerService extends Service { private Builder downloadDoneNotification = null; private StringBuilder downloadDoneList = null; - private final ArrayList mEchoObservers = new ArrayList<>(1); + private final List mEchoObservers = new ArrayList<>(1); private ConnectivityManager mConnectivityManager; private ConnectivityManager.NetworkCallback mNetworkStateListenerL = null; @@ -108,7 +108,8 @@ public class DownloadManagerService extends Service { private int downloadFailedNotificationID = DOWNLOADS_NOTIFICATION_ID + 1; private Builder downloadFailedNotification = null; - private final SparseArray mFailedDownloads = new SparseArray<>(5); + private final SparseArrayCompat mFailedDownloads = + new SparseArrayCompat<>(5); private Bitmap icLauncher; private Bitmap icDownloadDone; @@ -277,7 +278,7 @@ public class DownloadManagerService extends Service { } if (msg.what != MESSAGE_ERROR) - mFailedDownloads.delete(mFailedDownloads.indexOfValue(mission)); + mFailedDownloads.remove(mFailedDownloads.indexOfValue(mission)); for (Callback observer : mEchoObservers) observer.handleMessage(msg); @@ -461,7 +462,7 @@ public class DownloadManagerService extends Service { } public void notifyFailedDownload(DownloadMission mission) { - if (!mDownloadNotificationEnable || mFailedDownloads.indexOfValue(mission) >= 0) return; + if (!mDownloadNotificationEnable || mFailedDownloads.containsValue(mission)) return; int id = downloadFailedNotificationID++; mFailedDownloads.put(id, mission); From d6617007d4ec48f900bf37b4e9797330f5cdb38e Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Tue, 22 Nov 2022 18:31:58 +0530 Subject: [PATCH 2/2] Use SparseArrayCompat instead of SparseArray in StreamItemAdapter. Make additional small improvements as well. --- .../newpipe/util/StreamItemAdapterTest.kt | 18 ++---- .../newpipe/download/DownloadDialog.java | 12 ++-- .../newpipe/util/StreamItemAdapter.java | 57 +++++++------------ 3 files changed, 31 insertions(+), 56 deletions(-) diff --git a/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt b/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt index 016feb576..0fe251c16 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt @@ -1,12 +1,12 @@ package org.schabi.newpipe.util import android.content.Context -import android.util.SparseArray import android.view.View import android.view.View.GONE import android.view.View.INVISIBLE import android.view.View.VISIBLE import android.widget.Spinner +import androidx.collection.SparseArrayCompat import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest @@ -39,9 +39,7 @@ class StreamItemAdapterTest { @Test fun videoStreams_noSecondaryStream() { val adapter = StreamItemAdapter( - context, - getVideoStreams(true, true, true, true), - null + getVideoStreams(true, true, true, true) ) spinner.adapter = adapter @@ -54,7 +52,6 @@ class StreamItemAdapterTest { @Test fun videoStreams_hasSecondaryStream() { val adapter = StreamItemAdapter( - context, getVideoStreams(false, true, false, true), getAudioStreams(false, true, false, true) ) @@ -69,7 +66,6 @@ class StreamItemAdapterTest { @Test fun videoStreams_Mixed() { val adapter = StreamItemAdapter( - context, getVideoStreams(true, true, true, true, true, false, true, true), getAudioStreams(false, true, false, false, false, true, true, true) ) @@ -88,7 +84,6 @@ class StreamItemAdapterTest { @Test fun subtitleStreams_noIcon() { val adapter = StreamItemAdapter( - context, StreamItemAdapter.StreamSizeWrapper( (0 until 5).map { SubtitlesStream.Builder() @@ -99,8 +94,7 @@ class StreamItemAdapterTest { .build() }, context - ), - null + ) ) spinner.adapter = adapter for (i in 0 until spinner.count) { @@ -111,7 +105,6 @@ class StreamItemAdapterTest { @Test fun audioStreams_noIcon() { val adapter = StreamItemAdapter( - context, StreamItemAdapter.StreamSizeWrapper( (0 until 5).map { AudioStream.Builder() @@ -122,8 +115,7 @@ class StreamItemAdapterTest { .build() }, context - ), - null + ) ) spinner.adapter = adapter for (i in 0 until spinner.count) { @@ -200,7 +192,7 @@ class StreamItemAdapterTest { * Helper function that builds a secondary stream list. */ private fun getSecondaryStreamsFromList(streams: List) = - SparseArray?>(streams.size).apply { + SparseArrayCompat?>(streams.size).apply { streams.forEachIndexed { index, stream -> val secondaryStreamHelper: SecondaryStreamHelper? = stream?.let { SecondaryStreamHelper( diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java index 2975fe43a..3f3384b8e 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -17,7 +17,6 @@ import android.os.Bundle; import android.os.Environment; import android.os.IBinder; import android.util.Log; -import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -36,6 +35,7 @@ import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.menu.ActionMenuItemView; import androidx.appcompat.widget.Toolbar; +import androidx.collection.SparseArrayCompat; import androidx.documentfile.provider.DocumentFile; import androidx.fragment.app.DialogFragment; import androidx.preference.PreferenceManager; @@ -211,8 +211,7 @@ public class DownloadDialog extends DialogFragment setStyle(STYLE_NO_TITLE, ThemeHelper.getDialogTheme(context)); Icepick.restoreInstanceState(this, savedInstanceState); - final SparseArray> secondaryStreams = - new SparseArray<>(4); + final var secondaryStreams = new SparseArrayCompat>(4); final List videoStreams = wrappedVideoStreams.getStreamsList(); for (int i = 0; i < videoStreams.size(); i++) { @@ -236,10 +235,9 @@ public class DownloadDialog extends DialogFragment } } - this.videoStreamsAdapter = new StreamItemAdapter<>(context, wrappedVideoStreams, - secondaryStreams); - this.audioStreamsAdapter = new StreamItemAdapter<>(context, wrappedAudioStreams); - this.subtitleStreamsAdapter = new StreamItemAdapter<>(context, wrappedSubtitleStreams); + this.videoStreamsAdapter = new StreamItemAdapter<>(wrappedVideoStreams, secondaryStreams); + this.audioStreamsAdapter = new StreamItemAdapter<>(wrappedAudioStreams); + this.subtitleStreamsAdapter = new StreamItemAdapter<>(wrappedSubtitleStreams); final Intent intent = new Intent(context, DownloadManagerService.class); context.startService(intent); diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java index 4b5e675c9..74de45720 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java @@ -1,7 +1,6 @@ package org.schabi.newpipe.util; import android.content.Context; -import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -11,6 +10,8 @@ import android.widget.Spinner; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.collection.SparseArrayCompat; import org.schabi.newpipe.DownloaderImpl; import org.schabi.newpipe.R; @@ -39,10 +40,10 @@ import us.shandian.giga.util.Utility; * @param the secondary stream type's class extending {@link Stream} */ public class StreamItemAdapter extends BaseAdapter { - private final Context context; - + @NonNull private final StreamSizeWrapper streamsWrapper; - private final SparseArray> secondaryStreams; + @NonNull + private final SparseArrayCompat> secondaryStreams; /** * Indicates that at least one of the primary streams is an instance of {@link VideoStream}, @@ -51,9 +52,10 @@ public class StreamItemAdapter extends BaseA */ private final boolean hasAnyVideoOnlyStreamWithNoSecondaryStream; - public StreamItemAdapter(final Context context, final StreamSizeWrapper streamsWrapper, - final SparseArray> secondaryStreams) { - this.context = context; + public StreamItemAdapter( + @NonNull final StreamSizeWrapper streamsWrapper, + @NonNull final SparseArrayCompat> secondaryStreams + ) { this.streamsWrapper = streamsWrapper; this.secondaryStreams = secondaryStreams; @@ -61,15 +63,15 @@ public class StreamItemAdapter extends BaseA checkHasAnyVideoOnlyStreamWithNoSecondaryStream(); } - public StreamItemAdapter(final Context context, final StreamSizeWrapper streamsWrapper) { - this(context, streamsWrapper, null); + public StreamItemAdapter(final StreamSizeWrapper streamsWrapper) { + this(streamsWrapper, new SparseArrayCompat<>(0)); } public List getAll() { return streamsWrapper.getStreamsList(); } - public SparseArray> getAllSecondary() { + public SparseArrayCompat> getAllSecondary() { return secondaryStreams; } @@ -106,6 +108,7 @@ public class StreamItemAdapter extends BaseA final View view, final ViewGroup parent, final boolean isDropdownItem) { + final var context = parent.getContext(); View convertView = view; if (convertView == null) { convertView = LayoutInflater.from(context).inflate( @@ -129,7 +132,7 @@ public class StreamItemAdapter extends BaseA if (hasAnyVideoOnlyStreamWithNoSecondaryStream) { if (videoStream.isVideoOnly()) { - woSoundIconVisibility = hasSecondaryStream(position) + woSoundIconVisibility = secondaryStreams.get(position) != null // It has a secondary stream associated with it, so check if it's a // dropdown view so it doesn't look out of place (missing margin) // compared to those that don't. @@ -163,8 +166,7 @@ public class StreamItemAdapter extends BaseA } if (streamsWrapper.getSizeInBytes(position) > 0) { - final SecondaryStreamHelper secondary = secondaryStreams == null ? null - : secondaryStreams.get(position); + final var secondary = secondaryStreams.get(position); if (secondary != null) { final long size = secondary.getSizeInBytes() + streamsWrapper.getSizeInBytes(position); @@ -196,14 +198,6 @@ public class StreamItemAdapter extends BaseA return convertView; } - /** - * @param position which primary stream to check. - * @return whether the primary stream at position has a secondary stream associated with it. - */ - private boolean hasSecondaryStream(final int position) { - return secondaryStreams != null && secondaryStreams.get(position) != null; - } - /** * @return if there are any video-only streams with no secondary stream associated with them. * @see #hasAnyVideoOnlyStreamWithNoSecondaryStream @@ -213,7 +207,7 @@ public class StreamItemAdapter extends BaseA final T stream = streamsWrapper.getStreamsList().get(i); if (stream instanceof VideoStream) { final boolean videoOnly = ((VideoStream) stream).isVideoOnly(); - if (videoOnly && !hasSecondaryStream(i)) { + if (videoOnly && secondaryStreams.get(i) == null) { return true; } } @@ -228,16 +222,15 @@ public class StreamItemAdapter extends BaseA * @param the stream type's class extending {@link Stream} */ public static class StreamSizeWrapper implements Serializable { - private static final StreamSizeWrapper EMPTY = new StreamSizeWrapper<>( - Collections.emptyList(), null); + private static final StreamSizeWrapper EMPTY = + new StreamSizeWrapper<>(Collections.emptyList(), null); private final List streamsList; private final long[] streamSizes; private final String unknownSize; - public StreamSizeWrapper(final List sL, final Context context) { - this.streamsList = sL != null - ? sL - : Collections.emptyList(); + public StreamSizeWrapper(@NonNull final List streamList, + @Nullable final Context context) { + this.streamsList = streamList; this.streamSizes = new long[streamsList.size()]; this.unknownSize = context == null ? "--.-" : context.getString(R.string.unknown_content); @@ -297,10 +290,6 @@ public class StreamItemAdapter extends BaseA return formatSize(getSizeInBytes(streamIndex)); } - public String getFormattedSize(final T stream) { - return formatSize(getSizeInBytes(stream)); - } - private String formatSize(final long size) { if (size > -1) { return Utility.formatBytes(size); @@ -308,10 +297,6 @@ public class StreamItemAdapter extends BaseA return unknownSize; } - public void setSize(final int streamIndex, final long sizeInBytes) { - streamSizes[streamIndex] = sizeInBytes; - } - public void setSize(final T stream, final long sizeInBytes) { streamSizes[streamsList.indexOf(stream)] = sizeInBytes; }