diff options
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); |