Merge "Reset Optimization Mode of apps when users reset app settings." into tm-qpr-dev am: 614d2dfc0b
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/18309249 Change-Id: Ib7e9e58435110c22bf6ca10c4cd9f4181d1f9e7c Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -38,6 +38,7 @@ import android.util.Log;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -152,6 +153,7 @@ public class ResetAppsHelper implements DialogInterface.OnClickListener,
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
mAom.resetAllModes();
|
||||
BatteryOptimizeUtils.resetAppOptimizationMode(mContext, mIPm, mAom);
|
||||
final int[] restrictedUids = mNpm.getUidsWithPolicy(
|
||||
POLICY_REJECT_METERED_BACKGROUND);
|
||||
final int currentUserId = ActivityManager.getCurrentUser();
|
||||
|
||||
@@ -24,16 +24,13 @@ import android.app.backup.BackupHelper;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Build;
|
||||
import android.os.IDeviceIdleController;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -53,22 +50,13 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
private static final String DEVICE_IDLE_SERVICE = "deviceidle";
|
||||
private static final boolean DEBUG = Build.TYPE.equals("userdebug");
|
||||
|
||||
// Only the owner can see all apps.
|
||||
private static final int RETRIEVE_FLAG_ADMIN =
|
||||
PackageManager.MATCH_ANY_USER |
|
||||
PackageManager.MATCH_DISABLED_COMPONENTS |
|
||||
PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
|
||||
private static final int RETRIEVE_FLAG =
|
||||
PackageManager.MATCH_DISABLED_COMPONENTS |
|
||||
PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
|
||||
|
||||
static final String DELIMITER = ",";
|
||||
static final String DELIMITER_MODE = ":";
|
||||
static final String KEY_FULL_POWER_LIST = "full_power_list";
|
||||
static final String KEY_OPTIMIZATION_LIST = "optimization_mode_list";
|
||||
|
||||
@VisibleForTesting
|
||||
List<ApplicationInfo> mTestApplicationInfoList = null;
|
||||
ArraySet<ApplicationInfo> mTestApplicationInfoList = null;
|
||||
|
||||
@VisibleForTesting
|
||||
PowerAllowlistBackend mPowerAllowlistBackend;
|
||||
@@ -146,7 +134,7 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
@VisibleForTesting
|
||||
void backupOptimizationMode(BackupDataOutput data, List<String> allowlistedApps) {
|
||||
final long timestamp = System.currentTimeMillis();
|
||||
final List<ApplicationInfo> applications = getInstalledApplications();
|
||||
final ArraySet<ApplicationInfo> applications = getInstalledApplications();
|
||||
if (applications == null || applications.isEmpty()) {
|
||||
Log.w(TAG, "no data found in the getInstalledApplications()");
|
||||
return;
|
||||
@@ -269,36 +257,11 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
|| powerAllowlistBackend.isDefaultActiveApp(packageName);
|
||||
}
|
||||
|
||||
private List<ApplicationInfo> getInstalledApplications() {
|
||||
private ArraySet<ApplicationInfo> getInstalledApplications() {
|
||||
if (mTestApplicationInfoList != null) {
|
||||
return mTestApplicationInfoList;
|
||||
}
|
||||
final List<ApplicationInfo> applications = new ArrayList<>();
|
||||
final UserManager um = mContext.getSystemService(UserManager.class);
|
||||
for (UserInfo userInfo : um.getProfiles(UserHandle.myUserId())) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
final ParceledListSlice<ApplicationInfo> infoList =
|
||||
getIPackageManager().getInstalledApplications(
|
||||
userInfo.isAdmin() ? RETRIEVE_FLAG_ADMIN : RETRIEVE_FLAG,
|
||||
userInfo.id);
|
||||
if (infoList != null) {
|
||||
applications.addAll(infoList.getList());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getInstalledApplications() is failed", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// Removes the application which is disabled by the system.
|
||||
for (int index = applications.size() - 1; index >= 0; index--) {
|
||||
final ApplicationInfo info = applications.get(index);
|
||||
if (info.enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
|
||||
&& !info.enabled) {
|
||||
applications.remove(index);
|
||||
}
|
||||
}
|
||||
return applications;
|
||||
return BatteryOptimizeUtils.getInstalledApplications(mContext, getIPackageManager());
|
||||
}
|
||||
|
||||
private void debugLog(String debugContent) {
|
||||
|
||||
@@ -19,7 +19,15 @@ package com.android.settings.fuelgauge;
|
||||
import android.annotation.IntDef;
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -43,6 +51,15 @@ public class BatteryOptimizeUtils {
|
||||
private final String mPackageName;
|
||||
private final int mUid;
|
||||
|
||||
// If current user is admin, match apps from all users. Otherwise, only match the currect user.
|
||||
private static final int RETRIEVE_FLAG_ADMIN =
|
||||
PackageManager.MATCH_ANY_USER
|
||||
| PackageManager.MATCH_DISABLED_COMPONENTS
|
||||
| PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
|
||||
private static final int RETRIEVE_FLAG =
|
||||
PackageManager.MATCH_DISABLED_COMPONENTS
|
||||
| PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
|
||||
|
||||
// Optimization modes.
|
||||
static final int MODE_UNKNOWN = 0;
|
||||
static final int MODE_RESTRICTED = 1;
|
||||
@@ -90,28 +107,20 @@ public class BatteryOptimizeUtils {
|
||||
return getAppOptimizationMode(mMode, mAllowListed);
|
||||
}
|
||||
|
||||
/** Resets optimization mode for all applications. */
|
||||
public static void resetAppOptimizationMode(
|
||||
Context context, IPackageManager ipm, AppOpsManager aom) {
|
||||
resetAppOptimizationMode(context, ipm, aom,
|
||||
PowerAllowlistBackend.getInstance(context), BatteryUtils.getInstance(context));
|
||||
}
|
||||
|
||||
/** Sets the {@link OptimizationMode} for associated app. */
|
||||
public void setAppUsageState(@OptimizationMode int mode) {
|
||||
if (getAppOptimizationMode(mMode, mAllowListed) == mode) {
|
||||
Log.w(TAG, "set the same optimization mode for: " + mPackageName);
|
||||
return;
|
||||
}
|
||||
|
||||
AsyncTask.execute(() -> {
|
||||
switch (mode) {
|
||||
case MODE_RESTRICTED:
|
||||
setAppOptimizationMode(AppOpsManager.MODE_IGNORED, /* allowListed */ false);
|
||||
break;
|
||||
case MODE_UNRESTRICTED:
|
||||
setAppOptimizationMode(AppOpsManager.MODE_ALLOWED, /* allowListed */ true);
|
||||
break;
|
||||
case MODE_OPTIMIZED:
|
||||
setAppOptimizationMode(AppOpsManager.MODE_ALLOWED, /* allowListed */ false);
|
||||
break;
|
||||
default:
|
||||
Log.d(TAG, "set unknown app optimization mode.");
|
||||
}
|
||||
});
|
||||
setAppUsageStateInternal(mode, mUid, mPackageName, mBatteryUtils, mPowerAllowListBackend);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,25 +135,111 @@ public class BatteryOptimizeUtils {
|
||||
*/
|
||||
public boolean isSystemOrDefaultApp() {
|
||||
mPowerAllowListBackend.refreshList();
|
||||
return isSystemOrDefaultApp(mPowerAllowListBackend, mPackageName);
|
||||
}
|
||||
|
||||
return mPowerAllowListBackend.isSysAllowlisted(mPackageName)
|
||||
|| mPowerAllowListBackend.isDefaultActiveApp(mPackageName);
|
||||
/**
|
||||
* Gets the list of installed applications.
|
||||
*/
|
||||
public static ArraySet<ApplicationInfo> getInstalledApplications(
|
||||
Context context, IPackageManager ipm) {
|
||||
final ArraySet<ApplicationInfo> applications = new ArraySet<>();
|
||||
final UserManager um = context.getSystemService(UserManager.class);
|
||||
for (UserInfo userInfo : um.getProfiles(UserHandle.myUserId())) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
final ParceledListSlice<ApplicationInfo> infoList = ipm.getInstalledApplications(
|
||||
userInfo.isAdmin() ? RETRIEVE_FLAG_ADMIN : RETRIEVE_FLAG,
|
||||
userInfo.id);
|
||||
if (infoList != null) {
|
||||
applications.addAll(infoList.getList());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getInstalledApplications() is failed", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// Removes the application which is disabled by the system.
|
||||
applications.removeIf(
|
||||
info -> info.enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
|
||||
&& !info.enabled);
|
||||
return applications;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static void resetAppOptimizationMode(
|
||||
Context context, IPackageManager ipm, AppOpsManager aom,
|
||||
PowerAllowlistBackend allowlistBackend, BatteryUtils batteryUtils) {
|
||||
final ArraySet<ApplicationInfo> applications = getInstalledApplications(context, ipm);
|
||||
if (applications == null || applications.isEmpty()) {
|
||||
Log.w(TAG, "no data found in the getInstalledApplications()");
|
||||
return;
|
||||
}
|
||||
|
||||
allowlistBackend.refreshList();
|
||||
// Resets optimization mode for each application.
|
||||
for (ApplicationInfo info : applications) {
|
||||
final int mode = aom.checkOpNoThrow(
|
||||
AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, info.uid, info.packageName);
|
||||
@OptimizationMode
|
||||
final int optimizationMode = getAppOptimizationMode(
|
||||
mode, allowlistBackend.isAllowlisted(info.packageName));
|
||||
// Ignores default optimized/unknown state or system/default apps.
|
||||
if (optimizationMode == MODE_OPTIMIZED
|
||||
|| optimizationMode == MODE_UNKNOWN
|
||||
|| isSystemOrDefaultApp(allowlistBackend, info.packageName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Resets to the default mode: MODE_OPTIMIZED.
|
||||
setAppUsageStateInternal(MODE_OPTIMIZED, info.uid, info.packageName, batteryUtils,
|
||||
allowlistBackend);
|
||||
}
|
||||
}
|
||||
|
||||
String getPackageName() {
|
||||
return mPackageName == null ? UNKNOWN_PACKAGE : mPackageName;
|
||||
}
|
||||
|
||||
private void setAppOptimizationMode(int appStandbyMode, boolean allowListed) {
|
||||
private static boolean isSystemOrDefaultApp(
|
||||
PowerAllowlistBackend powerAllowlistBackend, String packageName) {
|
||||
return powerAllowlistBackend.isSysAllowlisted(packageName)
|
||||
|| powerAllowlistBackend.isDefaultActiveApp(packageName);
|
||||
}
|
||||
|
||||
private static void setAppUsageStateInternal(
|
||||
@OptimizationMode int mode, int uid, String packageName, BatteryUtils batteryUtils,
|
||||
PowerAllowlistBackend powerAllowlistBackend) {
|
||||
if (mode == MODE_UNKNOWN) {
|
||||
Log.d(TAG, "set unknown app optimization mode.");
|
||||
return;
|
||||
}
|
||||
|
||||
// MODE_RESTRICTED = AppOpsManager.MODE_IGNORED + !allowListed
|
||||
// MODE_UNRESTRICTED = AppOpsManager.MODE_ALLOWED + allowListed
|
||||
// MODE_OPTIMIZED = AppOpsManager.MODE_ALLOWED + !allowListed
|
||||
final int appOpsManagerMode =
|
||||
mode == MODE_RESTRICTED ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
|
||||
final boolean allowListed = mode == MODE_UNRESTRICTED;
|
||||
|
||||
AsyncTask.execute(() -> {
|
||||
setAppOptimizationModeInternal(appOpsManagerMode, allowListed, uid, packageName,
|
||||
batteryUtils, powerAllowlistBackend);
|
||||
});
|
||||
}
|
||||
|
||||
private static void setAppOptimizationModeInternal(
|
||||
int appStandbyMode, boolean allowListed, int uid, String packageName,
|
||||
BatteryUtils batteryUtils, PowerAllowlistBackend powerAllowlistBackend) {
|
||||
try {
|
||||
mBatteryUtils.setForceAppStandby(mUid, mPackageName, appStandbyMode);
|
||||
batteryUtils.setForceAppStandby(uid, packageName, appStandbyMode);
|
||||
if (allowListed) {
|
||||
mPowerAllowListBackend.addApp(mPackageName);
|
||||
powerAllowlistBackend.addApp(packageName);
|
||||
} else {
|
||||
mPowerAllowListBackend.removeApp(mPackageName);
|
||||
powerAllowlistBackend.removeApp(packageName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "set OPTIMIZED failed for " + mPackageName, e);
|
||||
Log.e(TAG, "set OPTIMIZATION MODE failed for " + packageName, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,8 +249,6 @@ public class BatteryOptimizeUtils {
|
||||
mMode = mAppOpsManager
|
||||
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mPackageName);
|
||||
Log.d(TAG, String.format("refresh %s state, allowlisted = %s, mode = %d",
|
||||
mPackageName,
|
||||
mAllowListed,
|
||||
mMode));
|
||||
mPackageName, mAllowListed, mMode));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user