Skip to content

Commit d661700

Browse files
Use SparseArrayCompat instead of SparseArray in StreamItemAdapter.
Make additional small improvements as well.
1 parent 8db90ba commit d661700

3 files changed

Lines changed: 31 additions & 56 deletions

File tree

app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package org.schabi.newpipe.util
22

33
import android.content.Context
4-
import android.util.SparseArray
54
import android.view.View
65
import android.view.View.GONE
76
import android.view.View.INVISIBLE
87
import android.view.View.VISIBLE
98
import android.widget.Spinner
9+
import androidx.collection.SparseArrayCompat
1010
import androidx.test.core.app.ApplicationProvider
1111
import androidx.test.ext.junit.runners.AndroidJUnit4
1212
import androidx.test.filters.MediumTest
@@ -39,9 +39,7 @@ class StreamItemAdapterTest {
3939
@Test
4040
fun videoStreams_noSecondaryStream() {
4141
val adapter = StreamItemAdapter<VideoStream, AudioStream>(
42-
context,
43-
getVideoStreams(true, true, true, true),
44-
null
42+
getVideoStreams(true, true, true, true)
4543
)
4644

4745
spinner.adapter = adapter
@@ -54,7 +52,6 @@ class StreamItemAdapterTest {
5452
@Test
5553
fun videoStreams_hasSecondaryStream() {
5654
val adapter = StreamItemAdapter(
57-
context,
5855
getVideoStreams(false, true, false, true),
5956
getAudioStreams(false, true, false, true)
6057
)
@@ -69,7 +66,6 @@ class StreamItemAdapterTest {
6966
@Test
7067
fun videoStreams_Mixed() {
7168
val adapter = StreamItemAdapter(
72-
context,
7369
getVideoStreams(true, true, true, true, true, false, true, true),
7470
getAudioStreams(false, true, false, false, false, true, true, true)
7571
)
@@ -88,7 +84,6 @@ class StreamItemAdapterTest {
8884
@Test
8985
fun subtitleStreams_noIcon() {
9086
val adapter = StreamItemAdapter<SubtitlesStream, Stream>(
91-
context,
9287
StreamItemAdapter.StreamSizeWrapper(
9388
(0 until 5).map {
9489
SubtitlesStream.Builder()
@@ -99,8 +94,7 @@ class StreamItemAdapterTest {
9994
.build()
10095
},
10196
context
102-
),
103-
null
97+
)
10498
)
10599
spinner.adapter = adapter
106100
for (i in 0 until spinner.count) {
@@ -111,7 +105,6 @@ class StreamItemAdapterTest {
111105
@Test
112106
fun audioStreams_noIcon() {
113107
val adapter = StreamItemAdapter<AudioStream, Stream>(
114-
context,
115108
StreamItemAdapter.StreamSizeWrapper(
116109
(0 until 5).map {
117110
AudioStream.Builder()
@@ -122,8 +115,7 @@ class StreamItemAdapterTest {
122115
.build()
123116
},
124117
context
125-
),
126-
null
118+
)
127119
)
128120
spinner.adapter = adapter
129121
for (i in 0 until spinner.count) {
@@ -200,7 +192,7 @@ class StreamItemAdapterTest {
200192
* Helper function that builds a secondary stream list.
201193
*/
202194
private fun <T : Stream> getSecondaryStreamsFromList(streams: List<T?>) =
203-
SparseArray<SecondaryStreamHelper<T>?>(streams.size).apply {
195+
SparseArrayCompat<SecondaryStreamHelper<T>?>(streams.size).apply {
204196
streams.forEachIndexed { index, stream ->
205197
val secondaryStreamHelper: SecondaryStreamHelper<T>? = stream?.let {
206198
SecondaryStreamHelper(

app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import android.os.Environment;
1818
import android.os.IBinder;
1919
import android.util.Log;
20-
import android.util.SparseArray;
2120
import android.view.LayoutInflater;
2221
import android.view.View;
2322
import android.view.ViewGroup;
@@ -36,6 +35,7 @@
3635
import androidx.appcompat.app.AlertDialog;
3736
import androidx.appcompat.view.menu.ActionMenuItemView;
3837
import androidx.appcompat.widget.Toolbar;
38+
import androidx.collection.SparseArrayCompat;
3939
import androidx.documentfile.provider.DocumentFile;
4040
import androidx.fragment.app.DialogFragment;
4141
import androidx.preference.PreferenceManager;
@@ -211,8 +211,7 @@ public void onCreate(@Nullable final Bundle savedInstanceState) {
211211
setStyle(STYLE_NO_TITLE, ThemeHelper.getDialogTheme(context));
212212
Icepick.restoreInstanceState(this, savedInstanceState);
213213

214-
final SparseArray<SecondaryStreamHelper<AudioStream>> secondaryStreams =
215-
new SparseArray<>(4);
214+
final var secondaryStreams = new SparseArrayCompat<SecondaryStreamHelper<AudioStream>>(4);
216215
final List<VideoStream> videoStreams = wrappedVideoStreams.getStreamsList();
217216

218217
for (int i = 0; i < videoStreams.size(); i++) {
@@ -236,10 +235,9 @@ public void onCreate(@Nullable final Bundle savedInstanceState) {
236235
}
237236
}
238237

239-
this.videoStreamsAdapter = new StreamItemAdapter<>(context, wrappedVideoStreams,
240-
secondaryStreams);
241-
this.audioStreamsAdapter = new StreamItemAdapter<>(context, wrappedAudioStreams);
242-
this.subtitleStreamsAdapter = new StreamItemAdapter<>(context, wrappedSubtitleStreams);
238+
this.videoStreamsAdapter = new StreamItemAdapter<>(wrappedVideoStreams, secondaryStreams);
239+
this.audioStreamsAdapter = new StreamItemAdapter<>(wrappedAudioStreams);
240+
this.subtitleStreamsAdapter = new StreamItemAdapter<>(wrappedSubtitleStreams);
243241

244242
final Intent intent = new Intent(context, DownloadManagerService.class);
245243
context.startService(intent);

app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.schabi.newpipe.util;
22

33
import android.content.Context;
4-
import android.util.SparseArray;
54
import android.view.LayoutInflater;
65
import android.view.View;
76
import android.view.ViewGroup;
@@ -11,6 +10,8 @@
1110
import android.widget.TextView;
1211

1312
import androidx.annotation.NonNull;
13+
import androidx.annotation.Nullable;
14+
import androidx.collection.SparseArrayCompat;
1415

1516
import org.schabi.newpipe.DownloaderImpl;
1617
import org.schabi.newpipe.R;
@@ -39,10 +40,10 @@
3940
* @param <U> the secondary stream type's class extending {@link Stream}
4041
*/
4142
public class StreamItemAdapter<T extends Stream, U extends Stream> extends BaseAdapter {
42-
private final Context context;
43-
43+
@NonNull
4444
private final StreamSizeWrapper<T> streamsWrapper;
45-
private final SparseArray<SecondaryStreamHelper<U>> secondaryStreams;
45+
@NonNull
46+
private final SparseArrayCompat<SecondaryStreamHelper<U>> secondaryStreams;
4647

4748
/**
4849
* Indicates that at least one of the primary streams is an instance of {@link VideoStream},
@@ -51,25 +52,26 @@ public class StreamItemAdapter<T extends Stream, U extends Stream> extends BaseA
5152
*/
5253
private final boolean hasAnyVideoOnlyStreamWithNoSecondaryStream;
5354

54-
public StreamItemAdapter(final Context context, final StreamSizeWrapper<T> streamsWrapper,
55-
final SparseArray<SecondaryStreamHelper<U>> secondaryStreams) {
56-
this.context = context;
55+
public StreamItemAdapter(
56+
@NonNull final StreamSizeWrapper<T> streamsWrapper,
57+
@NonNull final SparseArrayCompat<SecondaryStreamHelper<U>> secondaryStreams
58+
) {
5759
this.streamsWrapper = streamsWrapper;
5860
this.secondaryStreams = secondaryStreams;
5961

6062
this.hasAnyVideoOnlyStreamWithNoSecondaryStream =
6163
checkHasAnyVideoOnlyStreamWithNoSecondaryStream();
6264
}
6365

64-
public StreamItemAdapter(final Context context, final StreamSizeWrapper<T> streamsWrapper) {
65-
this(context, streamsWrapper, null);
66+
public StreamItemAdapter(final StreamSizeWrapper<T> streamsWrapper) {
67+
this(streamsWrapper, new SparseArrayCompat<>(0));
6668
}
6769

6870
public List<T> getAll() {
6971
return streamsWrapper.getStreamsList();
7072
}
7173

72-
public SparseArray<SecondaryStreamHelper<U>> getAllSecondary() {
74+
public SparseArrayCompat<SecondaryStreamHelper<U>> getAllSecondary() {
7375
return secondaryStreams;
7476
}
7577

@@ -106,6 +108,7 @@ private View getCustomView(final int position,
106108
final View view,
107109
final ViewGroup parent,
108110
final boolean isDropdownItem) {
111+
final var context = parent.getContext();
109112
View convertView = view;
110113
if (convertView == null) {
111114
convertView = LayoutInflater.from(context).inflate(
@@ -129,7 +132,7 @@ private View getCustomView(final int position,
129132

130133
if (hasAnyVideoOnlyStreamWithNoSecondaryStream) {
131134
if (videoStream.isVideoOnly()) {
132-
woSoundIconVisibility = hasSecondaryStream(position)
135+
woSoundIconVisibility = secondaryStreams.get(position) != null
133136
// It has a secondary stream associated with it, so check if it's a
134137
// dropdown view so it doesn't look out of place (missing margin)
135138
// compared to those that don't.
@@ -163,8 +166,7 @@ private View getCustomView(final int position,
163166
}
164167

165168
if (streamsWrapper.getSizeInBytes(position) > 0) {
166-
final SecondaryStreamHelper<U> secondary = secondaryStreams == null ? null
167-
: secondaryStreams.get(position);
169+
final var secondary = secondaryStreams.get(position);
168170
if (secondary != null) {
169171
final long size = secondary.getSizeInBytes()
170172
+ streamsWrapper.getSizeInBytes(position);
@@ -196,14 +198,6 @@ private View getCustomView(final int position,
196198
return convertView;
197199
}
198200

199-
/**
200-
* @param position which primary stream to check.
201-
* @return whether the primary stream at position has a secondary stream associated with it.
202-
*/
203-
private boolean hasSecondaryStream(final int position) {
204-
return secondaryStreams != null && secondaryStreams.get(position) != null;
205-
}
206-
207201
/**
208202
* @return if there are any video-only streams with no secondary stream associated with them.
209203
* @see #hasAnyVideoOnlyStreamWithNoSecondaryStream
@@ -213,7 +207,7 @@ private boolean checkHasAnyVideoOnlyStreamWithNoSecondaryStream() {
213207
final T stream = streamsWrapper.getStreamsList().get(i);
214208
if (stream instanceof VideoStream) {
215209
final boolean videoOnly = ((VideoStream) stream).isVideoOnly();
216-
if (videoOnly && !hasSecondaryStream(i)) {
210+
if (videoOnly && secondaryStreams.get(i) == null) {
217211
return true;
218212
}
219213
}
@@ -228,16 +222,15 @@ private boolean checkHasAnyVideoOnlyStreamWithNoSecondaryStream() {
228222
* @param <T> the stream type's class extending {@link Stream}
229223
*/
230224
public static class StreamSizeWrapper<T extends Stream> implements Serializable {
231-
private static final StreamSizeWrapper<Stream> EMPTY = new StreamSizeWrapper<>(
232-
Collections.emptyList(), null);
225+
private static final StreamSizeWrapper<Stream> EMPTY =
226+
new StreamSizeWrapper<>(Collections.emptyList(), null);
233227
private final List<T> streamsList;
234228
private final long[] streamSizes;
235229
private final String unknownSize;
236230

237-
public StreamSizeWrapper(final List<T> sL, final Context context) {
238-
this.streamsList = sL != null
239-
? sL
240-
: Collections.emptyList();
231+
public StreamSizeWrapper(@NonNull final List<T> streamList,
232+
@Nullable final Context context) {
233+
this.streamsList = streamList;
241234
this.streamSizes = new long[streamsList.size()];
242235
this.unknownSize = context == null
243236
? "--.-" : context.getString(R.string.unknown_content);
@@ -297,21 +290,13 @@ public String getFormattedSize(final int streamIndex) {
297290
return formatSize(getSizeInBytes(streamIndex));
298291
}
299292

300-
public String getFormattedSize(final T stream) {
301-
return formatSize(getSizeInBytes(stream));
302-
}
303-
304293
private String formatSize(final long size) {
305294
if (size > -1) {
306295
return Utility.formatBytes(size);
307296
}
308297
return unknownSize;
309298
}
310299

311-
public void setSize(final int streamIndex, final long sizeInBytes) {
312-
streamSizes[streamIndex] = sizeInBytes;
313-
}
314-
315300
public void setSize(final T stream, final long sizeInBytes) {
316301
streamSizes[streamsList.indexOf(stream)] = sizeInBytes;
317302
}

0 commit comments

Comments
 (0)