diff --git a/play-services-base/core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java b/play-services-base/core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java index 8919661950..5529363bdf 100644 --- a/play-services-base/core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java +++ b/play-services-base/core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java @@ -12,7 +12,6 @@ import android.content.ContextWrapper; import android.content.Intent; import android.graphics.drawable.Icon; -import android.net.Uri; import android.os.PowerManager; import android.provider.Settings; import android.util.Log; @@ -22,7 +21,6 @@ import org.microg.gms.base.core.R; import static android.os.Build.VERSION.SDK_INT; -import static android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS; public class ForegroundServiceContext extends ContextWrapper { private static final String TAG = "ForegroundService"; @@ -106,8 +104,7 @@ private static Notification buildForegroundNotification(Context context, String String secondLine = context.getString(R.string.foreground_service_notification_big_text, appTitle); // Open battery optimizations settings - @SuppressLint("BatteryLife") Intent batteryOptimizationIntent = new Intent(ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) - .setData(Uri.parse("package:" + context.getPackageName())); + Intent batteryOptimizationIntent = ForegroundServiceOemUtils.getBatteryOptimizationIntent(context); PendingIntent batteryPendingIntent = PendingIntent.getActivity( context, 0, batteryOptimizationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE diff --git a/play-services-base/core/src/main/java/org/microg/gms/common/ForegroundServiceOemUtils.java b/play-services-base/core/src/main/java/org/microg/gms/common/ForegroundServiceOemUtils.java new file mode 100644 index 0000000000..67f28b8a2d --- /dev/null +++ b/play-services-base/core/src/main/java/org/microg/gms/common/ForegroundServiceOemUtils.java @@ -0,0 +1,73 @@ +package org.microg.gms.common; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.provider.Settings; +import android.util.Log; +import android.widget.Toast; + +import java.util.Locale; + +public class ForegroundServiceOemUtils { + private static final String TAG = "BatteryOptimizationOemUtils"; + + private static final String[] KNOWN_RESTRICTED_MANUFACTURERS = { + "huawei", "xiaomi", "oneplus", "samsung", "meizu", "asus", "wiko", + "lenovo", "oppo", "vivo", "realme", "motorola", "blackview", "tecno", + "sony", "unihertz" + }; + + public static String getDkmaSlug() { + String manufacturer = Build.MANUFACTURER.toLowerCase(Locale.ROOT); + + for (String brand : KNOWN_RESTRICTED_MANUFACTURERS) { + if (manufacturer.contains(brand)) { + return brand; + } + } + + return ""; // Oem not listed, hide dontkillmyapp option + } + + public static Intent getDkmaIntent(String slug) { + String url = "https://dontkillmyapp.com/" + slug; + return new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + } + + public static boolean isXiaomi() { + return Build.MANUFACTURER.toLowerCase(Locale.ROOT).contains("xiaomi"); + } + + public static Intent getBatteryOptimizationIntent(Context context) { + // Temporary fix issues: https://github.com/MorpheApp/MicroG-RE/issues/112 + if (isXiaomi()) { + return new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS); + } else { + return new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) + .setData(Uri.parse("package:" + context.getPackageName())); + } + } + + public interface IntentLauncher { + void launch(Intent intent); + } + + public static void openBatteryOptimizationSettings(Context context, IntentLauncher launcher) { + Intent intent = getBatteryOptimizationIntent(context); + try { + launcher.launch(intent); + } catch (Exception e) { + if (!Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS.equals(intent.getAction())) { + try { + launcher.launch(new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)); + } catch (Exception e2) { + Log.w(TAG, "Failed to launch battery optimization settings", e2); + } + } else { + Log.w(TAG, "Failed to launch battery optimization settings", e); + } + } + } +} \ No newline at end of file diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/selfcheck/SelfCheckGroup.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/selfcheck/SelfCheckGroup.java index 882f822e58..ef6b960ff8 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/selfcheck/SelfCheckGroup.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/selfcheck/SelfCheckGroup.java @@ -37,6 +37,6 @@ interface CheckResolver { } enum Result { - Positive, Negative, Unknown + Positive, Negative, Neutral, Unknown } } diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSelfCheckFragment.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSelfCheckFragment.java index cf7fdf09f0..0db1ae379f 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSelfCheckFragment.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/AbstractSelfCheckFragment.java @@ -46,6 +46,7 @@ import static android.view.View.VISIBLE; import static android.view.View.INVISIBLE; import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Negative; +import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Neutral; import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Positive; import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Unknown; @@ -166,9 +167,11 @@ public void addResult(String name, SelfCheckGroup.Result result, String resoluti if (showIcon) { resultIcon.setVisibility(VISIBLE); if (result == Positive) { - resultIcon.setActivated(true); + resultIcon.setImageResource(R.drawable.ic_positive); } else if (result == Negative) { - resultIcon.setActivated(false); + resultIcon.setImageResource(R.drawable.ic_negative); + } else if (result == Neutral) { + resultIcon.setImageResource(R.drawable.ic_neutral); } else { resultIcon.setVisibility(INVISIBLE); } diff --git a/play-services-core/microg-ui-tools/src/main/res/drawable/ic_neutral.xml b/play-services-core/microg-ui-tools/src/main/res/drawable/ic_neutral.xml new file mode 100644 index 0000000000..f0f52b865f --- /dev/null +++ b/play-services-core/microg-ui-tools/src/main/res/drawable/ic_neutral.xml @@ -0,0 +1,10 @@ + + + \ No newline at end of file diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml index 609a1c00a0..77493a03b0 100644 --- a/play-services-core/src/main/AndroidManifest.xml +++ b/play-services-core/src/main/AndroidManifest.xml @@ -105,21 +105,25 @@ + android:exported="true" + tools:ignore="ExportedContentProvider" /> + android:exported="true" + tools:ignore="ExportedContentProvider" /> - + - + @@ -146,7 +150,8 @@ + android:process=":persistent" + tools:ignore="ExportedService,IntentFilterExportedReceiver"> @@ -157,7 +162,8 @@ + android:process=":persistent" + tools:ignore="ExportedReceiver,IntentFilterExportedReceiver"> @@ -169,7 +175,8 @@ + android:process=":persistent" + tools:ignore="ExportedReceiver,IntentFilterExportedReceiver"> @@ -181,7 +188,8 @@ + android:process=":persistent" + tools:ignore="IntentFilterExportedReceiver"> @@ -204,7 +212,8 @@ + android:process=":persistent" + tools:ignore="IntentFilterExportedReceiver"> @@ -216,7 +225,8 @@ - + @@ -236,7 +246,8 @@ - + @@ -288,7 +299,8 @@ + android:exported="true" + tools:ignore="ExportedService" /> + android:exported="true" + tools:ignore="ExportedContentProvider" /> @@ -309,25 +323,29 @@ - + - + - + - + @@ -344,14 +362,16 @@ - + - + @@ -411,11 +431,10 @@ + android:targetActivity="org.microg.gms.ui.MainSettingsActivity"> @@ -435,9 +454,7 @@ + android:targetActivity="org.microg.gms.ui.MainSettingsActivity"> + android:targetActivity="org.microg.gms.ui.AccountManagerActivity"> @@ -506,14 +519,16 @@ + android:exported="true" + tools:ignore="ExportedService"> - + diff --git a/play-services-core/src/main/java/org/microg/gms/ui/AccountsFragment.kt b/play-services-core/src/main/java/org/microg/gms/ui/AccountsFragment.kt index 807e69490e..744dfaadfd 100644 --- a/play-services-core/src/main/java/org/microg/gms/ui/AccountsFragment.kt +++ b/play-services-core/src/main/java/org/microg/gms/ui/AccountsFragment.kt @@ -84,7 +84,13 @@ class AccountsFragment : PreferenceFragmentCompat() { private fun setupPreferenceListeners() { findPreference("pref_privacy")?.setOnPreferenceClickListener { - findNavController().navigate(requireContext(), R.id.privacyFragment) + val activity = requireActivity() + + if (activity is AccountManagerActivity) { + activity.replaceFragment(PrivacyFragment()) + } else { + findNavController().navigate(R.id.privacyFragment) + } true } findPreference("pref_manage_accounts")?.setOnPreferenceClickListener { diff --git a/play-services-core/src/main/java/org/microg/gms/ui/Conditions.java b/play-services-core/src/main/java/org/microg/gms/ui/Conditions.java index 3c1425f01a..7b0cf40dfa 100644 --- a/play-services-core/src/main/java/org/microg/gms/ui/Conditions.java +++ b/play-services-core/src/main/java/org/microg/gms/ui/Conditions.java @@ -18,17 +18,14 @@ import android.app.Activity; import android.content.Context; -import android.content.Intent; -import android.net.Uri; import android.os.PowerManager; -import android.provider.Settings; -import android.view.View; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import com.google.android.gms.R; +import org.microg.gms.common.ForegroundServiceOemUtils; import org.microg.gms.gcm.GcmPrefs; import org.microg.tools.ui.Condition; @@ -54,14 +51,9 @@ public boolean isActive(Context context) { return !pm.isIgnoringBatteryOptimizations(context.getPackageName()); } }) - .firstAction(R.string.cond_gcm_bat_action, new View.OnClickListener() { - @Override - public void onClick(View v) { - if (SDK_INT < 23) return; - Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); - intent.setData(Uri.parse("package:" + v.getContext().getPackageName())); - v.getContext().startActivity(intent); - } + .firstAction(R.string.cond_gcm_bat_action, v -> { + if (SDK_INT < 23) return; + ForegroundServiceOemUtils.openBatteryOptimizationSettings(v.getContext(), intent -> v.getContext().startActivity(intent)); }).build(); private static final String[] REQUIRED_PERMISSIONS = new String[]{ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE, GET_ACCOUNTS, READ_PHONE_STATE}; @@ -87,13 +79,9 @@ public int getPluralsCount() { return count; } }) - .firstActionPlurals(R.plurals.cond_perm_action, new View.OnClickListener() { - - @Override - public void onClick(View v) { - if (v.getContext() instanceof Activity) { - ActivityCompat.requestPermissions((Activity) v.getContext(), REQUIRED_PERMISSIONS, 0); - } + .firstActionPlurals(R.plurals.cond_perm_action, v -> { + if (v.getContext() instanceof Activity) { + ActivityCompat.requestPermissions((Activity) v.getContext(), REQUIRED_PERMISSIONS, 0); } }).build(); } diff --git a/play-services-core/src/main/java/org/microg/tools/selfcheck/OemUtils.java b/play-services-core/src/main/java/org/microg/tools/selfcheck/OemUtils.java deleted file mode 100644 index 98c4b6cb40..0000000000 --- a/play-services-core/src/main/java/org/microg/tools/selfcheck/OemUtils.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.microg.tools.selfcheck; - -import android.content.Intent; -import android.net.Uri; -import android.os.Build; - -import java.util.Locale; - -public class OemUtils { - private static final String[] KNOWN_RESTRICTED_MANUFACTURERS = { - "huawei", "xiaomi", "oneplus", "samsung", "meizu", "asus", "wiko", - "lenovo", "oppo", "vivo", "realme", "motorola", "blackview", "tecno", - "sony", "unihertz" - }; - - public static String getDkmaSlug() { - String manufacturer = Build.MANUFACTURER.toLowerCase(Locale.ROOT); - - for (String brand : KNOWN_RESTRICTED_MANUFACTURERS) { - if (manufacturer.contains(brand)) { - return brand; - } - } - - return ""; // Oem not listed, hide dontkillmyapp option - } - - public static Intent getDkmaIntent(String slug) { - String url = "https://dontkillmyapp.com/" + slug; - return new Intent(Intent.ACTION_VIEW, Uri.parse(url)); - } -} \ No newline at end of file diff --git a/play-services-core/src/main/java/org/microg/tools/selfcheck/PermissionsChecks.java b/play-services-core/src/main/java/org/microg/tools/selfcheck/PermissionsChecks.java index 90411be0af..592db9b248 100644 --- a/play-services-core/src/main/java/org/microg/tools/selfcheck/PermissionsChecks.java +++ b/play-services-core/src/main/java/org/microg/tools/selfcheck/PermissionsChecks.java @@ -14,6 +14,7 @@ import org.microg.tools.ui.AbstractSelfCheckFragment; import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Negative; +import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Neutral; import static org.microg.tools.selfcheck.SelfCheckGroup.Result.Positive; public class PermissionsChecks implements SelfCheckGroup { @@ -55,7 +56,7 @@ private void isOverlayPermissionGranted(final Context context, ResultCollector c collector.addResult( context.getString(R.string.self_check_name_overlay), - canDraw ? Positive : Negative, + canDraw ? Positive : Neutral, context.getString(R.string.self_check_resolution_overlay), true, null, fragment -> { diff --git a/play-services-core/src/main/java/org/microg/tools/selfcheck/SystemChecks.java b/play-services-core/src/main/java/org/microg/tools/selfcheck/SystemChecks.java index 45cdebfe42..3be691f82a 100644 --- a/play-services-core/src/main/java/org/microg/tools/selfcheck/SystemChecks.java +++ b/play-services-core/src/main/java/org/microg/tools/selfcheck/SystemChecks.java @@ -19,15 +19,14 @@ import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; -import android.net.Uri; import android.os.PowerManager; -import android.provider.Settings; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import com.google.android.gms.R; +import org.microg.gms.common.ForegroundServiceOemUtils; import org.microg.tools.ui.AbstractSelfCheckFragment; import org.microg.tools.ui.AbstractSelfCheckFragment.ChipInfo; @@ -61,20 +60,18 @@ private void isBatterySavingDisabled(final Context context, ResultCollector coll context.getString(R.string.self_check_resolution_battery_optimizations), true, null, fragment -> { - Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); - intent.setData(Uri.parse("package:" + fragment.requireContext().getPackageName())); - launch(fragment, intent); + ForegroundServiceOemUtils.openBatteryOptimizationSettings(fragment.requireContext(), intent -> launch(fragment, intent)); }); } private void alertOemBackgroundRestrictionLink(Context context, ResultCollector collector) { - String slug = OemUtils.getDkmaSlug(); + String slug = ForegroundServiceOemUtils.getDkmaSlug(); if (!slug.isEmpty()) { ChipInfo dkmaChip = new ChipInfo( "dontkillmyapp.com", ContextCompat.getDrawable(context, R.drawable.ic_self_check_open), v -> { - Intent intent = OemUtils.getDkmaIntent(slug); + Intent intent = ForegroundServiceOemUtils.getDkmaIntent(slug); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/SettingsFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/SettingsFragment.kt index 5fd827651a..db128afc71 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/SettingsFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/SettingsFragment.kt @@ -12,7 +12,6 @@ import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.os.PowerManager -import android.provider.Settings import android.util.Log import android.view.View import androidx.activity.result.contract.ActivityResultContracts @@ -27,6 +26,7 @@ import com.google.android.material.floatingactionbutton.ExtendedFloatingActionBu import com.google.android.material.transition.MaterialSharedAxis import kotlinx.coroutines.launch import org.microg.gms.checkin.CheckinPreferences +import org.microg.gms.common.ForegroundServiceOemUtils import org.microg.gms.gcm.GcmDatabase import org.microg.gms.gcm.GcmPrefs import org.microg.gms.ui.settings.SettingsProvider @@ -172,18 +172,8 @@ class SettingsFragment : ResourceSettingsFragment() { private fun requestIgnoringBatteryOptimizations() { val ctx = context ?: return - val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply { - data = "package:${ctx.packageName}".toUri() - } - try { + ForegroundServiceOemUtils.openBatteryOptimizationSettings(ctx) { intent -> requestIgnoreBatteryOptimizationLauncher.launch(intent) - } catch (_: ActivityNotFoundException) { - try { - val fallbackIntent = Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) - requestIgnoreBatteryOptimizationLauncher.launch(fallbackIntent) - } catch (e2: ActivityNotFoundException) { - Log.w(TAG, "Device does not support ignoring battery optimizations", e2) - } } }