Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81c2274b authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Allow logging additional msgs for debugging broadcast delivery." into main

parents 0f3c3c0e 6c5b33ff
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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 {}
@@ -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.
@@ -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)
+24 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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,
@@ -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();
            }
@@ -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
@@ -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,
+18 −7
Original line number Diff line number Diff line
@@ -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);
@@ -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) {
@@ -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");

@@ -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);
+21 −9
Original line number Diff line number Diff line
@@ -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());
+5 −0
Original line number Diff line number Diff line
@@ -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;