Loading apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java +38 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading @@ -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 + '}'; } } apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java +40 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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:"); Loading Loading @@ -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(); } } } apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading services/tests/mockingservicestests/src/com/android/server/tare/AlarmManagerEconomicPolicyTest.java +3 −3 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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")); } Loading Loading @@ -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")); Loading Loading
apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java +38 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading @@ -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 + '}'; } }
apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java +40 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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:"); Loading Loading @@ -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(); } } }
apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
services/tests/mockingservicestests/src/com/android/server/tare/AlarmManagerEconomicPolicyTest.java +3 −3 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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")); } Loading Loading @@ -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")); Loading