1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.am; 18 19 import static android.app.AppProtoEnums.BROADCAST_TYPE_ORDERED; 20 import static android.app.AppProtoEnums.BROADCAST_TYPE_RESULT_TO; 21 import static android.app.AppProtoEnums.BROADCAST_TYPE_STICKY; 22 23 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT; 24 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__FAILED_STICKY_CANT_HAVE_PERMISSION; 25 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__FAILED_USER_STOPPED; 26 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__SUCCESS; 27 import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__UNKNOWN; 28 29 import android.annotation.NonNull; 30 import android.annotation.Nullable; 31 import android.app.ActivityManager; 32 import android.content.Intent; 33 import android.util.IntArray; 34 35 import com.android.internal.util.FrameworkStatsLog; 36 37 final class BroadcastSentEventRecord { 38 @NonNull private Intent mIntent; 39 private int mOriginalIntentFlags; 40 private int mSenderUid; 41 private int mRealSenderUid; 42 private boolean mSticky; 43 private boolean mOrdered; 44 private boolean mResultRequested; 45 private int mSenderProcState; 46 private int mSenderUidState; 47 @Nullable private BroadcastRecord mBroadcastRecord; 48 private int mResult; 49 setIntent(@onNull Intent intent)50 public void setIntent(@NonNull Intent intent) { 51 mIntent = intent; 52 } 53 setSenderUid(int uid)54 public void setSenderUid(int uid) { 55 mSenderUid = uid; 56 } 57 setRealSenderUid(int uid)58 public void setRealSenderUid(int uid) { 59 mRealSenderUid = uid; 60 } 61 setOriginalIntentFlags(int flags)62 public void setOriginalIntentFlags(int flags) { 63 mOriginalIntentFlags = flags; 64 } 65 setSticky(boolean sticky)66 public void setSticky(boolean sticky) { 67 mSticky = sticky; 68 } 69 setOrdered(boolean ordered)70 public void setOrdered(boolean ordered) { 71 mOrdered = ordered; 72 } 73 setResultRequested(boolean resultRequested)74 public void setResultRequested(boolean resultRequested) { 75 mResultRequested = resultRequested; 76 } 77 setSenderProcState(int procState)78 public void setSenderProcState(int procState) { 79 mSenderProcState = procState; 80 } 81 setSenderUidState(int procState)82 public void setSenderUidState(int procState) { 83 mSenderUidState = procState; 84 } 85 setBroadcastRecord(@onNull BroadcastRecord record)86 public void setBroadcastRecord(@NonNull BroadcastRecord record) { 87 mBroadcastRecord = record; 88 } 89 setResult(int result)90 public void setResult(int result) { 91 mResult = result; 92 } 93 logToStatsd()94 public void logToStatsd() { 95 if (Flags.logBroadcastSentEvent()) { 96 int loggingResult = switch (mResult) { 97 case ActivityManager.BROADCAST_SUCCESS -> 98 BROADCAST_SENT__RESULT__SUCCESS; 99 case ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION -> 100 BROADCAST_SENT__RESULT__FAILED_STICKY_CANT_HAVE_PERMISSION; 101 case ActivityManager.BROADCAST_FAILED_USER_STOPPED -> 102 BROADCAST_SENT__RESULT__FAILED_USER_STOPPED; 103 default -> BROADCAST_SENT__RESULT__UNKNOWN; 104 }; 105 int[] types = calculateTypesForLogging(); 106 FrameworkStatsLog.write(BROADCAST_SENT, mIntent.getAction(), mIntent.getFlags(), 107 mOriginalIntentFlags, mSenderUid, mRealSenderUid, mIntent.getPackage() != null, 108 mIntent.getComponent() != null, 109 mBroadcastRecord != null ? mBroadcastRecord.receivers.size() : 0, 110 loggingResult, 111 mBroadcastRecord != null ? mBroadcastRecord.getDeliveryGroupPolicy() : 0, 112 ActivityManager.processStateAmToProto(mSenderProcState), 113 ActivityManager.processStateAmToProto(mSenderUidState), types); 114 } 115 } 116 calculateTypesForLogging()117 private int[] calculateTypesForLogging() { 118 if (mBroadcastRecord != null) { 119 return mBroadcastRecord.calculateTypesForLogging(); 120 } else { 121 final IntArray types = new IntArray(); 122 if (mSticky) { 123 types.add(BROADCAST_TYPE_STICKY); 124 } 125 if (mOrdered) { 126 types.add(BROADCAST_TYPE_ORDERED); 127 } 128 if (mResultRequested) { 129 types.add(BROADCAST_TYPE_RESULT_TO); 130 } 131 return types.toArray(); 132 } 133 } 134 } 135