From 78e577d2601e4caea6d64b352335d71e6f9785e3 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Fri, 26 May 2023 14:46:53 +0200 Subject: [PATCH 1/5] Make some constants private and annotate params --- .../newpipe/settings/SettingMigrations.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java index 1bfaec6c287..bf691dc2850 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java @@ -4,6 +4,7 @@ import android.content.SharedPreferences; import android.util.Log; +import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; import org.schabi.newpipe.R; @@ -30,9 +31,9 @@ public final class SettingMigrations { private static final String TAG = SettingMigrations.class.toString(); private static SharedPreferences sp; - public static final Migration MIGRATION_0_1 = new Migration(0, 1) { + private static final Migration MIGRATION_0_1 = new Migration(0, 1) { @Override - public void migrate(final Context context) { + public void migrate(@NonNull final Context context) { // We changed the content of the dialog which opens when sharing a link to NewPipe // by removing the "open detail page" option. // Therefore, show the dialog once again to ensure users need to choose again and are @@ -44,9 +45,9 @@ public void migrate(final Context context) { } }; - public static final Migration MIGRATION_1_2 = new Migration(1, 2) { + private static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override - protected void migrate(final Context context) { + protected void migrate(@NonNull final Context context) { // The new application workflow introduced in #2907 allows minimizing videos // while playing to do other stuff within the app. // For an even better workflow, we minimize a stream when switching the app to play in @@ -63,9 +64,9 @@ protected void migrate(final Context context) { } }; - public static final Migration MIGRATION_2_3 = new Migration(2, 3) { + private static final Migration MIGRATION_2_3 = new Migration(2, 3) { @Override - protected void migrate(final Context context) { + protected void migrate(@NonNull final Context context) { // Storage Access Framework implementation was improved in #5415, allowing the modern // and standard way to access folders and files to be used consistently everywhere. // We reset the setting to its default value, i.e. "use SAF", since now there are no @@ -79,9 +80,9 @@ protected void migrate(final Context context) { } }; - public static final Migration MIGRATION_3_4 = new Migration(3, 4) { + private static final Migration MIGRATION_3_4 = new Migration(3, 4) { @Override - protected void migrate(final Context context) { + protected void migrate(@NonNull final Context context) { // Pull request #3546 added support for choosing the type of search suggestions to // show, replacing the on-off switch used before, so migrate the previous user choice @@ -108,9 +109,9 @@ protected void migrate(final Context context) { } }; - public static final Migration MIGRATION_4_5 = new Migration(4, 5) { + private static final Migration MIGRATION_4_5 = new Migration(4, 5) { @Override - protected void migrate(final Context context) { + protected void migrate(@NonNull final Context context) { final boolean brightness = sp.getBoolean("brightness_gesture_control", true); final boolean volume = sp.getBoolean("volume_gesture_control", true); @@ -144,10 +145,10 @@ protected void migrate(final Context context) { /** * Version number for preferences. Must be incremented every time a migration is necessary. */ - public static final int VERSION = 5; + private static final int VERSION = 5; - public static void initMigrations(final Context context, final boolean isFirstRun) { + public static void initMigrations(@NonNull final Context context, final boolean isFirstRun) { // setup migrations and check if there is something to do sp = PreferenceManager.getDefaultSharedPreferences(context); final String lastPrefVersionKey = context.getString(R.string.last_used_preferences_version); @@ -212,7 +213,7 @@ private boolean shouldMigrate(final int currentVersion) { return oldVersion >= currentVersion; } - protected abstract void migrate(Context context); + protected abstract void migrate(@NonNull Context context); } From 8b63b437d8542da898681230a683a92e7a50a7bc Mon Sep 17 00:00:00 2001 From: TobiGr Date: Tue, 18 Jul 2023 09:53:00 +0200 Subject: [PATCH 2/5] Disable media tunneling if the device is known for not supporting it Revert removing the Utils related to media tunneling. --- .../newpipe/settings/NewPipeSettings.java | 18 ++++++++ .../newpipe/settings/SettingMigrations.java | 14 ++++++- .../org/schabi/newpipe/util/DeviceUtils.java | 41 +++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java index 16df646f981..9e246574ef0 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java +++ b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java @@ -76,6 +76,10 @@ public static void initSettings(final Context context) { saveDefaultVideoDownloadDirectory(context); saveDefaultAudioDownloadDirectory(context); + + if (isFirstRun) { // NOSONAR: isFirstRun is never null + setMediaTunneling(context); + } } static void saveDefaultVideoDownloadDirectory(final Context context) { @@ -152,4 +156,18 @@ public static boolean showRemoteSearchSuggestions(final Context context, return showSearchSuggestions(context, sharedPreferences, R.string.show_remote_search_suggestions_key); } + + /** + * Check if device does not support media tunneling + * and disable that exoplayer feature if necessary. + * @see DeviceUtils#shouldSupportMediaTunneling() + * @param context + */ + public static void setMediaTunneling(@NonNull final Context context) { + if (!DeviceUtils.shouldSupportMediaTunneling()) { + PreferenceManager.getDefaultSharedPreferences(context).edit() + .putBoolean(context.getString(R.string.disable_media_tunneling_key), true) + .apply(); + } + } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java index bf691dc2850..8b8dddbade2 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java @@ -128,6 +128,17 @@ protected void migrate(@NonNull final Context context) { } }; + private static final Migration MIGRATION_5_6 = new Migration(5, 6) { + @Override + protected void migrate(@NonNull final Context context) { + // PR #8875 added a new settings page for exoplayer introducing a specific setting + // to disable media tunneling. However, media tunneling should be disabled by default + // for some devices, because they are known for not supporting media tunneling + // which can result in a black screen while playing videos. + NewPipeSettings.setMediaTunneling(context); + } + }; + /** * List of all implemented migrations. *

@@ -140,12 +151,13 @@ protected void migrate(@NonNull final Context context) { MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, + MIGRATION_5_6, }; /** * Version number for preferences. Must be incremented every time a migration is necessary. */ - private static final int VERSION = 5; + private static final int VERSION = 6; public static void initMigrations(@NonNull final Context context, final boolean isFirstRun) { diff --git a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java index f656c61446a..7111b8de9a5 100644 --- a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java @@ -36,6 +36,31 @@ public final class DeviceUtils { private static Boolean isTV = null; private static Boolean isFireTV = null; + /* + * Devices that do not support media tunneling + */ + + /** + * Formuler Z8 Pro, Z8, CC, Z Alpha, Z+ Neo. + */ + private static final boolean HI3798MV200 = Build.VERSION.SDK_INT == 24 + && Build.DEVICE.equals("Hi3798MV200"); + /** + * Zephir TS43UHD-2. + */ + private static final boolean CVT_MT5886_EU_1G = Build.VERSION.SDK_INT == 24 + && Build.DEVICE.equals("cvt_mt5886_eu_1g"); + /** + * Hilife TV. + */ + private static final boolean REALTEKATV = Build.VERSION.SDK_INT == 25 + && Build.DEVICE.equals("RealtekATV"); + /** + * Philips QM16XE. + */ + private static final boolean QM16XE_U = Build.VERSION.SDK_INT == 23 + && Build.DEVICE.equals("QM16XE_U"); + private DeviceUtils() { } @@ -224,4 +249,20 @@ public static int getWindowHeight(@NonNull final WindowManager windowManager) { return point.y; } } + + /** + * Some devices have broken tunneled video playback but claim to support it. + * See https://github.com/TeamNewPipe/NewPipe/issues/5911 + * @Note Add a new {@link org.schabi.newpipe.settings.SettingMigrations.Migration} which calls + * {@link org.schabi.newpipe.settings.NewPipeSettings#setMediaTunneling(Context)} + * when adding a new device to the method + * @return {@code false} if affected device; {@code true} otherwise + */ + public static boolean shouldSupportMediaTunneling() { + // Maintainers note: add a new SettingsMigration which calls + return !HI3798MV200 + && !CVT_MT5886_EU_1G + && !REALTEKATV + && !QM16XE_U; + } } From 1db73370a7219e64b472c77b57f9436c2abb4fcf Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sat, 29 Jul 2023 22:08:24 +0200 Subject: [PATCH 3/5] Ensure that imports handle disabling media tunneling correctly Store in preferences whether media tunneling was disabled automatically. Show info in ExoPlayer settings if media tunneling was disabled autmatically. --- .../settings/ContentSettingsFragment.java | 40 ++++++++++++++++++- .../settings/ContentSettingsManager.kt | 3 ++ .../settings/ExoPlayerSettingsFragment.java | 31 ++++++++++++++ .../newpipe/settings/NewPipeSettings.java | 2 + .../org/schabi/newpipe/util/DeviceUtils.java | 2 +- app/src/main/res/values/settings_keys.xml | 1 + app/src/main/res/values/strings.xml | 3 +- 7 files changed, 78 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 434056b208a..38a1fd8f8e8 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -15,6 +15,7 @@ import androidx.activity.result.ActivityResult; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; +import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; import androidx.preference.Preference; @@ -230,8 +231,11 @@ private void importDatabase(final StoredFileHelper file, final Uri importDataUri }) .setPositiveButton(R.string.ok, (dialog, which) -> { dialog.dismiss(); - manager.loadSharedPreferences(PreferenceManager - .getDefaultSharedPreferences(requireContext())); + final Context context = requireContext(); + final SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(context); + manager.loadSharedPreferences(prefs); + cleanImport(context, prefs); finishImport(importDataUri); }) .show(); @@ -243,6 +247,38 @@ private void importDatabase(final StoredFileHelper file, final Uri importDataUri } } + /** + * Remove settings that are not supposed to be imported on different devices + * and reset them to default values. + * @param context the context used for the import + * @param prefs the preferences used while running the import + */ + private void cleanImport(@NonNull final Context context, + @NonNull final SharedPreferences prefs) { + // Check if media tunnelling needs to be disabled automatically, + // if it was disabled automatically in the imported preferences. + final String tunnelingKey = context.getString(R.string.disable_media_tunneling_key); + final String automaticTunnelingKey = + context.getString(R.string.disabled_media_tunneling_automatically_key); + // R.string.disable_media_tunneling_key should always be true + // if R.string.disabled_media_tunneling_automatically_key equals 1, + // but we double check here just to be sure and to avoid regressions + // caused by possible later modification of the media tunneling functionality. + // R.string.disabled_media_tunneling_automatically_key == 0: + // automatic value overridden by user in settings + // R.string.disabled_media_tunneling_automatically_key == -1: not set + final boolean wasMediaTunnelingEnabledAutomatically = + prefs.getInt(automaticTunnelingKey, -1) == 1 + && prefs.getBoolean(tunnelingKey, false); + if (wasMediaTunnelingEnabledAutomatically) { + prefs.edit() + .putInt(automaticTunnelingKey, -1) + .putBoolean(tunnelingKey, false) + .apply(); + NewPipeSettings.setMediaTunneling(context); + } + } + /** * Save import path and restart system. * diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index 8adf6a64909..92be93a294c 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -67,6 +67,9 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { return ZipHelper.extractFileFromZip(file, fileLocator.settings.path, "newpipe.settings") } + /** + * Remove all shared preferences from the app and load the preferences supplied to the manager. + */ fun loadSharedPreferences(preferences: SharedPreferences) { try { val preferenceEditor = preferences.edit() diff --git a/app/src/main/java/org/schabi/newpipe/settings/ExoPlayerSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ExoPlayerSettingsFragment.java index 7e740f8698d..1cceea3361b 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ExoPlayerSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ExoPlayerSettingsFragment.java @@ -1,8 +1,14 @@ package org.schabi.newpipe.settings; +import android.content.SharedPreferences; import android.os.Bundle; import androidx.annotation.Nullable; +import androidx.preference.Preference; +import androidx.preference.PreferenceManager; +import androidx.preference.SwitchPreferenceCompat; + +import org.schabi.newpipe.R; public class ExoPlayerSettingsFragment extends BasePreferenceFragment { @@ -10,5 +16,30 @@ public class ExoPlayerSettingsFragment extends BasePreferenceFragment { public void onCreatePreferences(@Nullable final Bundle savedInstanceState, @Nullable final String rootKey) { addPreferencesFromResourceRegistry(); + + final String disableMediaTunnelingAutomaticallyKey = + getString(R.string.disabled_media_tunneling_automatically_key); + final SwitchPreferenceCompat disableMediaTunnelingPref = + (SwitchPreferenceCompat) requirePreference(R.string.disable_media_tunneling_key); + final SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(requireContext()); + final boolean mediaTunnelingAutomaticallyEnabled = + prefs.getInt(disableMediaTunnelingAutomaticallyKey, -1) == 1; + final String summaryText = getString(R.string.disable_media_tunneling_summary); + disableMediaTunnelingPref.setSummary(mediaTunnelingAutomaticallyEnabled + ? summaryText + getString(R.string.disable_media_tunneling_automatic_info) + : summaryText); + + disableMediaTunnelingPref.setOnPreferenceChangeListener((Preference p, Object enabled) -> { + if (Boolean.FALSE.equals(enabled)) { + PreferenceManager.getDefaultSharedPreferences(requireContext()) + .edit() + .putInt(disableMediaTunnelingAutomaticallyKey, 0) + .apply(); + // the info text might have been shown before + p.setSummary(R.string.disable_media_tunneling_summary); + } + return true; + }); } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java index 9e246574ef0..7057f0ec99d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java +++ b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java @@ -167,6 +167,8 @@ public static void setMediaTunneling(@NonNull final Context context) { if (!DeviceUtils.shouldSupportMediaTunneling()) { PreferenceManager.getDefaultSharedPreferences(context).edit() .putBoolean(context.getString(R.string.disable_media_tunneling_key), true) + .putInt(context.getString( + R.string.disabled_media_tunneling_automatically_key), 1) .apply(); } } diff --git a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java index 7111b8de9a5..111072a9650 100644 --- a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java @@ -255,7 +255,7 @@ public static int getWindowHeight(@NonNull final WindowManager windowManager) { * See https://github.com/TeamNewPipe/NewPipe/issues/5911 * @Note Add a new {@link org.schabi.newpipe.settings.SettingMigrations.Migration} which calls * {@link org.schabi.newpipe.settings.NewPipeSettings#setMediaTunneling(Context)} - * when adding a new device to the method + * when adding a new device to the method. * @return {@code false} if affected device; {@code true} otherwise */ public static boolean shouldSupportMediaTunneling() { diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index eebe29d8184..b2e2925f33f 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -1382,6 +1382,7 @@ exoplayer_settings_key disable_media_tunneling_key + disabled_media_tunneling_automatically_key use_exoplayer_decoder_fallback_key always_use_exoplayer_set_output_surface_workaround_key diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 75acedf9eed..e4fcdeedc83 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -480,7 +480,8 @@ Show original time ago on items Original texts from services will be visible in stream items Disable media tunneling - Disable media tunneling if you experience a black screen or stuttering on video playback + Disable media tunneling if you experience a black screen or stuttering on video playback. + Media tunneling was disabled by default on your device because your device model is known to not support it. Show image indicators Show Picasso colored ribbons on top of images indicating their source: red for network, blue for disk and green for memory Show \"Crash the player\" From 40d102fcb5f3424f94e6ea64e2db39357cb8be2b Mon Sep 17 00:00:00 2001 From: TobiGr Date: Tue, 18 Jul 2023 21:27:28 +0200 Subject: [PATCH 4/5] Disable media tunneling by default on new devices Sony BRAVIA_VH1, BRAVIA_VH2, BRAVIA_ATV2, BRAVIA_ATV3_4K Phillips 4K (O)LED TV (PH7M_EU_5596) Panasonic 4KTV-JUP (TX_50JXW834) Bouygtel4K (HMB9213NW) --- .../org/schabi/newpipe/util/DeviceUtils.java | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java index 111072a9650..096cf9523cc 100644 --- a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java @@ -36,10 +36,8 @@ public final class DeviceUtils { private static Boolean isTV = null; private static Boolean isFireTV = null; - /* - * Devices that do not support media tunneling - */ + // region: devices not supporting media tunneling /** * Formuler Z8 Pro, Z8, CC, Z Alpha, Z+ Neo. */ @@ -55,11 +53,53 @@ public final class DeviceUtils { */ private static final boolean REALTEKATV = Build.VERSION.SDK_INT == 25 && Build.DEVICE.equals("RealtekATV"); + /** + *

Phillips 4K (O)LED TV.

+ * Supports custom ROMs with different API levels + */ + private static final boolean PH7M_EU_5596 = Build.VERSION.SDK_INT >= 26 + && Build.DEVICE.equals("PH7M_EU_5596"); /** * Philips QM16XE. */ private static final boolean QM16XE_U = Build.VERSION.SDK_INT == 23 && Build.DEVICE.equals("QM16XE_U"); + /** + *

Sony Bravia VH1.

+ * Processor: MT5895 + */ + private static final boolean BRAVIA_VH1 = Build.VERSION.SDK_INT == 29 + && Build.DEVICE.equals("BRAVIA_VH1"); + /** + *

Sony Bravia VH2.

+ * This includes model A90J. + */ + private static final boolean BRAVIA_VH2 = Build.VERSION.SDK_INT == 29 + && Build.DEVICE.equals("BRAVIA_VH2"); + /** + *

Sony Bravia Android TV platform 2.

+ * Uses a MediaTek MT5891 (MT5596) SoC. + * @see + * https://github.com/CiNcH83/bravia_atv2 + */ + private static final boolean BRAVIA_ATV2 = Build.DEVICE.equals("BRAVIA_ATV2"); + /** + *

Sony Bravia Android TV platform 3 4K.

+ * Uses ARM MT5891 and a {@link #BRAVIA_ATV2} motherboard. + * @see + * https://browser.geekbench.com/v4/cpu/9101105 + */ + private static final boolean BRAVIA_ATV3_4K = Build.DEVICE.equals("BRAVIA_ATV3_4K"); + /** + * Panasonic 4KTV-JUP. + */ + private static final boolean TX_50JXW834 = Build.DEVICE.equals("TX_50JXW834"); + /** + *

Bouygtel4K / Bouygues Telecom Bbox 4K.

+ * Reported at https://github.com/TeamNewPipe/NewPipe/pull/10122#issuecomment-1638475769 + */ + private static final boolean HMB9213NW = Build.DEVICE.equals("HMB9213NW"); + // endregion private DeviceUtils() { } @@ -251,7 +291,7 @@ public static int getWindowHeight(@NonNull final WindowManager windowManager) { } /** - * Some devices have broken tunneled video playback but claim to support it. + *

Some devices have broken tunneled video playback but claim to support it.

* See https://github.com/TeamNewPipe/NewPipe/issues/5911 * @Note Add a new {@link org.schabi.newpipe.settings.SettingMigrations.Migration} which calls * {@link org.schabi.newpipe.settings.NewPipeSettings#setMediaTunneling(Context)} @@ -263,6 +303,13 @@ public static boolean shouldSupportMediaTunneling() { return !HI3798MV200 && !CVT_MT5886_EU_1G && !REALTEKATV - && !QM16XE_U; + && !QM16XE_U + && !BRAVIA_VH1 + && !BRAVIA_VH2 + && !BRAVIA_ATV2 // crash caused by exiting full screen + && !BRAVIA_ATV3_4K // crash caused by exiting full screen + && !PH7M_EU_5596 + && !TX_50JXW834 + && !HMB9213NW; // crash caused by exiting full screen } } From d6a1170ddb4bc67c5f008c334158eccc901b02e9 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Mon, 31 Jul 2023 21:34:20 +0200 Subject: [PATCH 5/5] Replace settings migration with automatic check for device blacklist version --- .../settings/ContentSettingsFragment.java | 4 +- .../settings/ExoPlayerSettingsFragment.java | 12 ++-- .../newpipe/settings/NewPipeSettings.java | 41 +++++++++++--- .../newpipe/settings/SettingMigrations.java | 17 +----- .../org/schabi/newpipe/util/DeviceUtils.java | 55 +++++++++++++------ app/src/main/res/values/settings_keys.xml | 1 + 6 files changed, 85 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 38a1fd8f8e8..ee34f01dd32 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -267,10 +267,10 @@ private void cleanImport(@NonNull final Context context, // R.string.disabled_media_tunneling_automatically_key == 0: // automatic value overridden by user in settings // R.string.disabled_media_tunneling_automatically_key == -1: not set - final boolean wasMediaTunnelingEnabledAutomatically = + final boolean wasMediaTunnelingDisabledAutomatically = prefs.getInt(automaticTunnelingKey, -1) == 1 && prefs.getBoolean(tunnelingKey, false); - if (wasMediaTunnelingEnabledAutomatically) { + if (wasMediaTunnelingDisabledAutomatically) { prefs.edit() .putInt(automaticTunnelingKey, -1) .putBoolean(tunnelingKey, false) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ExoPlayerSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ExoPlayerSettingsFragment.java index 1cceea3361b..14dd0c4093b 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ExoPlayerSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ExoPlayerSettingsFragment.java @@ -17,24 +17,24 @@ public void onCreatePreferences(@Nullable final Bundle savedInstanceState, @Nullable final String rootKey) { addPreferencesFromResourceRegistry(); - final String disableMediaTunnelingAutomaticallyKey = + final String disabledMediaTunnelingAutomaticallyKey = getString(R.string.disabled_media_tunneling_automatically_key); final SwitchPreferenceCompat disableMediaTunnelingPref = (SwitchPreferenceCompat) requirePreference(R.string.disable_media_tunneling_key); final SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(requireContext()); - final boolean mediaTunnelingAutomaticallyEnabled = - prefs.getInt(disableMediaTunnelingAutomaticallyKey, -1) == 1; + final boolean mediaTunnelingAutomaticallyDisabled = + prefs.getInt(disabledMediaTunnelingAutomaticallyKey, -1) == 1; final String summaryText = getString(R.string.disable_media_tunneling_summary); - disableMediaTunnelingPref.setSummary(mediaTunnelingAutomaticallyEnabled - ? summaryText + getString(R.string.disable_media_tunneling_automatic_info) + disableMediaTunnelingPref.setSummary(mediaTunnelingAutomaticallyDisabled + ? summaryText + " " + getString(R.string.disable_media_tunneling_automatic_info) : summaryText); disableMediaTunnelingPref.setOnPreferenceChangeListener((Preference p, Object enabled) -> { if (Boolean.FALSE.equals(enabled)) { PreferenceManager.getDefaultSharedPreferences(requireContext()) .edit() - .putInt(disableMediaTunnelingAutomaticallyKey, 0) + .putInt(disabledMediaTunnelingAutomaticallyKey, 0) .apply(); // the info text might have been shown before p.setSummary(R.string.disable_media_tunneling_summary); diff --git a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java index 7057f0ec99d..2cca0807270 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java +++ b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java @@ -1,5 +1,7 @@ package org.schabi.newpipe.settings; +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; + import android.content.Context; import android.content.SharedPreferences; import android.os.Build; @@ -15,8 +17,6 @@ import java.io.File; import java.util.Set; -import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; - /* * Created by k3b on 07.01.2016. * @@ -61,7 +61,7 @@ public static void initSettings(final Context context) { } // first run migrations, then setDefaultValues, since the latter requires the correct types - SettingMigrations.initMigrations(context, isFirstRun); + SettingMigrations.runMigrationsIfNeeded(context, isFirstRun); // readAgain is true so that if new settings are added their default value is set PreferenceManager.setDefaultValues(context, R.xml.main_settings, true); @@ -77,9 +77,7 @@ public static void initSettings(final Context context) { saveDefaultVideoDownloadDirectory(context); saveDefaultAudioDownloadDirectory(context); - if (isFirstRun) { // NOSONAR: isFirstRun is never null - setMediaTunneling(context); - } + disableMediaTunnelingIfNecessary(context, isFirstRun); } static void saveDefaultVideoDownloadDirectory(final Context context) { @@ -157,6 +155,28 @@ public static boolean showRemoteSearchSuggestions(final Context context, R.string.show_remote_search_suggestions_key); } + private static void disableMediaTunnelingIfNecessary(@NonNull final Context context, + final boolean isFirstRun) { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + final String disabledTunnelingKey = context.getString(R.string.disable_media_tunneling_key); + final String disabledTunnelingAutomaticallyKey = + context.getString(R.string.disabled_media_tunneling_automatically_key); + final String blacklistVersionKey = + context.getString(R.string.media_tunneling_device_blacklist_version); + + final int lastMediaTunnelingUpdate = prefs.getInt(blacklistVersionKey, 0); + final boolean wasDeviceBlacklistUpdated = + DeviceUtils.MEDIA_TUNNELING_DEVICE_BLACKLIST_VERSION != lastMediaTunnelingUpdate; + final boolean wasMediaTunnelingEnabledByUser = + prefs.getInt(disabledTunnelingAutomaticallyKey, -1) == 0 + && !prefs.getBoolean(disabledTunnelingKey, false); + + if (Boolean.TRUE.equals(isFirstRun) + || (wasDeviceBlacklistUpdated && !wasMediaTunnelingEnabledByUser)) { + setMediaTunneling(context); + } + } + /** * Check if device does not support media tunneling * and disable that exoplayer feature if necessary. @@ -164,12 +184,19 @@ public static boolean showRemoteSearchSuggestions(final Context context, * @param context */ public static void setMediaTunneling(@NonNull final Context context) { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); if (!DeviceUtils.shouldSupportMediaTunneling()) { - PreferenceManager.getDefaultSharedPreferences(context).edit() + prefs.edit() .putBoolean(context.getString(R.string.disable_media_tunneling_key), true) .putInt(context.getString( R.string.disabled_media_tunneling_automatically_key), 1) + .putInt(context.getString(R.string.media_tunneling_device_blacklist_version), + DeviceUtils.MEDIA_TUNNELING_DEVICE_BLACKLIST_VERSION) .apply(); + } else { + prefs.edit() + .putInt(context.getString(R.string.media_tunneling_device_blacklist_version), + DeviceUtils.MEDIA_TUNNELING_DEVICE_BLACKLIST_VERSION).apply(); } } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java index 8b8dddbade2..215caaa3894 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java @@ -128,17 +128,6 @@ protected void migrate(@NonNull final Context context) { } }; - private static final Migration MIGRATION_5_6 = new Migration(5, 6) { - @Override - protected void migrate(@NonNull final Context context) { - // PR #8875 added a new settings page for exoplayer introducing a specific setting - // to disable media tunneling. However, media tunneling should be disabled by default - // for some devices, because they are known for not supporting media tunneling - // which can result in a black screen while playing videos. - NewPipeSettings.setMediaTunneling(context); - } - }; - /** * List of all implemented migrations. *

@@ -151,16 +140,16 @@ protected void migrate(@NonNull final Context context) { MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, - MIGRATION_5_6, }; /** * Version number for preferences. Must be incremented every time a migration is necessary. */ - private static final int VERSION = 6; + private static final int VERSION = 5; - public static void initMigrations(@NonNull final Context context, final boolean isFirstRun) { + public static void runMigrationsIfNeeded(@NonNull final Context context, + final boolean isFirstRun) { // setup migrations and check if there is something to do sp = PreferenceManager.getDefaultSharedPreferences(context); final String lastPrefVersionKey = context.getString(R.string.last_used_preferences_version); diff --git a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java index 096cf9523cc..e9678c2b009 100644 --- a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java @@ -36,20 +36,32 @@ public final class DeviceUtils { private static Boolean isTV = null; private static Boolean isFireTV = null; + /** + *

The app version code that corresponds to the last update + * of the media tunneling device blacklist.

+ *

The value of this variable needs to be updated everytime a new device that does not + * support media tunneling to match the upcoming version code.

+ * @see #shouldSupportMediaTunneling() + */ + public static final int MEDIA_TUNNELING_DEVICE_BLACKLIST_VERSION = 994; - // region: devices not supporting media tunneling + // region: devices not supporting media tunneling / media tunneling blacklist /** - * Formuler Z8 Pro, Z8, CC, Z Alpha, Z+ Neo. + *

Formuler Z8 Pro, Z8, CC, Z Alpha, Z+ Neo.

+ *

Blacklist reason: black screen

+ *

Board: HiSilicon Hi3798MV200

*/ private static final boolean HI3798MV200 = Build.VERSION.SDK_INT == 24 && Build.DEVICE.equals("Hi3798MV200"); /** - * Zephir TS43UHD-2. + *

Zephir TS43UHD-2.

+ *

Blacklist reason: black screen

*/ private static final boolean CVT_MT5886_EU_1G = Build.VERSION.SDK_INT == 24 && Build.DEVICE.equals("cvt_mt5886_eu_1g"); /** * Hilife TV. + *

Blacklist reason: black screen

*/ private static final boolean REALTEKATV = Build.VERSION.SDK_INT == 25 && Build.DEVICE.equals("RealtekATV"); @@ -60,19 +72,23 @@ public final class DeviceUtils { private static final boolean PH7M_EU_5596 = Build.VERSION.SDK_INT >= 26 && Build.DEVICE.equals("PH7M_EU_5596"); /** - * Philips QM16XE. + *

Philips QM16XE.

+ *

Blacklist reason: black screen

*/ private static final boolean QM16XE_U = Build.VERSION.SDK_INT == 23 && Build.DEVICE.equals("QM16XE_U"); /** *

Sony Bravia VH1.

- * Processor: MT5895 + *

Processor: MT5895

+ *

Blacklist reason: fullscreen crash / stuttering

*/ private static final boolean BRAVIA_VH1 = Build.VERSION.SDK_INT == 29 && Build.DEVICE.equals("BRAVIA_VH1"); /** *

Sony Bravia VH2.

- * This includes model A90J. + *

Blacklist reason: fullscreen crash; this includes model A90J as reported in + * + * #9023

*/ private static final boolean BRAVIA_VH2 = Build.VERSION.SDK_INT == 29 && Build.DEVICE.equals("BRAVIA_VH2"); @@ -85,18 +101,22 @@ public final class DeviceUtils { private static final boolean BRAVIA_ATV2 = Build.DEVICE.equals("BRAVIA_ATV2"); /** *

Sony Bravia Android TV platform 3 4K.

- * Uses ARM MT5891 and a {@link #BRAVIA_ATV2} motherboard. + *

Uses ARM MT5891 and a {@link #BRAVIA_ATV2} motherboard.

+ * * @see * https://browser.geekbench.com/v4/cpu/9101105 */ private static final boolean BRAVIA_ATV3_4K = Build.DEVICE.equals("BRAVIA_ATV3_4K"); /** - * Panasonic 4KTV-JUP. + *

Panasonic 4KTV-JUP.

+ *

Blacklist reason: fullscreen crash

*/ private static final boolean TX_50JXW834 = Build.DEVICE.equals("TX_50JXW834"); /** *

Bouygtel4K / Bouygues Telecom Bbox 4K.

- * Reported at https://github.com/TeamNewPipe/NewPipe/pull/10122#issuecomment-1638475769 + *

Blacklist reason: black screen; reported at + * + * #10122

*/ private static final boolean HMB9213NW = Build.DEVICE.equals("HMB9213NW"); // endregion @@ -292,24 +312,27 @@ public static int getWindowHeight(@NonNull final WindowManager windowManager) { /** *

Some devices have broken tunneled video playback but claim to support it.

- * See https://github.com/TeamNewPipe/NewPipe/issues/5911 - * @Note Add a new {@link org.schabi.newpipe.settings.SettingMigrations.Migration} which calls - * {@link org.schabi.newpipe.settings.NewPipeSettings#setMediaTunneling(Context)} + *

This can cause a black video player surface while attempting to play a video or + * crashes while entering or exiting the full screen player. + * The issue effects Android TVs most commonly. + * See #5911 and + * #9023 for more info.

+ * @Note Update {@link #MEDIA_TUNNELING_DEVICE_BLACKLIST_VERSION} * when adding a new device to the method. * @return {@code false} if affected device; {@code true} otherwise */ public static boolean shouldSupportMediaTunneling() { - // Maintainers note: add a new SettingsMigration which calls + // Maintainers note: update MEDIA_TUNNELING_DEVICES_UPDATE_APP_VERSION_CODE return !HI3798MV200 && !CVT_MT5886_EU_1G && !REALTEKATV && !QM16XE_U && !BRAVIA_VH1 && !BRAVIA_VH2 - && !BRAVIA_ATV2 // crash caused by exiting full screen - && !BRAVIA_ATV3_4K // crash caused by exiting full screen + && !BRAVIA_ATV2 + && !BRAVIA_ATV3_4K && !PH7M_EU_5596 && !TX_50JXW834 - && !HMB9213NW; // crash caused by exiting full screen + && !HMB9213NW; } } diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index b2e2925f33f..a41d41fdbb3 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -1383,6 +1383,7 @@ exoplayer_settings_key disable_media_tunneling_key disabled_media_tunneling_automatically_key + media_tunneling_device_blacklist_version use_exoplayer_decoder_fallback_key always_use_exoplayer_set_output_surface_workaround_key