diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ExternalDownloaderPreference.java b/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ExternalDownloaderPreference.java index 0454f1424..0d1923b9f 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ExternalDownloaderPreference.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ExternalDownloaderPreference.java @@ -23,16 +23,13 @@ import app.revanced.extension.shared.settings.StringSetting; import app.revanced.extension.shared.utils.ResourceUtils; import app.revanced.extension.shared.utils.Utils; -/** - * @noinspection all - */ +@SuppressWarnings("StringOperationCanBeSimplified") public class ExternalDownloaderPreference { private static final StringSetting settings = Settings.EXTERNAL_DOWNLOADER_PACKAGE_NAME; private static final String[] mEntries = ResourceUtils.getStringArray("revanced_external_downloader_label"); private static final String[] mEntryValues = ResourceUtils.getStringArray("revanced_external_downloader_package_name"); private static final String[] mWebsiteEntries = ResourceUtils.getStringArray("revanced_external_downloader_website"); - private static EditText mEditText; private static String packageName; private static int mClickedDialogEntryIndex; @@ -50,7 +47,7 @@ public class ExternalDownloaderPreference { }; public static void showDialog(Activity mActivity) { - packageName = settings.get().toString(); + packageName = settings.get(); mClickedDialogEntryIndex = Arrays.asList(mEntryValues).indexOf(packageName); AlertDialog.Builder builder = getDialogBuilder(mActivity); @@ -61,7 +58,7 @@ public class ExternalDownloaderPreference { TableRow row = new TableRow(mActivity); - mEditText = new EditText(mActivity); + EditText mEditText = new EditText(mActivity); mEditText.setText(packageName); mEditText.addTextChangedListener(textWatcher); mEditText.setTextSize(TypedValue.COMPLEX_UNIT_PT, 9); @@ -94,10 +91,8 @@ public class ExternalDownloaderPreference { if (mClickedDialogEntryIndex >= 0) { appName = mEntries[mClickedDialogEntryIndex].toString(); website = mWebsiteEntries[mClickedDialogEntryIndex].toString(); - return showToastOrOpenWebsites(mActivity, appName, packageName, website); - } else { - return showToastOrOpenWebsites(mActivity, appName, packageName, website); } + return showToastOrOpenWebsites(mActivity, appName, packageName, website); } private static boolean showToastOrOpenWebsites(Activity mActivity, String appName, String packageName, String website) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/utils/VideoUtils.java b/extensions/shared/src/main/java/app/revanced/extension/music/utils/VideoUtils.java index 9f2b6b22f..e83321b4d 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/utils/VideoUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/utils/VideoUtils.java @@ -53,7 +53,8 @@ public class VideoUtils extends IntentUtils { return; } - if (context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE) instanceof AudioManager audioManager) { + Context mContext = getContext(); + if (mContext != null && mContext.getApplicationContext().getSystemService(Context.AUDIO_SERVICE) instanceof AudioManager audioManager) { audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); } @@ -68,7 +69,10 @@ public class VideoUtils extends IntentUtils { public static void openInYouTubeMusic(@NonNull String songId) { final String url = String.format("vnd.youtube.music://%s", songId); - launchView(url, context.getPackageName()); + Context mContext = getContext(); + if (mContext != null) { + launchView(url, mContext.getPackageName()); + } } /** diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/components/FilterGroupList.java b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/components/FilterGroupList.java index 62e08a7e2..fd370dfe7 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/components/FilterGroupList.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/components/FilterGroupList.java @@ -1,5 +1,7 @@ package app.revanced.extension.shared.patches.components; +import android.annotation.SuppressLint; + import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; @@ -12,6 +14,7 @@ import java.util.function.Consumer; import app.revanced.extension.shared.utils.TrieSearch; +@SuppressLint("ObsoleteSdkInt") @SuppressWarnings("unused") public abstract class FilterGroupList> implements Iterable { diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/IntentUtils.java b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/IntentUtils.java index 6c15a67ee..df1088123 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/IntentUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/IntentUtils.java @@ -23,7 +23,8 @@ public class IntentUtils extends Utils { Context mContext = getActivity(); if (mContext == null) { // Utils context is the application context, and not an activity context. - mContext = context; + mContext = getContext(); + if (mContext == null) return; intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } mContext.startActivity(intent); diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java index 1db1f137e..dcfd46864 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java @@ -31,7 +31,7 @@ public class PackageUtils extends Utils { public static boolean isPackageEnabled(@NonNull String packageName) { try { - return context.getPackageManager().getApplicationInfo(packageName, 0).enabled; + return getContext().getPackageManager().getApplicationInfo(packageName, 0).enabled; } catch (PackageManager.NameNotFoundException ignored) { } @@ -43,7 +43,7 @@ public class PackageUtils extends Utils { } public static int getSmallestScreenWidthDp() { - return context.getResources().getConfiguration().smallestScreenWidthDp; + return getContext().getResources().getConfiguration().smallestScreenWidthDp; } // utils @@ -51,7 +51,7 @@ public class PackageUtils extends Utils { private static PackageInfo getPackageInfo() { try { final PackageManager packageManager = getPackageManager(); - final String packageName = context.getPackageName(); + final String packageName = getContext().getPackageName(); return isSDKAbove(33) ? packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0)) : packageManager.getPackageInfo(packageName, 0); @@ -63,7 +63,7 @@ public class PackageUtils extends Utils { @NonNull private static PackageManager getPackageManager() { - return context.getPackageManager(); + return getContext().getPackageManager(); } public static boolean isVersionToLessThan(@NonNull String compareVersion, @NonNull String targetVersion) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/ResourceUtils.java b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/ResourceUtils.java index e3252ef9a..3aaba81ce 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/ResourceUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/ResourceUtils.java @@ -8,9 +8,7 @@ import android.view.animation.AnimationUtils; import androidx.annotation.NonNull; -/** - * @noinspection ALL - */ +@SuppressWarnings({"unused", "deprecation", "DiscouragedApi"}) public class ResourceUtils extends Utils { private ResourceUtils() { diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java index 33154e8c8..6e50f65a6 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java @@ -53,9 +53,7 @@ import kotlin.text.Regex; public class Utils { private static WeakReference activityRef = new WeakReference<>(null); - - @SuppressLint("StaticFieldLeak") - public static Context context; + private static WeakReference contextRef = new WeakReference<>(null); protected Utils() { } // utility class @@ -276,15 +274,17 @@ public class Utils { } public static Context getContext() { - if (context == null) { + Context mContext = contextRef.get(); + if (mContext == null) { Logger.initializationException(Utils.class, "Context is null, returning null!", null); } - return context; + return mContext; } public static Resources getResources() { - if (context != null) { - return context.getResources(); + Context mContext = contextRef.get(); + if (mContext != null) { + return mContext.getResources(); } Activity mActivity = activityRef.get(); if (mActivity != null) { @@ -346,36 +346,17 @@ public class Utils { return; } - context = appContext; + // Must initially set context to check the app language. + contextRef = new WeakReference<>(appContext); + Logger.initializationInfo(Utils.class, "Set context: " + appContext); AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get(); if (language != AppLanguage.DEFAULT) { // Create a new context with the desired language. Configuration config = appContext.getResources().getConfiguration(); config.setLocale(language.getLocale()); - context = appContext.createConfigurationContext(config); + contextRef = new WeakReference<>(appContext.createConfigurationContext(config)); } - - // In some apps like TikTok, the Setting classes can load in weird orders due to cyclic class dependencies. - // Calling the regular printDebug method here can cause a Settings context null pointer exception, - // even though the context is already set before the call. - // - // The initialization logger methods do not directly or indirectly - // reference the Context or any Settings and are unaffected by this problem. - // - // Info level also helps debug if a patch hook is called before - // the context is set since debug logging is off by default. - StringBuilder sb = new StringBuilder(); - sb.append("Set context: "); - sb.append(appContext); - StackTraceElement[] stackTraceElement = Thread.currentThread().getStackTrace(); - if (stackTraceElement.length > 3) { - sb.append("\n"); - sb.append("Called from method: "); - sb.append(stackTraceElement[3]); - } - - Logger.initializationInfo(Utils.class, sb.toString()); } public static void setClipboard(@NonNull String text) { @@ -383,16 +364,17 @@ public class Utils { } public static void setClipboard(@NonNull String text, @Nullable String toastMessage) { - if (!(context.getSystemService(Context.CLIPBOARD_SERVICE) instanceof ClipboardManager clipboard)) - return; - android.content.ClipData clip = android.content.ClipData.newPlainText("ReVanced", text); - clipboard.setPrimaryClip(clip); + Context mContext = contextRef.get(); + if (mContext != null && mContext.getSystemService(Context.CLIPBOARD_SERVICE) instanceof ClipboardManager clipboardManager) { + android.content.ClipData clip = android.content.ClipData.newPlainText("ReVanced", text); + clipboardManager.setPrimaryClip(clip); - // Do not show a toast if using Android 13+ as it shows it's own toast. - // But if the user copied with a timestamp then show a toast. - // Unfortunately this will show 2 toasts on Android 13+, but no way around this. - if (isSDKAbove(33) || toastMessage == null) return; - showToastShort(toastMessage); + // Do not show a toast if using Android 13+ as it shows it's own toast. + // But if the user copied with a timestamp then show a toast. + // Unfortunately this will show 2 toasts on Android 13+, but no way around this. + if (isSDKAbove(33) || toastMessage == null) return; + showToastShort(toastMessage); + } } public static String getFormattedTimeStamp(long videoTime) { @@ -534,11 +516,21 @@ public class Utils { } public static int dpToPx(float dp) { - return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); + Context mContext = contextRef.get(); + if (mContext == null) { + return (int) dp; + } else { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources().getDisplayMetrics()); + } } public static int dpToPx(int dp) { - return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); + Context mContext = contextRef.get(); + if (mContext == null) { + return dp; + } else { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources().getDisplayMetrics()); + } } /** @@ -558,18 +550,20 @@ public class Utils { private static void showToast(@NonNull String messageToToast, int toastDuration) { Objects.requireNonNull(messageToToast); runOnMainThreadNowOrLater(() -> { - if (context == null) { - Logger.initializationException(Utils.class, "Cannot show toast (context is null): " + messageToToast, null); - } else { - Logger.printDebug(() -> "Showing toast: " + messageToToast); - Toast.makeText(context, messageToToast, toastDuration).show(); - } - } - ); + Context mContext = contextRef.get(); + if (mContext == null) { + Logger.initializationException(Utils.class, "Cannot show toast (context is null): " + messageToToast, null); + } else { + Logger.printDebug(() -> "Showing toast: " + messageToToast); + Toast.makeText(mContext, messageToToast, toastDuration).show(); + } + }); } public static boolean isLandscapeOrientation() { - final int orientation = context.getResources().getConfiguration().orientation; + Context mContext = contextRef.get(); + if (mContext == null) return false; + final int orientation = mContext.getResources().getConfiguration().orientation; return orientation == Configuration.ORIENTATION_LANDSCAPE; } @@ -660,7 +654,8 @@ public class Utils { @SuppressLint("MissingPermission") // permission already included in YouTube public static NetworkType getNetworkType() { - if (context == null || !(context.getSystemService(Context.CONNECTIVITY_SERVICE) instanceof ConnectivityManager cm)) + Context mContext = contextRef.get(); + if (mContext == null || !(mContext.getSystemService(Context.CONNECTIVITY_SERVICE) instanceof ConnectivityManager cm)) return NetworkType.NONE; final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java index 84d2ceaa5..4623708fc 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/components/AdsFilter.java @@ -55,6 +55,7 @@ public final class AdsFilter extends Filter { // "video_display_button_group_layout" // "video_display_carousel_button_group_layout" // "video_display_full_buttoned_layout" + // "video_display_full_buttoned_short_dr_layout" // "video_display_full_layout" // "video_display_full_layout.eml" "video_display_", diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java index cf55b9b11..68f364829 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java @@ -170,7 +170,8 @@ public class VideoUtils extends IntentUtils { * Pause the media by changing audio focus. */ public static void pauseMedia() { - if (context != null && context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE) instanceof AudioManager audioManager) { + Context mContext = getContext(); + if (mContext != null && mContext.getApplicationContext().getSystemService(Context.AUDIO_SERVICE) instanceof AudioManager audioManager) { audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); } }