Implement OP_SYSTEM_EXEMPT_FROM_POWER_RESTRICTIONS exemption

OP_SYSTEM_EXEMPT_FROM_POWER_RESTRICTIONS details:
* An app with this appop will be made exempt from all
  power restrictions, including app standby and doze.
* In addition, the app will be able to start fgs from
  the bg, and the user will not be able to stop fgs
  run by the app.

Changes:
* Implement the OP_SYSTEM_EXEMPT_FROM_POWER_RESTRICTIONS

Bug: 246330879
Test: atest PowerAllowlistBackendTest

Manual testing:
- Give OP_SYSTEM_EXEMPT_FROM_POWER_RESTRICTIONS appop to TestDPC app
- Verify the app can start fg services from the bg
- Verify fgs started by the app cannot be stopped
- Verify the app cannot be put into background restricted via Settings

Change-Id: If9e76076c59195f1e6e5f3eee3c8e7a0c754d8de
This commit is contained in:
Alex Johnston
2023-02-06 18:21:55 +00:00
parent 02c3e876f4
commit 2747dc6e8c
13 changed files with 57 additions and 53 deletions

View File

@@ -96,7 +96,7 @@ public class AppStateAppBatteryUsageBridge extends AppStateBaseBridge {
// Unrestricted = AppOpsManager.MODE_ALLOWED + allowListed
// Optimized = AppOpsManager.MODE_ALLOWED + !allowListed
boolean allowListed = mPowerAllowlistBackend.isAllowlisted(pkg);
boolean allowListed = mPowerAllowlistBackend.isAllowlisted(pkg, uid);
int aomMode =
mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, pkg);
@OptimizationMode int mode = MODE_UNKNOWN;

View File

@@ -43,14 +43,14 @@ public class AppStatePowerBridge extends AppStateBaseBridge {
final int N = apps.size();
for (int i = 0; i < N; i++) {
AppEntry app = apps.get(i);
app.extraInfo = mBackend.isAllowlisted(app.info.packageName)
app.extraInfo = mBackend.isAllowlisted(app.info.packageName, app.info.uid)
? Boolean.TRUE : Boolean.FALSE;
}
}
@Override
protected void updateExtraInfo(AppEntry app, String pkg, int uid) {
app.extraInfo = mBackend.isAllowlisted(pkg) ? Boolean.TRUE : Boolean.FALSE;
app.extraInfo = mBackend.isAllowlisted(pkg, uid) ? Boolean.TRUE : Boolean.FALSE;
}
public static final AppFilter FILTER_POWER_ALLOWLISTED = new CompoundFilter(

View File

@@ -1722,7 +1722,7 @@ public class ManageApplications extends InstrumentedFragment
ApplicationsState.AppEntry entry = mEntries.get(applicationPosition);
return !mBackend.isSysAllowlisted(entry.info.packageName)
&& !mBackend.isDefaultActiveApp(entry.info.packageName);
&& !mBackend.isDefaultActiveApp(entry.info.packageName, entry.info.uid);
}
@Override

View File

@@ -153,7 +153,7 @@ public final class BatteryBackupHelper implements BackupHelper {
// Ignores default optimized/unknown state or system/default apps.
if (optimizationMode == BatteryOptimizeUtils.MODE_OPTIMIZED
|| optimizationMode == BatteryOptimizeUtils.MODE_UNKNOWN
|| isSystemOrDefaultApp(info.packageName)) {
|| isSystemOrDefaultApp(info.packageName, info.uid)) {
continue;
}
final String packageOptimizeMode =
@@ -191,8 +191,9 @@ public final class BatteryBackupHelper implements BackupHelper {
continue;
}
final String packageName = results[0];
final int uid = BatteryUtils.getInstance(mContext).getPackageUid(packageName);
// Ignores system/default apps.
if (isSystemOrDefaultApp(packageName)) {
if (isSystemOrDefaultApp(packageName, uid)) {
Log.w(TAG, "ignore from isSystemOrDefaultApp():" + packageName);
continue;
}
@@ -253,10 +254,10 @@ public final class BatteryBackupHelper implements BackupHelper {
return mPowerAllowlistBackend;
}
private boolean isSystemOrDefaultApp(String packageName) {
private boolean isSystemOrDefaultApp(String packageName, int uid) {
final PowerAllowlistBackend powerAllowlistBackend = getPowerAllowlistBackend();
return powerAllowlistBackend.isSysAllowlisted(packageName)
|| powerAllowlistBackend.isDefaultActiveApp(packageName);
|| powerAllowlistBackend.isDefaultActiveApp(packageName, uid);
}
private ArraySet<ApplicationInfo> getInstalledApplications() {

View File

@@ -85,7 +85,7 @@ public class BatteryOptimizeUtils {
mPowerAllowListBackend = PowerAllowlistBackend.getInstance(context);
mMode = mAppOpsManager
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mPackageName);
mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName);
mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName, mUid);
}
/** Gets the {@link OptimizationMode} based on mode and allowed list. */
@@ -138,7 +138,7 @@ public class BatteryOptimizeUtils {
*/
public boolean isSystemOrDefaultApp() {
mPowerAllowListBackend.refreshList();
return isSystemOrDefaultApp(mPowerAllowListBackend, mPackageName);
return isSystemOrDefaultApp(mPowerAllowListBackend, mPackageName, mUid);
}
/**
@@ -186,11 +186,11 @@ public class BatteryOptimizeUtils {
AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, info.uid, info.packageName);
@OptimizationMode
final int optimizationMode = getAppOptimizationMode(
mode, allowlistBackend.isAllowlisted(info.packageName));
mode, allowlistBackend.isAllowlisted(info.packageName, info.uid));
// Ignores default optimized/unknown state or system/default apps.
if (optimizationMode == MODE_OPTIMIZED
|| optimizationMode == MODE_UNKNOWN
|| isSystemOrDefaultApp(allowlistBackend, info.packageName)) {
|| isSystemOrDefaultApp(allowlistBackend, info.packageName, info.uid)) {
continue;
}
@@ -205,9 +205,9 @@ public class BatteryOptimizeUtils {
}
private static boolean isSystemOrDefaultApp(
PowerAllowlistBackend powerAllowlistBackend, String packageName) {
PowerAllowlistBackend powerAllowlistBackend, String packageName, int uid) {
return powerAllowlistBackend.isSysAllowlisted(packageName)
|| powerAllowlistBackend.isDefaultActiveApp(packageName);
|| powerAllowlistBackend.isDefaultActiveApp(packageName, uid);
}
private static void setAppUsageStateInternal(
@@ -257,7 +257,7 @@ public class BatteryOptimizeUtils {
private void refreshState() {
mPowerAllowListBackend.refreshList();
mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName);
mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName, mUid);
mMode = mAppOpsManager
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mPackageName);
Log.d(TAG, String.format("refresh %s state, allowlisted = %s, mode = %d",

View File

@@ -529,7 +529,7 @@ public class BatteryUtils {
return true;
}
return isSystemUid(uid) || powerAllowlistBackend.isAllowlisted(packageNames)
return isSystemUid(uid) || powerAllowlistBackend.isAllowlisted(packageNames, uid)
|| (isSystemApp(mPackageManager, packageNames) && !hasLauncherEntry(packageNames))
|| (isExcessiveBackgroundAnomaly(anomalyInfo) && !isPreOApp(packageNames));
}

View File

@@ -81,7 +81,7 @@ public class HighPowerDetail extends InstrumentedDialogFragment implements OnCli
mLabel = mPackageName;
}
mDefaultOn = getArguments().getBoolean(ARG_DEFAULT_ON);
mIsEnabled = mDefaultOn || mBackend.isAllowlisted(mPackageName);
mIsEnabled = mDefaultOn || mBackend.isAllowlisted(mPackageName, mPackageUid);
}
public Checkable setup(View view, boolean on) {
@@ -137,7 +137,7 @@ public class HighPowerDetail extends InstrumentedDialogFragment implements OnCli
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
boolean newValue = mIsEnabled;
boolean oldValue = mBackend.isAllowlisted(mPackageName);
boolean oldValue = mBackend.isAllowlisted(mPackageName, mPackageUid);
if (newValue != oldValue) {
logSpecialPermissionChange(newValue, mPackageName, getContext());
if (newValue) {
@@ -169,20 +169,20 @@ public class HighPowerDetail extends InstrumentedDialogFragment implements OnCli
}
public static CharSequence getSummary(Context context, AppEntry entry) {
return getSummary(context, entry.info.packageName);
return getSummary(context, entry.info.packageName, entry.info.uid);
}
public static CharSequence getSummary(Context context, String pkg) {
return getSummary(context, PowerAllowlistBackend.getInstance(context), pkg);
public static CharSequence getSummary(Context context, String pkg, int uid) {
return getSummary(context, PowerAllowlistBackend.getInstance(context), pkg, uid);
}
@VisibleForTesting
static CharSequence getSummary(Context context, PowerAllowlistBackend powerAllowlist,
String pkg) {
String pkg, int uid) {
return context.getString(
powerAllowlist.isSysAllowlisted(pkg) || powerAllowlist.isDefaultActiveApp(pkg)
powerAllowlist.isSysAllowlisted(pkg) || powerAllowlist.isDefaultActiveApp(pkg, uid)
? R.string.high_power_system
: powerAllowlist.isAllowlisted(pkg)
: powerAllowlist.isAllowlisted(pkg, uid)
? R.string.high_power_on
: R.string.high_power_off);
}