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 38a1fd8f8..ee34f01dd 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 @@ public class ContentSettingsFragment extends BasePreferenceFragment { // 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 1cceea336..14dd0c409 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 class ExoPlayerSettingsFragment extends BasePreferenceFragment { @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 7057f0ec9..2cca08072 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 org.schabi.newpipe.util.DeviceUtils; 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 final class NewPipeSettings { } // 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 final class NewPipeSettings { 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 final class NewPipeSettings { 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 final class NewPipeSettings { * @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 8b8dddbad..215caaa38 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 @@ public final class SettingMigrations { } }; - 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 @@ public final class SettingMigrations { 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 096cf9523..e9678c2b0 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; - - // region: devices not supporting media tunneling /** - * Formuler Z8 Pro, Z8, CC, Z Alpha, Z+ Neo. + *

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 / media tunneling blacklist + /** + *

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 final class DeviceUtils { /** *

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 b2e2925f3..a41d41fdb 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