Loading core/java/android/app/BroadcastOptions.java +31 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.os.BundleMerger; import android.os.PowerExemptionManager; import android.os.PowerExemptionManager.ReasonCode; import android.os.PowerExemptionManager.TempAllowListType; import android.os.Process; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -76,6 +77,7 @@ public class BroadcastOptions extends ComponentOptions { FLAG_IS_ALARM_BROADCAST, FLAG_SHARE_IDENTITY, FLAG_INTERACTIVE, FLAG_DEBUG_LOG, }) @Retention(RetentionPolicy.SOURCE) public @interface Flags {} Loading @@ -86,6 +88,7 @@ public class BroadcastOptions extends ComponentOptions { private static final int FLAG_IS_ALARM_BROADCAST = 1 << 3; private static final int FLAG_SHARE_IDENTITY = 1 << 4; private static final int FLAG_INTERACTIVE = 1 << 5; private static final int FLAG_DEBUG_LOG = 1 << 6; /** * Change ID which is invalid. Loading Loading @@ -1081,6 +1084,34 @@ public class BroadcastOptions extends ComponentOptions { return super.getPendingIntentBackgroundActivityStartMode(); } /** * If enabled, additional debug messages for broadcast delivery will be logged. * * <p> This will only take effect when used by {@link Process#SHELL_UID} * or {@link Process#ROOT_UID} or by apps under instrumentation. * * @hide */ @NonNull public BroadcastOptions setDebugLogEnabled(boolean enabled) { if (enabled) { mFlags |= FLAG_DEBUG_LOG; } else { mFlags &= ~FLAG_DEBUG_LOG; } return this; } /** * @return if additional debug messages for broadcast delivery are enabled. * * @see #setDebugLogEnabled(boolean) * @hide */ public boolean isDebugLogEnabled() { return (mFlags & FLAG_DEBUG_LOG) != 0; } /** * Returns the created options as a Bundle, which can be passed to * {@link android.content.Context#sendBroadcast(android.content.Intent) Loading services/core/java/com/android/server/am/BroadcastController.java +24 −1 Original line number Diff line number Diff line Loading @@ -47,6 +47,8 @@ import static com.android.server.am.ActivityManagerService.UPDATE_HTTP_PROXY_MSG import static com.android.server.am.ActivityManagerService.UPDATE_TIME_PREFERENCE_MSG; import static com.android.server.am.ActivityManagerService.UPDATE_TIME_ZONE; import static com.android.server.am.ActivityManagerService.checkComponentPermission; import static com.android.server.am.BroadcastRecord.debugLog; import static com.android.server.am.BroadcastRecord.intentToString; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -1017,6 +1019,13 @@ class BroadcastController { android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS, callingPid, callingUid, "recordResponseEventWhileInBackground"); } if (brOptions.isDebugLogEnabled()) { if (!isShellOrRoot(callingUid) && (callerApp == null || !callerApp.hasActiveInstrumentation())) { brOptions.setDebugLogEnabled(false); } } } // Verify that protected broadcasts are only being sent by system code, Loading Loading @@ -1622,6 +1631,10 @@ class BroadcastController { } } while (ir < NR) { // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS if (callerInstantApp) { intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); } if (receivers == null) { receivers = new ArrayList(); } Loading @@ -1647,7 +1660,9 @@ class BroadcastController { callerAppProcessState, mService.mPlatformCompat); broadcastSentEventRecord.setBroadcastRecord(r); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r); if (DEBUG_BROADCAST || r.debugLog()) { Slog.v(TAG_BROADCAST, "Enqueueing broadcast " + r); } queue.enqueueBroadcastLocked(r); } else { // There was nobody interested in the broadcast, but we still want to record Loading @@ -1657,11 +1672,19 @@ class BroadcastController { // This was an implicit broadcast... let's record it for posterity. addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0); } if (DEBUG_BROADCAST || debugLog(brOptions)) { Slog.v(TAG_BROADCAST, "Skipping broadcast " + intentToString(intent) + " due to no receivers"); } } return ActivityManager.BROADCAST_SUCCESS; } private boolean isShellOrRoot(int uid) { return uid == SHELL_UID || uid == ROOT_UID; } @GuardedBy("mService") private void scheduleCanceledResultTo(ProcessRecord resultToApp, IIntentReceiver resultTo, Intent intent, int userId, BroadcastOptions options, int callingUid, Loading services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +18 −7 Original line number Diff line number Diff line Loading @@ -798,7 +798,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue { mService.mOomAdjuster.mCachedAppOptimizer.freezeAppAsyncImmediateLSP(r.callerApp); return; } if (DEBUG_BROADCAST) logv("Enqueuing " + r + " for " + r.receivers.size() + " receivers"); if (DEBUG_BROADCAST || r.debugLog()) { logv("Enqueuing " + r + " for " + r.receivers.size() + " receivers"); } final int cookie = traceBegin("enqueueBroadcast"); r.applySingletonPolicy(mService); Loading Loading @@ -1019,7 +1021,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue { & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0; long startTimeNs = SystemClock.uptimeNanos(); if (DEBUG_BROADCAST) logv("Scheduling " + r + " to cold " + queue); if (DEBUG_BROADCAST || r.debugLog()) { logv("Scheduling " + r + " to cold " + queue); } queue.app = mService.startProcessLocked(queue.processName, info, true, intentFlags, hostingRecord, zygotePolicyFlags, allowWhileBooting, false); if (queue.app == null) { Loading Loading @@ -1176,7 +1180,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue { } } if (DEBUG_BROADCAST) logv("Scheduling " + r + " to warm " + app); if (DEBUG_BROADCAST || r.debugLog()) { logv("Scheduling " + r + " to warm " + app); } setDeliveryState(queue, app, r, index, receiver, BroadcastRecord.DELIVERY_SCHEDULED, "scheduleReceiverWarmLocked"); Loading Loading @@ -1562,12 +1568,17 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // bookkeeping to update for ordered broadcasts if (!isDeliveryStateTerminal(oldDeliveryState) && isDeliveryStateTerminal(newDeliveryState)) { if (DEBUG_BROADCAST && newDeliveryState != BroadcastRecord.DELIVERY_DELIVERED) { logw("Delivery state of " + r + " to " + receiver if ((DEBUG_BROADCAST && newDeliveryState != BroadcastRecord.DELIVERY_DELIVERED) || r.debugLog()) { final String msg = "Delivery state of " + r + " to " + receiver + " via " + app + " changed from " + deliveryStateToString(oldDeliveryState) + " to " + deliveryStateToString(newDeliveryState) + " because " + reason); + deliveryStateToString(newDeliveryState) + " because " + reason; if (newDeliveryState == BroadcastRecord.DELIVERY_DELIVERED) { logv(msg); } else { logw(msg); } } notifyFinishReceiver(queue, app, r, index, receiver); Loading services/core/java/com/android/server/am/BroadcastRecord.java +21 −9 Original line number Diff line number Diff line Loading @@ -1285,31 +1285,43 @@ final class BroadcastRecord extends Binder { } @Override @NonNull public String toString() { if (mCachedToString == null) { String label = intent.getAction(); if (label == null) { label = intent.toString(); } mCachedToString = "BroadcastRecord{" + toShortString() + "}"; } return mCachedToString; } @NonNull public String toShortString() { if (mCachedToShortString == null) { final String label = intentToString(intent); mCachedToShortString = Integer.toHexString(System.identityHashCode(this)) + " " + label + "/u" + userId; } return mCachedToShortString; } @NonNull public static String intentToString(@NonNull Intent intent) { String label = intent.getAction(); if (label == null) { label = intent.toString(); } mCachedToShortString = Integer.toHexString(System.identityHashCode(this)) + " " + label + "/u" + userId; return label; } return mCachedToShortString; public boolean debugLog() { return debugLog(options); } public static boolean debugLog(@Nullable BroadcastOptions options) { return options != null && options.isDebugLogEnabled(); } @NeverCompile public void dumpDebug(ProtoOutputStream proto, long fieldId) { public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) { long token = proto.start(fieldId); proto.write(BroadcastRecordProto.USER_ID, userId); proto.write(BroadcastRecordProto.INTENT_ACTION, intent.getAction()); Loading services/core/java/com/android/server/am/ProcessRecord.java +5 −0 Original line number Diff line number Diff line Loading @@ -1004,6 +1004,11 @@ class ProcessRecord implements WindowProcessListener { return mInstr; } @GuardedBy(anyOf = {"mService", "mProcLock"}) boolean hasActiveInstrumentation() { return mInstr != null; } @GuardedBy(anyOf = {"mService", "mProcLock"}) boolean isKilledByAm() { return mKilledByAm; Loading Loading
core/java/android/app/BroadcastOptions.java +31 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.os.BundleMerger; import android.os.PowerExemptionManager; import android.os.PowerExemptionManager.ReasonCode; import android.os.PowerExemptionManager.TempAllowListType; import android.os.Process; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -76,6 +77,7 @@ public class BroadcastOptions extends ComponentOptions { FLAG_IS_ALARM_BROADCAST, FLAG_SHARE_IDENTITY, FLAG_INTERACTIVE, FLAG_DEBUG_LOG, }) @Retention(RetentionPolicy.SOURCE) public @interface Flags {} Loading @@ -86,6 +88,7 @@ public class BroadcastOptions extends ComponentOptions { private static final int FLAG_IS_ALARM_BROADCAST = 1 << 3; private static final int FLAG_SHARE_IDENTITY = 1 << 4; private static final int FLAG_INTERACTIVE = 1 << 5; private static final int FLAG_DEBUG_LOG = 1 << 6; /** * Change ID which is invalid. Loading Loading @@ -1081,6 +1084,34 @@ public class BroadcastOptions extends ComponentOptions { return super.getPendingIntentBackgroundActivityStartMode(); } /** * If enabled, additional debug messages for broadcast delivery will be logged. * * <p> This will only take effect when used by {@link Process#SHELL_UID} * or {@link Process#ROOT_UID} or by apps under instrumentation. * * @hide */ @NonNull public BroadcastOptions setDebugLogEnabled(boolean enabled) { if (enabled) { mFlags |= FLAG_DEBUG_LOG; } else { mFlags &= ~FLAG_DEBUG_LOG; } return this; } /** * @return if additional debug messages for broadcast delivery are enabled. * * @see #setDebugLogEnabled(boolean) * @hide */ public boolean isDebugLogEnabled() { return (mFlags & FLAG_DEBUG_LOG) != 0; } /** * Returns the created options as a Bundle, which can be passed to * {@link android.content.Context#sendBroadcast(android.content.Intent) Loading
services/core/java/com/android/server/am/BroadcastController.java +24 −1 Original line number Diff line number Diff line Loading @@ -47,6 +47,8 @@ import static com.android.server.am.ActivityManagerService.UPDATE_HTTP_PROXY_MSG import static com.android.server.am.ActivityManagerService.UPDATE_TIME_PREFERENCE_MSG; import static com.android.server.am.ActivityManagerService.UPDATE_TIME_ZONE; import static com.android.server.am.ActivityManagerService.checkComponentPermission; import static com.android.server.am.BroadcastRecord.debugLog; import static com.android.server.am.BroadcastRecord.intentToString; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -1017,6 +1019,13 @@ class BroadcastController { android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS, callingPid, callingUid, "recordResponseEventWhileInBackground"); } if (brOptions.isDebugLogEnabled()) { if (!isShellOrRoot(callingUid) && (callerApp == null || !callerApp.hasActiveInstrumentation())) { brOptions.setDebugLogEnabled(false); } } } // Verify that protected broadcasts are only being sent by system code, Loading Loading @@ -1622,6 +1631,10 @@ class BroadcastController { } } while (ir < NR) { // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS if (callerInstantApp) { intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); } if (receivers == null) { receivers = new ArrayList(); } Loading @@ -1647,7 +1660,9 @@ class BroadcastController { callerAppProcessState, mService.mPlatformCompat); broadcastSentEventRecord.setBroadcastRecord(r); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r); if (DEBUG_BROADCAST || r.debugLog()) { Slog.v(TAG_BROADCAST, "Enqueueing broadcast " + r); } queue.enqueueBroadcastLocked(r); } else { // There was nobody interested in the broadcast, but we still want to record Loading @@ -1657,11 +1672,19 @@ class BroadcastController { // This was an implicit broadcast... let's record it for posterity. addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0); } if (DEBUG_BROADCAST || debugLog(brOptions)) { Slog.v(TAG_BROADCAST, "Skipping broadcast " + intentToString(intent) + " due to no receivers"); } } return ActivityManager.BROADCAST_SUCCESS; } private boolean isShellOrRoot(int uid) { return uid == SHELL_UID || uid == ROOT_UID; } @GuardedBy("mService") private void scheduleCanceledResultTo(ProcessRecord resultToApp, IIntentReceiver resultTo, Intent intent, int userId, BroadcastOptions options, int callingUid, Loading
services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +18 −7 Original line number Diff line number Diff line Loading @@ -798,7 +798,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue { mService.mOomAdjuster.mCachedAppOptimizer.freezeAppAsyncImmediateLSP(r.callerApp); return; } if (DEBUG_BROADCAST) logv("Enqueuing " + r + " for " + r.receivers.size() + " receivers"); if (DEBUG_BROADCAST || r.debugLog()) { logv("Enqueuing " + r + " for " + r.receivers.size() + " receivers"); } final int cookie = traceBegin("enqueueBroadcast"); r.applySingletonPolicy(mService); Loading Loading @@ -1019,7 +1021,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue { & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0; long startTimeNs = SystemClock.uptimeNanos(); if (DEBUG_BROADCAST) logv("Scheduling " + r + " to cold " + queue); if (DEBUG_BROADCAST || r.debugLog()) { logv("Scheduling " + r + " to cold " + queue); } queue.app = mService.startProcessLocked(queue.processName, info, true, intentFlags, hostingRecord, zygotePolicyFlags, allowWhileBooting, false); if (queue.app == null) { Loading Loading @@ -1176,7 +1180,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue { } } if (DEBUG_BROADCAST) logv("Scheduling " + r + " to warm " + app); if (DEBUG_BROADCAST || r.debugLog()) { logv("Scheduling " + r + " to warm " + app); } setDeliveryState(queue, app, r, index, receiver, BroadcastRecord.DELIVERY_SCHEDULED, "scheduleReceiverWarmLocked"); Loading Loading @@ -1562,12 +1568,17 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // bookkeeping to update for ordered broadcasts if (!isDeliveryStateTerminal(oldDeliveryState) && isDeliveryStateTerminal(newDeliveryState)) { if (DEBUG_BROADCAST && newDeliveryState != BroadcastRecord.DELIVERY_DELIVERED) { logw("Delivery state of " + r + " to " + receiver if ((DEBUG_BROADCAST && newDeliveryState != BroadcastRecord.DELIVERY_DELIVERED) || r.debugLog()) { final String msg = "Delivery state of " + r + " to " + receiver + " via " + app + " changed from " + deliveryStateToString(oldDeliveryState) + " to " + deliveryStateToString(newDeliveryState) + " because " + reason); + deliveryStateToString(newDeliveryState) + " because " + reason; if (newDeliveryState == BroadcastRecord.DELIVERY_DELIVERED) { logv(msg); } else { logw(msg); } } notifyFinishReceiver(queue, app, r, index, receiver); Loading
services/core/java/com/android/server/am/BroadcastRecord.java +21 −9 Original line number Diff line number Diff line Loading @@ -1285,31 +1285,43 @@ final class BroadcastRecord extends Binder { } @Override @NonNull public String toString() { if (mCachedToString == null) { String label = intent.getAction(); if (label == null) { label = intent.toString(); } mCachedToString = "BroadcastRecord{" + toShortString() + "}"; } return mCachedToString; } @NonNull public String toShortString() { if (mCachedToShortString == null) { final String label = intentToString(intent); mCachedToShortString = Integer.toHexString(System.identityHashCode(this)) + " " + label + "/u" + userId; } return mCachedToShortString; } @NonNull public static String intentToString(@NonNull Intent intent) { String label = intent.getAction(); if (label == null) { label = intent.toString(); } mCachedToShortString = Integer.toHexString(System.identityHashCode(this)) + " " + label + "/u" + userId; return label; } return mCachedToShortString; public boolean debugLog() { return debugLog(options); } public static boolean debugLog(@Nullable BroadcastOptions options) { return options != null && options.isDebugLogEnabled(); } @NeverCompile public void dumpDebug(ProtoOutputStream proto, long fieldId) { public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) { long token = proto.start(fieldId); proto.write(BroadcastRecordProto.USER_ID, userId); proto.write(BroadcastRecordProto.INTENT_ACTION, intent.getAction()); Loading
services/core/java/com/android/server/am/ProcessRecord.java +5 −0 Original line number Diff line number Diff line Loading @@ -1004,6 +1004,11 @@ class ProcessRecord implements WindowProcessListener { return mInstr; } @GuardedBy(anyOf = {"mService", "mProcLock"}) boolean hasActiveInstrumentation() { return mInstr != null; } @GuardedBy(anyOf = {"mService", "mProcLock"}) boolean isKilledByAm() { return mKilledByAm; Loading