Loading services/core/java/com/android/server/am/ActiveServices.java +14 −7 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.server.am; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.Manifest.permission.SYSTEM_ALERT_WINDOW; import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; import static android.os.Process.NFC_UID; Loading Loading @@ -168,6 +167,7 @@ public final class ActiveServices { public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION = 16; public static final int FGS_FEATURE_ALLOWED_BY_FGS_BINDING = 17; public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE = 18; public static final int FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD = 19; @IntDef(flag = true, prefix = { "FGS_FEATURE_" }, value = { FGS_FEATURE_DENIED, Loading @@ -187,7 +187,8 @@ public final class ActiveServices { FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST, FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION, FGS_FEATURE_ALLOWED_BY_FGS_BINDING, FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE, FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD }) @Retention(RetentionPolicy.SOURCE) public @interface FgsFeatureRetCode {} Loading Loading @@ -5244,13 +5245,17 @@ public final class ActiveServices { if (ret == FGS_FEATURE_DENIED) { for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) { final ProcessRecord pr = mAm.mProcessList.mLruProcesses.get(i); if (pr.uid == callingUid && pr.mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { if (pr.uid == callingUid) { if (pr.mAllowStartFgs) { ret = FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD; break; } else if (pr.isAllowedStartFgsState()) { ret = FGS_FEATURE_ALLOWED_BY_PROC_STATE; break; } } } } if (ret == FGS_FEATURE_DENIED) { for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) { Loading Loading @@ -5286,7 +5291,7 @@ public final class ActiveServices { } if (ret == FGS_FEATURE_DENIED) { if (mAm.isWhitelistedForFgsStartLocked(r.appInfo.uid)) { if (mAm.isWhitelistedForFgsStartLocked(callingUid)) { // uid is on DeviceIdleController's user/system allowlist // or AMS's FgsStartTempAllowList. ret = FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST; Loading Loading @@ -5354,6 +5359,8 @@ public final class ActiveServices { return "ALLOWED_BY_FGS_BINDING"; case FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE: return "ALLOWED_BY_DEVICE_DEMO_MODE"; case FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD: return "ALLOWED_BY_PROCESS_RECORD"; default: return ""; } Loading services/core/java/com/android/server/am/OomAdjuster.java +9 −3 Original line number Diff line number Diff line Loading @@ -1329,7 +1329,7 @@ public final class OomAdjuster { app.setCached(false); app.shouldNotFreeze = false; app.mAllowStartFgsState = PROCESS_STATE_NONEXISTENT; app.resetAllowStartFgs(); final int appUid = app.info.uid; final int logUid = mService.mCurOomAdjUid; Loading @@ -1351,7 +1351,6 @@ public final class OomAdjuster { app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT); app.curCapability = PROCESS_CAPABILITY_ALL; app.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT); app.bumpAllowStartFgsState(PROCESS_STATE_PERSISTENT); // System processes can do UI, and when they do we want to have // them trim their memory after the user leaves the UI. To // facilitate this, here we need to determine whether or not it Loading Loading @@ -1382,6 +1381,8 @@ public final class OomAdjuster { app.setCurRawProcState(app.getCurProcState()); app.curAdj = app.maxAdj; app.completedAdjSeq = app.adjSeq; app.bumpAllowStartFgsState(app.getCurProcState()); app.setAllowStartFgs(); // if curAdj is less than prevAppAdj, then this process was promoted return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState; } Loading Loading @@ -1773,6 +1774,11 @@ public final class OomAdjuster { int clientAdj = client.getCurRawAdj(); int clientProcState = client.getCurRawProcState(); // pass client's mAllowStartFgs to the app if client is not persistent process. if (client.mAllowStartFgs && client.maxAdj >= ProcessList.FOREGROUND_APP_ADJ) { app.mAllowStartFgs = true; } if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) { if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) { continue; Loading Loading @@ -2236,7 +2242,7 @@ public final class OomAdjuster { app.setCurRawProcState(procState); app.setHasForegroundActivities(foregroundActivities); app.completedAdjSeq = mAdjSeq; app.setAllowStartFgs(); // if curAdj or curProcState improved, then this process was promoted return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState || app.curCapability != prevCapability ; Loading services/core/java/com/android/server/am/ProcessRecord.java +90 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,16 @@ package com.android.server.am; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.Manifest.permission.SYSTEM_ALERT_WINDOW; import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.NFC_UID; import static android.os.Process.ROOT_UID; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR; Loading Loading @@ -361,6 +370,17 @@ class ProcessRecord implements WindowProcessListener { private final ArraySet<Binder> mBackgroundFgsStartTokens = new ArraySet<>(); // The list of permissions that can start FGS from background. private static String[] ALLOW_BG_START_FGS_PERMISSIONS = {START_ACTIVITIES_FROM_BACKGROUND, START_FOREGROUND_SERVICES_FROM_BACKGROUND, SYSTEM_ALERT_WINDOW}; // Does the process has permission to start FGS from background. boolean mAllowStartFgsByPermission; // Can this process start FGS from background? // If this process has the ability to start FGS from background, this ability can be passed to // another process through service binding. boolean mAllowStartFgs; void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo, long startTime) { this.startUid = startUid; Loading Loading @@ -476,6 +496,9 @@ class ProcessRecord implements WindowProcessListener { pw.println(); pw.print(prefix); pw.print("allowStartFgsState="); pw.println(mAllowStartFgsState); if (mAllowStartFgs) { pw.print(prefix); pw.print("allowStartFgs="); pw.println(mAllowStartFgs); } if (hasShownUi || mPendingUiClean || hasAboveClient || treatLikeActivity) { pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi); pw.print(" pendingUiClean="); pw.print(mPendingUiClean); Loading Loading @@ -672,6 +695,7 @@ class ProcessRecord implements WindowProcessListener { mWindowProcessController = new WindowProcessController( mService.mActivityTaskManager, info, processName, uid, userId, this, this); pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode)); setAllowStartFgsByPermission(); } public void setPid(int _pid) { Loading Loading @@ -1983,12 +2007,78 @@ class ProcessRecord implements WindowProcessListener { return mDialogController; } void resetAllowStartFgs() { mAllowStartFgsState = PROCESS_STATE_NONEXISTENT; mAllowStartFgs = mAllowStartFgsByPermission; } void bumpAllowStartFgsState(int newProcState) { if (newProcState < mAllowStartFgsState) { mAllowStartFgsState = newProcState; } } void setAllowStartFgsByPermission() { boolean ret = false; if (!ret) { boolean isSystem = false; final int uid = UserHandle.getAppId(info.uid); switch (uid) { case ROOT_UID: case SYSTEM_UID: case NFC_UID: case SHELL_UID: isSystem = true; break; default: isSystem = false; break; } if (isSystem) { ret = true; } } if (!ret) { for (int i = 0; i < ALLOW_BG_START_FGS_PERMISSIONS.length; ++i) { if (ActivityManager.checkComponentPermission(ALLOW_BG_START_FGS_PERMISSIONS[i], info.uid, -1, true) == PERMISSION_GRANTED) { ret = true; break; } } } mAllowStartFgs = mAllowStartFgsByPermission = ret; } boolean isAllowedStartFgsState() { return mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } void setAllowStartFgs() { if (mAllowStartFgs) { return; } if (!mAllowStartFgs) { mAllowStartFgs = isAllowedStartFgsState(); } if (!mAllowStartFgs) { // Is the calling UID a device owner app? if (mService.mInternal != null) { mAllowStartFgs = mService.mInternal.isDeviceOwner(info.uid); } } if (!mAllowStartFgs) { // uid is on DeviceIdleController's user/system allowlist // or AMS's FgsStartTempAllowList. mAllowStartFgs = mService.isWhitelistedForFgsStartLocked(info.uid); } } /** A controller to generate error dialogs in {@link ProcessRecord} */ class ErrorDialogController { /** dialogs being displayed due to crash */ Loading Loading
services/core/java/com/android/server/am/ActiveServices.java +14 −7 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.server.am; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.Manifest.permission.SYSTEM_ALERT_WINDOW; import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; import static android.os.Process.NFC_UID; Loading Loading @@ -168,6 +167,7 @@ public final class ActiveServices { public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION = 16; public static final int FGS_FEATURE_ALLOWED_BY_FGS_BINDING = 17; public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE = 18; public static final int FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD = 19; @IntDef(flag = true, prefix = { "FGS_FEATURE_" }, value = { FGS_FEATURE_DENIED, Loading @@ -187,7 +187,8 @@ public final class ActiveServices { FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST, FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION, FGS_FEATURE_ALLOWED_BY_FGS_BINDING, FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE, FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD }) @Retention(RetentionPolicy.SOURCE) public @interface FgsFeatureRetCode {} Loading Loading @@ -5244,13 +5245,17 @@ public final class ActiveServices { if (ret == FGS_FEATURE_DENIED) { for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) { final ProcessRecord pr = mAm.mProcessList.mLruProcesses.get(i); if (pr.uid == callingUid && pr.mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { if (pr.uid == callingUid) { if (pr.mAllowStartFgs) { ret = FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD; break; } else if (pr.isAllowedStartFgsState()) { ret = FGS_FEATURE_ALLOWED_BY_PROC_STATE; break; } } } } if (ret == FGS_FEATURE_DENIED) { for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) { Loading Loading @@ -5286,7 +5291,7 @@ public final class ActiveServices { } if (ret == FGS_FEATURE_DENIED) { if (mAm.isWhitelistedForFgsStartLocked(r.appInfo.uid)) { if (mAm.isWhitelistedForFgsStartLocked(callingUid)) { // uid is on DeviceIdleController's user/system allowlist // or AMS's FgsStartTempAllowList. ret = FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST; Loading Loading @@ -5354,6 +5359,8 @@ public final class ActiveServices { return "ALLOWED_BY_FGS_BINDING"; case FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE: return "ALLOWED_BY_DEVICE_DEMO_MODE"; case FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD: return "ALLOWED_BY_PROCESS_RECORD"; default: return ""; } Loading
services/core/java/com/android/server/am/OomAdjuster.java +9 −3 Original line number Diff line number Diff line Loading @@ -1329,7 +1329,7 @@ public final class OomAdjuster { app.setCached(false); app.shouldNotFreeze = false; app.mAllowStartFgsState = PROCESS_STATE_NONEXISTENT; app.resetAllowStartFgs(); final int appUid = app.info.uid; final int logUid = mService.mCurOomAdjUid; Loading @@ -1351,7 +1351,6 @@ public final class OomAdjuster { app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT); app.curCapability = PROCESS_CAPABILITY_ALL; app.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT); app.bumpAllowStartFgsState(PROCESS_STATE_PERSISTENT); // System processes can do UI, and when they do we want to have // them trim their memory after the user leaves the UI. To // facilitate this, here we need to determine whether or not it Loading Loading @@ -1382,6 +1381,8 @@ public final class OomAdjuster { app.setCurRawProcState(app.getCurProcState()); app.curAdj = app.maxAdj; app.completedAdjSeq = app.adjSeq; app.bumpAllowStartFgsState(app.getCurProcState()); app.setAllowStartFgs(); // if curAdj is less than prevAppAdj, then this process was promoted return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState; } Loading Loading @@ -1773,6 +1774,11 @@ public final class OomAdjuster { int clientAdj = client.getCurRawAdj(); int clientProcState = client.getCurRawProcState(); // pass client's mAllowStartFgs to the app if client is not persistent process. if (client.mAllowStartFgs && client.maxAdj >= ProcessList.FOREGROUND_APP_ADJ) { app.mAllowStartFgs = true; } if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) { if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) { continue; Loading Loading @@ -2236,7 +2242,7 @@ public final class OomAdjuster { app.setCurRawProcState(procState); app.setHasForegroundActivities(foregroundActivities); app.completedAdjSeq = mAdjSeq; app.setAllowStartFgs(); // if curAdj or curProcState improved, then this process was promoted return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState || app.curCapability != prevCapability ; Loading
services/core/java/com/android/server/am/ProcessRecord.java +90 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,16 @@ package com.android.server.am; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.Manifest.permission.SYSTEM_ALERT_WINDOW; import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.NFC_UID; import static android.os.Process.ROOT_UID; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR; Loading Loading @@ -361,6 +370,17 @@ class ProcessRecord implements WindowProcessListener { private final ArraySet<Binder> mBackgroundFgsStartTokens = new ArraySet<>(); // The list of permissions that can start FGS from background. private static String[] ALLOW_BG_START_FGS_PERMISSIONS = {START_ACTIVITIES_FROM_BACKGROUND, START_FOREGROUND_SERVICES_FROM_BACKGROUND, SYSTEM_ALERT_WINDOW}; // Does the process has permission to start FGS from background. boolean mAllowStartFgsByPermission; // Can this process start FGS from background? // If this process has the ability to start FGS from background, this ability can be passed to // another process through service binding. boolean mAllowStartFgs; void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo, long startTime) { this.startUid = startUid; Loading Loading @@ -476,6 +496,9 @@ class ProcessRecord implements WindowProcessListener { pw.println(); pw.print(prefix); pw.print("allowStartFgsState="); pw.println(mAllowStartFgsState); if (mAllowStartFgs) { pw.print(prefix); pw.print("allowStartFgs="); pw.println(mAllowStartFgs); } if (hasShownUi || mPendingUiClean || hasAboveClient || treatLikeActivity) { pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi); pw.print(" pendingUiClean="); pw.print(mPendingUiClean); Loading Loading @@ -672,6 +695,7 @@ class ProcessRecord implements WindowProcessListener { mWindowProcessController = new WindowProcessController( mService.mActivityTaskManager, info, processName, uid, userId, this, this); pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode)); setAllowStartFgsByPermission(); } public void setPid(int _pid) { Loading Loading @@ -1983,12 +2007,78 @@ class ProcessRecord implements WindowProcessListener { return mDialogController; } void resetAllowStartFgs() { mAllowStartFgsState = PROCESS_STATE_NONEXISTENT; mAllowStartFgs = mAllowStartFgsByPermission; } void bumpAllowStartFgsState(int newProcState) { if (newProcState < mAllowStartFgsState) { mAllowStartFgsState = newProcState; } } void setAllowStartFgsByPermission() { boolean ret = false; if (!ret) { boolean isSystem = false; final int uid = UserHandle.getAppId(info.uid); switch (uid) { case ROOT_UID: case SYSTEM_UID: case NFC_UID: case SHELL_UID: isSystem = true; break; default: isSystem = false; break; } if (isSystem) { ret = true; } } if (!ret) { for (int i = 0; i < ALLOW_BG_START_FGS_PERMISSIONS.length; ++i) { if (ActivityManager.checkComponentPermission(ALLOW_BG_START_FGS_PERMISSIONS[i], info.uid, -1, true) == PERMISSION_GRANTED) { ret = true; break; } } } mAllowStartFgs = mAllowStartFgsByPermission = ret; } boolean isAllowedStartFgsState() { return mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } void setAllowStartFgs() { if (mAllowStartFgs) { return; } if (!mAllowStartFgs) { mAllowStartFgs = isAllowedStartFgsState(); } if (!mAllowStartFgs) { // Is the calling UID a device owner app? if (mService.mInternal != null) { mAllowStartFgs = mService.mInternal.isDeviceOwner(info.uid); } } if (!mAllowStartFgs) { // uid is on DeviceIdleController's user/system allowlist // or AMS's FgsStartTempAllowList. mAllowStartFgs = mService.isWhitelistedForFgsStartLocked(info.uid); } } /** A controller to generate error dialogs in {@link ProcessRecord} */ class ErrorDialogController { /** dialogs being displayed due to crash */ Loading