Loading services/core/java/com/android/server/am/ActiveServices.java +93 −30 Original line number Diff line number Diff line Loading @@ -21,38 +21,40 @@ import static android.Manifest.permission.REQUEST_COMPANION_START_FOREGROUND_SER import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.app.ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI; import static android.app.ActivityManager.PROCESS_STATE_RECEIVER; import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; import static android.os.PowerExemptionManager.REASON_ACTIVITY_STARTER; import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD; import static android.os.PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE; import static android.os.PowerExemptionManager.REASON_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerExemptionManager.REASON_BACKGROUND_FGS_PERMISSION; import static android.os.PowerExemptionManager.REASON_COMPANION_DEVICE_MANAGER; import static android.os.PowerExemptionManager.REASON_DENIED; import static android.os.PowerExemptionManager.REASON_DEVICE_DEMO_MODE; import static android.os.PowerExemptionManager.REASON_DEVICE_OWNER; import static android.os.PowerExemptionManager.REASON_FGS_BINDING; import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_FGS_PERMISSION; import static android.os.PowerExemptionManager.REASON_OPT_OUT_REQUESTED; import static android.os.PowerExemptionManager.REASON_OP_ACTIVATE_PLATFORM_VPN; import static android.os.PowerExemptionManager.REASON_OP_ACTIVATE_VPN; import static android.os.PowerExemptionManager.REASON_PROC_STATE_PERSISTENT; import static android.os.PowerExemptionManager.REASON_PROC_STATE_PERSISTENT_UI; import static android.os.PowerExemptionManager.REASON_PROC_STATE_TOP; import static android.os.PowerExemptionManager.REASON_PROFILE_OWNER; import static android.os.PowerExemptionManager.REASON_SERVICE_LAUNCH; import static android.os.PowerExemptionManager.REASON_START_ACTIVITY_FLAG; import static android.os.PowerExemptionManager.REASON_SYSTEM_ALERT_WINDOW_PERMISSION; import static android.os.PowerExemptionManager.REASON_SYSTEM_ALLOW_LISTED; import static android.os.PowerExemptionManager.REASON_SYSTEM_UID; import static android.os.PowerExemptionManager.REASON_TEMP_ALLOWED_WHILE_IN_USE; import static android.os.PowerWhitelistManager.REASON_ACTIVITY_STARTER; import static android.os.PowerWhitelistManager.REASON_ALLOWLISTED_PACKAGE; import static android.os.PowerWhitelistManager.REASON_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerWhitelistManager.REASON_BACKGROUND_FGS_PERMISSION; import static android.os.PowerWhitelistManager.REASON_COMPANION_DEVICE_MANAGER; import static android.os.PowerWhitelistManager.REASON_DENIED; import static android.os.PowerWhitelistManager.REASON_DEVICE_DEMO_MODE; import static android.os.PowerWhitelistManager.REASON_DEVICE_OWNER; import static android.os.PowerWhitelistManager.REASON_FGS_BINDING; import static android.os.PowerWhitelistManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerWhitelistManager.REASON_INSTR_BACKGROUND_FGS_PERMISSION; import static android.os.PowerWhitelistManager.REASON_PROC_STATE_PERSISTENT; import static android.os.PowerWhitelistManager.REASON_PROC_STATE_PERSISTENT_UI; import static android.os.PowerWhitelistManager.REASON_PROC_STATE_TOP; import static android.os.PowerWhitelistManager.REASON_PROFILE_OWNER; import static android.os.PowerWhitelistManager.REASON_START_ACTIVITY_FLAG; import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALERT_WINDOW_PERMISSION; import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALLOW_LISTED; import static android.os.PowerWhitelistManager.REASON_SYSTEM_UID; import static android.os.PowerWhitelistManager.REASON_UID_VISIBLE; import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.PowerWhitelistManager.getReasonCodeFromProcState; import static android.os.PowerWhitelistManager.reasonCodeToString; import static android.os.PowerExemptionManager.REASON_UID_VISIBLE; import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.PowerExemptionManager.getReasonCodeFromProcState; import static android.os.PowerExemptionManager.reasonCodeToString; import static android.os.Process.INVALID_UID; import static android.os.Process.NFC_UID; import static android.os.Process.ROOT_UID; Loading Loading @@ -118,8 +120,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.PowerWhitelistManager; import android.os.PowerWhitelistManager.ReasonCode; import android.os.PowerExemptionManager.ReasonCode; import android.os.Process; import android.os.RemoteCallback; import android.os.RemoteException; Loading @@ -135,6 +136,7 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -3614,8 +3616,9 @@ public final class ActiveServices { + " for fg-service launch"); } mAm.tempAllowlistUidLocked(r.appInfo.uid, SERVICE_START_FOREGROUND_TIMEOUT, PowerWhitelistManager.REASON_SERVICE_LAUNCH, "fg-service-launch", TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, SERVICE_START_FOREGROUND_TIMEOUT, REASON_SERVICE_LAUNCH, "fg-service-launch", TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, r.mRecentCallingUid); } Loading Loading @@ -5740,6 +5743,66 @@ public final class ActiveServices { int ret = shouldAllowFgsStartForegroundLocked(allowWhileInUse, callingPid, callingUid, callingPackage, r); String bindFromPackage = null; if (ret == REASON_DENIED) { // If the callingUid is not allowed to start FGS, check if the callingUid has any // service that is bound by a clientUid, the clientUid can propagate its BG-FGS-start // capability down to the callingUid. final ArraySet<Integer> checkedClientUids = new ArraySet<>(); final Pair<Integer, String> isAllowed = mAm.mProcessList.searchEachLruProcessesLOSP( false, pr -> { if (pr.uid == callingUid) { final ProcessServiceRecord psr = pr.mServices; final int serviceCount = psr.mServices.size(); for (int svc = 0; svc < serviceCount; svc++) { final ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns = psr.mServices.valueAt(svc).getConnections(); final int size = conns.size(); for (int conni = 0; conni < size; conni++) { final ArrayList<ConnectionRecord> crs = conns.valueAt(conni); for (int con = 0; con < crs.size(); con++) { final ConnectionRecord cr = crs.get(con); final ProcessRecord clientPr = cr.binding.client; // Persistent process does not propagate BG-FGS-start capability // down to service over binding. if (clientPr.mState.getCurProcState() <= PROCESS_STATE_PERSISTENT_UI) { continue; } final int clientPid = clientPr.mPid; final int clientUid = clientPr.uid; // An UID can bind to itself, do not check on itself again. // Also skip already checked clientUid. if (clientUid == callingUid || checkedClientUids.contains(clientUid)) { continue; } final String clientPackageName = cr.clientPackageName; final @ReasonCode int allowWhileInUse2 = shouldAllowFgsWhileInUsePermissionLocked(clientPackageName, clientPid, clientUid, null /* serviceRecord */, false /* allowBackgroundActivityStarts */); final @ReasonCode int allowStartFgs = shouldAllowFgsStartForegroundLocked(allowWhileInUse2, clientPid, clientUid, clientPackageName, null /* targetService */); if (allowStartFgs != REASON_DENIED) { return new Pair<>(allowStartFgs, clientPackageName); } else { checkedClientUids.add(clientUid); } } } } } return null; }); if (isAllowed != null) { ret = REASON_FGS_BINDING; bindFromPackage = isAllowed.second; } } final int uidState = mAm.getUidStateLocked(callingUid); int callerTargetSdkVersion = INVALID_UID; try { Loading @@ -5765,6 +5828,7 @@ public final class ActiveServices { + "; targetSdkVersion:" + r.appInfo.targetSdkVersion + "; callerTargetSdkVersion:" + callerTargetSdkVersion + "; startForegroundCount:" + r.mStartForegroundCount + "; bindFromPackage:" + bindFromPackage + "]"; if (!debugInfo.equals(r.mInfoAllowStartForeground)) { r.mLoggedInfoAllowStartForeground = false; Loading @@ -5790,9 +5854,7 @@ public final class ActiveServices { final Integer allowedType = mAm.mProcessList.searchEachLruProcessesLOSP(false, app -> { if (app.uid == callingUid) { final ProcessStateRecord state = app.mState; if (state.getAllowedStartFgs() != REASON_DENIED) { return state.getAllowedStartFgs(); } else if (state.isAllowedStartFgsState()) { if (state.isAllowedStartFgsState()) { return getReasonCodeFromProcState(state.getAllowStartFgsState()); } else if (state.areBackgroundFgsStartsAllowedByToken()) { return REASON_FGS_BINDING; Loading Loading @@ -5891,6 +5953,7 @@ public final class ActiveServices { } if (ret == REASON_DENIED) { if (mAm.mConstants.mFgsAllowOptOut && targetService != null && targetService.appInfo.hasRequestForegroundServiceExemption()) { ret = REASON_OPT_OUT_REQUESTED; } Loading services/core/java/com/android/server/am/OomAdjuster.java +1 −11 Original line number Diff line number Diff line Loading @@ -42,7 +42,6 @@ import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE; import static android.os.PowerWhitelistManager.REASON_DENIED; import static android.os.Process.SCHED_OTHER; import static android.os.Process.THREAD_GROUP_BACKGROUND; import static android.os.Process.THREAD_GROUP_DEFAULT; Loading Loading @@ -1574,8 +1573,7 @@ public class OomAdjuster { state.setAdjTarget(null); state.setEmpty(false); state.setCached(false); state.setAllowStartFgsState(PROCESS_STATE_NONEXISTENT); state.resetAllowStartFgs(); state.resetAllowStartFgsState(); app.mOptRecord.setShouldNotFreeze(false); final int appUid = app.info.uid; Loading Loading @@ -1630,7 +1628,6 @@ public class OomAdjuster { state.setCurAdj(state.getMaxAdj()); state.setCompletedAdjSeq(state.getAdjSeq()); state.bumpAllowStartFgsState(state.getCurProcState()); state.setAllowStartFgs(); // if curAdj is less than prevAppAdj, then this process was promoted return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState; } Loading Loading @@ -2028,12 +2025,6 @@ public class OomAdjuster { final boolean clientIsSystem = clientProcState < PROCESS_STATE_TOP; // pass client's mAllowStartFgs to the app if client is not persistent process. if (cstate.getAllowedStartFgs() != REASON_DENIED && cstate.getMaxAdj() >= ProcessList.FOREGROUND_APP_ADJ) { state.setAllowStartFgs(cstate.getAllowedStartFgs()); } if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) { if (shouldSkipDueToCycle(state, cstate, procState, adj, cycleReEval)) { continue; Loading Loading @@ -2524,7 +2515,6 @@ public class OomAdjuster { state.updateLastInvisibleTime(hasVisibleActivities); state.setHasForegroundActivities(foregroundActivities); state.setCompletedAdjSeq(mAdjSeq); state.setAllowStartFgs(); // if curAdj or curProcState improved, then this process was promoted return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState Loading services/core/java/com/android/server/am/ProcessServiceRecord.java +1 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ final class ProcessServiceRecord { /** * All ServiceRecord running in this process. */ private final ArraySet<ServiceRecord> mServices = new ArraySet<>(); final ArraySet<ServiceRecord> mServices = new ArraySet<>(); /** * Services that are currently executing code (need to remain foreground). Loading services/core/java/com/android/server/am/ProcessStateRecord.java +1 −139 Original line number Diff line number Diff line Loading @@ -16,28 +16,9 @@ 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_CAPABILITY_NONE; 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.PowerWhitelistManager.REASON_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerWhitelistManager.REASON_BACKGROUND_FGS_PERMISSION; import static android.os.PowerWhitelistManager.REASON_DENIED; import static android.os.PowerWhitelistManager.REASON_DEVICE_OWNER; import static android.os.PowerWhitelistManager.REASON_PROFILE_OWNER; import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALERT_WINDOW_PERMISSION; import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALLOW_LISTED; import static android.os.PowerWhitelistManager.REASON_SYSTEM_UID; import static android.os.PowerWhitelistManager.ReasonCode; import static android.os.PowerWhitelistManager.getReasonCodeFromProcState; import static android.os.PowerWhitelistManager.reasonCodeToString; 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.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; import static com.android.server.am.ProcessRecord.TAG; Loading @@ -47,7 +28,6 @@ import android.app.ActivityManager; import android.content.ComponentName; import android.os.Binder; import android.os.SystemClock; import android.os.UserHandle; import android.util.ArraySet; import android.util.Slog; import android.util.TimeUtils; Loading @@ -56,7 +36,6 @@ import com.android.internal.annotations.CompositeRWLock; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.FrameworkStatsLog; import java.io.PrintWriter; /** Loading Loading @@ -326,20 +305,6 @@ final class ProcessStateRecord { @GuardedBy("mService") private final ArraySet<Binder> mBackgroundFgsStartTokens = new ArraySet<>(); /** * Does the process has permission to start FGS from background. */ @GuardedBy("mService") private @ReasonCode int mAllowStartFgsByPermission = REASON_DENIED; /** * 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. */ @GuardedBy("mService") private @ReasonCode int mAllowStartFgs = REASON_DENIED; /** * Whether or not this process has been in forced-app-standby state. */ Loading Loading @@ -435,7 +400,6 @@ final class ProcessStateRecord { mApp = app; mService = app.mService; mProcLock = mService.mProcLock; setAllowStartFgsByPermission(); } void init(long now) { Loading Loading @@ -1152,9 +1116,8 @@ final class ProcessStateRecord { } @GuardedBy("mService") void resetAllowStartFgs() { void resetAllowStartFgsState() { mAllowStartFgsState = PROCESS_STATE_NONEXISTENT; mAllowStartFgs = mAllowStartFgsByPermission; } @GuardedBy("mService") Loading @@ -1164,11 +1127,6 @@ final class ProcessStateRecord { } } @GuardedBy("mService") void setAllowStartFgsState(int allowStartFgsState) { mAllowStartFgsState = allowStartFgsState; } @GuardedBy("mService") int getAllowStartFgsState() { return mAllowStartFgsState; Loading @@ -1179,98 +1137,6 @@ final class ProcessStateRecord { return mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } @GuardedBy("mService") void setAllowStartFgsByPermission() { int ret = REASON_DENIED; boolean isSystem = false; final int uid = UserHandle.getAppId(mApp.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 = REASON_SYSTEM_UID; } if (ret == REASON_DENIED) { if (ActivityManager.checkComponentPermission(START_ACTIVITIES_FROM_BACKGROUND, mApp.info.uid, -1, true) == PERMISSION_GRANTED) { ret = REASON_BACKGROUND_ACTIVITY_PERMISSION; } else if (ActivityManager.checkComponentPermission( START_FOREGROUND_SERVICES_FROM_BACKGROUND, mApp.info.uid, -1, true) == PERMISSION_GRANTED) { ret = REASON_BACKGROUND_FGS_PERMISSION; } else if (ActivityManager.checkComponentPermission(SYSTEM_ALERT_WINDOW, mApp.info.uid, -1, true) == PERMISSION_GRANTED) { ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION; } } mAllowStartFgs = mAllowStartFgsByPermission = ret; } // TODO(b/188063200) Clean up this method. Why do we need to duplicate only some of the checks? @GuardedBy("mService") void setAllowStartFgs() { if (mAllowStartFgs != REASON_DENIED) { return; } if (mAllowStartFgs == REASON_DENIED) { if (isAllowedStartFgsState()) { mAllowStartFgs = getReasonCodeFromProcState(mAllowStartFgsState); } } if (mAllowStartFgs == REASON_DENIED) { // Is the calling UID a device owner app? if (mService.mInternal != null) { if (mService.mInternal.isDeviceOwner(mApp.info.uid)) { mAllowStartFgs = REASON_DEVICE_OWNER; } } } if (mAllowStartFgs == REASON_DENIED) { // Is the calling UID a profile owner app? if (mService.mInternal != null) { if (mService.mInternal.isProfileOwner(mApp.info.uid)) { mAllowStartFgs = REASON_PROFILE_OWNER; } } } if (mAllowStartFgs == REASON_DENIED) { // uid is on DeviceIdleController's user/system allowlist // or AMS's FgsStartTempAllowList. ActivityManagerService.FgsTempAllowListItem item = mService.isAllowlistedForFgsStartLOSP(mApp.info.uid); if (item != null) { if (item == ActivityManagerService.FAKE_TEMP_ALLOW_LIST_ITEM) { mAllowStartFgs = REASON_SYSTEM_ALLOW_LISTED; } else { mAllowStartFgs = item.mReasonCode; } } } } @GuardedBy("mService") void setAllowStartFgs(@ReasonCode int allowStartFgs) { mAllowStartFgs = allowStartFgs; } @GuardedBy("mService") @ReasonCode int getAllowedStartFgs() { return mAllowStartFgs; } @GuardedBy("mService") void setForcedAppStandby(boolean standby) { mForcedAppStandby = standby; Loading Loading @@ -1334,10 +1200,6 @@ final class ProcessStateRecord { pw.println(); pw.print(prefix); pw.print("allowStartFgsState="); pw.println(mAllowStartFgsState); if (mAllowStartFgs != REASON_DENIED) { pw.print(prefix); pw.print("allowStartFgs="); pw.println(reasonCodeToString(mAllowStartFgs)); } if (mHasShownUi || mApp.mProfile.hasPendingUiClean()) { pw.print(prefix); pw.print("hasShownUi="); pw.print(mHasShownUi); pw.print(" pendingUiClean="); pw.println(mApp.mProfile.hasPendingUiClean()); Loading Loading
services/core/java/com/android/server/am/ActiveServices.java +93 −30 Original line number Diff line number Diff line Loading @@ -21,38 +21,40 @@ import static android.Manifest.permission.REQUEST_COMPANION_START_FOREGROUND_SER import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.app.ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI; import static android.app.ActivityManager.PROCESS_STATE_RECEIVER; import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; import static android.os.PowerExemptionManager.REASON_ACTIVITY_STARTER; import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD; import static android.os.PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE; import static android.os.PowerExemptionManager.REASON_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerExemptionManager.REASON_BACKGROUND_FGS_PERMISSION; import static android.os.PowerExemptionManager.REASON_COMPANION_DEVICE_MANAGER; import static android.os.PowerExemptionManager.REASON_DENIED; import static android.os.PowerExemptionManager.REASON_DEVICE_DEMO_MODE; import static android.os.PowerExemptionManager.REASON_DEVICE_OWNER; import static android.os.PowerExemptionManager.REASON_FGS_BINDING; import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_FGS_PERMISSION; import static android.os.PowerExemptionManager.REASON_OPT_OUT_REQUESTED; import static android.os.PowerExemptionManager.REASON_OP_ACTIVATE_PLATFORM_VPN; import static android.os.PowerExemptionManager.REASON_OP_ACTIVATE_VPN; import static android.os.PowerExemptionManager.REASON_PROC_STATE_PERSISTENT; import static android.os.PowerExemptionManager.REASON_PROC_STATE_PERSISTENT_UI; import static android.os.PowerExemptionManager.REASON_PROC_STATE_TOP; import static android.os.PowerExemptionManager.REASON_PROFILE_OWNER; import static android.os.PowerExemptionManager.REASON_SERVICE_LAUNCH; import static android.os.PowerExemptionManager.REASON_START_ACTIVITY_FLAG; import static android.os.PowerExemptionManager.REASON_SYSTEM_ALERT_WINDOW_PERMISSION; import static android.os.PowerExemptionManager.REASON_SYSTEM_ALLOW_LISTED; import static android.os.PowerExemptionManager.REASON_SYSTEM_UID; import static android.os.PowerExemptionManager.REASON_TEMP_ALLOWED_WHILE_IN_USE; import static android.os.PowerWhitelistManager.REASON_ACTIVITY_STARTER; import static android.os.PowerWhitelistManager.REASON_ALLOWLISTED_PACKAGE; import static android.os.PowerWhitelistManager.REASON_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerWhitelistManager.REASON_BACKGROUND_FGS_PERMISSION; import static android.os.PowerWhitelistManager.REASON_COMPANION_DEVICE_MANAGER; import static android.os.PowerWhitelistManager.REASON_DENIED; import static android.os.PowerWhitelistManager.REASON_DEVICE_DEMO_MODE; import static android.os.PowerWhitelistManager.REASON_DEVICE_OWNER; import static android.os.PowerWhitelistManager.REASON_FGS_BINDING; import static android.os.PowerWhitelistManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerWhitelistManager.REASON_INSTR_BACKGROUND_FGS_PERMISSION; import static android.os.PowerWhitelistManager.REASON_PROC_STATE_PERSISTENT; import static android.os.PowerWhitelistManager.REASON_PROC_STATE_PERSISTENT_UI; import static android.os.PowerWhitelistManager.REASON_PROC_STATE_TOP; import static android.os.PowerWhitelistManager.REASON_PROFILE_OWNER; import static android.os.PowerWhitelistManager.REASON_START_ACTIVITY_FLAG; import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALERT_WINDOW_PERMISSION; import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALLOW_LISTED; import static android.os.PowerWhitelistManager.REASON_SYSTEM_UID; import static android.os.PowerWhitelistManager.REASON_UID_VISIBLE; import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.PowerWhitelistManager.getReasonCodeFromProcState; import static android.os.PowerWhitelistManager.reasonCodeToString; import static android.os.PowerExemptionManager.REASON_UID_VISIBLE; import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.PowerExemptionManager.getReasonCodeFromProcState; import static android.os.PowerExemptionManager.reasonCodeToString; import static android.os.Process.INVALID_UID; import static android.os.Process.NFC_UID; import static android.os.Process.ROOT_UID; Loading Loading @@ -118,8 +120,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.PowerWhitelistManager; import android.os.PowerWhitelistManager.ReasonCode; import android.os.PowerExemptionManager.ReasonCode; import android.os.Process; import android.os.RemoteCallback; import android.os.RemoteException; Loading @@ -135,6 +136,7 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -3614,8 +3616,9 @@ public final class ActiveServices { + " for fg-service launch"); } mAm.tempAllowlistUidLocked(r.appInfo.uid, SERVICE_START_FOREGROUND_TIMEOUT, PowerWhitelistManager.REASON_SERVICE_LAUNCH, "fg-service-launch", TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, SERVICE_START_FOREGROUND_TIMEOUT, REASON_SERVICE_LAUNCH, "fg-service-launch", TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, r.mRecentCallingUid); } Loading Loading @@ -5740,6 +5743,66 @@ public final class ActiveServices { int ret = shouldAllowFgsStartForegroundLocked(allowWhileInUse, callingPid, callingUid, callingPackage, r); String bindFromPackage = null; if (ret == REASON_DENIED) { // If the callingUid is not allowed to start FGS, check if the callingUid has any // service that is bound by a clientUid, the clientUid can propagate its BG-FGS-start // capability down to the callingUid. final ArraySet<Integer> checkedClientUids = new ArraySet<>(); final Pair<Integer, String> isAllowed = mAm.mProcessList.searchEachLruProcessesLOSP( false, pr -> { if (pr.uid == callingUid) { final ProcessServiceRecord psr = pr.mServices; final int serviceCount = psr.mServices.size(); for (int svc = 0; svc < serviceCount; svc++) { final ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns = psr.mServices.valueAt(svc).getConnections(); final int size = conns.size(); for (int conni = 0; conni < size; conni++) { final ArrayList<ConnectionRecord> crs = conns.valueAt(conni); for (int con = 0; con < crs.size(); con++) { final ConnectionRecord cr = crs.get(con); final ProcessRecord clientPr = cr.binding.client; // Persistent process does not propagate BG-FGS-start capability // down to service over binding. if (clientPr.mState.getCurProcState() <= PROCESS_STATE_PERSISTENT_UI) { continue; } final int clientPid = clientPr.mPid; final int clientUid = clientPr.uid; // An UID can bind to itself, do not check on itself again. // Also skip already checked clientUid. if (clientUid == callingUid || checkedClientUids.contains(clientUid)) { continue; } final String clientPackageName = cr.clientPackageName; final @ReasonCode int allowWhileInUse2 = shouldAllowFgsWhileInUsePermissionLocked(clientPackageName, clientPid, clientUid, null /* serviceRecord */, false /* allowBackgroundActivityStarts */); final @ReasonCode int allowStartFgs = shouldAllowFgsStartForegroundLocked(allowWhileInUse2, clientPid, clientUid, clientPackageName, null /* targetService */); if (allowStartFgs != REASON_DENIED) { return new Pair<>(allowStartFgs, clientPackageName); } else { checkedClientUids.add(clientUid); } } } } } return null; }); if (isAllowed != null) { ret = REASON_FGS_BINDING; bindFromPackage = isAllowed.second; } } final int uidState = mAm.getUidStateLocked(callingUid); int callerTargetSdkVersion = INVALID_UID; try { Loading @@ -5765,6 +5828,7 @@ public final class ActiveServices { + "; targetSdkVersion:" + r.appInfo.targetSdkVersion + "; callerTargetSdkVersion:" + callerTargetSdkVersion + "; startForegroundCount:" + r.mStartForegroundCount + "; bindFromPackage:" + bindFromPackage + "]"; if (!debugInfo.equals(r.mInfoAllowStartForeground)) { r.mLoggedInfoAllowStartForeground = false; Loading @@ -5790,9 +5854,7 @@ public final class ActiveServices { final Integer allowedType = mAm.mProcessList.searchEachLruProcessesLOSP(false, app -> { if (app.uid == callingUid) { final ProcessStateRecord state = app.mState; if (state.getAllowedStartFgs() != REASON_DENIED) { return state.getAllowedStartFgs(); } else if (state.isAllowedStartFgsState()) { if (state.isAllowedStartFgsState()) { return getReasonCodeFromProcState(state.getAllowStartFgsState()); } else if (state.areBackgroundFgsStartsAllowedByToken()) { return REASON_FGS_BINDING; Loading Loading @@ -5891,6 +5953,7 @@ public final class ActiveServices { } if (ret == REASON_DENIED) { if (mAm.mConstants.mFgsAllowOptOut && targetService != null && targetService.appInfo.hasRequestForegroundServiceExemption()) { ret = REASON_OPT_OUT_REQUESTED; } Loading
services/core/java/com/android/server/am/OomAdjuster.java +1 −11 Original line number Diff line number Diff line Loading @@ -42,7 +42,6 @@ import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE; import static android.os.PowerWhitelistManager.REASON_DENIED; import static android.os.Process.SCHED_OTHER; import static android.os.Process.THREAD_GROUP_BACKGROUND; import static android.os.Process.THREAD_GROUP_DEFAULT; Loading Loading @@ -1574,8 +1573,7 @@ public class OomAdjuster { state.setAdjTarget(null); state.setEmpty(false); state.setCached(false); state.setAllowStartFgsState(PROCESS_STATE_NONEXISTENT); state.resetAllowStartFgs(); state.resetAllowStartFgsState(); app.mOptRecord.setShouldNotFreeze(false); final int appUid = app.info.uid; Loading Loading @@ -1630,7 +1628,6 @@ public class OomAdjuster { state.setCurAdj(state.getMaxAdj()); state.setCompletedAdjSeq(state.getAdjSeq()); state.bumpAllowStartFgsState(state.getCurProcState()); state.setAllowStartFgs(); // if curAdj is less than prevAppAdj, then this process was promoted return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState; } Loading Loading @@ -2028,12 +2025,6 @@ public class OomAdjuster { final boolean clientIsSystem = clientProcState < PROCESS_STATE_TOP; // pass client's mAllowStartFgs to the app if client is not persistent process. if (cstate.getAllowedStartFgs() != REASON_DENIED && cstate.getMaxAdj() >= ProcessList.FOREGROUND_APP_ADJ) { state.setAllowStartFgs(cstate.getAllowedStartFgs()); } if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) { if (shouldSkipDueToCycle(state, cstate, procState, adj, cycleReEval)) { continue; Loading Loading @@ -2524,7 +2515,6 @@ public class OomAdjuster { state.updateLastInvisibleTime(hasVisibleActivities); state.setHasForegroundActivities(foregroundActivities); state.setCompletedAdjSeq(mAdjSeq); state.setAllowStartFgs(); // if curAdj or curProcState improved, then this process was promoted return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState Loading
services/core/java/com/android/server/am/ProcessServiceRecord.java +1 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ final class ProcessServiceRecord { /** * All ServiceRecord running in this process. */ private final ArraySet<ServiceRecord> mServices = new ArraySet<>(); final ArraySet<ServiceRecord> mServices = new ArraySet<>(); /** * Services that are currently executing code (need to remain foreground). Loading
services/core/java/com/android/server/am/ProcessStateRecord.java +1 −139 Original line number Diff line number Diff line Loading @@ -16,28 +16,9 @@ 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_CAPABILITY_NONE; 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.PowerWhitelistManager.REASON_BACKGROUND_ACTIVITY_PERMISSION; import static android.os.PowerWhitelistManager.REASON_BACKGROUND_FGS_PERMISSION; import static android.os.PowerWhitelistManager.REASON_DENIED; import static android.os.PowerWhitelistManager.REASON_DEVICE_OWNER; import static android.os.PowerWhitelistManager.REASON_PROFILE_OWNER; import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALERT_WINDOW_PERMISSION; import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALLOW_LISTED; import static android.os.PowerWhitelistManager.REASON_SYSTEM_UID; import static android.os.PowerWhitelistManager.ReasonCode; import static android.os.PowerWhitelistManager.getReasonCodeFromProcState; import static android.os.PowerWhitelistManager.reasonCodeToString; 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.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; import static com.android.server.am.ProcessRecord.TAG; Loading @@ -47,7 +28,6 @@ import android.app.ActivityManager; import android.content.ComponentName; import android.os.Binder; import android.os.SystemClock; import android.os.UserHandle; import android.util.ArraySet; import android.util.Slog; import android.util.TimeUtils; Loading @@ -56,7 +36,6 @@ import com.android.internal.annotations.CompositeRWLock; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.FrameworkStatsLog; import java.io.PrintWriter; /** Loading Loading @@ -326,20 +305,6 @@ final class ProcessStateRecord { @GuardedBy("mService") private final ArraySet<Binder> mBackgroundFgsStartTokens = new ArraySet<>(); /** * Does the process has permission to start FGS from background. */ @GuardedBy("mService") private @ReasonCode int mAllowStartFgsByPermission = REASON_DENIED; /** * 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. */ @GuardedBy("mService") private @ReasonCode int mAllowStartFgs = REASON_DENIED; /** * Whether or not this process has been in forced-app-standby state. */ Loading Loading @@ -435,7 +400,6 @@ final class ProcessStateRecord { mApp = app; mService = app.mService; mProcLock = mService.mProcLock; setAllowStartFgsByPermission(); } void init(long now) { Loading Loading @@ -1152,9 +1116,8 @@ final class ProcessStateRecord { } @GuardedBy("mService") void resetAllowStartFgs() { void resetAllowStartFgsState() { mAllowStartFgsState = PROCESS_STATE_NONEXISTENT; mAllowStartFgs = mAllowStartFgsByPermission; } @GuardedBy("mService") Loading @@ -1164,11 +1127,6 @@ final class ProcessStateRecord { } } @GuardedBy("mService") void setAllowStartFgsState(int allowStartFgsState) { mAllowStartFgsState = allowStartFgsState; } @GuardedBy("mService") int getAllowStartFgsState() { return mAllowStartFgsState; Loading @@ -1179,98 +1137,6 @@ final class ProcessStateRecord { return mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } @GuardedBy("mService") void setAllowStartFgsByPermission() { int ret = REASON_DENIED; boolean isSystem = false; final int uid = UserHandle.getAppId(mApp.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 = REASON_SYSTEM_UID; } if (ret == REASON_DENIED) { if (ActivityManager.checkComponentPermission(START_ACTIVITIES_FROM_BACKGROUND, mApp.info.uid, -1, true) == PERMISSION_GRANTED) { ret = REASON_BACKGROUND_ACTIVITY_PERMISSION; } else if (ActivityManager.checkComponentPermission( START_FOREGROUND_SERVICES_FROM_BACKGROUND, mApp.info.uid, -1, true) == PERMISSION_GRANTED) { ret = REASON_BACKGROUND_FGS_PERMISSION; } else if (ActivityManager.checkComponentPermission(SYSTEM_ALERT_WINDOW, mApp.info.uid, -1, true) == PERMISSION_GRANTED) { ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION; } } mAllowStartFgs = mAllowStartFgsByPermission = ret; } // TODO(b/188063200) Clean up this method. Why do we need to duplicate only some of the checks? @GuardedBy("mService") void setAllowStartFgs() { if (mAllowStartFgs != REASON_DENIED) { return; } if (mAllowStartFgs == REASON_DENIED) { if (isAllowedStartFgsState()) { mAllowStartFgs = getReasonCodeFromProcState(mAllowStartFgsState); } } if (mAllowStartFgs == REASON_DENIED) { // Is the calling UID a device owner app? if (mService.mInternal != null) { if (mService.mInternal.isDeviceOwner(mApp.info.uid)) { mAllowStartFgs = REASON_DEVICE_OWNER; } } } if (mAllowStartFgs == REASON_DENIED) { // Is the calling UID a profile owner app? if (mService.mInternal != null) { if (mService.mInternal.isProfileOwner(mApp.info.uid)) { mAllowStartFgs = REASON_PROFILE_OWNER; } } } if (mAllowStartFgs == REASON_DENIED) { // uid is on DeviceIdleController's user/system allowlist // or AMS's FgsStartTempAllowList. ActivityManagerService.FgsTempAllowListItem item = mService.isAllowlistedForFgsStartLOSP(mApp.info.uid); if (item != null) { if (item == ActivityManagerService.FAKE_TEMP_ALLOW_LIST_ITEM) { mAllowStartFgs = REASON_SYSTEM_ALLOW_LISTED; } else { mAllowStartFgs = item.mReasonCode; } } } } @GuardedBy("mService") void setAllowStartFgs(@ReasonCode int allowStartFgs) { mAllowStartFgs = allowStartFgs; } @GuardedBy("mService") @ReasonCode int getAllowedStartFgs() { return mAllowStartFgs; } @GuardedBy("mService") void setForcedAppStandby(boolean standby) { mForcedAppStandby = standby; Loading Loading @@ -1334,10 +1200,6 @@ final class ProcessStateRecord { pw.println(); pw.print(prefix); pw.print("allowStartFgsState="); pw.println(mAllowStartFgsState); if (mAllowStartFgs != REASON_DENIED) { pw.print(prefix); pw.print("allowStartFgs="); pw.println(reasonCodeToString(mAllowStartFgs)); } if (mHasShownUi || mApp.mProfile.hasPendingUiClean()) { pw.print(prefix); pw.print("hasShownUi="); pw.print(mHasShownUi); pw.print(" pendingUiClean="); pw.println(mApp.mProfile.hasPendingUiClean()); Loading