Merge "Add client/service process states for broadcast/service/provider" into udc-dev am: 0f529d03a8 am: cb4d966258
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23558767
Change-Id: Ibca4ffa4a1f154459581aa37ba2f69f0c7f067eb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 6f20563..fc84e13 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 @@
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 @@
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 @@
// 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 @@
}
}
- 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 @@
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 @@
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 @@
@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 @@
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 @@
} 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 @@
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 @@
getShortServiceNameForStats(r),
packageState,
packageName,
- callingPackage);
+ callingPackage,
+ callingProcessState,
+ r.mProcessStateOnRequest);
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
@@ -3611,11 +3620,22 @@
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 @@
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 @@
// 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 @@
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 6d55058..a94fdad 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 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 + "}";
}
}
@@ -14042,7 +14046,8 @@
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);
}
}
@@ -14857,6 +14862,7 @@
}
}
+ final int callerAppProcessState = getRealProcessStateLocked(callerApp, realCallingPid);
// Add to the sticky list if requested.
if (sticky) {
if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
@@ -14919,12 +14925,13 @@
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));
}
}
@@ -15007,7 +15014,8 @@
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;
@@ -15101,7 +15109,8 @@
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);
@@ -15118,6 +15127,19 @@
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 4b6d324..a80ad59 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 @@
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 8688f25..f13dc89 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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 8380308..397eef4 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 @@
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 @@
? 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 @@
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 67d43fd..198adcb 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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 e744eee..3f7d8ba 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 @@
}
}
+ 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 @@
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 @@
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 @@
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 @@
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 @@
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 dccbb0a..0f5defb 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 @@
*/
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 Intent intent;
final NeededUriGrants neededGrants;
final @Nullable String mCallingPackageName;
+ final int mCallingProcessState;
long deliveredTime;
int deliveryCount;
int doneExecutingCount;
@@ -262,7 +269,8 @@
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 @@
callingId = _callingId;
mCallingProcessName = callingProcessName;
mCallingPackageName = callingPackageName;
+ mCallingProcessState = callingProcessState;
}
UriPermissionOwner getUriPermissionsLocked() {
@@ -873,6 +882,7 @@
app.mServices.updateHostingComonentTypeForBindingsLocked();
}
app = proc;
+ updateProcessStateOnRequest();
if (pendingConnectionGroup > 0 && proc != null) {
final ProcessServiceRecord psr = proc.mServices;
psr.setConnectionService(this);
@@ -899,6 +909,11 @@
}
}
+ 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 a614c4d..2bc66ac 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_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 @@
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 582685c..ccaaa87 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 @@
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 @@
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 03231ec..0f75ea5 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 @@
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 @@
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 08952ea..f0efb79 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 @@
userId,
BackgroundStartPrivileges.NONE,
false /* timeoutExempt */,
- filterExtrasForReceiver);
+ filterExtrasForReceiver,
+ PROCESS_STATE_UNKNOWN);
}
private static int getAppId(int i) {