Merge "Give headless system apps a higher min balance." into udc-dev

This commit is contained in:
Kweku Adams
2023-03-24 20:19:49 +00:00
committed by Android (Google) Code Review
7 changed files with 87 additions and 10 deletions

View File

@@ -182,7 +182,7 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
if (mIrs.isPackageExempted(userId, pkgName)) {
return mMinSatiatedBalanceExempted;
}
if (mIrs.isHeadlessSystemApp(pkgName)) {
if (mIrs.isHeadlessSystemApp(userId, pkgName)) {
return mMinSatiatedBalanceHeadlessSystemApp;
}
// TODO: take other exemptions into account

View File

@@ -22,6 +22,7 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppGlobals;
import android.content.Context;
import android.content.Intent;
import android.content.PermissionChecker;
import android.content.pm.ApplicationInfo;
import android.content.pm.InstallSourceInfo;
@@ -35,9 +36,23 @@ import com.android.internal.util.ArrayUtils;
class InstalledPackageInfo {
static final int NO_UID = -1;
/**
* Flags to use when querying for front door activities. Disabled components are included
* are included for completeness since the app can enable them at any time.
*/
private static final int HEADLESS_APP_QUERY_FLAGS = PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_DISABLED_COMPONENTS;
public final int uid;
public final String packageName;
public final boolean hasCode;
/**
* Whether the app is a system app that is "headless." Headless in this context means that
* the app doesn't have any "front door" activities --- activities that would show in the
* launcher.
*/
public final boolean isHeadlessSystemApp;
public final boolean isSystemInstaller;
@Nullable
public final String installerPackageName;
@@ -48,6 +63,17 @@ class InstalledPackageInfo {
uid = applicationInfo == null ? NO_UID : applicationInfo.uid;
packageName = packageInfo.packageName;
hasCode = applicationInfo != null && applicationInfo.hasCode();
final PackageManager packageManager = context.getPackageManager();
final Intent frontDoorActivityIntent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_LAUNCHER)
.setPackage(packageName);
isHeadlessSystemApp = applicationInfo != null
&& (applicationInfo.isSystemApp() || applicationInfo.isUpdatedSystemApp())
&& ArrayUtils.isEmpty(
packageManager.queryIntentActivitiesAsUser(
frontDoorActivityIntent, HEADLESS_APP_QUERY_FLAGS, userId));
isSystemInstaller = applicationInfo != null
&& ArrayUtils.indexOf(
packageInfo.requestedPermissions, Manifest.permission.INSTALL_PACKAGES) >= 0
@@ -65,4 +91,16 @@ class InstalledPackageInfo {
installerPackageName =
installSourceInfo == null ? null : installSourceInfo.getInstallingPackageName();
}
@Override
public String toString() {
return "IPO{"
+ "uid=" + uid
+ ", pkgName=" + packageName
+ (hasCode ? " HAS_CODE" : "")
+ (isHeadlessSystemApp ? " HEADLESS_SYSTEM" : "")
+ (isSystemInstaller ? " SYSTEM_INSTALLER" : "")
+ ", installer=" + installerPackageName
+ '}';
}
}

View File

@@ -501,12 +501,16 @@ public class InternalResourceService extends SystemService {
}
}
boolean isHeadlessSystemApp(@NonNull String pkgName) {
boolean isHeadlessSystemApp(final int userId, @NonNull String pkgName) {
if (pkgName == null) {
Slog.wtfStack(TAG, "isHeadlessSystemApp called with null package");
return false;
}
synchronized (mLock) {
final InstalledPackageInfo ipo = getInstalledPackageInfo(userId, pkgName);
if (ipo != null && ipo.isHeadlessSystemApp) {
return true;
}
// The wellbeing app is pre-set on the device, not expected to be interacted with
// much by the user, but can be expected to do work in the background on behalf of
// the user. As such, it's a pseudo-headless system app, so treat it as a headless
@@ -1754,6 +1758,10 @@ public class InternalResourceService extends SystemService {
pw.print("Exempted apps", mExemptedApps);
pw.println();
pw.println();
pw.print("Wellbeing app=");
pw.println(mWellbeingPackage == null ? "None" : mWellbeingPackage);
boolean printedVips = false;
pw.println();
pw.print("VIPs:");
@@ -1832,6 +1840,37 @@ public class InternalResourceService extends SystemService {
pw.println();
mAnalyst.dump(pw);
// Put this at the end since this may be a lot and we want to have the earlier
// information easily accessible.
boolean printedInterestingIpos = false;
pw.println();
pw.print("Interesting apps:");
pw.increaseIndent();
for (int u = 0; u < mPkgCache.numMaps(); ++u) {
for (int p = 0; p < mPkgCache.numElementsForKeyAt(u); ++p) {
final InstalledPackageInfo ipo = mPkgCache.valueAt(u, p);
// Printing out every single app will be too much. Only print apps that
// have some interesting characteristic.
final boolean isInteresting = ipo.hasCode
&& ipo.isHeadlessSystemApp
&& !UserHandle.isCore(ipo.uid);
if (!isInteresting) {
continue;
}
printedInterestingIpos = true;
pw.println();
pw.print(ipo);
}
}
if (printedInterestingIpos) {
pw.println();
} else {
pw.print(" None");
}
pw.decreaseIndent();
}
}
}

View File

@@ -197,7 +197,7 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
final long baseBalance;
if (mIrs.isPackageExempted(userId, pkgName)) {
baseBalance = mMinSatiatedBalanceExempted;
} else if (mIrs.isHeadlessSystemApp(pkgName)) {
} else if (mIrs.isHeadlessSystemApp(userId, pkgName)) {
baseBalance = mMinSatiatedBalanceHeadlessSystemApp;
} else {
baseBalance = mMinSatiatedBalanceOther;

View File

@@ -150,7 +150,7 @@ public class AlarmManagerEconomicPolicyTest {
mEconomicPolicy.getMaxSatiatedBalance(0, pkgExempted));
final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
@@ -184,7 +184,7 @@ public class AlarmManagerEconomicPolicyTest {
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(arcToCake(9), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
assertEquals(arcToCake(8), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(7), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
}
@@ -212,7 +212,7 @@ public class AlarmManagerEconomicPolicyTest {
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));

View File

@@ -207,7 +207,7 @@ public class CompleteEconomicPolicyTest {
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
assertEquals(arcToCake(10), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(5), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
}

View File

@@ -150,7 +150,7 @@ public class JobSchedulerEconomicPolicyTest {
mEconomicPolicy.getMaxSatiatedBalance(0, pkgExempted));
final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
@@ -201,7 +201,7 @@ public class JobSchedulerEconomicPolicyTest {
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(arcToCake(6), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
assertEquals(arcToCake(5), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(4), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
final String pkgUpdater = "com.pkg.updater";
@@ -235,7 +235,7 @@ public class JobSchedulerEconomicPolicyTest {
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
final String pkgUpdater = "com.pkg.updater";