mirror of
https://github.com/revanced/revanced-integrations.git
synced 2024-12-02 16:52:55 +01:00
feat(YouTube - GmsCore): Require ignoring battery optimizations (#599)
This commit is contained in:
parent
f11d291c3d
commit
fd2a9d0287
@ -1,15 +1,18 @@
|
|||||||
package app.revanced.integrations.shared;
|
package app.revanced.integrations.shared;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.app.SearchManager;
|
import android.app.SearchManager;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.PowerManager;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static app.revanced.integrations.shared.StringRef.str;
|
import static app.revanced.integrations.shared.StringRef.str;
|
||||||
|
|
||||||
@ -18,15 +21,13 @@ import static app.revanced.integrations.shared.StringRef.str;
|
|||||||
*/
|
*/
|
||||||
public class GmsCoreSupport {
|
public class GmsCoreSupport {
|
||||||
private static final String GMS_CORE_PACKAGE_NAME
|
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
|
private static final String DONT_KILL_MY_APP_LINK
|
||||||
= "https://dontkillmyapp.com";
|
= "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);
|
|
||||||
|
|
||||||
|
private static void open(String queryOrLink) {
|
||||||
Intent intent;
|
Intent intent;
|
||||||
try {
|
try {
|
||||||
// Check if queryOrLink is a valid URL.
|
// Check if queryOrLink is a valid URL.
|
||||||
@ -40,48 +41,93 @@ public class GmsCoreSupport {
|
|||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
Utils.getContext().startActivity(intent);
|
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);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
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)
|
||||||
|
.setIconAttribute(android.R.attr.alertDialogIcon)
|
||||||
|
.setTitle(str("gms_core_dialog_title"))
|
||||||
|
.setMessage(str(dialogMessageKey))
|
||||||
|
.setPositiveButton(str("gms_core_dialog_ok_button_text"), (dialog, id) -> {
|
||||||
|
open(link);
|
||||||
|
})
|
||||||
|
// Manually allow using the back button to dismiss the dialog with the back button,
|
||||||
|
// if troubleshooting and somehow the GmsCore verification checks always fail.
|
||||||
|
.setCancelable(true)
|
||||||
|
.show();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
public static void checkAvailability() {
|
public static void checkGmsCore(Context context) {
|
||||||
var context = Objects.requireNonNull(Utils.getContext());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context.getPackageManager().getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
|
// Verify GmsCore is installed.
|
||||||
|
try {
|
||||||
|
PackageManager manager = context.getPackageManager();
|
||||||
|
manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
|
||||||
} catch (PackageManager.NameNotFoundException exception) {
|
} 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"));
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) {
|
// Check if GmsCore is whitelisted from battery optimizations.
|
||||||
if (client != null) return;
|
var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||||
|
if (!powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME)) {
|
||||||
|
Logger.printDebug(() -> "GmsCore is not whitelisted from battery optimizations");
|
||||||
|
showToastOrDialog(context,
|
||||||
|
"gms_core_toast_not_whitelisted_message",
|
||||||
|
"gms_core_dialog_not_whitelisted_using_battery_optimizations_message",
|
||||||
|
DONT_KILL_MY_APP_LINK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Logger.printInfo(() -> "GmsCore is not running in the background");
|
// Check if GmsCore is running in the background.
|
||||||
open(DONT_KILL_MY_APP_LINK, str("gms_core_not_running_warning"));
|
try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) {
|
||||||
|
if (client == null) {
|
||||||
|
Logger.printDebug(() -> "GmsCore is not running in the background");
|
||||||
|
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) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "Could not check GmsCore background task", ex);
|
Logger.printException(() -> "checkGmsCore failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getGmsCoreDownload() {
|
private static String getGmsCoreDownload() {
|
||||||
final var vendor = getGmsCoreVendor();
|
final var vendorGroupId = getGmsCoreVendorGroupId();
|
||||||
//noinspection SwitchStatementWithTooFewBranches
|
//noinspection SwitchStatementWithTooFewBranches
|
||||||
switch (vendor) {
|
switch (vendorGroupId) {
|
||||||
case "app.revanced":
|
case "app.revanced":
|
||||||
return "https://github.com/revanced/gmscore/releases/latest";
|
return "https://github.com/revanced/gmscore/releases/latest";
|
||||||
default:
|
default:
|
||||||
return vendor + ".android.gms";
|
return vendorGroupId + ".android.gms";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modified by a patch. Do not touch.
|
// Modified by a patch. Do not touch.
|
||||||
private static String getGmsCoreVendor() {
|
private static String getGmsCoreVendorGroupId() {
|
||||||
return "app.revanced";
|
return "app.revanced";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.text.Html;
|
|||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
import app.revanced.integrations.shared.Logger;
|
import app.revanced.integrations.shared.Logger;
|
||||||
import app.revanced.integrations.shared.Utils;
|
import app.revanced.integrations.shared.Utils;
|
||||||
import app.revanced.integrations.youtube.patches.announcements.requests.AnnouncementsRoutes;
|
import app.revanced.integrations.youtube.patches.announcements.requests.AnnouncementsRoutes;
|
||||||
@ -115,10 +116,10 @@ public final class AnnouncementsPatch {
|
|||||||
.setTitle(finalTitle)
|
.setTitle(finalTitle)
|
||||||
.setMessage(finalMessage)
|
.setMessage(finalMessage)
|
||||||
.setIcon(finalLevel.icon)
|
.setIcon(finalLevel.icon)
|
||||||
.setPositiveButton("Ok", (dialog, which) -> {
|
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||||
Settings.ANNOUNCEMENT_LAST_ID.save(finalId);
|
Settings.ANNOUNCEMENT_LAST_ID.save(finalId);
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}).setNegativeButton("Dismiss", (dialog, which) -> {
|
}).setNegativeButton(str("revanced_announcements_dialog_dismiss"), (dialog, which) -> {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
})
|
})
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
|
Loading…
Reference in New Issue
Block a user