summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ForegroundServiceTypePolicy.java16
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java110
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java20
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java85
-rw-r--r--services/core/java/com/android/server/am/ProcessServiceRecord.java58
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java17
-rw-r--r--services/core/java/com/android/server/am/UidRecord.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java118
8 files changed, 340 insertions, 86 deletions
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index eccc5631d86a..e419e0602f2a 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -31,6 +31,7 @@ import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED;
@@ -378,6 +379,19 @@ public abstract class ForegroundServiceTypePolicy {
);
/**
+ * The policy for the {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE}.
+ *
+ * @hide
+ */
+ public static final @NonNull ForegroundServiceTypePolicyInfo FGS_TYPE_POLICY_SHORT_SERVICE =
+ new ForegroundServiceTypePolicyInfo(
+ FOREGROUND_SERVICE_TYPE_SHORT_SERVICE,
+ ForegroundServiceTypePolicyInfo.INVALID_CHANGE_ID,
+ ForegroundServiceTypePolicyInfo.INVALID_CHANGE_ID,
+ null /* no type specific permissions */, null /* no type specific permissions */
+ );
+
+ /**
* The policy for the {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SPECIAL_USE}.
*
* @hide
@@ -964,6 +978,8 @@ public abstract class ForegroundServiceTypePolicy {
FGS_TYPE_POLICY_REMOTE_MESSAGING);
mForegroundServiceTypePolicies.put(FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED,
FGS_TYPE_POLICY_SYSTEM_EXEMPTED);
+ mForegroundServiceTypePolicies.put(FOREGROUND_SERVICE_TYPE_SHORT_SERVICE,
+ FGS_TYPE_POLICY_SHORT_SERVICE);
mForegroundServiceTypePolicies.put(FOREGROUND_SERVICE_TYPE_SPECIAL_USE,
FGS_TYPE_POLICY_SPECIAL_USE);
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 6bb3306bc894..319b5aa4e29d 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -225,7 +225,9 @@ public final class ActiveServices {
private static final boolean DEBUG_DELAYED_SERVICE = DEBUG_SERVICE;
private static final boolean DEBUG_DELAYED_STARTS = DEBUG_DELAYED_SERVICE;
- private static final boolean LOG_SERVICE_START_STOP = false;
+ private static final boolean DEBUG_SHORT_SERVICE = DEBUG_SERVICE;
+
+ private static final boolean LOG_SERVICE_START_STOP = DEBUG_SERVICE;
// How long we wait for a service to finish executing.
static final int SERVICE_TIMEOUT = 20 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
@@ -729,6 +731,12 @@ public final class ActiveServices {
? res.permission : "private to package");
}
+
+ // TODO(short-service): This is inside startService() / startForegroundService().
+ // Consider if there's anything special we have to do if these are called on an already-
+ // running short-FGS... But given these APIs shouldn't change the FGS type, we likely
+ // don't need to do anything. (If they would change the FGS type, we'd have to stop
+ // the timeout)
ServiceRecord r = res.record;
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, r, userId,
allowBackgroundActivityStarts, false /* isBindService */);
@@ -1291,7 +1299,8 @@ public final class ActiveServices {
}
service.callStart = false;
- bringDownServiceIfNeededLocked(service, false, false, enqueueOomAdj);
+ bringDownServiceIfNeededLocked(service, false, false, enqueueOomAdj,
+ "stopService");
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -1473,7 +1482,7 @@ public final class ActiveServices {
}
r.callStart = false;
final long origId = Binder.clearCallingIdentity();
- bringDownServiceIfNeededLocked(r, false, false, false);
+ bringDownServiceIfNeededLocked(r, false, false, false, "stopServiceToken");
Binder.restoreCallingIdentity(origId);
return true;
}
@@ -1801,15 +1810,23 @@ public final class ActiveServices {
r.app.getPid(), r.appInfo.uid, "startForeground");
}
+ // TODO(short-service): This part really should be above the if block,
+ // so we'll apply the same check for instant apps too.
int manifestType = r.serviceInfo.getForegroundServiceType();
// If passed in foreground service type is FOREGROUND_SERVICE_TYPE_MANIFEST,
// consider it is the same as manifest foreground service type.
if (foregroundServiceType == FOREGROUND_SERVICE_TYPE_MANIFEST) {
foregroundServiceType = manifestType;
}
+
// Check the passed in foreground service type flags is a subset of manifest
// foreground service type flags.
- if ((foregroundServiceType & manifestType) != foregroundServiceType) {
+ final String prop = "debug.skip_fgs_manifest_type_check";
+ if (((foregroundServiceType & manifestType) != foregroundServiceType)
+ // When building a test app on Studio, the SDK may not have all the
+ // FGS types yet. This debug flag will allow using FGS types that are
+ // not set in the manifest.
+ && !SystemProperties.getBoolean(prop, false)) {
throw new IllegalArgumentException("foregroundServiceType "
+ String.format("0x%08X", foregroundServiceType)
+ " is not a subset of foregroundServiceType attribute "
@@ -1866,6 +1883,16 @@ public final class ActiveServices {
int fgsTypeCheckCode = FGS_TYPE_POLICY_CHECK_UNKNOWN;
if (!ignoreForeground) {
+ // TODO(short-service): There's a known long-standing bug that allows
+ // a abound service to become "foreground" if setForeground() is called
+ // (without actually "starting" it).
+ // Unfortunately we can't just "fix" it because some apps are relying on it,
+ // but this will cause a problem to short-fgs, so we should disallow it if
+ // this happens and the type is SHORT_SERVICE.
+ //
+ // OTOH, if a valid short-service (which has to be "started"), happens to
+ // also be bound, then we still _will_ apply a timeout, because it still has
+ // to be stopped.
if (r.mStartForegroundCount == 0) {
/*
If the service was started with startService(), not
@@ -1898,6 +1925,28 @@ public final class ActiveServices {
}
}
} else if (r.mStartForegroundCount >= 1) {
+ // We get here if startForeground() is called multiple times
+ // on the same sarvice after it's created, regardless of whether
+ // stopForeground() has been called or not.
+
+ // TODO(short-service): Consider transitions:
+ // A. Short -> other types:
+ // Apply the BG restriction again. Don't just allow it.
+ // i.e. unless the app is in a situation where it's allowed to start
+ // a FGS, this transition shouldn't be allowed.
+ // ... But think about it more, there may be a case this should be
+ // allowed.
+ //
+ // If the transition is allowed, stop the timeout.
+ // If the transition is _not_ allowed... keep the timeout?
+ //
+ // B. Short -> Short:
+ // This should be the same as case A
+ // If this is allowed, the new timeout should start.
+ // C. Other -> short:
+ // This should always be allowed.
+ // A timeout should start.
+
// The second or later time startForeground() is called after service is
// started. Check for app state again.
setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
@@ -1977,6 +2026,10 @@ public final class ActiveServices {
cancelForegroundNotificationLocked(r);
r.foregroundId = id;
}
+
+ // TODO(short-service): Stop the short service timeout, if the type is changing
+ // from short to non-short. (should we do it earlier?)
+
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
r.foregroundNoti = notification;
r.foregroundServiceType = foregroundServiceType;
@@ -2048,6 +2101,9 @@ public final class ActiveServices {
getServiceMapLocked(r.userId).ensureNotStartingBackgroundLocked(r);
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE);
+
+ // TODO(short-service): Start counting a timeout.
+
} else {
if (DEBUG_FOREGROUND_SERVICE) {
Slog.d(TAG, "Suppressing startForeground() for FAS " + r);
@@ -2081,6 +2137,8 @@ public final class ActiveServices {
decActiveForegroundAppLocked(smap, r);
}
+ // TODO(short-service): Stop the timeout. (any better place to do it?)
+
// Adjust notification handling before setting isForeground to false, because
// that state is relevant to the notification policy side.
// Leave the time-to-display as already set: re-entering foreground mode will
@@ -2121,6 +2179,10 @@ public final class ActiveServices {
? (int) (r.mFgsExitTime - r.mFgsEnterTime) : 0,
FGS_STOP_REASON_STOP_FOREGROUND,
FGS_TYPE_POLICY_CHECK_UNKNOWN);
+
+ // foregroundServiceType is used in logFGSStateChangeLocked(), so we can't clear it
+ // earlier.
+ r.foregroundServiceType = 0;
r.mFgsNotificationWasDeferred = false;
signalForegroundServiceObserversLocked(r);
resetFgsRestrictionLocked(r);
@@ -2408,7 +2470,9 @@ public final class ActiveServices {
final int uid = r.appInfo.uid;
// schedule the actual notification post
- long when = now + mAm.mConstants.mFgsNotificationDeferralInterval;
+ long when = now
+ + (r.isShortFgs() ? mAm.mConstants.mFgsNotificationDeferralIntervalForShort
+ : mAm.mConstants.mFgsNotificationDeferralInterval);
// If there are already deferred FGS notifications for this app,
// inherit that deferred-show timestamp
for (int i = 0; i < mPendingFgsNotifications.size(); i++) {
@@ -2427,7 +2491,9 @@ public final class ActiveServices {
}
if (mFgsDeferralRateLimited) {
- final long nextEligible = when + mAm.mConstants.mFgsNotificationDeferralExclusionTime;
+ final long nextEligible = when
+ + (r.isShortFgs() ? mAm.mConstants.mFgsNotificationDeferralExclusionTimeForShort
+ : mAm.mConstants.mFgsNotificationDeferralExclusionTime);
mFgsDeferralEligible.put(uid, nextEligible);
}
r.fgDisplayTime = when;
@@ -2791,14 +2857,19 @@ public final class ActiveServices {
private void updateServiceForegroundLocked(ProcessServiceRecord psr, boolean oomAdj) {
boolean anyForeground = false;
int fgServiceTypes = 0;
+ boolean hasTypeNone = false;
for (int i = psr.numberOfRunningServices() - 1; i >= 0; i--) {
ServiceRecord sr = psr.getRunningServiceAt(i);
if (sr.isForeground || sr.fgRequired) {
anyForeground = true;
fgServiceTypes |= sr.foregroundServiceType;
+ if (sr.foregroundServiceType == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE) {
+ hasTypeNone = true;
+ }
}
}
- mAm.updateProcessForegroundLocked(psr.mApp, anyForeground, fgServiceTypes, oomAdj);
+ mAm.updateProcessForegroundLocked(psr.mApp, anyForeground,
+ fgServiceTypes, hasTypeNone, oomAdj);
psr.setHasReportedForegroundServices(anyForeground);
}
@@ -4773,10 +4844,18 @@ public final class ActiveServices {
return false;
}
- private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
- boolean hasConn, boolean enqueueOomAdj) {
- //Slog.i(TAG, "Bring down service:");
- //r.dump(" ");
+ private void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
+ boolean hasConn, boolean enqueueOomAdj, String debugReason) {
+ if (DEBUG_SERVICE) {
+ Slog.i(TAG, "Bring down service for " + debugReason + " :" + r.toString());
+ }
+
+ // TODO(short-service): Hmm, when the app stops a short-fgs, we should stop the timeout
+ // here.
+ // However we have a couple if's here and if these conditions are met, we stop here
+ // without bringing down the service.
+ // We need to make sure this can't be used (somehow) to keep having a short-FGS running
+ // while having the timeout stopped.
if (isServiceNeededLocked(r, knowConn, hasConn)) {
return;
@@ -4844,6 +4923,8 @@ public final class ActiveServices {
// Check to see if the service had been started as foreground, but being
// brought down before actually showing a notification. That is not allowed.
+ // TODO(short-service): This is unlikely related to short-FGS, but I'm curious why it's
+ // not allowed. Look into it.
if (r.fgRequired) {
Slog.w(TAG_SERVICE, "Bringing down service while still waiting for start foreground: "
+ r);
@@ -4934,6 +5015,8 @@ public final class ActiveServices {
FGS_STOP_REASON_STOP_SERVICE,
FGS_TYPE_POLICY_CHECK_UNKNOWN);
mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
+
+ // TODO(short-service): Make sure we stop the timeout by here.
}
r.isForeground = false;
@@ -5161,7 +5244,8 @@ public final class ActiveServices {
}
}
}
- bringDownServiceIfNeededLocked(s, true, hasAutoCreate, enqueueOomAdj);
+ bringDownServiceIfNeededLocked(s, true, hasAutoCreate, enqueueOomAdj,
+ "removeConnection");
}
}
}
@@ -6988,7 +7072,7 @@ public final class ActiveServices {
final Integer allowedType = mAm.mProcessList.searchEachLruProcessesLOSP(false, app -> {
if (app.uid == callingUid) {
final ProcessStateRecord state = app.mState;
- if (state.isAllowedStartFgs()) {
+ if (state.isAllowedStartFgs()) { // Procstate <= BFGS?
return getReasonCodeFromProcState(state.getCurProcState());
} else {
final ActiveInstrumentation instr = app.getActiveInstrumentation();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6394d7744645..f180ffa1a57c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4945,7 +4945,7 @@ public class ActivityManagerService extends IActivityManager.Stub
app.mState.setVerifiedAdj(ProcessList.INVALID_ADJ);
mOomAdjuster.setAttachingSchedGroupLSP(app);
app.mState.setForcingToImportant(null);
- updateProcessForegroundLocked(app, false, 0, false);
+ clearProcessForegroundLocked(app);
app.mState.setHasShownUi(false);
app.mState.setCached(false);
app.setDebugging(false);
@@ -5805,7 +5805,7 @@ public class ActivityManagerService extends IActivityManager.Stub
return;
}
pr.mState.setForcingToImportant(null);
- updateProcessForegroundLocked(pr, false, 0, false);
+ clearProcessForegroundLocked(pr);
}
updateOomAdjLocked(pr, OomAdjuster.OOM_ADJ_REASON_UI_VISIBILITY);
}
@@ -12706,7 +12706,7 @@ public class ActivityManagerService extends IActivityManager.Stub
for (BroadcastQueue queue : mBroadcastQueues) {
queue.onApplicationCleanupLocked(app);
}
- updateProcessForegroundLocked(app, false, 0, false);
+ clearProcessForegroundLocked(app);
mServices.killServicesLocked(app, allowRestart);
mPhantomProcessList.onAppDied(pid);
@@ -15830,12 +15830,18 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@GuardedBy("this")
+ final void clearProcessForegroundLocked(ProcessRecord proc) {
+ updateProcessForegroundLocked(proc, /* isForeground =*/ false,
+ /* fgsTypes =*/0, /* hasTypeNoneFgs =*/false, /* oomAdj= */ false);
+ }
+
+ @GuardedBy("this")
final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
- int fgServiceTypes, boolean oomAdj) {
+ int fgServiceTypes, boolean hasTypeNoneFgs, boolean oomAdj) {
final ProcessServiceRecord psr = proc.mServices;
final boolean foregroundStateChanged = isForeground != psr.hasForegroundServices();
if (foregroundStateChanged
- || psr.getForegroundServiceTypes() != fgServiceTypes) {
+ || !psr.areForegroundServiceTypesSame(fgServiceTypes, hasTypeNoneFgs)) {
if (foregroundStateChanged) {
// Notify internal listeners.
for (int i = mForegroundServiceStateListeners.size() - 1; i >= 0; i--) {
@@ -15843,7 +15849,7 @@ public class ActivityManagerService extends IActivityManager.Stub
proc.info.packageName, proc.info.uid, proc.getPid(), isForeground);
}
}
- psr.setHasForegroundServices(isForeground, fgServiceTypes);
+ psr.setHasForegroundServices(isForeground, fgServiceTypes, hasTypeNoneFgs);
ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
proc.info.uid);
if (isForeground) {
@@ -17762,7 +17768,7 @@ public class ActivityManagerService extends IActivityManager.Stub
return null;
}
- if ((app.mServices.getForegroundServiceTypes() & foregroundServicetype) != 0) {
+ if ((app.mServices.containsAnyForegroundServiceTypes(foregroundServicetype))) {
return Boolean.TRUE;
}
return null;
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 93c7d79c8d8c..8082e45b3238 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1798,28 +1798,53 @@ public class OomAdjuster {
}
}
+ int capabilityFromFGS = 0; // capability from foreground service.
+
+ // Adjust for FGS or "has-overlay-ui".
if (adj > PERCEPTIBLE_APP_ADJ
|| procState > PROCESS_STATE_FOREGROUND_SERVICE) {
- if (psr.hasForegroundServices()) {
- // The user is aware of this app, so make it visible.
- adj = PERCEPTIBLE_APP_ADJ;
- procState = PROCESS_STATE_FOREGROUND_SERVICE;
- state.setAdjType("fg-service");
- state.setCached(false);
- schedGroup = SCHED_GROUP_DEFAULT;
- if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
- reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + state.getAdjType() + ": "
- + app + " ");
- }
+ String adjType = null;
+ int newAdj = 0;
+ int newProcState = 0;
+
+ if (psr.hasForegroundServices() && psr.hasNonShortForegroundServices()) {
+ // For regular (non-short) FGS.
+ adjType = "fg-service";
+ newAdj = PERCEPTIBLE_APP_ADJ;
+ newProcState = PROCESS_STATE_FOREGROUND_SERVICE;
+
} else if (state.hasOverlayUi()) {
- // The process is display an overlay UI.
- adj = PERCEPTIBLE_APP_ADJ;
- procState = PROCESS_STATE_IMPORTANT_FOREGROUND;
+ adjType = "has-overlay-ui";
+ newAdj = PERCEPTIBLE_APP_ADJ;
+ newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
+
+ } else if (psr.hasForegroundServices() && !psr.hasNonShortForegroundServices()) {
+ // For short FGS.
+ adjType = "fg-service-short";
+ // We use MEDIUM_APP_ADJ + 1 so we can tell apart EJ (which uses MEDIUM_APP_ADJ + 1)
+ // from short-FGS.
+ // (We use +1 and +2, not +0 and +1, to be consistent with the following
+ // RECENT_FOREGROUND_APP_ADJ tweak)
+ newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 1;
+
+ // Short-FGS gets a below-BFGS procstate, so it can't start another FGS from it.
+ newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
+
+ // Same as EJ, we explicitly grant network access to short FGS,
+ // even when battery saver or data saver is enabled.
+ capabilityFromFGS |= PROCESS_CAPABILITY_NETWORK;
+ }
+
+ if (adjType != null) {
+ adj = newAdj;
+ procState = newProcState;
+ state.setAdjType(adjType);
state.setCached(false);
- state.setAdjType("has-overlay-ui");
schedGroup = SCHED_GROUP_DEFAULT;
+
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
- reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to overlay ui: " + app);
+ reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType + ": "
+ + app + " ");
}
}
}
@@ -1830,8 +1855,15 @@ public class OomAdjuster {
if (psr.hasForegroundServices() && adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
&& (state.getLastTopTime() + mConstants.TOP_TO_FGS_GRACE_DURATION > now
|| state.getSetProcState() <= PROCESS_STATE_TOP)) {
- adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
- state.setAdjType("fg-service-act");
+ if (psr.hasNonShortForegroundServices()) {
+ adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
+ state.setAdjType("fg-service-act");
+ } else {
+ // For short-service FGS, we +1 the value, so we'll be able to detect it in
+ // various dashboards.
+ adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 1;
+ state.setAdjType("fg-service-short-act");
+ }
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app);
}
@@ -1842,11 +1874,13 @@ public class OomAdjuster {
// foreground services so that it can finish performing any persistence/processing of
// in-memory state.
if (psr.hasTopStartedAlmostPerceptibleServices()
- && adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
+ && (adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2)
&& (state.getLastTopTime()
+ mConstants.TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION > now
|| state.getSetProcState() <= PROCESS_STATE_TOP)) {
- adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
+ // For EJ, we +2 the value, so we'll be able to detect it in
+ // various dashboards.
+ adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2;
// This shall henceforth be called the "EJ" exemption, despite utilizing the
// ALMOST_PERCEPTIBLE flag to work.
state.setAdjType("top-ej-act");
@@ -1979,7 +2013,6 @@ public class OomAdjuster {
}
}
- int capabilityFromFGS = 0; // capability from foreground service.
boolean boundByNonBgRestricted = state.isCurBoundByNonBgRestrictedApp();
boolean scheduleLikeTopApp = false;
for (int is = psr.numberOfRunningServices() - 1;
@@ -2031,6 +2064,8 @@ public class OomAdjuster {
}
}
+ // TODO(short-service): While-in-user permissions. Do we need any change here for
+ // short-FGS? (Likely not)
if (s.isForeground) {
final int fgsType = s.foregroundServiceType;
if (s.mAllowWhileInUsePermissionInFgs) {
@@ -2113,6 +2148,7 @@ public class OomAdjuster {
// in this case unless they explicitly request it.
if ((cstate.getCurCapability() & PROCESS_CAPABILITY_NETWORK) != 0) {
if (clientProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+ // This is used to grant network access to Expedited Jobs.
if ((cr.flags & Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS)
!= 0) {
capability |= PROCESS_CAPABILITY_NETWORK;
@@ -2200,8 +2236,11 @@ public class OomAdjuster {
newAdj = PERCEPTIBLE_LOW_APP_ADJ;
} else if ((cr.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0
&& clientAdj < PERCEPTIBLE_APP_ADJ
- && adj >= (lbAdj = PERCEPTIBLE_MEDIUM_APP_ADJ)) {
- newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ;
+ && adj >= (lbAdj = (PERCEPTIBLE_MEDIUM_APP_ADJ + 2))) {
+ // This is for expedited jobs.
+ // We use MEDIUM_APP_ADJ + 2 here, so we can tell apart
+ // EJ and short-FGS.
+ newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 2;
} else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
&& clientAdj < PERCEPTIBLE_APP_ADJ
&& adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) {
diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java
index 67eb675503ad..13264db01680 100644
--- a/services/core/java/com/android/server/am/ProcessServiceRecord.java
+++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java
@@ -21,6 +21,7 @@ import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_
import android.app.ActivityManager;
import android.content.Context;
+import android.content.pm.ServiceInfo;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.ArrayMap;
@@ -78,11 +79,20 @@ final class ProcessServiceRecord {
private int mConnectionImportance;
/**
- * Type of foreground service, if there is a foreground service.
+ * The OR'ed foreground service types that are running on this process.
+ * Note, because TYPE_NONE (==0) is also a valid type for pre-U apps, this field doesn't tell
+ * if the process has any TYPE_NONE FGS or not, but {@link #mHasTypeNoneFgs} will be set
+ * in that case.
*/
private int mFgServiceTypes;
/**
+ * Whether the process has any foreground services of TYPE_NONE running.
+ * @see #mFgServiceTypes
+ */
+ private boolean mHasTypeNoneFgs;
+
+ /**
* Last reported foreground service types.
*/
private int mRepFgServiceTypes;
@@ -145,9 +155,18 @@ final class ProcessServiceRecord {
return mHasClientActivities;
}
- void setHasForegroundServices(boolean hasForegroundServices, int fgServiceTypes) {
+ void setHasForegroundServices(boolean hasForegroundServices, int fgServiceTypes,
+ boolean hasTypeNoneFgs) {
+ // hasForegroundServices should be the same as "either it has any FGS types, or none types".
+ // We still take this as a parameter because it's used in the callsite...
+ if (ActivityManagerDebugConfig.DEBUG_SERVICE
+ && hasForegroundServices != ((fgServiceTypes != 0) || hasTypeNoneFgs)) {
+ throw new IllegalStateException("hasForegroundServices mismatch");
+ }
+
mHasForegroundServices = hasForegroundServices;
mFgServiceTypes = fgServiceTypes;
+ mHasTypeNoneFgs = hasTypeNoneFgs;
mApp.getWindowProcessController().setHasForegroundServices(hasForegroundServices);
if (hasForegroundServices) {
mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE);
@@ -168,10 +187,43 @@ final class ProcessServiceRecord {
return mRepHasForegroundServices;
}
- int getForegroundServiceTypes() {
+ /**
+ * Returns the FGS typps, but it doesn't tell if the types include "NONE" or not, so
+ * do not use it outside of this class.
+ */
+ private int getForegroundServiceTypes() {
return mHasForegroundServices ? mFgServiceTypes : 0;
}
+ boolean areForegroundServiceTypesSame(@ServiceInfo.ForegroundServiceType int types,
+ boolean hasTypeNoneFgs) {
+ return ((getForegroundServiceTypes() & types) == types)
+ && (mHasTypeNoneFgs == hasTypeNoneFgs);
+ }
+
+ /**
+ * @return true if the fgs types includes any of the given types.
+ * (wouldn't work for TYPE_NONE, which is 0)
+ */
+ boolean containsAnyForegroundServiceTypes(@ServiceInfo.ForegroundServiceType int types) {
+ return (getForegroundServiceTypes() & types) != 0;
+ }
+
+ /**
+ * @return true if the process has any FGS that are _not_ a "short" FGS.
+ */
+ boolean hasNonShortForegroundServices() {
+ if (!mHasForegroundServices) {
+ return false; // Process has no FGS running.
+ }
+ // Does the process has any FGS of TYPE_NONE?
+ if (mHasTypeNoneFgs) {
+ return true;
+ }
+ // If not, we can just check mFgServiceTypes.
+ return mFgServiceTypes != ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
+ }
+
int getReportedForegroundServiceTypes() {
return mRepFgServiceTypes;
}
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index c27ed7a46844..0468152acdd8 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -201,7 +201,9 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
ActivityManagerService.FgsTempAllowListItem mInfoTempFgsAllowListReason;
// Is the same mInfoAllowStartForeground string has been logged before? Used for dedup.
boolean mLoggedInfoAllowStartForeground;
- // The number of times Service.startForeground() is called;
+ // The number of times Service.startForeground() is called, after this service record is
+ // created. (i.e. due to "bound" or "start".) It never decreases, even when stopForeground()
+ // is called.
int mStartForegroundCount;
// Last time mAllowWhileInUsePermissionInFgs or mAllowStartForeground is set.
long mLastSetFgsRestrictionTime;
@@ -769,6 +771,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
* has no reason to start again. Note this condition doesn't consider the bindings.
*/
boolean canStopIfKilled(boolean isStartCanceled) {
+ // TODO(short-service): If it's a "short FGS", we should stop it if killed.
return startRequested && (stopIfKilled || isStartCanceled) && pendingStarts.isEmpty();
}
@@ -1223,4 +1226,16 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
public ComponentName getComponentName() {
return name;
}
+
+ /**
+ * @return true if it's a foreground service of the "short service" type and don't have
+ * other fgs type bits set.
+ */
+ public boolean isShortFgs() {
+ // Note if the type contains FOREGROUND_SERVICE_TYPE_SHORT_SERVICE but also other bits
+ // set, it's _not_ considered be a short service. (because we shouldn't apply
+ // the short-service restrictions)
+ return isForeground
+ && (foregroundServiceType == ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE);
+ }
}
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index 51568d83157e..b617582dce44 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -238,11 +238,13 @@ public final class UidRecord {
mEphemeral = ephemeral;
}
+ /** Returns whether the UID has any FGS of any type or not (including "short fgs") */
@GuardedBy(anyOf = {"mService", "mProcLock"})
boolean hasForegroundServices() {
return mForegroundServices;
}
+ /** Sets whether the UID has any FGS of any type or not (including "short fgs") */
@GuardedBy({"mService", "mProcLock"})
void setForegroundServices(boolean foregroundServices) {
mForegroundServices = foregroundServices;
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 9132e31f9a60..55d116043f15 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_NETWORK;
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;
@@ -413,7 +414,8 @@ public class MockingOomAdjusterTests {
public void testUpdateOomAdj_DoOne_FgServiceLocation() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
- app.mServices.setHasForegroundServices(true, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
+ app.mServices.setHasForegroundServices(true, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION,
+ /* hasNoneType=*/false);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -426,7 +428,7 @@ public class MockingOomAdjusterTests {
public void testUpdateOomAdj_DoOne_FgService() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
- app.mServices.setHasForegroundServices(true, 0);
+ app.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -436,6 +438,43 @@ public class MockingOomAdjusterTests {
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_FgService_ShortFgs() {
+ // SHORT_SERVICE FGS will get IMP_FG and a slightly different recent-adjustment.
+ {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ app.mServices.setHasForegroundServices(true,
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
+ app.mState.setLastTopTime(SystemClock.uptimeMillis());
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+ sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app, PROCESS_STATE_IMPORTANT_FOREGROUND,
+ PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 1, SCHED_GROUP_DEFAULT);
+ // Should get network access.
+ assertTrue((app.mState.getSetCapability() & PROCESS_CAPABILITY_NETWORK) != 0);
+ }
+
+ // SHORT_SERVICE, but no longer recent.
+ {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+ app.mServices.setHasForegroundServices(true,
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
+ app.mState.setLastTopTime(SystemClock.uptimeMillis()
+ - sService.mConstants.TOP_TO_FGS_GRACE_DURATION);
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+ sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app, PROCESS_STATE_IMPORTANT_FOREGROUND,
+ PERCEPTIBLE_MEDIUM_APP_ADJ + 1, SCHED_GROUP_DEFAULT);
+ // Still should get network access.
+ assertTrue((app.mState.getSetCapability() & PROCESS_CAPABILITY_NETWORK) != 0);
+ }
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_DoOne_OverlayUi() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
@@ -452,7 +491,7 @@ public class MockingOomAdjusterTests {
public void testUpdateOomAdj_DoOne_PerceptibleRecent_FgService() {
ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
- app.mServices.setHasForegroundServices(true, 0);
+ app.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
app.mState.setLastTopTime(SystemClock.uptimeMillis());
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -481,7 +520,7 @@ public class MockingOomAdjusterTests {
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
- assertEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+ assertEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2, app.mState.getSetAdj());
}
// Out of grace period but valid binding allows the adjustment.
@@ -494,14 +533,14 @@ public class MockingOomAdjusterTests {
app.mState.setLastTopTime(nowUptime);
// Simulate the system starting and binding to a service in the app.
ServiceRecord s = bindService(app, system,
- null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class));
+ null, Context.BIND_ALMOST_PERCEPTIBLE + 2, mock(IBinder.class));
s.lastTopAlmostPerceptibleBindRequestUptimeMs =
nowUptime - 2 * sService.mConstants.mServiceBindAlmostPerceptibleTimeoutMs;
app.mServices.updateHasTopStartedAlmostPerceptibleServices();
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
- assertEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+ assertEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2, app.mState.getSetAdj());
}
// Out of grace period and no valid binding so no adjustment.
@@ -522,7 +561,7 @@ public class MockingOomAdjusterTests {
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
- assertNotEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+ assertNotEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2, app.mState.getSetAdj());
}
}
@SuppressWarnings("GuardedBy")
@@ -875,7 +914,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
bindService(app, client, null, 0, mock(IBinder.class));
- client.mServices.setHasForegroundServices(true, 0);
+ client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -963,7 +1002,7 @@ public class MockingOomAdjusterTests {
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
- assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ, app.mState.getSetAdj());
+ assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ + 2, app.mState.getSetAdj());
}
{
@@ -979,7 +1018,7 @@ public class MockingOomAdjusterTests {
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
doReturn(false).when(wpc).isHeavyWeightProcess();
- assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ, app.mState.getSetAdj());
+ assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ + 2, app.mState.getSetAdj());
}
}
@@ -1067,7 +1106,7 @@ public class MockingOomAdjusterTests {
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
- client.mServices.setHasForegroundServices(true, 0);
+ client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindProvider(app, client, null, null, false);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1136,7 +1175,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(app, client2, null, 0, mock(IBinder.class));
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1155,7 +1194,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(client, client2, null, 0, mock(IBinder.class));
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1174,7 +1213,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(client, client2, null, 0, mock(IBinder.class));
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(client2, app, null, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1191,7 +1230,7 @@ public class MockingOomAdjusterTests {
assertProcStates(client2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
SCHED_GROUP_DEFAULT);
- client2.mServices.setHasForegroundServices(false, 0);
+ client2.mServices.setHasForegroundServices(false, 0, /* hasNoneType=*/false);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(client2, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1212,7 +1251,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(client2, client, null, 0, mock(IBinder.class));
- client.mServices.setHasForegroundServices(true, 0);
+ client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
lru.add(app);
@@ -1241,7 +1280,7 @@ public class MockingOomAdjusterTests {
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(client, client2, null, 0, mock(IBinder.class));
bindService(client2, client, null, 0, mock(IBinder.class));
- client.mServices.setHasForegroundServices(true, 0);
+ client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
lru.add(app);
@@ -1277,7 +1316,7 @@ public class MockingOomAdjusterTests {
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
bindService(client3, client4, null, 0, mock(IBinder.class));
bindService(client4, client3, null, 0, mock(IBinder.class));
- client.mServices.setHasForegroundServices(true, 0);
+ client.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
lru.add(app);
@@ -1311,7 +1350,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(client, client2, null, 0, mock(IBinder.class));
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(client2, app, null, 0, mock(IBinder.class));
ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID,
MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false));
@@ -1415,7 +1454,7 @@ public class MockingOomAdjusterTests {
bindService(app, client3, null, 0, mock(IBinder.class));
ProcessRecord client4 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID,
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
- client4.mServices.setHasForegroundServices(true, 0);
+ client4.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app, client4, null, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1444,7 +1483,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(app, client2, null, 0, mock(IBinder.class));
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
ProcessRecord client3 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID,
MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false));
client3.mState.setForcingToImportant(new Object());
@@ -1467,7 +1506,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindProvider(client, client2, null, null, false);
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1486,7 +1525,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindProvider(client, client2, null, null, false);
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(client2, app, null, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1511,7 +1550,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindProvider(client, client2, null, null, false);
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1530,7 +1569,7 @@ public class MockingOomAdjusterTests {
ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindProvider(client, client2, null, null, false);
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindProvider(client2, app, null, null, false);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1561,7 +1600,7 @@ public class MockingOomAdjusterTests {
bindService(app2, client2, null, Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
mock(IBinder.class));
client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
- client2.mServices.setHasForegroundServices(true, 0);
+ client2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
sService.mOomAdjuster.updateOomAdjLocked(app1, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1628,7 +1667,7 @@ public class MockingOomAdjusterTests {
s2.getConnections().clear();
client1.mState.setMaxAdj(UNKNOWN_ADJ);
client2.mState.setMaxAdj(UNKNOWN_ADJ);
- client1.mServices.setHasForegroundServices(true, 0);
+ client1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
client2.mState.setHasOverlayUi(true);
bindService(app1, client1, s1, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE,
@@ -1663,7 +1702,7 @@ public class MockingOomAdjusterTests {
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
- app1.mServices.setHasForegroundServices(true, 0);
+ app1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
bindService(app1, client1, null, Context.BIND_NOT_PERCEPTIBLE, mock(IBinder.class));
@@ -1683,7 +1722,7 @@ public class MockingOomAdjusterTests {
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
- app1.mServices.setHasForegroundServices(true, 0);
+ app1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
bindService(app1, client1, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class));
@@ -1717,7 +1756,7 @@ public class MockingOomAdjusterTests {
client1.setUidRecord(clientUidRecord);
client2.setUidRecord(clientUidRecord);
- client1.mServices.setHasForegroundServices(true, 0);
+ client1.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
client2.mState.setForcingToImportant(new Object());
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1774,7 +1813,7 @@ public class MockingOomAdjusterTests {
assertEquals(PROCESS_STATE_TRANSIENT_BACKGROUND, app2.mState.getSetProcState());
assertEquals(PROCESS_STATE_TRANSIENT_BACKGROUND, client2.mState.getSetProcState());
- client1.mServices.setHasForegroundServices(false, 0);
+ client1.mServices.setHasForegroundServices(false, 0, /* hasNoneType=*/false);
client2.mState.setForcingToImportant(null);
app1UidRecord.reset();
app2UidRecord.reset();
@@ -1811,7 +1850,7 @@ public class MockingOomAdjusterTests {
app.mState.setForcingToImportant(new Object());
ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
- app2.mServices.setHasForegroundServices(true, 0);
+ app2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
lru.add(app);
@@ -1834,7 +1873,7 @@ public class MockingOomAdjusterTests {
app.mState.setForcingToImportant(new Object());
ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
- app2.mServices.setHasForegroundServices(true, 0);
+ app2.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app, app2, null, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1861,7 +1900,7 @@ public class MockingOomAdjusterTests {
ProcessRecord app3 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
bindService(app2, app3, null, 0, mock(IBinder.class));
- app3.mServices.setHasForegroundServices(true, 0);
+ app3.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app3, app, null, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1909,7 +1948,7 @@ public class MockingOomAdjusterTests {
bindService(app, app4, s, 0, mock(IBinder.class));
ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID,
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
- app5.mServices.setHasForegroundServices(true, 0);
+ app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app, app5, s, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1954,7 +1993,7 @@ public class MockingOomAdjusterTests {
bindService(app, app4, s, 0, mock(IBinder.class));
ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID,
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
- app5.mServices.setHasForegroundServices(true, 0);
+ app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app, app5, s, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -1999,7 +2038,7 @@ public class MockingOomAdjusterTests {
bindService(app, app4, s, 0, mock(IBinder.class));
ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID,
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
- app5.mServices.setHasForegroundServices(true, 0);
+ app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindService(app, app5, s, 0, mock(IBinder.class));
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -2074,7 +2113,7 @@ public class MockingOomAdjusterTests {
bindProvider(app, app4, cr, null, false);
ProcessRecord app5 = spy(makeDefaultProcessRecord(MOCKAPP5_PID, MOCKAPP5_UID,
MOCKAPP5_PROCESSNAME, MOCKAPP5_PACKAGENAME, false));
- app5.mServices.setHasForegroundServices(true, 0);
+ app5.mServices.setHasForegroundServices(true, 0, /* hasNoneType=*/true);
bindProvider(app, app5, cr, null, false);
ArrayList<ProcessRecord> lru = sService.mProcessList.getLruProcessesLOSP();
lru.clear();
@@ -2321,7 +2360,8 @@ public class MockingOomAdjusterTests {
services.setConnectionGroup(connectionGroup);
services.setConnectionImportance(connectionImportance);
services.setHasClientActivities(hasClientActivities);
- services.setHasForegroundServices(hasForegroundServices, fgServiceTypes);
+ services.setHasForegroundServices(hasForegroundServices, fgServiceTypes,
+ /* hasNoneType=*/false);
services.setHasAboveClient(hasAboveClient);
services.setTreatLikeActivity(treatLikeActivity);
services.setExecServicesFg(execServicesFg);