blob: fd2458222a89812d9edb689e9d96188884d941b3 [file] [log] [blame]
Dianne Hackbornbc02a392016-06-02 17:15:08 -07001/*
2 * Copyright (C) 2016 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
17package com.android.server.am;
18
19import android.os.SystemClock;
20import android.util.ArrayMap;
21import android.util.TimeUtils;
22
23import java.io.PrintWriter;
24import java.util.ArrayList;
25import java.util.Collections;
26import java.util.Comparator;
27
28public final class BroadcastStats {
29 final long mStartRealtime;
30 final long mStartUptime;
31 long mEndRealtime;
32 long mEndUptime;
33 final ArrayMap<String, ActionEntry> mActions = new ArrayMap<>();
34
35 static final Comparator<ActionEntry> ACTIONS_COMPARATOR = new Comparator<ActionEntry>() {
36 @Override public int compare(ActionEntry o1, ActionEntry o2) {
37 if (o1.mTotalDispatchTime < o2.mTotalDispatchTime) {
38 return -1;
39 }
40 if (o1.mTotalDispatchTime > o2.mTotalDispatchTime) {
41 return 1;
42 }
43 return 0;
44 }
45 };
46
47 static final class ActionEntry {
48 final String mAction;
49 final ArrayMap<String, PackageEntry> mPackages = new ArrayMap<>();
Dianne Hackborn7fc46d82017-02-14 15:20:06 -080050 final ArrayMap<String, ViolationEntry> mBackgroundCheckViolations = new ArrayMap<>();
Dianne Hackbornbc02a392016-06-02 17:15:08 -070051 int mReceiveCount;
52 int mSkipCount;
53 long mTotalDispatchTime;
54 long mMaxDispatchTime;
55
56 ActionEntry(String action) {
57 mAction = action;
58 }
59 }
60
61 static final class PackageEntry {
62 int mSendCount;
63 }
64
Dianne Hackborn7fc46d82017-02-14 15:20:06 -080065 static final class ViolationEntry {
66 int mCount;
67 }
68
Dianne Hackbornbc02a392016-06-02 17:15:08 -070069 public BroadcastStats() {
70 mStartRealtime = SystemClock.elapsedRealtime();
71 mStartUptime = SystemClock.uptimeMillis();
72 }
73
74 public void addBroadcast(String action, String srcPackage, int receiveCount,
75 int skipCount, long dispatchTime) {
76 ActionEntry ae = mActions.get(action);
77 if (ae == null) {
78 ae = new ActionEntry(action);
79 mActions.put(action, ae);
80 }
81 ae.mReceiveCount += receiveCount;
82 ae.mSkipCount += skipCount;
83 ae.mTotalDispatchTime += dispatchTime;
84 if (ae.mMaxDispatchTime < dispatchTime) {
85 ae.mMaxDispatchTime = dispatchTime;
86 }
87 PackageEntry pe = ae.mPackages.get(srcPackage);
88 if (pe == null) {
89 pe = new PackageEntry();
90 ae.mPackages.put(srcPackage, pe);
91 }
92 pe.mSendCount++;
93 }
94
Dianne Hackborn7fc46d82017-02-14 15:20:06 -080095 public void addBackgroundCheckViolation(String action, String targetPackage) {
96 ActionEntry ae = mActions.get(action);
97 if (ae == null) {
98 ae = new ActionEntry(action);
99 mActions.put(action, ae);
100 }
101 ViolationEntry ve = ae.mBackgroundCheckViolations.get(targetPackage);
102 if (ve == null) {
103 ve = new ViolationEntry();
104 ae.mBackgroundCheckViolations.put(targetPackage, ve);
105 }
106 ve.mCount++;
107 }
108
Dianne Hackbornbc02a392016-06-02 17:15:08 -0700109 public boolean dumpStats(PrintWriter pw, String prefix, String dumpPackage) {
110 boolean printedSomething = false;
111 ArrayList<ActionEntry> actions = new ArrayList<>(mActions.size());
112 for (int i=mActions.size()-1; i>=0; i--) {
113 actions.add(mActions.valueAt(i));
114 }
115 Collections.sort(actions, ACTIONS_COMPARATOR);
116 for (int i=actions.size()-1; i>=0; i--) {
117 ActionEntry ae = actions.get(i);
118 if (dumpPackage != null && !ae.mPackages.containsKey(dumpPackage)) {
119 continue;
120 }
121 printedSomething = true;
122 pw.print(prefix);
123 pw.print(ae.mAction);
124 pw.println(":");
125 pw.print(prefix);
126 pw.print(" Number received: ");
127 pw.print(ae.mReceiveCount);
128 pw.print(", skipped: ");
129 pw.println(ae.mSkipCount);
130 pw.print(prefix);
131 pw.print(" Total dispatch time: ");
132 TimeUtils.formatDuration(ae.mTotalDispatchTime, pw);
133 pw.print(", max: ");
134 TimeUtils.formatDuration(ae.mMaxDispatchTime, pw);
135 pw.println();
136 for (int j=ae.mPackages.size()-1; j>=0; j--) {
137 pw.print(prefix);
138 pw.print(" Package ");
139 pw.print(ae.mPackages.keyAt(j));
140 pw.print(": ");
141 PackageEntry pe = ae.mPackages.valueAt(j);
142 pw.print(pe.mSendCount);
143 pw.println(" times");
144 }
Dianne Hackborn7fc46d82017-02-14 15:20:06 -0800145 for (int j=ae.mBackgroundCheckViolations.size()-1; j>=0; j--) {
146 pw.print(prefix);
147 pw.print(" Bg Check Violation ");
148 pw.print(ae.mBackgroundCheckViolations.keyAt(j));
149 pw.print(": ");
150 ViolationEntry ve = ae.mBackgroundCheckViolations.valueAt(j);
151 pw.print(ve.mCount);
152 pw.println(" times");
153 }
Dianne Hackbornbc02a392016-06-02 17:15:08 -0700154 }
155 return printedSomething;
156 }
157
158 public void dumpCheckinStats(PrintWriter pw, String dumpPackage) {
159 pw.print("broadcast-stats,1,");
160 pw.print(mStartRealtime);
161 pw.print(",");
162 pw.print(mEndRealtime == 0 ? SystemClock.elapsedRealtime() : mEndRealtime);
163 pw.print(",");
164 pw.println((mEndUptime == 0 ? SystemClock.uptimeMillis() : mEndUptime) - mStartUptime);
165 for (int i=mActions.size()-1; i>=0; i--) {
166 ActionEntry ae = mActions.valueAt(i);
167 if (dumpPackage != null && !ae.mPackages.containsKey(dumpPackage)) {
168 continue;
169 }
170 pw.print("a,");
171 pw.print(mActions.keyAt(i));
172 pw.print(",");
173 pw.print(ae.mReceiveCount);
174 pw.print(",");
175 pw.print(ae.mSkipCount);
176 pw.print(",");
177 pw.print(ae.mTotalDispatchTime);
178 pw.print(",");
179 pw.print(ae.mMaxDispatchTime);
180 pw.println();
181 for (int j=ae.mPackages.size()-1; j>=0; j--) {
182 pw.print("p,");
183 pw.print(ae.mPackages.keyAt(j));
184 PackageEntry pe = ae.mPackages.valueAt(j);
185 pw.print(",");
186 pw.print(pe.mSendCount);
187 pw.println();
188 }
Dianne Hackborn7fc46d82017-02-14 15:20:06 -0800189 for (int j=ae.mBackgroundCheckViolations.size()-1; j>=0; j--) {
190 pw.print("v,");
191 pw.print(ae.mBackgroundCheckViolations.keyAt(j));
192 ViolationEntry ve = ae.mBackgroundCheckViolations.valueAt(j);
193 pw.print(",");
194 pw.print(ve.mCount);
195 pw.println();
196 }
Dianne Hackbornbc02a392016-06-02 17:15:08 -0700197 }
198 }
199}