Skip to content

Commit 769791a

Browse files
committed
Added a "Crash the player" debug option
1 parent e632fab commit 769791a

6 files changed

Lines changed: 226 additions & 3 deletions

File tree

app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ public final class VideoDetailFragment
205205
private Player player;
206206
private final PlayerHolder playerHolder = PlayerHolder.getInstance();
207207

208+
@Nullable
209+
private VideoDetailPlayerCrasher videoDetailPlayerCrasher = null;
210+
208211
/*//////////////////////////////////////////////////////////////////////////
209212
// Service management
210213
//////////////////////////////////////////////////////////////////////////*/
@@ -594,6 +597,18 @@ private void toggleTitleAndSecondaryControls() {
594597
// Init
595598
//////////////////////////////////////////////////////////////////////////*/
596599

600+
@Override
601+
public void onViewCreated(@NonNull final View rootView, final Bundle savedInstanceState) {
602+
super.onViewCreated(rootView, savedInstanceState);
603+
604+
if (DEBUG) {
605+
this.videoDetailPlayerCrasher = new VideoDetailPlayerCrasher(
606+
() -> this.getContext(),
607+
() -> this.getLayoutInflater()
608+
);
609+
}
610+
}
611+
597612
@Override // called from onViewCreated in {@link BaseFragment#onViewCreated}
598613
protected void initViews(final View rootView, final Bundle savedInstanceState) {
599614
super.initViews(rootView, savedInstanceState);
@@ -604,6 +619,18 @@ protected void initViews(final View rootView, final Bundle savedInstanceState) {
604619

605620
binding.detailThumbnailRootLayout.requestFocus();
606621

622+
binding.detailControlsPlayWithKodi.setVisibility(
623+
KoreUtils.shouldShowPlayWithKodi(requireContext(), serviceId)
624+
? View.VISIBLE
625+
: View.GONE
626+
);
627+
binding.detailControlsCrashThePlayer.setVisibility(
628+
DEBUG && PreferenceManager.getDefaultSharedPreferences(getContext())
629+
.getBoolean(getString(R.string.show_crash_the_player_key), false)
630+
? View.VISIBLE
631+
: View.GONE
632+
);
633+
607634
if (DeviceUtils.isTv(getContext())) {
608635
// remove ripple effects from detail controls
609636
final int transparent = ContextCompat.getColor(requireContext(),
@@ -638,8 +665,10 @@ protected void initListeners() {
638665
binding.detailControlsShare.setOnClickListener(this);
639666
binding.detailControlsOpenInBrowser.setOnClickListener(this);
640667
binding.detailControlsPlayWithKodi.setOnClickListener(this);
641-
binding.detailControlsPlayWithKodi.setVisibility(KoreUtils.shouldShowPlayWithKodi(
642-
requireContext(), serviceId) ? View.VISIBLE : View.GONE);
668+
if (DEBUG) {
669+
binding.detailControlsCrashThePlayer.setOnClickListener(
670+
v -> videoDetailPlayerCrasher.onCrashThePlayer(this.player));
671+
}
643672

644673
binding.overlayThumbnail.setOnClickListener(this);
645674
binding.overlayThumbnail.setOnLongClickListener(this);
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package org.schabi.newpipe.fragments.detail;
2+
3+
import android.content.Context;
4+
import android.util.Log;
5+
import android.view.ContextThemeWrapper;
6+
import android.view.LayoutInflater;
7+
import android.view.ViewGroup;
8+
import android.widget.RadioButton;
9+
import android.widget.RadioGroup;
10+
import android.widget.Toast;
11+
12+
import androidx.annotation.NonNull;
13+
import androidx.appcompat.app.AlertDialog;
14+
15+
import com.google.android.exoplayer2.ExoPlaybackException;
16+
import com.google.android.exoplayer2.RendererCapabilities;
17+
18+
import org.schabi.newpipe.R;
19+
import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
20+
import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
21+
import org.schabi.newpipe.player.Player;
22+
import org.schabi.newpipe.util.ThemeHelper;
23+
24+
import java.io.IOException;
25+
import java.util.LinkedHashMap;
26+
import java.util.Map;
27+
import java.util.concurrent.TimeoutException;
28+
import java.util.function.Supplier;
29+
30+
public class VideoDetailPlayerCrasher {
31+
32+
private static final String TAG = "VideoDetPlayerCrasher";
33+
34+
@NonNull
35+
private final Supplier<Context> contextSupplier;
36+
@NonNull
37+
private final Supplier<LayoutInflater> layoutInflaterSupplier;
38+
39+
public VideoDetailPlayerCrasher(
40+
@NonNull final Supplier<Context> contextSupplier,
41+
@NonNull final Supplier<LayoutInflater> layoutInflaterSupplier
42+
) {
43+
this.contextSupplier = contextSupplier;
44+
this.layoutInflaterSupplier = layoutInflaterSupplier;
45+
}
46+
47+
private static Map<String, Supplier<ExoPlaybackException>> getExceptionTypes() {
48+
final String defaultMsg = "Dummy";
49+
final Map<String, Supplier<ExoPlaybackException>> exceptionTypes = new LinkedHashMap<>();
50+
exceptionTypes.put(
51+
"Source",
52+
() -> ExoPlaybackException.createForSource(
53+
new IOException(defaultMsg)
54+
)
55+
);
56+
exceptionTypes.put(
57+
"Renderer",
58+
() -> ExoPlaybackException.createForRenderer(
59+
new Exception(defaultMsg),
60+
"Dummy renderer",
61+
0,
62+
null,
63+
RendererCapabilities.FORMAT_HANDLED
64+
)
65+
);
66+
exceptionTypes.put(
67+
"Unexpected",
68+
() -> ExoPlaybackException.createForUnexpected(
69+
new RuntimeException(defaultMsg)
70+
)
71+
);
72+
exceptionTypes.put(
73+
"Remote",
74+
() -> ExoPlaybackException.createForRemote(defaultMsg)
75+
);
76+
exceptionTypes.put(
77+
"Timeout",
78+
() -> ExoPlaybackException.createForTimeout(
79+
new TimeoutException(defaultMsg),
80+
ExoPlaybackException.TIMEOUT_OPERATION_UNDEFINED
81+
)
82+
);
83+
84+
return exceptionTypes;
85+
}
86+
87+
private Context getContext() {
88+
return this.contextSupplier.get();
89+
}
90+
91+
private LayoutInflater getLayoutInflater() {
92+
return this.layoutInflaterSupplier.get();
93+
}
94+
95+
private Context getThemeWrapperContext() {
96+
return new ContextThemeWrapper(
97+
getContext(),
98+
ThemeHelper.isLightThemeSelected(getContext())
99+
? R.style.LightTheme
100+
: R.style.DarkTheme);
101+
}
102+
103+
public void onCrashThePlayer(final Player player) {
104+
if (!isPlayerAvailable(player)) {
105+
Log.d(TAG, "Player is not available");
106+
Toast.makeText(getContext(), "Player is not available", Toast.LENGTH_SHORT)
107+
.show();
108+
109+
return;
110+
}
111+
112+
final Context themeWrapperContext = getThemeWrapperContext();
113+
114+
final LayoutInflater inflater = LayoutInflater.from(themeWrapperContext);
115+
final RadioGroup radioGroup = SingleChoiceDialogViewBinding.inflate(getLayoutInflater())
116+
.list;
117+
118+
final AlertDialog alertDialog = new AlertDialog.Builder(getThemeWrapperContext())
119+
.setTitle("Choose an exception")
120+
.setView(radioGroup)
121+
.setCancelable(true)
122+
.setNegativeButton(R.string.cancel, null)
123+
.create();
124+
125+
for (final Map.Entry<String, Supplier<ExoPlaybackException>> entry
126+
: getExceptionTypes().entrySet()) {
127+
final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater).getRoot();
128+
radioButton.setText(entry.getKey());
129+
radioButton.setChecked(false);
130+
radioButton.setLayoutParams(
131+
new RadioGroup.LayoutParams(
132+
ViewGroup.LayoutParams.MATCH_PARENT,
133+
ViewGroup.LayoutParams.WRAP_CONTENT
134+
)
135+
);
136+
radioButton.setOnClickListener(v -> {
137+
tryCrashPlayerWith(player, entry.getValue().get());
138+
if (alertDialog != null) {
139+
alertDialog.cancel();
140+
}
141+
});
142+
radioGroup.addView(radioButton);
143+
}
144+
145+
alertDialog.show();
146+
}
147+
148+
private void tryCrashPlayerWith(
149+
@NonNull final Player player,
150+
@NonNull final ExoPlaybackException exception
151+
) {
152+
Log.d(TAG, "Crashing the player using player.onPlayerError(ex)");
153+
try {
154+
player.onPlayerError(exception);
155+
} catch (final Exception exPlayer) {
156+
Log.e(TAG,
157+
"Run into an exception while crashing the player:",
158+
exPlayer);
159+
}
160+
}
161+
162+
private boolean isPlayerAvailable(final Player player) {
163+
return player != null;
164+
}
165+
}

app/src/main/res/layout/fragment_video_detail.xml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@
213213
android:layout_below="@id/detail_title_root_layout"
214214
android:layout_marginTop="@dimen/video_item_detail_error_panel_margin"
215215
android:visibility="gone"
216-
tools:visibility="visible" />
216+
tools:visibility="gone" />
217217

218218
<!--HIDING ROOT-->
219219
<LinearLayout
@@ -547,6 +547,22 @@
547547
android:textSize="@dimen/detail_control_text_size"
548548
app:drawableTopCompat="@drawable/ic_cast" />
549549

550+
<TextView
551+
android:id="@+id/detail_controls_crash_the_player"
552+
android:layout_width="@dimen/detail_control_width"
553+
android:layout_height="@dimen/detail_control_height"
554+
android:layout_gravity="center_vertical"
555+
android:layout_weight="1"
556+
android:background="?attr/selectableItemBackgroundBorderless"
557+
android:clickable="true"
558+
android:contentDescription="@string/crash_the_player"
559+
android:focusable="true"
560+
android:gravity="center"
561+
android:paddingVertical="@dimen/detail_control_padding"
562+
android:text="@string/crash_the_player"
563+
android:textSize="@dimen/detail_control_text_size"
564+
app:drawableTopCompat="@drawable/ic_bug_report" />
565+
550566
</LinearLayout>
551567

552568
<View

app/src/main/res/values/settings_keys.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@
190190
<string name="disable_media_tunneling_key" translatable="false">disable_media_tunneling_key</string>
191191
<string name="crash_the_app_key" translatable="false">crash_the_app_key</string>
192192
<string name="show_image_indicators_key" translatable="false">show_image_indicators_key</string>
193+
<string name="show_crash_the_player_key" translatable="false">show_crash_the_player_key</string>
193194

194195
<!-- THEMES -->
195196
<string name="theme_key" translatable="false">theme</string>

app/src/main/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
<string name="kore_package" translatable="false">org.xbmc.kore</string>
5353
<string name="show_play_with_kodi_title">Show \"Play with Kodi\" option</string>
5454
<string name="show_play_with_kodi_summary">Display an option to play a video via Kodi media center</string>
55+
<string name="crash_the_player">Crash the player</string>
5556
<string name="report_player_errors_title">Report player errors</string>
5657
<string name="report_player_errors_summary">Reports player errors in full detail instead of showing a short-lived toast message (useful for diagnosing problems)</string>
5758
<string name="notification_scale_to_square_image_title">Scale thumbnail to 1:1 aspect ratio</string>
@@ -475,6 +476,8 @@
475476
<string name="show_image_indicators_title">Show image indicators</string>
476477
<string name="show_image_indicators_summary">Show Picasso colored ribbons on top of images indicating their source: red for network, blue for disk and green for memory</string>
477478
<string name="crash_the_app">Crash the app</string>
479+
<string name="show_crash_the_player_title">Show \"crash the player\"</string>
480+
<string name="show_crash_the_player_summary">Shows a crash option when using the player</string>
478481
<!-- Subscriptions import/export -->
479482
<string name="import_title">Import</string>
480483
<string name="import_from">Import from</string>

app/src/main/res/xml/debug_settings.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,13 @@
5454
android:title="@string/crash_the_app"
5555
app:singleLineTitle="false"
5656
app:iconSpaceReserved="false" />
57+
58+
<SwitchPreferenceCompat
59+
android:layout_width="wrap_content"
60+
android:layout_height="wrap_content"
61+
android:defaultValue="false"
62+
android:key="@string/show_crash_the_player_key"
63+
android:summary="@string/show_crash_the_player_summary"
64+
android:title="@string/show_crash_the_player_title"
65+
app:iconSpaceReserved="false" />
5766
</PreferenceScreen>

0 commit comments

Comments
 (0)