diff options
13 files changed, 173 insertions, 192 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 80b6349ca284..395c867de9d7 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -513,71 +513,75 @@ public class ActivityManager { /** @hide Process is hosting a foreground service with location type. */ public static final int PROCESS_STATE_FOREGROUND_SERVICE_LOCATION = 3; + /** @hide Process is bound to a TOP app. This is ranked below SERVICE_LOCATION so that + * it doesn't get the capability of location access while-in-use. */ + public static final int PROCESS_STATE_BOUND_TOP = 4; + /** @hide Process is hosting a foreground service. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; + public static final int PROCESS_STATE_FOREGROUND_SERVICE = 5; /** @hide Process is hosting a foreground service due to a system binding. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 5; + public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 6; /** @hide Process is important to the user, and something they are aware of. */ - public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6; + public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 7; /** @hide Process is important to the user, but not something they are aware of. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7; + public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 8; /** @hide Process is in the background transient so we will try to keep running. */ - public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 8; + public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 9; /** @hide Process is in the background running a backup/restore operation. */ - public static final int PROCESS_STATE_BACKUP = 9; + public static final int PROCESS_STATE_BACKUP = 10; /** @hide Process is in the background running a service. Unlike oom_adj, this level * is used for both the normal running in background state and the executing * operations state. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_SERVICE = 10; + public static final int PROCESS_STATE_SERVICE = 11; /** @hide Process is in the background running a receiver. Note that from the * perspective of oom_adj, receivers run at a higher foreground level, but for our * prioritization here that is not necessary and putting them below services means * many fewer changes in some process states as they receive broadcasts. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_RECEIVER = 11; + public static final int PROCESS_STATE_RECEIVER = 12; /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */ - public static final int PROCESS_STATE_TOP_SLEEPING = 12; + public static final int PROCESS_STATE_TOP_SLEEPING = 13; /** @hide Process is in the background, but it can't restore its state so we want * to try to avoid killing it. */ - public static final int PROCESS_STATE_HEAVY_WEIGHT = 13; + public static final int PROCESS_STATE_HEAVY_WEIGHT = 14; /** @hide Process is in the background but hosts the home activity. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_HOME = 14; + public static final int PROCESS_STATE_HOME = 15; /** @hide Process is in the background but hosts the last shown activity. */ - public static final int PROCESS_STATE_LAST_ACTIVITY = 15; + public static final int PROCESS_STATE_LAST_ACTIVITY = 16; /** @hide Process is being cached for later use and contains activities. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_CACHED_ACTIVITY = 16; + public static final int PROCESS_STATE_CACHED_ACTIVITY = 17; /** @hide Process is being cached for later use and is a client of another cached * process that contains activities. */ - public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 17; + public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 18; /** @hide Process is being cached for later use and has an activity that corresponds * to an existing recent task. */ - public static final int PROCESS_STATE_CACHED_RECENT = 18; + public static final int PROCESS_STATE_CACHED_RECENT = 19; /** @hide Process is being cached for later use and is empty. */ - public static final int PROCESS_STATE_CACHED_EMPTY = 19; + public static final int PROCESS_STATE_CACHED_EMPTY = 20; /** @hide Process does not exist. */ - public static final int PROCESS_STATE_NONEXISTENT = 20; + public static final int PROCESS_STATE_NONEXISTENT = 21; // NOTE: If PROCESS_STATEs are added, then new fields must be added // to frameworks/base/core/proto/android/app/enums.proto and the following method must @@ -602,6 +606,8 @@ public class ActivityManager { return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI; case PROCESS_STATE_TOP: return AppProtoEnums.PROCESS_STATE_TOP; + case PROCESS_STATE_BOUND_TOP: + return AppProtoEnums.PROCESS_STATE_BOUND_TOP; case PROCESS_STATE_FOREGROUND_SERVICE_LOCATION: case PROCESS_STATE_FOREGROUND_SERVICE: return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE; diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index d7a2e1b80f84..af738da20621 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -427,7 +427,7 @@ public abstract class Context { * invisible background activities. This will impact the number of * recent activities the user can switch between without having them * restart. There is no guarantee this will be respected, as the system - * tries to balance such requests from one app vs. the importantance of + * tries to balance such requests from one app vs. the importance of * keeping other apps around. */ public static final int BIND_VISIBLE = 0x10000000; diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index b64fe007bcd9..00d522bae27f 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -16,6 +16,7 @@ package android.os; +import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION; import android.annotation.UnsupportedAppUsage; @@ -859,7 +860,8 @@ public abstract class BatteryStats implements Parcelable { */ public static final int[] CRITICAL_PROC_STATES = { PROCESS_STATE_TOP, - PROCESS_STATE_FOREGROUND_SERVICE_LOCATION, PROCESS_STATE_FOREGROUND_SERVICE, + PROCESS_STATE_FOREGROUND_SERVICE_LOCATION, + PROCESS_STATE_BOUND_TOP, PROCESS_STATE_FOREGROUND_SERVICE, PROCESS_STATE_FOREGROUND }; diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java index 0e4897f9eb9c..b26efc0dbd10 100644 --- a/core/java/com/android/internal/app/procstats/ProcessState.java +++ b/core/java/com/android/internal/app/procstats/ProcessState.java @@ -79,6 +79,7 @@ public final class ProcessState { STATE_TOP, // ActivityManager.PROCESS_STATE_TOP STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE + STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_TOP STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND STATE_IMPORTANT_BACKGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND diff --git a/core/proto/android/app/enums.proto b/core/proto/android/app/enums.proto index 1754e426fe93..9abe92330cb0 100644 --- a/core/proto/android/app/enums.proto +++ b/core/proto/android/app/enums.proto @@ -38,6 +38,7 @@ enum AppTransitionReasonEnum { } // ActivityManager.java PROCESS_STATEs +// Next tag: 1021 enum ProcessStateEnum { // Unlike the ActivityManager PROCESS_STATE values, the ordering and numerical values // here are completely fixed and arbitrary. Order is irrelevant. @@ -56,9 +57,11 @@ enum ProcessStateEnum { // Process is hosting the current top activities. Note that this covers // all activities that are visible to the user. PROCESS_STATE_TOP = 1002; + // Process is bound to a TOP app. + PROCESS_STATE_BOUND_TOP = 1020; // Process is hosting a foreground service. PROCESS_STATE_FOREGROUND_SERVICE = 1003; - // Process is hosting a foreground service due to a system binding. + // Process is hosting a service bound by the system or another foreground app. PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 1004; // Process is important to the user, and something they are aware of. PROCESS_STATE_IMPORTANT_FOREGROUND = 1005; diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 261ed4c7e854..f0982d3aa142 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -1344,7 +1344,8 @@ public final class ActiveServices { if (!r.isForeground) { final ServiceMap smap = getServiceMapLocked(r.userId); if (smap != null) { - ActiveForegroundApp active = smap.mActiveForegroundApps.get(r.packageName); + ActiveForegroundApp active = smap.mActiveForegroundApps + .get(r.packageName); if (active == null) { active = new ActiveForegroundApp(); active.mPackageName = r.packageName; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 3eb7c0374a01..69e69f0f186d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -15333,18 +15333,20 @@ public class ActivityManagerService extends IActivityManager.Stub final ProcessRecord callerApp = getRecordForAppLocked(caller); final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); + final long origId = Binder.clearCallingIdentity(); - int res = broadcastIntentLocked(callerApp, - callerApp != null ? callerApp.info.packageName : null, - intent, resolvedType, resultTo, resultCode, resultData, resultExtras, - requiredPermissions, appOp, bOptions, serialized, sticky, - callingPid, callingUid, callingUid, callingPid, userId); - Binder.restoreCallingIdentity(origId); - return res; + try { + return broadcastIntentLocked(callerApp, + callerApp != null ? callerApp.info.packageName : null, + intent, resolvedType, resultTo, resultCode, resultData, resultExtras, + requiredPermissions, appOp, bOptions, serialized, sticky, + callingPid, callingUid, callingUid, callingPid, userId); + } finally { + Binder.restoreCallingIdentity(origId); + } } } - int broadcastIntentInPackage(String packageName, int uid, int realCallingUid, int realCallingPid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, @@ -15356,13 +15358,15 @@ public class ActivityManagerService extends IActivityManager.Stub final long origId = Binder.clearCallingIdentity(); String[] requiredPermissions = requiredPermission == null ? null : new String[] {requiredPermission}; - int res = broadcastIntentLocked(null, packageName, intent, resolvedType, - resultTo, resultCode, resultData, resultExtras, - requiredPermissions, OP_NONE, bOptions, serialized, - sticky, -1, uid, realCallingUid, realCallingPid, userId, - allowBackgroundActivityStarts); - Binder.restoreCallingIdentity(origId); - return res; + try { + return broadcastIntentLocked(null, packageName, intent, resolvedType, + resultTo, resultCode, resultData, resultExtras, + requiredPermissions, OP_NONE, bOptions, serialized, + sticky, -1, uid, realCallingUid, realCallingPid, userId, + allowBackgroundActivityStarts); + } finally { + Binder.restoreCallingIdentity(origId); + } } } diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java index a1c941e085a6..fe9554255feb 100644 --- a/services/core/java/com/android/server/am/ConnectionRecord.java +++ b/services/core/java/com/android/server/am/ConnectionRecord.java @@ -109,6 +109,14 @@ final class ConnectionRecord { clientPackageName = _clientPackageName; } + public boolean hasFlag(final int flag) { + return (flags & flag) != 0; + } + + public boolean notHasFlag(final int flag) { + return (flags & flag) == 0; + } + public void startAssociationIfNeeded() { // If we don't already have an active association, create one... but only if this // is an association between two different processes. diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 924e3310fbd2..5d47c9dfdddd 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -16,10 +16,19 @@ package com.android.server.am; +import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; +import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY; +import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; +import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION; +import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; +import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; +import static android.app.ActivityManager.PROCESS_STATE_SERVICE; +import static android.app.ActivityManager.PROCESS_STATE_TOP; +import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; import static android.os.Process.SCHED_OTHER; import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE; import static android.os.Process.THREAD_GROUP_DEFAULT; @@ -413,7 +422,7 @@ public final class OomAdjuster { app.kill("cached #" + numCached, true); } break; - case ActivityManager.PROCESS_STATE_CACHED_EMPTY: + case PROCESS_STATE_CACHED_EMPTY: if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES && app.lastActivityTime < oldTime) { app.kill("empty for " @@ -718,7 +727,7 @@ public final class OomAdjuster { if (app.thread == null) { app.adjSeq = mAdjSeq; app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_BACKGROUND); - app.setCurProcState(ActivityManager.PROCESS_STATE_CACHED_EMPTY); + app.setCurProcState(PROCESS_STATE_CACHED_EMPTY); app.curAdj = ProcessList.CACHED_APP_MAX_ADJ; app.setCurRawAdj(ProcessList.CACHED_APP_MAX_ADJ); app.completedAdjSeq = app.adjSeq; @@ -773,7 +782,7 @@ public final class OomAdjuster { app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP); } else { // screen off, restrict UI scheduling - app.setCurProcState(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); + app.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE); app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED); } } @@ -797,7 +806,7 @@ public final class OomAdjuster { boolean foregroundActivities = false; mTmpBroadcastQueue.clear(); - if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) { + if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == TOP_APP) { // The last app on the list is the foreground app. adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_TOP_APP; @@ -820,7 +829,7 @@ public final class OomAdjuster { adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_DEFAULT; app.adjType = "instrumentation"; - procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; + procState = PROCESS_STATE_FOREGROUND_SERVICE; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app); } @@ -844,7 +853,7 @@ public final class OomAdjuster { schedGroup = app.execServicesFg ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; app.adjType = "exec-service"; - procState = ActivityManager.PROCESS_STATE_SERVICE; + procState = PROCESS_STATE_SERVICE; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app); } @@ -864,7 +873,7 @@ public final class OomAdjuster { // At this point we don't actually know the adjustment. Use the cached adj // value that the caller wants us to. adj = cachedAdj; - procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; + procState = PROCESS_STATE_CACHED_EMPTY; app.cached = true; app.empty = true; app.adjType = "cch-empty"; @@ -899,23 +908,28 @@ public final class OomAdjuster { } if (adj > ProcessList.PERCEPTIBLE_APP_ADJ - || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION) { + || procState > PROCESS_STATE_FOREGROUND_SERVICE_LOCATION) { if (app.hasForegroundServices()) { // The user is aware of this app, so make it visible. adj = ProcessList.PERCEPTIBLE_APP_ADJ; - procState = app.hasLocationForegroundServices() - ? ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION - : ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; + if (app.hasLocationForegroundServices()) { + procState = PROCESS_STATE_FOREGROUND_SERVICE_LOCATION; + app.adjType = "fg-service-location"; + + } else { + procState = PROCESS_STATE_FOREGROUND_SERVICE; + app.adjType = "fg-service"; + } app.cached = false; - app.adjType = "fg-service"; schedGroup = ProcessList.SCHED_GROUP_DEFAULT; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to fg service: " + app); + reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + app.adjType + ": " + + app + " "); } } else if (app.hasOverlayUi()) { // The process is display an overlay UI. adj = ProcessList.PERCEPTIBLE_APP_ADJ; - procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; + procState = PROCESS_STATE_IMPORTANT_FOREGROUND; app.cached = false; app.adjType = "has-overlay-ui"; schedGroup = ProcessList.SCHED_GROUP_DEFAULT; @@ -930,7 +944,7 @@ public final class OomAdjuster { // services so that it can finish performing any persistence/processing of in-memory state. if (app.hasForegroundServices() && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now - || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) { + || app.setProcState <= PROCESS_STATE_TOP)) { adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ; app.adjType = "fg-service-act"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { @@ -939,13 +953,13 @@ public final class OomAdjuster { } if (adj > ProcessList.PERCEPTIBLE_APP_ADJ - || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { + || procState > PROCESS_STATE_TRANSIENT_BACKGROUND) { if (app.forcingToImportant != null) { // This is currently used for toasts... they are not interactive, and // we don't want them to cause the app to become fully foreground (and // thus out of background check), so we yes the best background level we can. adj = ProcessList.PERCEPTIBLE_APP_ADJ; - procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; + procState = PROCESS_STATE_TRANSIENT_BACKGROUND; app.cached = false; app.adjType = "force-imp"; app.adjSource = app.forcingToImportant; @@ -1041,8 +1055,8 @@ public final class OomAdjuster { if (adj > ProcessList.BACKUP_APP_ADJ) { if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app); adj = ProcessList.BACKUP_APP_ADJ; - if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { - procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; + if (procState > PROCESS_STATE_TRANSIENT_BACKGROUND) { + procState = PROCESS_STATE_TRANSIENT_BACKGROUND; } app.adjType = "backup"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { @@ -1059,21 +1073,16 @@ public final class OomAdjuster { } } - boolean mayBeTop = false; - String mayBeTopType = null; - Object mayBeTopSource = null; - Object mayBeTopTarget = null; - for (int is = app.services.size() - 1; is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND - || procState > ActivityManager.PROCESS_STATE_TOP); + || procState > PROCESS_STATE_TOP); is--) { ServiceRecord s = app.services.valueAt(is); if (s.startRequested) { app.hasStartedServices = true; - if (procState > ActivityManager.PROCESS_STATE_SERVICE) { - procState = ActivityManager.PROCESS_STATE_SERVICE; + if (procState > PROCESS_STATE_SERVICE) { + procState = PROCESS_STATE_SERVICE; app.adjType = "started-services"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, @@ -1116,13 +1125,13 @@ public final class OomAdjuster { for (int conni = serviceConnections.size() - 1; conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND - || procState > ActivityManager.PROCESS_STATE_TOP); + || procState > PROCESS_STATE_TOP); conni--) { ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni); for (int i = 0; i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND - || procState > ActivityManager.PROCESS_STATE_TOP); + || procState > PROCESS_STATE_TOP); i++) { // XXX should compute this based on the max of // all connected clients. @@ -1148,7 +1157,7 @@ public final class OomAdjuster { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. The specific cached state // doesn't propagate except under certain conditions. - clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; + clientProcState = PROCESS_STATE_CACHED_EMPTY; } String adjType = null; if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { @@ -1219,6 +1228,7 @@ public final class OomAdjuster { newAdj = clientAdj; } else { if (adj > ProcessList.VISIBLE_APP_ADJ) { + // TODO: Is this too limiting for apps bound from TOP? newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ); } else { newAdj = adj; @@ -1247,55 +1257,50 @@ public final class OomAdjuster { schedGroup = ProcessList.SCHED_GROUP_DEFAULT; } } - if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { - if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { - // Special handling of clients who are in the top state. - // We *may* want to consider this process to be in the - // top state as well, but only if there is not another - // reason for it to be running. Being on the top is a - // special state, meaning you are specifically running - // for the current top app. If the process is already - // running in the background for some other reason, it - // is more important to continue considering it to be - // in the background state. - mayBeTop = true; - mayBeTopType = "service"; - mayBeTopSource = cr.binding.client; - mayBeTopTarget = s.instanceName; - clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; + if (clientProcState < PROCESS_STATE_TOP) { + // Special handling for above-top states (persistent + // processes). These should not bring the current process + // into the top state, since they are not on top. Instead + // give them the best bound state after that. + if ((cr.flags & Context.BIND_FOREGROUND_SERVICE) != 0) { + clientProcState = + PROCESS_STATE_BOUND_FOREGROUND_SERVICE; + } else if (mService.mWakefulness + == PowerManagerInternal.WAKEFULNESS_AWAKE + && (cr.flags & Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) + != 0) { + clientProcState = + PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } else { - // Special handling for above-top states (persistent - // processes). These should not bring the current process - // into the top state, since they are not on top. Instead - // give them the best state after that. - if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) { - clientProcState = - ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; - } else if (mService.mWakefulness - == PowerManagerInternal.WAKEFULNESS_AWAKE && - (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) - != 0) { - clientProcState = - ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; - } else { - clientProcState = - ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; - } + clientProcState = + PROCESS_STATE_IMPORTANT_FOREGROUND; + } + } else if (clientProcState == PROCESS_STATE_TOP) { + if (cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { + // Go at most to BOUND_TOP, unless requested to elevate + // to client's state. + clientProcState = PROCESS_STATE_BOUND_TOP; + } + } else if (clientProcState + <= PROCESS_STATE_FOREGROUND_SERVICE) { + if (cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { + clientProcState = PROCESS_STATE_FOREGROUND_SERVICE; } } } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) { if (clientProcState < - ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { + PROCESS_STATE_TRANSIENT_BACKGROUND) { clientProcState = - ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; + PROCESS_STATE_TRANSIENT_BACKGROUND; } } else { if (clientProcState < - ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { + PROCESS_STATE_IMPORTANT_BACKGROUND) { clientProcState = - ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; + PROCESS_STATE_IMPORTANT_BACKGROUND; } } + if (schedGroup < ProcessList.SCHED_GROUP_TOP_APP && (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0) { schedGroup = ProcessList.SCHED_GROUP_TOP_APP; @@ -1304,6 +1309,7 @@ public final class OomAdjuster { if (!trackedProcState) { cr.trackProcState(clientProcState, mAdjSeq, now); } + if (procState > clientProcState) { procState = clientProcState; app.setCurRawProcState(procState); @@ -1311,7 +1317,7 @@ public final class OomAdjuster { adjType = "service"; } } - if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND + if (procState < PROCESS_STATE_IMPORTANT_BACKGROUND && (cr.flags & Context.BIND_SHOWING_UI) != 0) { app.setPendingUiClean(true); } @@ -1366,13 +1372,13 @@ public final class OomAdjuster { for (int provi = app.pubProviders.size() - 1; provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND - || procState > ActivityManager.PROCESS_STATE_TOP); + || procState > PROCESS_STATE_TOP); provi--) { ContentProviderRecord cpr = app.pubProviders.valueAt(provi); for (int i = cpr.connections.size() - 1; i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND - || procState > ActivityManager.PROCESS_STATE_TOP); + || procState > PROCESS_STATE_TOP); i--) { ContentProviderConnection conn = cpr.connections.get(i); ProcessRecord client = conn.client; @@ -1392,7 +1398,7 @@ public final class OomAdjuster { if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. - clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; + clientProcState = PROCESS_STATE_CACHED_EMPTY; } String adjType = null; if (adj > clientAdj) { @@ -1407,34 +1413,18 @@ public final class OomAdjuster { } app.cached &= client.cached; } - if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { - if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { - // Special handling of clients who are in the top state. - // We *may* want to consider this process to be in the - // top state as well, but only if there is not another - // reason for it to be running. Being on the top is a - // special state, meaning you are specifically running - // for the current top app. If the process is already - // running in the background for some other reason, it - // is more important to continue considering it to be - // in the background state. - mayBeTop = true; - clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; - mayBeTopType = adjType = "provider-top"; - mayBeTopSource = client; - mayBeTopTarget = cpr.name; + + if (clientProcState <= PROCESS_STATE_FOREGROUND_SERVICE) { + if (adjType == null) { + adjType = "provider"; + } + if (clientProcState == PROCESS_STATE_TOP) { + clientProcState = PROCESS_STATE_BOUND_TOP; } else { - // Special handling for above-top states (persistent - // processes). These should not bring the current process - // into the top state, since they are not on top. Instead - // give them the best state after that. - clientProcState = - ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; - if (adjType == null) { - adjType = "provider"; - } + clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } } + conn.trackProcState(clientProcState, mAdjSeq, now); if (procState > clientProcState) { procState = clientProcState; @@ -1474,8 +1464,8 @@ public final class OomAdjuster { "Raise adj to external provider: " + app); } } - if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { - procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; + if (procState > PROCESS_STATE_IMPORTANT_FOREGROUND) { + procState = PROCESS_STATE_IMPORTANT_FOREGROUND; app.setCurRawProcState(procState); if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, @@ -1507,53 +1497,7 @@ public final class OomAdjuster { } } - if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { - // A client of one of our services or providers is in the top state. We - // *may* want to be in the top state, but not if we are already running in - // the background for some other reason. For the decision here, we are going - // to pick out a few specific states that we want to remain in when a client - // is top (states that tend to be longer-term) and otherwise allow it to go - // to the top state. - switch (procState) { - case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: - case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: - case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION: - // Something else is keeping it at this level, just leave it. - break; - case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: - case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: - case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND: - case ActivityManager.PROCESS_STATE_SERVICE: - // These all are longer-term states, so pull them up to the top - // of the background states, but not all the way to the top state. - procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; - app.adjType = mayBeTopType; - app.adjSource = mayBeTopSource; - app.adjTarget = mayBeTopTarget; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType - + ": " + app + ", due to " + mayBeTopSource - + " adj=" + adj + " procState=" - + ProcessList.makeProcStateString(procState)); - } - break; - default: - // Otherwise, top is a better choice, so take it. - procState = ActivityManager.PROCESS_STATE_TOP; - app.adjType = mayBeTopType; - app.adjSource = mayBeTopSource; - app.adjTarget = mayBeTopTarget; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType - + ": " + app + ", due to " + mayBeTopSource - + " adj=" + adj + " procState=" - + ProcessList.makeProcStateString(procState)); - } - break; - } - } - - if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { + if (procState >= PROCESS_STATE_CACHED_EMPTY) { if (app.hasClientActivities()) { // This is a cached process, but with client activities. Mark it so. procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; @@ -1607,8 +1551,8 @@ public final class OomAdjuster { // Put bound foreground services in a special sched group for additional // restrictions on screen off - if (procState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE && - mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) { + if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE + && mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) { if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) { schedGroup = ProcessList.SCHED_GROUP_RESTRICTED; } @@ -1905,8 +1849,8 @@ public final class OomAdjuster { + " (" + app.getCurProcState() + ")" + ": " + app.adjType; reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); } - boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; - boolean curImportant = app.getCurProcState() < ActivityManager.PROCESS_STATE_SERVICE; + boolean setImportant = app.setProcState < PROCESS_STATE_SERVICE; + boolean curImportant = app.getCurProcState() < PROCESS_STATE_SERVICE; if (setImportant && !curImportant) { // This app is no longer something we consider important enough to allow to use // arbitrary amounts of battery power. Note its current CPU time to later know to @@ -1969,10 +1913,11 @@ public final class OomAdjuster { // To avoid some abuse patterns, we are going to be careful about what we consider // to be an app interaction. Being the top activity doesn't count while the display // is sleeping, nor do short foreground services. - if (app.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP) { + if (app.getCurProcState() <= PROCESS_STATE_TOP + || app.getCurProcState() == PROCESS_STATE_BOUND_TOP) { isInteraction = true; app.setFgInteractionTime(0); - } else if (app.getCurProcState() <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { + } else if (app.getCurProcState() <= PROCESS_STATE_FOREGROUND_SERVICE) { if (app.getFgInteractionTime() == 0) { app.setFgInteractionTime(nowElapsed); isInteraction = false; @@ -1982,7 +1927,7 @@ public final class OomAdjuster { } } else { isInteraction = - app.getCurProcState() <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; + app.getCurProcState() <= PROCESS_STATE_IMPORTANT_FOREGROUND; app.setFgInteractionTime(0); } if (isInteraction @@ -2004,8 +1949,8 @@ public final class OomAdjuster { } private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) { - if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP - && app.getCurProcState() > ActivityManager.PROCESS_STATE_TOP) { + if (app.setProcState <= PROCESS_STATE_TOP + && app.getCurProcState() > PROCESS_STATE_TOP) { app.lastTopTime = nowUptime; } } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index d02fd7387f59..f1f40d49ccd1 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -769,6 +769,9 @@ public final class ProcessList { case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION: procState = "FGSL"; break; + case ActivityManager.PROCESS_STATE_BOUND_TOP: + procState = "BTOP"; + break; case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: procState = "FGS "; break; @@ -836,6 +839,9 @@ public final class ProcessList { case ActivityManager.PROCESS_STATE_TOP: return AppProtoEnums.PROCESS_STATE_TOP; case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION: + return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE; + case ActivityManager.PROCESS_STATE_BOUND_TOP: + return AppProtoEnums.PROCESS_STATE_BOUND_TOP; case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE; case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: @@ -966,6 +972,7 @@ public final class ProcessList { PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE + PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_BOUND_TOP PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 2e5dd3b0941e..c9e7cfa73259 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -153,6 +153,7 @@ public class AppOpsService extends IAppOpsService.Stub { UID_STATE_TOP, // ActivityManager.PROCESS_STATE_TOP UID_STATE_FOREGROUND_SERVICE_LOCATION, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION + UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_TOP UID_STATE_FOREGROUND_SERVICE, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index 4e4b15fc5b9b..ba4dcdbb7ee3 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -1317,7 +1317,9 @@ public final class ContentService extends IContentService.Stub { final int procState = ami.getUidProcessState(callingUid); final boolean isUidActive = ami.isUidActive(callingUid); - if (procState <= ActivityManager.PROCESS_STATE_TOP) { + // Providers bound by a TOP app will get PROCESS_STATE_BOUND_TOP, so include those as well + if (procState <= ActivityManager.PROCESS_STATE_TOP + || procState == ActivityManager.PROCESS_STATE_BOUND_TOP) { return ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP; } if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND || isUidActive) { diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 7c12c1ebc2be..cd15587918ec 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -949,7 +949,8 @@ class ActivityStarter { final boolean callingUidHasAnyVisibleWindow = mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid); final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow - || callingUidProcState == ActivityManager.PROCESS_STATE_TOP; + || callingUidProcState == ActivityManager.PROCESS_STATE_TOP + || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP; final boolean isCallingUidPersistentSystemProcess = (callingUid == Process.SYSTEM_UID) || callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; if (isCallingUidForeground || isCallingUidPersistentSystemProcess) { |