diff options
12 files changed, 171 insertions, 64 deletions
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 6f205636b476..fc84e1386d1f 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -621,7 +621,8 @@ public final class ActiveServices { try { final ServiceRecord.StartItem si = r.pendingStarts.get(0); startServiceInnerLocked(this, si.intent, r, false, true, si.callingId, - si.mCallingProcessName, r.startRequested, si.mCallingPackageName); + si.mCallingProcessName, si.mCallingProcessState, + r.startRequested, si.mCallingPackageName); } catch (TransactionTooLargeException e) { // Ignore, nobody upstack cares. } @@ -977,10 +978,22 @@ public final class ActiveServices { fgRequired = false; } + final ProcessRecord callingApp; + synchronized (mAm.mPidsSelfLocked) { + callingApp = mAm.mPidsSelfLocked.get(callingPid); + } + final String callingProcessName = callingApp != null + ? callingApp.processName : callingPackage; + final int callingProcessState = + callingApp != null && callingApp.getThread() != null && !callingApp.isKilled() + ? callingApp.mState.getCurProcState() : ActivityManager.PROCESS_STATE_UNKNOWN; + r.updateProcessStateOnRequest(); + // The package could be frozen (meaning it's doing surgery), defer the actual // start until the package is unfrozen. if (deferServiceBringupIfFrozenLocked(r, service, callingPackage, callingFeatureId, - callingUid, callingPid, fgRequired, callerFg, userId, + callingUid, callingPid, callingProcessName, + callingProcessState, fgRequired, callerFg, userId, backgroundStartPrivileges, false, null)) { return null; } @@ -1001,7 +1014,7 @@ public final class ActiveServices { // what realResult contains. final ComponentName realResult = startServiceInnerLocked(r, service, callingUid, callingPid, - getCallingProcessNameLocked(callingUid, callingPid, callingPackage), + callingProcessName, callingProcessState, fgRequired, callerFg, backgroundStartPrivileges, callingPackage); if (res.aliasComponent != null @@ -1013,17 +1026,9 @@ public final class ActiveServices { } } - private String getCallingProcessNameLocked(int callingUid, int callingPid, - String callingPackage) { - synchronized (mAm.mPidsSelfLocked) { - final ProcessRecord callingApp = mAm.mPidsSelfLocked.get(callingPid); - return callingApp != null ? callingApp.processName : callingPackage; - } - } - private ComponentName startServiceInnerLocked(ServiceRecord r, Intent service, - int callingUid, int callingPid, String callingProcessName, boolean fgRequired, - boolean callerFg, + int callingUid, int callingPid, String callingProcessName, + int callingProcessState, boolean fgRequired, boolean callerFg, BackgroundStartPrivileges backgroundStartPrivileges, String callingPackage) throws TransactionTooLargeException { NeededUriGrants neededGrants = mAm.mUgmInternal.checkGrantUriPermissionFromIntent( @@ -1037,7 +1042,8 @@ public final class ActiveServices { r.delayedStop = false; r.fgRequired = fgRequired; r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), - service, neededGrants, callingUid, callingProcessName, callingPackage)); + service, neededGrants, callingUid, callingProcessName, callingPackage, + callingProcessState)); // We want to allow scheduling user-initiated jobs when the app is running a // foreground service that was started in the same conditions that allows for scheduling @@ -1140,7 +1146,8 @@ public final class ActiveServices { r.allowBgActivityStartsOnServiceStart(backgroundStartPrivileges); } ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting, - callingUid, callingProcessName, wasStartRequested, callingPackage); + callingUid, callingProcessName, callingProcessState, + wasStartRequested, callingPackage); return cmp; } @@ -1244,7 +1251,8 @@ public final class ActiveServices { @GuardedBy("mAm") private boolean deferServiceBringupIfFrozenLocked(ServiceRecord s, Intent serviceIntent, String callingPackage, @Nullable String callingFeatureId, - int callingUid, int callingPid, boolean fgRequired, boolean callerFg, int userId, + int callingUid, int callingPid, String callingProcessName, + int callingProcessState, boolean fgRequired, boolean callerFg, int userId, BackgroundStartPrivileges backgroundStartPrivileges, boolean isBinding, IServiceConnection connection) { final PackageManagerInternal pm = mAm.getPackageManagerInternal(); @@ -1258,8 +1266,6 @@ public final class ActiveServices { curPendingBringups = new ArrayList<>(); mPendingBringups.put(s, curPendingBringups); } - final String callingProcessName = getCallingProcessNameLocked( - callingUid, callingPid, callingPackage); curPendingBringups.add(new Runnable() { @Override public void run() { @@ -1291,7 +1297,7 @@ public final class ActiveServices { } else { // Starting a service try { startServiceInnerLocked(s, serviceIntent, callingUid, callingPid, - callingProcessName, fgRequired, callerFg, + callingProcessName, callingProcessState, fgRequired, callerFg, backgroundStartPrivileges, callingPackage); } catch (TransactionTooLargeException e) { /* ignore - local call */ @@ -1338,7 +1344,8 @@ public final class ActiveServices { ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting, int callingUid, String callingProcessName, - boolean wasStartRequested, String callingPackage) throws TransactionTooLargeException { + int callingProcessState, boolean wasStartRequested, String callingPackage) + throws TransactionTooLargeException { synchronized (mAm.mProcessStats.mLock) { final ServiceState stracker = r.getTracker(); if (stracker != null) { @@ -1381,7 +1388,9 @@ public final class ActiveServices { getShortServiceNameForStats(r), packageState, packageName, - callingPackage); + callingPackage, + callingProcessState, + r.mProcessStateOnRequest); if (r.startRequested && addToStarting) { boolean first = smap.mStartingBackground.size() == 0; @@ -3611,11 +3620,22 @@ public final class ActiveServices { return 0; } + final ProcessRecord callingApp; + synchronized (mAm.mPidsSelfLocked) { + callingApp = mAm.mPidsSelfLocked.get(callingPid); + } + final String callingProcessName = callingApp != null + ? callingApp.processName : callingPackage; + final int callingProcessState = + callingApp != null && callingApp.getThread() != null && !callingApp.isKilled() + ? callingApp.mState.getCurProcState() : ActivityManager.PROCESS_STATE_UNKNOWN; + s.updateProcessStateOnRequest(); + // The package could be frozen (meaning it's doing surgery), defer the actual // binding until the package is unfrozen. boolean packageFrozen = deferServiceBringupIfFrozenLocked(s, service, callingPackage, null, - callingUid, callingPid, false, callerFg, userId, BackgroundStartPrivileges.NONE, - true, connection); + callingUid, callingPid, callingProcessName, callingProcessState, + false, callerFg, userId, BackgroundStartPrivileges.NONE, true, connection); // If permissions need a review before any of the app components can run, // we schedule binding to the service but do not start its process, then @@ -3756,7 +3776,9 @@ public final class ActiveServices { getShortServiceNameForStats(s), packageState, s.packageName, - callerApp.info.packageName); + callerApp.info.packageName, + callerApp.mState.getCurProcState(), + s.mProcessStateOnRequest); if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b + ": received=" + b.intent.received @@ -5355,7 +5377,7 @@ public final class ActiveServices { // be called. if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), - null, null, 0, null, null)); + null, null, 0, null, null, ActivityManager.PROCESS_STATE_UNKNOWN)); } sendServiceArgsLocked(r, execInFg, true); @@ -6351,7 +6373,8 @@ public final class ActiveServices { stopServiceLocked(sr, true); } else { sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true, - sr.getLastStartId(), baseIntent, null, 0, null, null)); + sr.getLastStartId(), baseIntent, null, 0, null, null, + ActivityManager.PROCESS_STATE_UNKNOWN)); if (sr.app != null && sr.app.getThread() != null) { // We always run in the foreground, since this is called as // part of the "remove task" UI operation. diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 5c1dad978095..8835d19ef287 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1176,20 +1176,24 @@ public class ActivityManagerService extends IActivityManager.Stub public Intent intent; public boolean deferUntilActive; public int originalCallingUid; + /** The snapshot process state of the app who sent this broadcast */ + public int originalCallingAppProcessState; public static StickyBroadcast create(Intent intent, boolean deferUntilActive, - int originalCallingUid) { + int originalCallingUid, int originalCallingAppProcessState) { final StickyBroadcast b = new StickyBroadcast(); b.intent = intent; b.deferUntilActive = deferUntilActive; b.originalCallingUid = originalCallingUid; + b.originalCallingAppProcessState = originalCallingAppProcessState; return b; } @Override public String toString() { return "{intent=" + intent + ", defer=" + deferUntilActive + ", originalCallingUid=" - + originalCallingUid + "}"; + + originalCallingUid + ", originalCallingAppProcessState=" + + originalCallingAppProcessState + "}"; } } @@ -14033,7 +14037,8 @@ public class ActivityManagerService extends IActivityManager.Stub receivers, null, null, 0, null, null, false, true, true, -1, originalStickyCallingUid, BackgroundStartPrivileges.NONE, false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */, - null /* filterExtrasForReceiver */); + null /* filterExtrasForReceiver */, + broadcast.originalCallingAppProcessState); queue.enqueueBroadcastLocked(r); } } @@ -14848,6 +14853,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } + final int callerAppProcessState = getRealProcessStateLocked(callerApp, realCallingPid); // Add to the sticky list if requested. if (sticky) { if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, @@ -14910,12 +14916,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (intent.filterEquals(list.get(i).intent)) { // This sticky already exists, replace it. list.set(i, StickyBroadcast.create(new Intent(intent), deferUntilActive, - callingUid)); + callingUid, callerAppProcessState)); break; } } if (i >= stickiesCount) { - list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive, callingUid)); + list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive, callingUid, + callerAppProcessState)); } } @@ -14998,7 +15005,8 @@ public class ActivityManagerService extends IActivityManager.Stub requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions, registeredReceivers, resultToApp, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId, - backgroundStartPrivileges, timeoutExempt, filterExtrasForReceiver); + backgroundStartPrivileges, timeoutExempt, filterExtrasForReceiver, + callerAppProcessState); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r); queue.enqueueBroadcastLocked(r); registeredReceivers = null; @@ -15092,7 +15100,8 @@ public class ActivityManagerService extends IActivityManager.Stub requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions, receivers, resultToApp, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId, - backgroundStartPrivileges, timeoutExempt, filterExtrasForReceiver); + backgroundStartPrivileges, timeoutExempt, filterExtrasForReceiver, + callerAppProcessState); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r); queue.enqueueBroadcastLocked(r); @@ -15109,6 +15118,19 @@ public class ActivityManagerService extends IActivityManager.Stub return ActivityManager.BROADCAST_SUCCESS; } + @GuardedBy("this") + private int getRealProcessStateLocked(ProcessRecord app, int pid) { + if (app == null) { + synchronized (mPidsSelfLocked) { + app = mPidsSelfLocked.get(pid); + } + } + if (app != null && app.getThread() != null && !app.isKilled()) { + return app.mState.getCurProcState(); + } + return PROCESS_STATE_NONEXISTENT; + } + @VisibleForTesting ArrayList<StickyBroadcast> getStickyBroadcasts(String action, int userId) { final ArrayMap<String, ArrayList<StickyBroadcast>> stickyBroadcasts = diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java index 4b6d32427d68..a80ad599a3e2 100644 --- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java +++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java @@ -106,6 +106,12 @@ class BroadcastProcessQueue { long lastCpuDelayTime; /** + * Snapshotted value of {@link ProcessStateRecord#getCurProcState()} before + * dispatching the current broadcast to the receiver in this process. + */ + int lastProcessState; + + /** * Ordered collection of broadcasts that are waiting to be dispatched to * this process, as a pair of {@link BroadcastRecord} and the index into * {@link BroadcastRecord#receivers} that represents the receiver. diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java index 8688f25ba002..f13dc89f2bd2 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java @@ -269,7 +269,10 @@ public class BroadcastQueueImpl extends BroadcastQueue { Activity.RESULT_CANCELED, null, null, false, false, oldRecord.shareIdentity, oldRecord.userId, oldRecord.callingUid, r.callingUid, r.callerPackage, - SystemClock.uptimeMillis() - oldRecord.enqueueTime, 0, 0); + SystemClock.uptimeMillis() - oldRecord.enqueueTime, 0, 0, + oldRecord.resultToApp != null + ? oldRecord.resultToApp.mState.getCurProcState() + : ActivityManager.PROCESS_STATE_UNKNOWN); } catch (RemoteException e) { Slog.w(TAG, "Failure [" + mQueueName + "] sending broadcast result of " @@ -367,6 +370,7 @@ public class BroadcastQueueImpl extends BroadcastQueue { } r.curApp = app; + r.curAppLastProcessState = app.mState.getCurProcState(); final ProcessReceiverRecord prr = app.mReceivers; prr.addCurReceiver(r); app.mState.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER); @@ -418,6 +422,7 @@ public class BroadcastQueueImpl extends BroadcastQueue { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Process cur broadcast " + r + ": NOT STARTED!"); r.curApp = null; + r.curAppLastProcessState = ActivityManager.PROCESS_STATE_UNKNOWN; prr.removeCurReceiver(r); } } @@ -620,7 +625,8 @@ public class BroadcastQueueImpl extends BroadcastQueue { r.getDeliveryGroupPolicy(), r.intent.getFlags(), BroadcastRecord.getReceiverPriority(curReceiver), - r.callerProcState); + r.callerProcState, + r.curAppLastProcessState); } if (state == BroadcastRecord.IDLE) { Slog.w(TAG_BROADCAST, "finishReceiver [" + mQueueName + "] called but state is IDLE"); @@ -682,6 +688,7 @@ public class BroadcastQueueImpl extends BroadcastQueue { r.curFilter = null; r.curReceiver = null; r.curApp = null; + r.curAppLastProcessState = ActivityManager.PROCESS_STATE_UNKNOWN; r.curFilteredExtras = null; r.mWasReceiverAppStopped = false; mPendingBroadcast = null; @@ -751,7 +758,8 @@ public class BroadcastQueueImpl extends BroadcastQueue { Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, boolean shareIdentity, int sendingUser, int receiverUid, int callingUid, String callingPackage, - long dispatchDelay, long receiveDelay, int priority) throws RemoteException { + long dispatchDelay, long receiveDelay, int priority, + int receiverProcessState) throws RemoteException { // If the broadcaster opted-in to sharing their identity, then expose package visibility for // the receiver. if (shareIdentity) { @@ -802,7 +810,7 @@ public class BroadcastQueueImpl extends BroadcastQueue { SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL, app != null ? app.info.packageName : null, callingPackage, r.calculateTypeForLogging(), r.getDeliveryGroupPolicy(), r.intent.getFlags(), - priority, r.callerProcState); + priority, r.callerProcState, receiverProcessState); } } @@ -849,6 +857,7 @@ public class BroadcastQueueImpl extends BroadcastQueue { // things that directly call the IActivityManager API, which // are already core system stuff so don't matter for this. r.curApp = filter.receiverList.app; + r.curAppLastProcessState = r.curApp.mState.getCurProcState(); filter.receiverList.app.mReceivers.addCurReceiver(r); mService.enqueueOomAdjTargetLocked(r.curApp); mService.updateOomAdjPendingTargetsLocked( @@ -883,7 +892,10 @@ public class BroadcastQueueImpl extends BroadcastQueue { r.resultExtras, r.ordered, r.initialSticky, r.shareIdentity, r.userId, filter.receiverList.uid, r.callingUid, r.callerPackage, r.dispatchTime - r.enqueueTime, - r.receiverTime - r.dispatchTime, filter.getPriority()); + r.receiverTime - r.dispatchTime, filter.getPriority(), + filter.receiverList.app != null + ? filter.receiverList.app.mState.getCurProcState() + : ActivityManager.PROCESS_STATE_UNKNOWN); // parallel broadcasts are fire-and-forget, not bookended by a call to // finishReceiverLocked(), so we manage their activity-start token here if (filter.receiverList.app != null @@ -1174,7 +1186,10 @@ public class BroadcastQueueImpl extends BroadcastQueue { r.resultData, r.resultExtras, false, false, r.shareIdentity, r.userId, r.callingUid, r.callingUid, r.callerPackage, r.dispatchTime - r.enqueueTime, - now - r.dispatchTime, 0); + now - r.dispatchTime, 0, + r.resultToApp != null + ? r.resultToApp.mState.getCurProcState() + : ActivityManager.PROCESS_STATE_UNKNOWN); logBootCompletedBroadcastCompletionLatencyIfPossible(r); // Set this to null so that the reference // (local and remote) isn't kept in the mBroadcastHistory. @@ -1480,6 +1495,7 @@ public class BroadcastQueueImpl extends BroadcastQueue { r.intent.getAction(), r.getHostingRecordTriggerType()), isActivityCapable ? ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE : ZYGOTE_POLICY_FLAG_EMPTY, (r.intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false); + r.curAppLastProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; if (r.curApp == null) { // Ah, this recipient is unavailable. Finish it if necessary, // and mark the broadcast record as ready for the next. diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index 8380308812d5..397eef4216a1 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -1002,6 +1002,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { mService.mPackageManagerInt.grantImplicitAccess(r.userId, r.intent, UserHandle.getAppId(app.uid), r.callingUid, true); } + queue.lastProcessState = app.mState.getCurProcState(); if (receiver instanceof BroadcastFilter) { notifyScheduleRegisteredReceiver(app, r, (BroadcastFilter) receiver); thread.scheduleRegisteredReceiver( @@ -1914,12 +1915,16 @@ class BroadcastQueueModernImpl extends BroadcastQueue { ? BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__RUNTIME : BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST; final int type; + final int receiverProcessState; if (queue == null) { type = BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_UNKNOWN; + receiverProcessState = ActivityManager.PROCESS_STATE_UNKNOWN; } else if (queue.getActiveViaColdStart()) { type = BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD; + receiverProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; } else { type = BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM; + receiverProcessState = queue.lastProcessState; } // With the new per-process queues, there's no delay between being // "dispatched" and "scheduled", so we report no "receive delay" @@ -1934,7 +1939,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue { receiverType, type, dispatchDelay, receiveDelay, finishDelay, packageState, app != null ? app.info.packageName : null, r.callerPackage, r.calculateTypeForLogging(), r.getDeliveryGroupPolicy(), r.intent.getFlags(), - BroadcastRecord.getReceiverPriority(receiver), r.callerProcState); + BroadcastRecord.getReceiverPriority(receiver), r.callerProcState, + receiverProcessState); } } diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java index 67d43fd30bad..198adcb7606a 100644 --- a/services/core/java/com/android/server/am/BroadcastRecord.java +++ b/services/core/java/com/android/server/am/BroadcastRecord.java @@ -44,7 +44,6 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UptimeMillisLong; -import android.app.ActivityManager; import android.app.ActivityManager.ProcessState; import android.app.ActivityManagerInternal; import android.app.AppOpsManager; @@ -271,6 +270,8 @@ final class BroadcastRecord extends Binder { BroadcastFilter curFilter; // the registered receiver currently running. Bundle curFilteredExtras; // the bundle that has been filtered by the package visibility rules + int curAppLastProcessState; // The last process state of the current receiver before receiving + boolean mIsReceiverAppRunning; // Was the receiver's app already running. boolean mWasReceiverAppStopped; // Was the receiver app stopped prior to starting @@ -432,13 +433,14 @@ final class BroadcastRecord extends Binder { boolean initialSticky, int userId, @NonNull BackgroundStartPrivileges backgroundStartPrivileges, boolean timeoutExempt, - @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) { + @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, + int callerAppProcessState) { this(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, requiredPermissions, excludedPermissions, excludedPackages, appOp, options, receivers, resultToApp, resultTo, resultCode, resultData, resultExtras, serialized, sticky, initialSticky, userId, -1, backgroundStartPrivileges, timeoutExempt, - filterExtrasForReceiver); + filterExtrasForReceiver, callerAppProcessState); } BroadcastRecord(BroadcastQueue _queue, @@ -453,7 +455,8 @@ final class BroadcastRecord extends Binder { boolean _initialSticky, int _userId, int originalStickyCallingUid, @NonNull BackgroundStartPrivileges backgroundStartPrivileges, boolean timeoutExempt, - @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) { + @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, + int callerAppProcessState) { if (_intent == null) { throw new NullPointerException("Can't construct with a null intent"); } @@ -465,8 +468,7 @@ final class BroadcastRecord extends Binder { callerFeatureId = _callerFeatureId; callingPid = _callingPid; callingUid = _callingUid; - callerProcState = callerApp == null ? ActivityManager.PROCESS_STATE_UNKNOWN - : callerApp.getCurProcState(); + callerProcState = callerAppProcessState; callerInstantApp = _callerInstantApp; callerInstrumented = isCallerInstrumented(_callerApp, _callingUid); resolvedType = _resolvedType; @@ -606,7 +608,8 @@ final class BroadcastRecord extends Binder { requiredPermissions, excludedPermissions, excludedPackages, appOp, options, splitReceivers, resultToApp, resultTo, resultCode, resultData, resultExtras, ordered, sticky, initialSticky, userId, - mBackgroundStartPrivileges, timeoutExempt, filterExtrasForReceiver); + mBackgroundStartPrivileges, timeoutExempt, filterExtrasForReceiver, + callerProcState); split.enqueueTime = this.enqueueTime; split.enqueueRealTime = this.enqueueRealTime; split.enqueueClockTime = this.enqueueClockTime; @@ -686,7 +689,7 @@ final class BroadcastRecord extends Binder { uid2receiverList.valueAt(i), null /* _resultToApp */, null /* _resultTo */, resultCode, resultData, resultExtras, ordered, sticky, initialSticky, userId, mBackgroundStartPrivileges, timeoutExempt, - filterExtrasForReceiver); + filterExtrasForReceiver, callerProcState); br.enqueueTime = this.enqueueTime; br.enqueueRealTime = this.enqueueRealTime; br.enqueueClockTime = this.enqueueClockTime; diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java index e744eee8b485..3f7d8ba1a120 100644 --- a/services/core/java/com/android/server/am/ContentProviderHelper.java +++ b/services/core/java/com/android/server/am/ContentProviderHelper.java @@ -246,9 +246,13 @@ public class ContentProviderHelper { } } + final int callingProcessState = r != null + ? r.mState.getCurProcState() : ActivityManager.PROCESS_STATE_UNKNOWN; + if (providerRunning) { cpi = cpr.info; + if (r != null && cpr.canRunHere(r)) { checkAssociationAndPermissionLocked(r, cpi, callingUid, userId, checkCrossUser, cpr.name.flattenToShortString(), startTime); @@ -266,7 +270,8 @@ public class ContentProviderHelper { r.uid, callingUid, PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM, PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL, - cpi.packageName, callingPackage); + cpi.packageName, callingPackage, + callingProcessState, callingProcessState); return holder; } @@ -282,6 +287,8 @@ public class ContentProviderHelper { checkAssociationAndPermissionLocked(r, cpi, callingUid, userId, checkCrossUser, cpr.name.flattenToShortString(), startTime); + final int providerProcessState = cpr.proc.mState.getCurProcState(); + final long origId = Binder.clearCallingIdentity(); try { checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); @@ -338,7 +345,8 @@ public class ContentProviderHelper { cpr.proc.uid, callingUid, PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM, PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL, - cpi.packageName, callingPackage); + cpi.packageName, callingPackage, + callingProcessState, providerProcessState); } } finally { Binder.restoreCallingIdentity(origId); @@ -516,7 +524,8 @@ public class ContentProviderHelper { proc.uid, callingUid, PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM, PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL, - cpi.packageName, callingPackage); + cpi.packageName, callingPackage, + callingProcessState, proc.mState.getCurProcState()); } else { final int packageState = ((cpr.appInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0) @@ -541,7 +550,8 @@ public class ContentProviderHelper { PROVIDER_ACQUISITION_EVENT_REPORTED, proc.uid, callingUid, PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD, - packageState, cpi.packageName, callingPackage); + packageState, cpi.packageName, callingPackage, + callingProcessState, ActivityManager.PROCESS_STATE_NONEXISTENT); } cpr.launchingApp = proc; mLaunchingProviders.add(cpr); diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index dccbb0accadd..0f5defbef919 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -16,6 +16,7 @@ package com.android.server.am; +import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_BOUND_SERVICE; @@ -244,6 +245,11 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN */ long mRestartSchedulingTime; + /** + * The snapshot process state when the service is requested (either start or bind). + */ + int mProcessStateOnRequest; + static class StartItem { final ServiceRecord sr; final boolean taskRemoved; @@ -253,6 +259,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN final Intent intent; final NeededUriGrants neededGrants; final @Nullable String mCallingPackageName; + final int mCallingProcessState; long deliveredTime; int deliveryCount; int doneExecutingCount; @@ -262,7 +269,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent, NeededUriGrants _neededGrants, int _callingId, - String callingProcessName, @Nullable String callingPackageName) { + String callingProcessName, @Nullable String callingPackageName, + int callingProcessState) { sr = _sr; taskRemoved = _taskRemoved; id = _id; @@ -271,6 +279,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN callingId = _callingId; mCallingProcessName = callingProcessName; mCallingPackageName = callingPackageName; + mCallingProcessState = callingProcessState; } UriPermissionOwner getUriPermissionsLocked() { @@ -873,6 +882,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN app.mServices.updateHostingComonentTypeForBindingsLocked(); } app = proc; + updateProcessStateOnRequest(); if (pendingConnectionGroup > 0 && proc != null) { final ProcessServiceRecord psr = proc.mServices; psr.setConnectionService(this); @@ -899,6 +909,11 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } } + void updateProcessStateOnRequest() { + mProcessStateOnRequest = app != null && app.getThread() != null && !app.isKilled() + ? app.mState.getCurProcState() : PROCESS_STATE_NONEXISTENT; + } + @NonNull ArrayMap<IBinder, ArrayList<ConnectionRecord>> getConnections() { return connections; diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java index a614c4dd1d61..2bc66ace454b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java @@ -27,6 +27,7 @@ import static android.app.ActivityManager.PROCESS_STATE_RECEIVER; import static android.app.ActivityManager.PROCESS_STATE_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; +import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; import static android.util.DebugUtils.valueToString; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; @@ -742,24 +743,24 @@ public class ActivityManagerServiceTest { broadcastIntent(intent1, null, true); assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER), - StickyBroadcast.create(intent1, false, Process.myUid())); + StickyBroadcast.create(intent1, false, Process.myUid(), PROCESS_STATE_UNKNOWN)); assertNull(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER)); assertNull(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER)); broadcastIntent(intent2, options.toBundle(), true); assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER), - StickyBroadcast.create(intent1, false, Process.myUid())); + StickyBroadcast.create(intent1, false, Process.myUid(), PROCESS_STATE_UNKNOWN)); assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER), - StickyBroadcast.create(intent2, true, Process.myUid())); + StickyBroadcast.create(intent2, true, Process.myUid(), PROCESS_STATE_UNKNOWN)); assertNull(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER)); broadcastIntent(intent3, null, true); assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER), - StickyBroadcast.create(intent1, false, Process.myUid())); + StickyBroadcast.create(intent1, false, Process.myUid(), PROCESS_STATE_UNKNOWN)); assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER), - StickyBroadcast.create(intent2, true, Process.myUid())); + StickyBroadcast.create(intent2, true, Process.myUid(), PROCESS_STATE_UNKNOWN)); assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER), - StickyBroadcast.create(intent3, false, Process.myUid())); + StickyBroadcast.create(intent3, false, Process.myUid(), PROCESS_STATE_UNKNOWN)); } @SuppressWarnings("GuardedBy") diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java index 582685cf009e..ccaaa87f8e06 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java @@ -16,6 +16,8 @@ package com.android.server.am; +import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; + import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED; import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD; @@ -246,7 +248,7 @@ public final class BroadcastQueueModernImplTest { return new BroadcastRecord(mImpl, intent, mProcess, PACKAGE_RED, null, 21, 42, false, null, null, null, null, AppOpsManager.OP_NONE, options, receivers, null, resultTo, Activity.RESULT_OK, null, null, ordered, false, false, UserHandle.USER_SYSTEM, - BackgroundStartPrivileges.NONE, false, null); + BackgroundStartPrivileges.NONE, false, null, PROCESS_STATE_UNKNOWN); } private void enqueueOrReplaceBroadcast(BroadcastProcessQueue queue, @@ -1407,7 +1409,7 @@ public final class BroadcastQueueModernImplTest { eq(BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST), eq(BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD), anyLong(), anyLong(), anyLong(), anyInt(), nullable(String.class), - anyString(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()), + anyString(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()), times(1)); } diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java index 03231ecfb723..0f75ea5fb7ef 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java @@ -16,6 +16,7 @@ package com.android.server.am; +import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_FINISH_RECEIVER; import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_RECEIVER; import static android.os.UserHandle.USER_SYSTEM; @@ -611,7 +612,7 @@ public class BroadcastQueueTest { callerApp.getPid(), callerApp.info.uid, false, null, null, null, null, AppOpsManager.OP_NONE, options, receivers, callerApp, resultTo, Activity.RESULT_OK, null, resultExtras, ordered, false, false, userId, - BackgroundStartPrivileges.NONE, false, null); + BackgroundStartPrivileges.NONE, false, null, PROCESS_STATE_UNKNOWN); } private void assertHealth() { @@ -1599,7 +1600,7 @@ public class BroadcastQueueTest { null, null, null, null, AppOpsManager.OP_NONE, BroadcastOptions.makeBasic(), List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)), null, null, Activity.RESULT_OK, null, null, false, false, false, UserHandle.USER_SYSTEM, - backgroundStartPrivileges, false, null); + backgroundStartPrivileges, false, null, PROCESS_STATE_UNKNOWN); enqueueBroadcast(r); waitForIdle(); diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java index 08952eab071f..f0efb795f5a1 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java @@ -16,6 +16,7 @@ package com.android.server.am; +import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; import static android.app.ActivityManager.RESTRICTION_LEVEL_BACKGROUND_RESTRICTED; import static android.content.Intent.ACTION_BOOT_COMPLETED; import static android.content.Intent.ACTION_LOCKED_BOOT_COMPLETED; @@ -958,7 +959,8 @@ public class BroadcastRecordTest { userId, BackgroundStartPrivileges.NONE, false /* timeoutExempt */, - filterExtrasForReceiver); + filterExtrasForReceiver, + PROCESS_STATE_UNKNOWN); } private static int getAppId(int i) { |