Merge "Log a WTF message if sendBroadcast() or bindService() is called from a cached state."
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index baf5af5..81a3d53 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -20,7 +20,9 @@
import static android.Manifest.permission.REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND;
import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
+import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
+import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
@@ -2896,6 +2898,7 @@
}
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, userId,
false);
+ logBindServiceFromCachedState(callingPackage, callingUid, service);
if (s.app != null) {
ProcessServiceRecord servicePsr = s.app.mServices;
@@ -2960,6 +2963,30 @@
return 1;
}
+ /**
+ * Log a WTF message if the bindService is called by a process from a cached proc state.
+ * This WTF log is to debug background restriction, it will be removed in before final release.
+ * @param callerPackage the caller's package name.
+ * @param callingUid the caller's UID.
+ * @param intent the service's intent.
+ */
+ private void logBindServiceFromCachedState(String callerPackage, int callingUid,
+ Intent intent) {
+ final int callerUidState = mAm.getUidStateLocked(callingUid);
+ if (callerUidState == PROCESS_STATE_NONEXISTENT
+ || callerUidState < PROCESS_STATE_CACHED_ACTIVITY) {
+ return;
+ }
+ final String msg = "bindService from cached state "
+ + "[callerPackage:" + callerPackage
+ + "; callingUid:" + callingUid
+ + "; uidState:" + ProcessList.makeProcStateString(callerUidState)
+ + "; intent:" + intent
+ + ";]";
+ Slog.wtfQuiet(TAG, msg);
+ Slog.i(TAG, msg);
+ }
+
private void maybeLogBindCrossProfileService(
int userId, String callingPackage, int callingUid) {
if (UserHandle.isCore(callingUid)) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0e57236..5179c0d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -12682,7 +12682,8 @@
Intent intent = allSticky.get(i);
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
- null, null, -1, -1, false, null, null, null, OP_NONE, null, receivers,
+ null, null, -1, -1, PROCESS_STATE_NONEXISTENT, false, null, null, null,
+ OP_NONE, null, receivers,
null, 0, null, null, false, true, true, -1, false, null,
false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */);
queue.enqueueParallelBroadcastLocked(r);
@@ -12960,6 +12961,7 @@
@Nullable int[] broadcastAllowList) {
intent = new Intent(intent);
+ final int callerUidState = getUidStateLocked(realCallingUid);
final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
// Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
if (callerInstantApp) {
@@ -13527,7 +13529,8 @@
}
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
- callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
+ callerFeatureId, callingPid, callingUid, callerUidState, callerInstantApp,
+ resolvedType,
requiredPermissions, excludedPermissions, appOp, brOptions, registeredReceivers,
resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId,
allowBackgroundActivityStarts, backgroundActivityStartsToken,
@@ -13625,7 +13628,8 @@
|| resultTo != null) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
- callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
+ callerFeatureId, callingPid, callingUid, callerUidState, callerInstantApp,
+ resolvedType,
requiredPermissions, excludedPermissions, appOp, brOptions,
receivers, resultTo, resultCode, resultData, resultExtras,
ordered, sticky, false, userId, allowBackgroundActivityStarts,
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index ed70d2b..fd64c3c 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -16,6 +16,8 @@
package com.android.server.am;
+import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
+import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY;
import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE;
import static android.text.TextUtils.formatSimple;
@@ -1656,6 +1658,9 @@
scheduleBroadcastsLocked();
return;
}
+
+ logSendBroadcastFromCachedState(r, component);
+
r.manifestCount++;
r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
@@ -1750,6 +1755,29 @@
mPendingBroadcastRecvIndex = recIdx;
}
+ /**
+ * Log a WTF message if the broadcast is sent by a process from a cached proc state.
+ * This WTF log is to debug background restriction, it will be removed in before final release.
+ * @param r the BroadcastRecord.
+ * @param component the broadcast's resolved ComponentName.
+ */
+ private void logSendBroadcastFromCachedState(BroadcastRecord r, ComponentName component) {
+ if (r.callerUidState == PROCESS_STATE_NONEXISTENT
+ || r.callerUidState < PROCESS_STATE_CACHED_ACTIVITY) {
+ return;
+ }
+ final String msg = "sendBroadcast from cached state"
+ + "[callerPackage:" + r.callerPackage
+ + "; callingUid:" + r.callingUid
+ + "; realCallingUid:" + r.callingUid
+ + "; uidState:" + ProcessList.makeProcStateString(r.callerUidState)
+ + "; intent:" + r.intent
+ + "; component:" + component.flattenToShortString()
+ + ";]";
+ Slog.wtfQuiet(TAG, msg);
+ Slog.i(TAG, msg);
+ }
+
private boolean noteOpForManifestReceiver(int appOp, BroadcastRecord r, ResolveInfo info,
ComponentName component) {
if (info.activityInfo.attributionTags == null) {
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 8015596..53445b3 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -55,6 +55,7 @@
final @Nullable String callerFeatureId; // which feature in the package sent this
final int callingPid; // the pid of who sent this
final int callingUid; // the uid of who sent this
+ final int callerUidState; // the sender's UID state when sent this.
final boolean callerInstantApp; // caller is an Instant App?
final boolean ordered; // serialize the send to receivers?
final boolean sticky; // originated from existing sticky data?
@@ -244,7 +245,7 @@
BroadcastRecord(BroadcastQueue _queue,
Intent _intent, ProcessRecord _callerApp, String _callerPackage,
@Nullable String _callerFeatureId, int _callingPid, int _callingUid,
- boolean _callerInstantApp, String _resolvedType,
+ int _callerUidState, boolean _callerInstantApp, String _resolvedType,
String[] _requiredPermissions, String[] _excludedPermissions, int _appOp,
BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo, int _resultCode,
String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky,
@@ -261,6 +262,7 @@
callerFeatureId = _callerFeatureId;
callingPid = _callingPid;
callingUid = _callingUid;
+ this.callerUidState = _callerUidState;
callerInstantApp = _callerInstantApp;
resolvedType = _resolvedType;
requiredPermissions = _requiredPermissions;
@@ -298,6 +300,7 @@
callerFeatureId = from.callerFeatureId;
callingPid = from.callingPid;
callingUid = from.callingUid;
+ callerUidState = from.callerUidState;
callerInstantApp = from.callerInstantApp;
ordered = from.ordered;
sticky = from.sticky;
@@ -362,7 +365,8 @@
// build a new BroadcastRecord around that single-target list
BroadcastRecord split = new BroadcastRecord(queue, intent, callerApp, callerPackage,
- callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
+ callerFeatureId, callingPid, callingUid, callerUidState, callerInstantApp,
+ resolvedType,
requiredPermissions, excludedPermissions, appOp, options, splitReceivers, resultTo,
resultCode, resultData, resultExtras, ordered, sticky, initialSticky, userId,
allowBackgroundActivityStarts, mBackgroundActivityStartsToken, timeoutExempt);
diff --git a/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java b/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java
index e9b5b62..ce90d99 100644
--- a/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java
@@ -16,6 +16,8 @@
package com.android.server.am;
+import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+
import static org.junit.Assert.assertNull;
import android.content.Intent;
@@ -181,6 +183,7 @@
null /* callerFeatureId */,
0 /* callingPid */,
0 /* callingUid */,
+ PROCESS_STATE_NONEXISTENT,
false /* callerInstantApp */,
null /* resolvedType */,
null /* requiredPermissions */,
@@ -198,6 +201,6 @@
userId,
false /* allowBackgroundActivityStarts */,
null /* activityStartsToken */,
- false /* timeoutExempt */ );
+ false /* timeoutExempt */);
}
}