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; }