• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.server.am;
18 
19 import android.os.SystemClock;
20 import android.util.ArrayMap;
21 import android.util.TimeUtils;
22 
23 import java.io.PrintWriter;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Comparator;
27 
28 public 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<>();
50         int mReceiveCount;
51         int mSkipCount;
52         long mTotalDispatchTime;
53         long mMaxDispatchTime;
54 
ActionEntry(String action)55         ActionEntry(String action) {
56             mAction = action;
57         }
58     }
59 
60     static final class PackageEntry {
61         int mSendCount;
62     }
63 
BroadcastStats()64     public BroadcastStats() {
65         mStartRealtime = SystemClock.elapsedRealtime();
66         mStartUptime = SystemClock.uptimeMillis();
67     }
68 
addBroadcast(String action, String srcPackage, int receiveCount, int skipCount, long dispatchTime)69     public void addBroadcast(String action, String srcPackage, int receiveCount,
70             int skipCount, long dispatchTime) {
71         ActionEntry ae = mActions.get(action);
72         if (ae == null) {
73             ae = new ActionEntry(action);
74             mActions.put(action, ae);
75         }
76         ae.mReceiveCount += receiveCount;
77         ae.mSkipCount += skipCount;
78         ae.mTotalDispatchTime += dispatchTime;
79         if (ae.mMaxDispatchTime < dispatchTime) {
80             ae.mMaxDispatchTime = dispatchTime;
81         }
82         PackageEntry pe = ae.mPackages.get(srcPackage);
83         if (pe == null) {
84             pe = new PackageEntry();
85             ae.mPackages.put(srcPackage, pe);
86         }
87         pe.mSendCount++;
88     }
89 
dumpStats(PrintWriter pw, String prefix, String dumpPackage)90     public boolean dumpStats(PrintWriter pw, String prefix, String dumpPackage) {
91         boolean printedSomething = false;
92         ArrayList<ActionEntry> actions = new ArrayList<>(mActions.size());
93         for (int i=mActions.size()-1; i>=0; i--) {
94             actions.add(mActions.valueAt(i));
95         }
96         Collections.sort(actions, ACTIONS_COMPARATOR);
97         for (int i=actions.size()-1; i>=0; i--) {
98             ActionEntry ae = actions.get(i);
99             if (dumpPackage != null && !ae.mPackages.containsKey(dumpPackage)) {
100                 continue;
101             }
102             printedSomething = true;
103             pw.print(prefix);
104             pw.print(ae.mAction);
105             pw.println(":");
106             pw.print(prefix);
107             pw.print("  Number received: ");
108             pw.print(ae.mReceiveCount);
109             pw.print(", skipped: ");
110             pw.println(ae.mSkipCount);
111             pw.print(prefix);
112             pw.print("  Total dispatch time: ");
113             TimeUtils.formatDuration(ae.mTotalDispatchTime, pw);
114             pw.print(", max: ");
115             TimeUtils.formatDuration(ae.mMaxDispatchTime, pw);
116             pw.println();
117             for (int j=ae.mPackages.size()-1; j>=0; j--) {
118                 pw.print(prefix);
119                 pw.print("  Package ");
120                 pw.print(ae.mPackages.keyAt(j));
121                 pw.print(": ");
122                 PackageEntry pe = ae.mPackages.valueAt(j);
123                 pw.print(pe.mSendCount);
124                 pw.println(" times");
125             }
126         }
127         return printedSomething;
128     }
129 
dumpCheckinStats(PrintWriter pw, String dumpPackage)130     public void dumpCheckinStats(PrintWriter pw, String dumpPackage) {
131         pw.print("broadcast-stats,1,");
132         pw.print(mStartRealtime);
133         pw.print(",");
134         pw.print(mEndRealtime == 0 ? SystemClock.elapsedRealtime() : mEndRealtime);
135         pw.print(",");
136         pw.println((mEndUptime == 0 ? SystemClock.uptimeMillis() : mEndUptime) - mStartUptime);
137         for (int i=mActions.size()-1; i>=0; i--) {
138             ActionEntry ae = mActions.valueAt(i);
139             if (dumpPackage != null && !ae.mPackages.containsKey(dumpPackage)) {
140                 continue;
141             }
142             pw.print("a,");
143             pw.print(mActions.keyAt(i));
144             pw.print(",");
145             pw.print(ae.mReceiveCount);
146             pw.print(",");
147             pw.print(ae.mSkipCount);
148             pw.print(",");
149             pw.print(ae.mTotalDispatchTime);
150             pw.print(",");
151             pw.print(ae.mMaxDispatchTime);
152             pw.println();
153             for (int j=ae.mPackages.size()-1; j>=0; j--) {
154                 pw.print("p,");
155                 pw.print(ae.mPackages.keyAt(j));
156                 PackageEntry pe = ae.mPackages.valueAt(j);
157                 pw.print(",");
158                 pw.print(pe.mSendCount);
159                 pw.println();
160             }
161         }
162     }
163 }
164