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

Commit 9b3f4dd4 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Log BroadcastProcessed atom." into main

parents afbdde0d 6c6aaf77
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -1961,7 +1961,9 @@ class BroadcastController {

    private void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
        mService.mProcessList.sendPackageBroadcastLocked(cmd, packages, userId);
    }private List<ResolveInfo> collectReceiverComponents(
    }

    private List<ResolveInfo> collectReceiverComponents(
            Intent intent, String resolvedType, int callingUid, int callingPid,
            int[] users, int[] broadcastAllowList) {
        // TODO: come back and remove this assumption to triage all broadcasts
+142 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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 com.android.internal.util.FrameworkStatsLog.BROADCAST_PROCESSED;

import android.annotation.NonNull;
import android.annotation.Nullable;

import com.android.internal.util.FrameworkStatsLog;

final class BroadcastProcessedEventRecord {

    /**
     * Minimum threshold for logging the broadcast processed event.
     */
    private static final int MIN_THRESHOLD_FOR_LOGGING_TIME_MILLIS = 10;

    @Nullable
    private String mIntentAction;

    private int mSenderUid;

    private int mReceiverUid;

    private int mNumberOfReceivers;

    @NonNull
    private String mReceiverProcessName;

    private long mTotalBroadcastFinishTimeMillis;

    private long mMaxReceiverFinishTimeMillis = Long.MIN_VALUE;

    @NonNull
    private int[] mBroadcastTypes;

    @NonNull
    public BroadcastProcessedEventRecord setBroadcastTypes(@NonNull int[] broadcastTypes) {
        this.mBroadcastTypes = broadcastTypes;
        return this;
    }

    @NonNull
    public BroadcastProcessedEventRecord setReceiverProcessName(
            @NonNull String receiverProcessName) {
        mReceiverProcessName = receiverProcessName;
        return this;
    }

    @NonNull
    public BroadcastProcessedEventRecord setIntentAction(@Nullable String intentAction) {
        mIntentAction = intentAction;
        return this;
    }

    @NonNull
    public BroadcastProcessedEventRecord setSenderUid(int uid) {
        mSenderUid = uid;
        return this;
    }

    @NonNull
    public BroadcastProcessedEventRecord setReceiverUid(int uid) {
        mReceiverUid = uid;
        return this;
    }

    public void addReceiverFinishTime(long timeMillis) {
        mTotalBroadcastFinishTimeMillis += timeMillis;
        mMaxReceiverFinishTimeMillis = Math.max(mMaxReceiverFinishTimeMillis, timeMillis);
        mNumberOfReceivers++;
    }

    @Nullable
    String getIntentActionForTest() {
        return mIntentAction;
    }

    int getSenderUidForTest() {
        return mSenderUid;
    }

    int getReceiverUidForTest() {
        return mReceiverUid;
    }

    int getNumberOfReceiversForTest() {
        return mNumberOfReceivers;
    }

    @NonNull
    String getReceiverProcessNameForTest() {
        return mReceiverProcessName;
    }

    long getTotalBroadcastFinishTimeMillisForTest() {
        return mTotalBroadcastFinishTimeMillis;
    }

    long getMaxReceiverFinishTimeMillisForTest() {
        return mMaxReceiverFinishTimeMillis;
    }

    @NonNull
    int[] getBroadcastTypesForTest() {
        return mBroadcastTypes;
    }

    public void logToStatsD() {
        // We do not care about the processes where total time to process the
        // broadcast is less than 10ms/ are quick to process the broadcast.
        if (mTotalBroadcastFinishTimeMillis <= MIN_THRESHOLD_FOR_LOGGING_TIME_MILLIS) {
            return;
        }

        FrameworkStatsLog.write(
                BROADCAST_PROCESSED,
                mIntentAction,
                mSenderUid,
                mReceiverUid,
                mNumberOfReceivers,
                mReceiverProcessName,
                mTotalBroadcastFinishTimeMillis,
                mMaxReceiverFinishTimeMillis,
                mBroadcastTypes);
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -2189,6 +2189,11 @@ class BroadcastQueueImpl extends BroadcastQueue {
            logBroadcastDeliveryEventReported(queue, app, r, index, receiver);
        }

        if (!r.isAssumedDelivered(index) && r.wasDelivered(index)) {
            r.updateBroadcastProcessedEventRecord(receiver,
                    r.terminalTime[index] - r.scheduledTime[index]);
        }

        final boolean recordFinished = (r.terminalCount == r.receivers.size());
        if (recordFinished) {
            notifyFinishBroadcast(r);
@@ -2254,6 +2259,7 @@ class BroadcastQueueImpl extends BroadcastQueue {
        mHistory.onBroadcastFinishedLocked(r);

        logBootCompletedBroadcastCompletionLatencyIfPossible(r);
        r.logBroadcastProcessedEventRecord();

        if (r.intent.getComponent() == null && r.intent.getPackage() == null
                && (r.intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
+61 −0
Original line number Diff line number Diff line
@@ -167,6 +167,12 @@ final class BroadcastRecord extends Binder {
    @Nullable
    private ArrayMap<BroadcastRecord, Boolean> mMatchingRecordsCache;

    // Stores the {@link BroadcastProcessedEventRecord} for each process associated with this
    // record.
    @NonNull
    private ArrayMap<String, BroadcastProcessedEventRecord> mBroadcastProcessedRecords =
            new ArrayMap<>();

    private @Nullable String mCachedToString;
    private @Nullable String mCachedToShortString;

@@ -654,6 +660,17 @@ final class BroadcastRecord extends Binder {
        }
    }

    boolean wasDelivered(int index) {
        final int deliveryState = getDeliveryState(index);
        switch (deliveryState) {
            case DELIVERY_DELIVERED:
            case DELIVERY_TIMEOUT:
                return true;
            default:
                return false;
        }
    }

    void copyEnqueueTimeFrom(@NonNull BroadcastRecord replacedBroadcast) {
        originalEnqueueClockTime = enqueueClockTime;
        enqueueTime = replacedBroadcast.enqueueTime;
@@ -1327,4 +1344,48 @@ final class BroadcastRecord extends Binder {
        proto.write(BroadcastRecordProto.INTENT_ACTION, intent.getAction());
        proto.end(token);
    }

    /**
     * Uses the {@link BroadcastProcessedEventRecord} pojo to store the logging information related
     * to {@param receiver} object.
     */
    public void updateBroadcastProcessedEventRecord(@NonNull Object receiver, long timeMillis) {
        if (!Flags.logBroadcastProcessedEvent()) {
            return;
        }

        final String receiverProcessName = getReceiverProcessName(receiver);
        BroadcastProcessedEventRecord broadcastProcessedEventRecord =
                mBroadcastProcessedRecords.get(receiverProcessName);
        if (broadcastProcessedEventRecord == null) {
            broadcastProcessedEventRecord = new BroadcastProcessedEventRecord()
                    .setBroadcastTypes(calculateTypesForLogging())
                    .setIntentAction(intent.getAction())
                    .setReceiverProcessName(receiverProcessName)
                    .setReceiverUid(getReceiverUid(receiver))
                    .setSenderUid(callingUid);

            mBroadcastProcessedRecords.put(receiverProcessName, broadcastProcessedEventRecord);
        }

        broadcastProcessedEventRecord.addReceiverFinishTime(timeMillis);
    }

    public void logBroadcastProcessedEventRecord() {
        if (!Flags.logBroadcastProcessedEvent()) {
            return;
        }

        int size = mBroadcastProcessedRecords.size();
        for (int i = 0; i < size; i++) {
            mBroadcastProcessedRecords.valueAt(i).logToStatsD();
        }
        mBroadcastProcessedRecords.clear();
    }

    @VisibleForTesting
    @NonNull
    ArrayMap<String, BroadcastProcessedEventRecord> getBroadcastProcessedRecordsForTest() {
        return mBroadcastProcessedRecords;
    }
}
+12 −1
Original line number Diff line number Diff line
@@ -27,3 +27,14 @@ flag {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "log_broadcast_processed_event"
    namespace: "backstage_power"
    description: "Log the broadcast processed event to Statsd"
    bug: "387576580"
    is_fixed_read_only: true
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
Loading