From cb384b591f73e6982d94802de73f2fca7cf1bb6c Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 29 Mar 2024 19:40:56 +0100 Subject: [PATCH 01/13] refactor: Name methods and properties correctly --- .../integrations/shared/GmsCoreSupport.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index 35a8beada7..12daec060f 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -1,10 +1,12 @@ package app.revanced.integrations.shared; import android.app.SearchManager; +import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; +import android.os.PowerManager; import androidx.annotation.RequiresApi; import java.net.MalformedURLException; @@ -18,11 +20,11 @@ */ public class GmsCoreSupport { private static final String GMS_CORE_PACKAGE_NAME - = getGmsCoreVendor() + ".android.gms"; + = getGmsCoreVendorGroupId() + ".android.gms"; + private static final Uri GMS_CORE_PROVIDER + = Uri.parse("content://" + getGmsCoreVendorGroupId() + ".android.gsf.gservices/prefix"); private static final String DONT_KILL_MY_APP_LINK = "https://dontkillmyapp.com"; - private static final Uri GMS_CORE_PROVIDER - = Uri.parse("content://" + getGmsCoreVendor() + ".android.gsf.gservices/prefix"); private static void open(String queryOrLink, String message) { Utils.showToastLong(message); @@ -56,7 +58,6 @@ public static void checkAvailability() { } catch (PackageManager.NameNotFoundException exception) { Logger.printInfo(() -> "GmsCore was not found", exception); open(getGmsCoreDownload(), str("gms_core_not_installed_warning")); - return; } try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { @@ -70,18 +71,18 @@ public static void checkAvailability() { } private static String getGmsCoreDownload() { - final var vendor = getGmsCoreVendor(); + final var vendorGroupId = getGmsCoreVendorGroupId(); //noinspection SwitchStatementWithTooFewBranches - switch (vendor) { + switch (vendorGroupId) { case "app.revanced": return "https://github.com/revanced/gmscore/releases/latest"; default: - return vendor + ".android.gms"; + return vendorGroupId + ".android.gms"; } } // Modified by a patch. Do not touch. - private static String getGmsCoreVendor() { + private static String getGmsCoreVendorGroupId() { return "app.revanced"; } } From d24258b580497e8140778a186288f9cb3dc96fa2 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 29 Mar 2024 19:44:02 +0100 Subject: [PATCH 02/13] feat(YouTube - GmsCore): Require ignoring battery optimizations --- .../integrations/shared/GmsCoreSupport.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index 12daec060f..c9a0a006ef 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -53,18 +53,27 @@ private static void open(String queryOrLink, String message) { public static void checkAvailability() { var context = Objects.requireNonNull(Utils.getContext()); + // Check, if GmsCore is installed. try { context.getPackageManager().getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); } catch (PackageManager.NameNotFoundException exception) { - Logger.printInfo(() -> "GmsCore was not found", exception); + Logger.printDebug(() -> "GmsCore was not found"); open(getGmsCoreDownload(), str("gms_core_not_installed_warning")); } - try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { - if (client != null) return; + // Check, if GmsCore is whitelisted from battery optimizations. + var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + if (!powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME)) { + Logger.printDebug(() -> "GmsCore is not whitelisted from battery optimizations"); + open(DONT_KILL_MY_APP_LINK, str("gms_core_not_whitelisted_warning")); + } - Logger.printInfo(() -> "GmsCore is not running in the background"); - open(DONT_KILL_MY_APP_LINK, str("gms_core_not_running_warning")); + // Check, if GmsCore is running in the background. + try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { + if (client == null) { + Logger.printDebug(() -> "GmsCore is not running in the background"); + open(DONT_KILL_MY_APP_LINK, str("gms_core_not_whitelisted_warning")); + } } catch (Exception ex) { Logger.printException(() -> "Could not check GmsCore background task", ex); } From 194cff83a707506d9586e87ba17f90eaf8226623 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 30 Mar 2024 01:18:25 +0400 Subject: [PATCH 03/13] fix: Show a dialog --- .../integrations/shared/GmsCoreSupport.java | 72 +++++++++++++------ 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index c9a0a006ef..25e2dfe762 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -1,5 +1,7 @@ package app.revanced.integrations.shared; +import android.app.Activity; +import android.app.AlertDialog; import android.app.SearchManager; import android.content.Context; import android.content.Intent; @@ -7,6 +9,8 @@ import android.net.Uri; import android.os.Build; import android.os.PowerManager; + +import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import java.net.MalformedURLException; @@ -26,9 +30,7 @@ public class GmsCoreSupport { private static final String DONT_KILL_MY_APP_LINK = "https://dontkillmyapp.com"; - private static void open(String queryOrLink, String message) { - Utils.showToastLong(message); - + private static void open(String queryOrLink) { Intent intent; try { // Check if queryOrLink is a valid URL. @@ -50,32 +52,60 @@ private static void open(String queryOrLink, String message) { * Injection point. */ @RequiresApi(api = Build.VERSION_CODES.N) - public static void checkAvailability() { - var context = Objects.requireNonNull(Utils.getContext()); - - // Check, if GmsCore is installed. + public static void checkGmsInstalled(Activity activity) { try { - context.getPackageManager().getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); + // verify GmsCore is installed. + PackageManager manager = activity.getPackageManager(); + manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); } catch (PackageManager.NameNotFoundException exception) { Logger.printDebug(() -> "GmsCore was not found"); - open(getGmsCoreDownload(), str("gms_core_not_installed_warning")); + Utils.showToastLong(str("gms_core_not_installed_warning")); + open(getGmsCoreDownload()); + } catch (Exception ex) { + Logger.printException(() -> "checkAvailability failure", ex); } + } - // Check, if GmsCore is whitelisted from battery optimizations. - var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - if (!powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME)) { - Logger.printDebug(() -> "GmsCore is not whitelisted from battery optimizations"); - open(DONT_KILL_MY_APP_LINK, str("gms_core_not_whitelisted_warning")); - } + private static void showDoNotKillMyAppDialog(Context context, String messageKey) { + // Use a delay to allow the activity to finish initializing. + // Otherwise if device is in dark mode the dialog is missing a dark mode color scheme. + Utils.runOnMainThreadDelayed(() -> { + new AlertDialog.Builder(context) + .setTitle(str("gms_core_not_whitelisted_title")) + .setMessage(str(messageKey)) + .setPositiveButton(android.R.string.ok, (dialog, id) -> { + open(DONT_KILL_MY_APP_LINK); + System.exit(0); + }) + // Do not use .setCancelable(), so if something is wrong + // the user can use back button to dismiss the dialog (without shutting down). + .show(); + }, 100); + } + + /** + * Injection point. + */ + @RequiresApi(api = Build.VERSION_CODES.N) + public static void checkGmsWhitelisted(Activity context) { + try { + // Check, if GmsCore is whitelisted from battery optimizations. + var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + if (!powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME)) { + Logger.printDebug(() -> "GmsCore is not whitelisted from battery optimizations"); + showDoNotKillMyAppDialog(context, "gms_core_not_whitelisted_using_battery_optimizations_message"); + return; + } - // Check, if GmsCore is running in the background. - try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { - if (client == null) { - Logger.printDebug(() -> "GmsCore is not running in the background"); - open(DONT_KILL_MY_APP_LINK, str("gms_core_not_whitelisted_warning")); + // Check, if GmsCore is running in the background. + try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { + if (client == null) { + Logger.printDebug(() -> "GmsCore is not running in the background"); + showDoNotKillMyAppDialog(context, "gms_core_not_whitelisted_not_allowed_in_background_message"); + } } } catch (Exception ex) { - Logger.printException(() -> "Could not check GmsCore background task", ex); + Logger.printException(() -> "checkGmsWhitelisted failure", ex); } } From 893adb04de1ecbd27e4b9fb3100a9c376b160a08 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 29 Mar 2024 22:39:00 +0100 Subject: [PATCH 04/13] Add icon and make uncancellable --- .../java/app/revanced/integrations/shared/GmsCoreSupport.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index 25e2dfe762..bc772f5e20 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -71,12 +71,14 @@ private static void showDoNotKillMyAppDialog(Context context, String messageKey) // Otherwise if device is in dark mode the dialog is missing a dark mode color scheme. Utils.runOnMainThreadDelayed(() -> { new AlertDialog.Builder(context) + .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(str("gms_core_not_whitelisted_title")) .setMessage(str(messageKey)) .setPositiveButton(android.R.string.ok, (dialog, id) -> { open(DONT_KILL_MY_APP_LINK); System.exit(0); }) + .setCancelable(false) // Do not use .setCancelable(), so if something is wrong // the user can use back button to dismiss the dialog (without shutting down). .show(); From 2026ffd2f363cc359342b154cf63a5b9370d617a Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 29 Mar 2024 22:39:19 +0100 Subject: [PATCH 05/13] Refactor method names --- .../revanced/integrations/shared/GmsCoreSupport.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index bc772f5e20..d9ff57a110 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -9,13 +9,10 @@ import android.net.Uri; import android.os.Build; import android.os.PowerManager; - -import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import java.net.MalformedURLException; import java.net.URL; -import java.util.Objects; import static app.revanced.integrations.shared.StringRef.str; @@ -52,9 +49,9 @@ private static void open(String queryOrLink) { * Injection point. */ @RequiresApi(api = Build.VERSION_CODES.N) - public static void checkGmsInstalled(Activity activity) { + public static void checkGmsCoreInstalled(Activity activity) { try { - // verify GmsCore is installed. + // Verify, GmsCore is installed. PackageManager manager = activity.getPackageManager(); manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); } catch (PackageManager.NameNotFoundException exception) { @@ -68,7 +65,7 @@ public static void checkGmsInstalled(Activity activity) { private static void showDoNotKillMyAppDialog(Context context, String messageKey) { // Use a delay to allow the activity to finish initializing. - // Otherwise if device is in dark mode the dialog is missing a dark mode color scheme. + // Otherwise, if device is in dark mode the dialog is missing a dark mode color scheme. Utils.runOnMainThreadDelayed(() -> { new AlertDialog.Builder(context) .setIcon(android.R.drawable.ic_dialog_alert) @@ -89,7 +86,7 @@ private static void showDoNotKillMyAppDialog(Context context, String messageKey) * Injection point. */ @RequiresApi(api = Build.VERSION_CODES.N) - public static void checkGmsWhitelisted(Activity context) { + public static void checkGmsCoreWhitelisted(Activity context) { try { // Check, if GmsCore is whitelisted from battery optimizations. var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); From 1bf52a641abc358ef466a3f6c45bfeacb2892a74 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 30 Mar 2024 02:40:35 +0400 Subject: [PATCH 06/13] fix: Work around for Announcements showing https error at the same time as 'gms not installed' dialog. --- .../app/revanced/integrations/shared/GmsCoreSupport.java | 9 +++++++++ .../patches/announcements/AnnouncementsPatch.java | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index d9ff57a110..71a226e039 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -27,6 +27,15 @@ public class GmsCoreSupport { private static final String DONT_KILL_MY_APP_LINK = "https://dontkillmyapp.com"; + private static volatile boolean gmsIsNotInstalled; + + /** + * If GmsCore is not installed. + */ + public static boolean gmsIsNotInstalled() { + return gmsIsNotInstalled; + } + private static void open(String queryOrLink) { Intent intent; try { diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java index 865b13cf10..f89327f79a 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java @@ -6,6 +6,8 @@ import android.text.method.LinkMovementMethod; import android.widget.TextView; import androidx.annotation.RequiresApi; + +import app.revanced.integrations.shared.GmsCoreSupport; import app.revanced.integrations.shared.Logger; import app.revanced.integrations.shared.Utils; import app.revanced.integrations.youtube.patches.announcements.requests.AnnouncementsRoutes; @@ -35,6 +37,12 @@ public static void showAnnouncement(final Activity context) { // Check if there is internet connection if (!Utils.isNetworkConnected()) return; + // If GmsCore is not installed, the https call will always fail with a security exception. + if (GmsCoreSupport.gmsIsNotInstalled()) { + Logger.printDebug(() -> "GmsCore not installed. Skipping announcement check"); + return; + } + Utils.runOnBackgroundThread(() -> { try { HttpURLConnection connection = AnnouncementsRoutes.getAnnouncementsConnectionFromRoute( From 83da57f98e331e641fd2ffa33cae1bc929fd319d Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 30 Mar 2024 02:42:49 +0400 Subject: [PATCH 07/13] fix: Show a dialog for 'GmsCore not found' --- .../integrations/shared/GmsCoreSupport.java | 68 ++++++++++--------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index 71a226e039..e114682f3c 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -54,39 +54,20 @@ private static void open(String queryOrLink) { System.exit(0); } - /** - * Injection point. - */ - @RequiresApi(api = Build.VERSION_CODES.N) - public static void checkGmsCoreInstalled(Activity activity) { - try { - // Verify, GmsCore is installed. - PackageManager manager = activity.getPackageManager(); - manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); - } catch (PackageManager.NameNotFoundException exception) { - Logger.printDebug(() -> "GmsCore was not found"); - Utils.showToastLong(str("gms_core_not_installed_warning")); - open(getGmsCoreDownload()); - } catch (Exception ex) { - Logger.printException(() -> "checkAvailability failure", ex); - } - } - - private static void showDoNotKillMyAppDialog(Context context, String messageKey) { + private static void showDoNotKillMyAppDialog(Context context, String messageKey, String link) { // Use a delay to allow the activity to finish initializing. // Otherwise, if device is in dark mode the dialog is missing a dark mode color scheme. Utils.runOnMainThreadDelayed(() -> { new AlertDialog.Builder(context) .setIcon(android.R.drawable.ic_dialog_alert) - .setTitle(str("gms_core_not_whitelisted_title")) + .setTitle(str("gms_core_dialog_title")) .setMessage(str(messageKey)) - .setPositiveButton(android.R.string.ok, (dialog, id) -> { - open(DONT_KILL_MY_APP_LINK); - System.exit(0); + .setPositiveButton(str("gms_core_dialog_ok_button_text"), (dialog, id) -> { + open(link); }) - .setCancelable(false) - // Do not use .setCancelable(), so if something is wrong - // the user can use back button to dismiss the dialog (without shutting down). + // Manually allow using the back button to dismiss the dialog with the back button, + // if troubleshooting and somehow the Gms verification checks always fail. + .setCancelable(true) .show(); }, 100); } @@ -95,25 +76,48 @@ private static void showDoNotKillMyAppDialog(Context context, String messageKey) * Injection point. */ @RequiresApi(api = Build.VERSION_CODES.N) - public static void checkGmsCoreWhitelisted(Activity context) { + public static void checkGmsCore(Activity context) { try { - // Check, if GmsCore is whitelisted from battery optimizations. + // Verify GmsCore is installed. + try { + PackageManager manager = context.getPackageManager(); + manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); + } catch (PackageManager.NameNotFoundException exception) { + Logger.printDebug(() -> "GmsCore was not found"); + gmsIsNotInstalled = true; + showDoNotKillMyAppDialog( + context, + "gms_core_not_installed_message", + getGmsCoreDownload() + ); + return; + } + + // Check if GmsCore is whitelisted from battery optimizations. var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (!powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME)) { Logger.printDebug(() -> "GmsCore is not whitelisted from battery optimizations"); - showDoNotKillMyAppDialog(context, "gms_core_not_whitelisted_using_battery_optimizations_message"); + showDoNotKillMyAppDialog( + context, + "gms_core_not_whitelisted_using_battery_optimizations_message", + DONT_KILL_MY_APP_LINK + ); return; } - // Check, if GmsCore is running in the background. + // Check if GmsCore is running in the background. try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { if (client == null) { Logger.printDebug(() -> "GmsCore is not running in the background"); - showDoNotKillMyAppDialog(context, "gms_core_not_whitelisted_not_allowed_in_background_message"); + showDoNotKillMyAppDialog( + context, + "gms_core_not_whitelisted_not_allowed_in_background_message", + DONT_KILL_MY_APP_LINK + ); } } } catch (Exception ex) { - Logger.printException(() -> "checkGmsWhitelisted failure", ex); + Logger.printException(() -> "checkGmsCore failure", ex); } } From 15c9f739b0ecb905cb9a3362079d86c3c1ff3f0d Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 30 Mar 2024 03:14:00 +0400 Subject: [PATCH 08/13] fixing YTMusic --- .../integrations/shared/GmsCoreSupport.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index e114682f3c..1e9f619849 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -50,13 +50,13 @@ private static void open(String queryOrLink) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Utils.getContext().startActivity(intent); - // Gracefully exit, otherwise without Gms the app crashes and Android can nag the user. + // Gracefully exit, otherwise the broken app will continue to run. System.exit(0); } private static void showDoNotKillMyAppDialog(Context context, String messageKey, String link) { // Use a delay to allow the activity to finish initializing. - // Otherwise, if device is in dark mode the dialog is missing a dark mode color scheme. + // Otherwise, if device is in dark mode the dialog is shown with wrong color scheme. Utils.runOnMainThreadDelayed(() -> { new AlertDialog.Builder(context) .setIcon(android.R.drawable.ic_dialog_alert) @@ -76,17 +76,17 @@ private static void showDoNotKillMyAppDialog(Context context, String messageKey, * Injection point. */ @RequiresApi(api = Build.VERSION_CODES.N) - public static void checkGmsCore(Activity context) { + public static void checkGmsCore(Context activityContext) { try { // Verify GmsCore is installed. try { - PackageManager manager = context.getPackageManager(); + PackageManager manager = activityContext.getPackageManager(); manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); } catch (PackageManager.NameNotFoundException exception) { Logger.printDebug(() -> "GmsCore was not found"); gmsIsNotInstalled = true; showDoNotKillMyAppDialog( - context, + activityContext, "gms_core_not_installed_message", getGmsCoreDownload() ); @@ -94,11 +94,11 @@ public static void checkGmsCore(Activity context) { } // Check if GmsCore is whitelisted from battery optimizations. - var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + var powerManager = (PowerManager) activityContext.getSystemService(Context.POWER_SERVICE); if (!powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME)) { Logger.printDebug(() -> "GmsCore is not whitelisted from battery optimizations"); showDoNotKillMyAppDialog( - context, + activityContext, "gms_core_not_whitelisted_using_battery_optimizations_message", DONT_KILL_MY_APP_LINK ); @@ -106,11 +106,11 @@ public static void checkGmsCore(Activity context) { } // Check if GmsCore is running in the background. - try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { + try (var client = activityContext.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { if (client == null) { Logger.printDebug(() -> "GmsCore is not running in the background"); showDoNotKillMyAppDialog( - context, + activityContext, "gms_core_not_whitelisted_not_allowed_in_background_message", DONT_KILL_MY_APP_LINK ); From b423ed778066f4f29cef6f59182155688a06f93a Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 30 Mar 2024 03:52:20 +0400 Subject: [PATCH 09/13] Finish fixing YT Music --- .../integrations/shared/GmsCoreSupport.java | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index 1e9f619849..2d5dd4a198 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -54,14 +54,25 @@ private static void open(String queryOrLink) { System.exit(0); } - private static void showDoNotKillMyAppDialog(Context context, String messageKey, String link) { + private static void showToastOrDialog(Context context, String toastMessageKey, String dialogMessageKey, String link) { + if (!(context instanceof Activity)) { + // Context is for the application and cannot show a dialog using it. + // This situation only occurs for YT Music. + // Of note: Even if the context was for an Activity, + // YT Music cannot show a dialog if Gms is not installed + // because without Gms it crashes before the app can finish initializing. + Utils.showToastLong(str(toastMessageKey)); + open(link); + return; + } + // Use a delay to allow the activity to finish initializing. // Otherwise, if device is in dark mode the dialog is shown with wrong color scheme. Utils.runOnMainThreadDelayed(() -> { new AlertDialog.Builder(context) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(str("gms_core_dialog_title")) - .setMessage(str(messageKey)) + .setMessage(str(dialogMessageKey)) .setPositiveButton(str("gms_core_dialog_ok_button_text"), (dialog, id) -> { open(link); }) @@ -76,44 +87,41 @@ private static void showDoNotKillMyAppDialog(Context context, String messageKey, * Injection point. */ @RequiresApi(api = Build.VERSION_CODES.N) - public static void checkGmsCore(Context activityContext) { + public static void checkGmsCore(Context context) { try { // Verify GmsCore is installed. try { - PackageManager manager = activityContext.getPackageManager(); + PackageManager manager = context.getPackageManager(); manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); } catch (PackageManager.NameNotFoundException exception) { Logger.printDebug(() -> "GmsCore was not found"); gmsIsNotInstalled = true; - showDoNotKillMyAppDialog( - activityContext, - "gms_core_not_installed_message", - getGmsCoreDownload() - ); + showToastOrDialog(context, + "gms_core_toast_not_installed_message", + "gms_core_dialog_not_installed_message", + getGmsCoreDownload()); return; } // Check if GmsCore is whitelisted from battery optimizations. - var powerManager = (PowerManager) activityContext.getSystemService(Context.POWER_SERVICE); + var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); if (!powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME)) { Logger.printDebug(() -> "GmsCore is not whitelisted from battery optimizations"); - showDoNotKillMyAppDialog( - activityContext, - "gms_core_not_whitelisted_using_battery_optimizations_message", - DONT_KILL_MY_APP_LINK - ); + showToastOrDialog(context, + "gms_core_toast_not_whitelisted_message", + "gms_core_dialog_not_whitelisted_using_battery_optimizations_message", + DONT_KILL_MY_APP_LINK); return; } // Check if GmsCore is running in the background. - try (var client = activityContext.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { + try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { if (client == null) { Logger.printDebug(() -> "GmsCore is not running in the background"); - showDoNotKillMyAppDialog( - activityContext, - "gms_core_not_whitelisted_not_allowed_in_background_message", - DONT_KILL_MY_APP_LINK - ); + showToastOrDialog(context, + "gms_core_toast_not_whitelisted_message", + "gms_core_dialog_not_whitelisted_not_allowed_in_background_message", + DONT_KILL_MY_APP_LINK); } } } catch (Exception ex) { From 18224b86c26311258bcaa7980f0553eac81d9b7f Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 30 Mar 2024 03:17:51 +0100 Subject: [PATCH 10/13] Renaming/refactor --- .../integrations/shared/GmsCoreSupport.java | 19 ++++++++++--------- .../announcements/AnnouncementsPatch.java | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index 2d5dd4a198..762efe4a29 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -27,13 +27,13 @@ public class GmsCoreSupport { private static final String DONT_KILL_MY_APP_LINK = "https://dontkillmyapp.com"; - private static volatile boolean gmsIsNotInstalled; + private static volatile boolean gmsCoreIsNotInstalled; /** * If GmsCore is not installed. */ - public static boolean gmsIsNotInstalled() { - return gmsIsNotInstalled; + public static boolean gmsCoreIsNotInstalled() { + return gmsCoreIsNotInstalled; } private static void open(String queryOrLink) { @@ -57,10 +57,11 @@ private static void open(String queryOrLink) { private static void showToastOrDialog(Context context, String toastMessageKey, String dialogMessageKey, String link) { if (!(context instanceof Activity)) { // Context is for the application and cannot show a dialog using it. - // This situation only occurs for YT Music. - // Of note: Even if the context was for an Activity, - // YT Music cannot show a dialog if Gms is not installed - // because without Gms it crashes before the app can finish initializing. + // Of note: + // This situation also occurs for YT Music. + // Even if the context was for an Activity, + // YT Music cannot show a dialog if GmsCore is not installed + // because without GmsCore it crashes before the app can finish initializing. Utils.showToastLong(str(toastMessageKey)); open(link); return; @@ -77,7 +78,7 @@ private static void showToastOrDialog(Context context, String toastMessageKey, S open(link); }) // Manually allow using the back button to dismiss the dialog with the back button, - // if troubleshooting and somehow the Gms verification checks always fail. + // if troubleshooting and somehow the GmsCore verification checks always fail. .setCancelable(true) .show(); }, 100); @@ -95,7 +96,7 @@ public static void checkGmsCore(Context context) { manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); } catch (PackageManager.NameNotFoundException exception) { Logger.printDebug(() -> "GmsCore was not found"); - gmsIsNotInstalled = true; + gmsCoreIsNotInstalled = true; showToastOrDialog(context, "gms_core_toast_not_installed_message", "gms_core_dialog_not_installed_message", diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java index f89327f79a..c7f95ecaf7 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java @@ -38,7 +38,7 @@ public static void showAnnouncement(final Activity context) { if (!Utils.isNetworkConnected()) return; // If GmsCore is not installed, the https call will always fail with a security exception. - if (GmsCoreSupport.gmsIsNotInstalled()) { + if (GmsCoreSupport.gmsCoreIsNotInstalled()) { Logger.printDebug(() -> "GmsCore not installed. Skipping announcement check"); return; } From 30bea71771dfd400bde74144acadb23e777b8584 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 30 Mar 2024 11:54:27 +0400 Subject: [PATCH 11/13] fix: Use a toast for 'Gms not installed' --- .../integrations/shared/GmsCoreSupport.java | 23 ++++--------------- .../announcements/AnnouncementsPatch.java | 6 ----- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index 762efe4a29..a38e48cb44 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -27,15 +27,6 @@ public class GmsCoreSupport { private static final String DONT_KILL_MY_APP_LINK = "https://dontkillmyapp.com"; - private static volatile boolean gmsCoreIsNotInstalled; - - /** - * If GmsCore is not installed. - */ - public static boolean gmsCoreIsNotInstalled() { - return gmsCoreIsNotInstalled; - } - private static void open(String queryOrLink) { Intent intent; try { @@ -57,11 +48,6 @@ private static void open(String queryOrLink) { private static void showToastOrDialog(Context context, String toastMessageKey, String dialogMessageKey, String link) { if (!(context instanceof Activity)) { // Context is for the application and cannot show a dialog using it. - // Of note: - // This situation also occurs for YT Music. - // Even if the context was for an Activity, - // YT Music cannot show a dialog if GmsCore is not installed - // because without GmsCore it crashes before the app can finish initializing. Utils.showToastLong(str(toastMessageKey)); open(link); return; @@ -96,11 +82,10 @@ public static void checkGmsCore(Context context) { manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); } catch (PackageManager.NameNotFoundException exception) { Logger.printDebug(() -> "GmsCore was not found"); - gmsCoreIsNotInstalled = true; - showToastOrDialog(context, - "gms_core_toast_not_installed_message", - "gms_core_dialog_not_installed_message", - getGmsCoreDownload()); + // Cannot show a dialog and must show a toast, + // because on some installations the app crashes before the dialog can display. + Utils.showToastLong(str("gms_core_toast_not_installed_message")); + open(getGmsCoreDownload()); return; } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java index c7f95ecaf7..3477619971 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java @@ -37,12 +37,6 @@ public static void showAnnouncement(final Activity context) { // Check if there is internet connection if (!Utils.isNetworkConnected()) return; - // If GmsCore is not installed, the https call will always fail with a security exception. - if (GmsCoreSupport.gmsCoreIsNotInstalled()) { - Logger.printDebug(() -> "GmsCore not installed. Skipping announcement check"); - return; - } - Utils.runOnBackgroundThread(() -> { try { HttpURLConnection connection = AnnouncementsRoutes.getAnnouncementsConnectionFromRoute( From b117613a90ff4c634f9270f50321535161a4866c Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 30 Mar 2024 12:37:20 +0400 Subject: [PATCH 12/13] fix: Use alert icon that follows light/dark theme --- .../java/app/revanced/integrations/shared/GmsCoreSupport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java index a38e48cb44..bab1a99402 100644 --- a/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/shared/GmsCoreSupport.java @@ -57,7 +57,7 @@ private static void showToastOrDialog(Context context, String toastMessageKey, S // Otherwise, if device is in dark mode the dialog is shown with wrong color scheme. Utils.runOnMainThreadDelayed(() -> { new AlertDialog.Builder(context) - .setIcon(android.R.drawable.ic_dialog_alert) + .setIconAttribute(android.R.attr.alertDialogIcon) .setTitle(str("gms_core_dialog_title")) .setMessage(str(dialogMessageKey)) .setPositiveButton(str("gms_core_dialog_ok_button_text"), (dialog, id) -> { From 15b26925fdad98d9e87e0c9fe63b88cb046d5f58 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:31:27 +0400 Subject: [PATCH 13/13] refactor(Announcements): Extract strings --- .../youtube/patches/announcements/AnnouncementsPatch.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java index 3477619971..db1e37554c 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java @@ -7,7 +7,6 @@ import android.widget.TextView; import androidx.annotation.RequiresApi; -import app.revanced.integrations.shared.GmsCoreSupport; import app.revanced.integrations.shared.Logger; import app.revanced.integrations.shared.Utils; import app.revanced.integrations.youtube.patches.announcements.requests.AnnouncementsRoutes; @@ -117,10 +116,10 @@ public static void showAnnouncement(final Activity context) { .setTitle(finalTitle) .setMessage(finalMessage) .setIcon(finalLevel.icon) - .setPositiveButton("Ok", (dialog, which) -> { + .setPositiveButton(android.R.string.ok, (dialog, which) -> { Settings.ANNOUNCEMENT_LAST_ID.save(finalId); dialog.dismiss(); - }).setNegativeButton("Dismiss", (dialog, which) -> { + }).setNegativeButton(str("revanced_announcements_dialog_dismiss"), (dialog, which) -> { dialog.dismiss(); }) .setCancelable(false)