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

Commit bad9bce4 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Log the list of broadcasts sent.

Bug: 355261986
Test: statsd_testdrive 922
Flag: com.android.server.am.log_broadcast_sent_event
Change-Id: I509f443151eaec2d45ace7534829fc83ef3b0073
parent 8b9bb07a
Loading
Loading
Loading
Loading
+36 −3
Original line number Diff line number Diff line
@@ -15312,12 +15312,17 @@ public class ActivityManagerService extends IActivityManager.Stub
        final int cookie = traceBroadcastIntentBegin(intent, resultTo, ordered, sticky,
                callingUid, realCallingUid, userId);
        try {
            final BroadcastSentEventRecord broadcastSentEventRecord =
                    new BroadcastSentEventRecord();
            final int res = broadcastIntentLockedTraced(callerApp, callerPackage, callerFeatureId,
                    intent, resolvedType, resultToApp, resultTo, resultCode, resultData,
                    resultExtras, requiredPermissions, excludedPermissions, excludedPackages,
                    appOp, BroadcastOptions.fromBundleNullable(bOptions), ordered, sticky,
                    callingPid, callingUid, realCallingUid, realCallingPid, userId,
                    backgroundStartPrivileges, broadcastAllowList, filterExtrasForReceiver);
                    backgroundStartPrivileges, broadcastAllowList, filterExtrasForReceiver,
                    broadcastSentEventRecord);
            broadcastSentEventRecord.setResult(res);
            broadcastSentEventRecord.logToStatsd();
            return res;
        } finally {
            traceBroadcastIntentEnd(cookie);
@@ -15365,7 +15370,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            int callingUid, int realCallingUid, int realCallingPid, int userId,
            BackgroundStartPrivileges backgroundStartPrivileges,
            @Nullable int[] broadcastAllowList,
            @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
            @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
            @NonNull BroadcastSentEventRecord broadcastSentEventRecord) {
        // Ensure all internal loopers are registered for idle checks
        BroadcastLoopers.addMyLooper();
@@ -15398,6 +15404,17 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        intent = new Intent(intent);
        broadcastSentEventRecord.setIntent(intent);
        broadcastSentEventRecord.setOriginalIntentFlags(intent.getFlags());
        broadcastSentEventRecord.setSenderUid(callingUid);
        broadcastSentEventRecord.setRealSenderUid(realCallingUid);
        broadcastSentEventRecord.setSticky(sticky);
        broadcastSentEventRecord.setOrdered(ordered);
        broadcastSentEventRecord.setResultRequested(resultTo != null);
        final int callerAppProcessState = getRealProcessStateLocked(callerApp, realCallingPid);
        broadcastSentEventRecord.setSenderProcState(callerAppProcessState);
        broadcastSentEventRecord.setSenderUidState(getRealUidStateLocked(callerApp,
                realCallingPid));
        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
@@ -15891,7 +15908,6 @@ 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,
@@ -16131,6 +16147,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    ordered, sticky, false, userId,
                    backgroundStartPrivileges, timeoutExempt, filterExtrasForReceiver,
                    callerAppProcessState);
            broadcastSentEventRecord.setBroadcastRecord(r);
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);
            queue.enqueueBroadcastLocked(r);
@@ -16187,6 +16204,22 @@ public class ActivityManagerService extends IActivityManager.Stub
        return PROCESS_STATE_NONEXISTENT;
    }
    @GuardedBy("this")
    private int getRealUidStateLocked(ProcessRecord app, int pid) {
        if (app == null) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        }
        if (app != null && app.getThread() != null && !app.isKilled()) {
            final UidRecord uidRecord = app.getUidRecord();
            if (uidRecord != null) {
                return uidRecord.getCurProcState();
            }
        }
        return PROCESS_STATE_NONEXISTENT;
    }
    @VisibleForTesting
    ArrayList<StickyBroadcast> getStickyBroadcastsForTest(String action, int userId) {
        synchronized (mStickyBroadcasts) {
+41 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.os.Bundle;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.IntArray;
import android.util.PrintWriterPrinter;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -940,6 +941,46 @@ final class BroadcastRecord extends Binder {
        return type;
    }

    int[] calculateTypesForLogging() {
        final IntArray types = new IntArray();
        if (isForeground()) {
            types.add(BROADCAST_TYPE_FOREGROUND);
        } else {
            types.add(BROADCAST_TYPE_BACKGROUND);
        }
        if (alarm) {
            types.add(BROADCAST_TYPE_ALARM);
        }
        if (interactive) {
            types.add(BROADCAST_TYPE_INTERACTIVE);
        }
        if (ordered) {
            types.add(BROADCAST_TYPE_ORDERED);
        }
        if (prioritized) {
            types.add(BROADCAST_TYPE_PRIORITIZED);
        }
        if (resultTo != null) {
            types.add(BROADCAST_TYPE_RESULT_TO);
        }
        if (deferUntilActive) {
            types.add(BROADCAST_TYPE_DEFERRABLE_UNTIL_ACTIVE);
        }
        if (pushMessage) {
            types.add(BROADCAST_TYPE_PUSH_MESSAGE);
        }
        if (pushMessageOverQuota) {
            types.add(BROADCAST_TYPE_PUSH_MESSAGE_OVER_QUOTA);
        }
        if (sticky) {
            types.add(BROADCAST_TYPE_STICKY);
        }
        if (initialSticky) {
            types.add(BROADCAST_TYPE_INITIAL_STICKY);
        }
        return types.toArray();
    }

    public BroadcastRecord maybeStripForHistory() {
        if (!intent.canStripForHistory()) {
            return this;
+134 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.am;

import static android.app.AppProtoEnums.BROADCAST_TYPE_ORDERED;
import static android.app.AppProtoEnums.BROADCAST_TYPE_RESULT_TO;
import static android.app.AppProtoEnums.BROADCAST_TYPE_STICKY;

import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT;
import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__FAILED_STICKY_CANT_HAVE_PERMISSION;
import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__FAILED_USER_STOPPED;
import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__SUCCESS;
import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__UNKNOWN;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Intent;
import android.util.IntArray;

import com.android.internal.util.FrameworkStatsLog;

final class BroadcastSentEventRecord {
    @NonNull private Intent mIntent;
    private int mOriginalIntentFlags;
    private int mSenderUid;
    private int mRealSenderUid;
    private boolean mSticky;
    private boolean mOrdered;
    private boolean mResultRequested;
    private int mSenderProcState;
    private int mSenderUidState;
    @Nullable private BroadcastRecord mBroadcastRecord;
    private int mResult;

    public void setIntent(@NonNull Intent intent) {
        mIntent = intent;
    }

    public void setSenderUid(int uid) {
        mSenderUid = uid;
    }

    public void setRealSenderUid(int uid) {
        mRealSenderUid = uid;
    }

    public void setOriginalIntentFlags(int flags) {
        mOriginalIntentFlags = flags;
    }

    public void setSticky(boolean sticky) {
        mSticky = sticky;
    }

    public void setOrdered(boolean ordered) {
        mOrdered = ordered;
    }

    public void setResultRequested(boolean resultRequested) {
        mResultRequested = resultRequested;
    }

    public void setSenderProcState(int procState) {
        mSenderProcState = procState;
    }

    public void setSenderUidState(int procState) {
        mSenderUidState = procState;
    }

    public void setBroadcastRecord(@NonNull BroadcastRecord record) {
        mBroadcastRecord = record;
    }

    public void setResult(int result) {
        mResult = result;
    }

    public void logToStatsd() {
        if (Flags.logBroadcastSentEvent()) {
            int loggingResult = switch (mResult) {
                case ActivityManager.BROADCAST_SUCCESS ->
                        BROADCAST_SENT__RESULT__SUCCESS;
                case ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION ->
                        BROADCAST_SENT__RESULT__FAILED_STICKY_CANT_HAVE_PERMISSION;
                case ActivityManager.BROADCAST_FAILED_USER_STOPPED ->
                        BROADCAST_SENT__RESULT__FAILED_USER_STOPPED;
                default -> BROADCAST_SENT__RESULT__UNKNOWN;
            };
            int[] types = calculateTypesForLogging();
            FrameworkStatsLog.write(BROADCAST_SENT, mIntent.getAction(), mIntent.getFlags(),
                    mOriginalIntentFlags, mSenderUid, mRealSenderUid, mIntent.getPackage() != null,
                    mIntent.getComponent() != null,
                    mBroadcastRecord != null ? mBroadcastRecord.receivers.size() : 0,
                    loggingResult,
                    mBroadcastRecord != null ? mBroadcastRecord.getDeliveryGroupPolicy() : 0,
                    ActivityManager.processStateAmToProto(mSenderProcState),
                    ActivityManager.processStateAmToProto(mSenderUidState), types);
        }
    }

    private int[] calculateTypesForLogging() {
        if (mBroadcastRecord != null) {
            return mBroadcastRecord.calculateTypesForLogging();
        } else {
            final IntArray types = new IntArray();
            if (mSticky) {
                types.add(BROADCAST_TYPE_STICKY);
            }
            if (mOrdered) {
                types.add(BROADCAST_TYPE_ORDERED);
            }
            if (mResultRequested) {
                types.add(BROADCAST_TYPE_RESULT_TO);
            }
            return types.toArray();
        }
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -184,3 +184,14 @@ flag {
    description: "Defer submitting binder calls to paused processes."
    bug: "327038797"
}

flag {
    name: "log_broadcast_sent_event"
    namespace: "backstage_power"
    description: "Log the broadcast send event to Statsd"
    bug: "355261986"
    is_fixed_read_only: true
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
 No newline at end of file