blob: 1f3a83090845e67e1d9861f33dad664226efc476 [file] [log] [blame]
John Spurlock813552c2014-09-19 08:30:21 -04001/*
2 * Copyright (C) 2014 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.systemui.doze;
18
19import android.content.Context;
20import android.os.Build;
21import android.util.Log;
22import android.util.TimeUtils;
23
24import com.android.keyguard.KeyguardUpdateMonitor;
25import com.android.keyguard.KeyguardUpdateMonitorCallback;
26
27import java.io.PrintWriter;
28import java.text.SimpleDateFormat;
29import java.util.Date;
30
31public class DozeLog {
32 private static final String TAG = "DozeLog";
33 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
34 private static final boolean ENABLED = true;
35 private static final int SIZE = Build.IS_DEBUGGABLE ? 400 : 50;
36 private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
37
John Spurlockeab28e62014-11-29 11:33:49 -050038 private static final int PULSE_REASONS = 4;
39
40 public static final int PULSE_REASON_INTENT = 0;
41 public static final int PULSE_REASON_NOTIFICATION = 1;
42 public static final int PULSE_REASON_SENSOR_SIGMOTION = 2;
43 public static final int PULSE_REASON_SENSOR_PICKUP = 3;
44
John Spurlock813552c2014-09-19 08:30:21 -040045 private static long[] sTimes;
46 private static String[] sMessages;
47 private static int sPosition;
48 private static int sCount;
49 private static boolean sPulsing;
50
51 private static long sSince;
52 private static SummaryStats sPickupPulseNearVibrationStats;
53 private static SummaryStats sPickupPulseNotNearVibrationStats;
54 private static SummaryStats sNotificationPulseStats;
55 private static SummaryStats sScreenOnPulsingStats;
56 private static SummaryStats sScreenOnNotPulsingStats;
57 private static SummaryStats sEmergencyCallStats;
John Spurlockeab28e62014-11-29 11:33:49 -050058 private static SummaryStats[][] sProxStats; // [reason][near/far]
John Spurlock813552c2014-09-19 08:30:21 -040059
60 public static void tracePickupPulse(boolean withinVibrationThreshold) {
61 if (!ENABLED) return;
62 log("pickupPulse withinVibrationThreshold=" + withinVibrationThreshold);
63 (withinVibrationThreshold ? sPickupPulseNearVibrationStats
64 : sPickupPulseNotNearVibrationStats).append();
65 }
66
John Spurlockeab28e62014-11-29 11:33:49 -050067 public static void tracePulseStart(int reason) {
John Spurlock813552c2014-09-19 08:30:21 -040068 if (!ENABLED) return;
69 sPulsing = true;
John Spurlockeab28e62014-11-29 11:33:49 -050070 log("pulseStart reason=" + pulseReasonToString(reason));
John Spurlock813552c2014-09-19 08:30:21 -040071 }
72
73 public static void tracePulseFinish() {
74 if (!ENABLED) return;
75 sPulsing = false;
76 log("pulseFinish");
77 }
78
79 public static void traceNotificationPulse(long instance) {
80 if (!ENABLED) return;
81 log("notificationPulse instance=" + instance);
82 sNotificationPulseStats.append();
83 }
84
85 public static void traceDozing(Context context, boolean dozing) {
86 if (!ENABLED) return;
87 sPulsing = false;
88 synchronized (DozeLog.class) {
89 if (dozing && sMessages == null) {
90 sTimes = new long[SIZE];
91 sMessages = new String[SIZE];
92 sSince = System.currentTimeMillis();
93 sPickupPulseNearVibrationStats = new SummaryStats();
94 sPickupPulseNotNearVibrationStats = new SummaryStats();
95 sNotificationPulseStats = new SummaryStats();
96 sScreenOnPulsingStats = new SummaryStats();
97 sScreenOnNotPulsingStats = new SummaryStats();
98 sEmergencyCallStats = new SummaryStats();
John Spurlockeab28e62014-11-29 11:33:49 -050099 sProxStats = new SummaryStats[PULSE_REASONS][2];
100 for (int i = 0; i < PULSE_REASONS; i++) {
101 sProxStats[i][0] = new SummaryStats();
102 sProxStats[i][1] = new SummaryStats();
103 }
John Spurlock813552c2014-09-19 08:30:21 -0400104 log("init");
John Spurlockbee3b0a2014-09-29 11:30:12 -0400105 KeyguardUpdateMonitor.getInstance(context).registerCallback(sKeyguardCallback);
John Spurlock813552c2014-09-19 08:30:21 -0400106 }
107 }
108 log("dozing " + dozing);
109 }
110
John Spurlockee98df72014-09-30 09:56:05 -0400111 public static void traceFling(boolean expand, boolean aboveThreshold, boolean thresholdNeeded,
112 boolean screenOnFromTouch) {
John Spurlock813552c2014-09-19 08:30:21 -0400113 if (!ENABLED) return;
114 log("fling expand=" + expand + " aboveThreshold=" + aboveThreshold + " thresholdNeeded="
John Spurlockee98df72014-09-30 09:56:05 -0400115 + thresholdNeeded + " screenOnFromTouch=" + screenOnFromTouch);
John Spurlock813552c2014-09-19 08:30:21 -0400116 }
117
118 public static void traceEmergencyCall() {
119 if (!ENABLED) return;
120 log("emergencyCall");
John Spurlockbee3b0a2014-09-29 11:30:12 -0400121 sEmergencyCallStats.append();
John Spurlock813552c2014-09-19 08:30:21 -0400122 }
123
124 public static void traceKeyguardBouncerChanged(boolean showing) {
125 if (!ENABLED) return;
126 log("bouncer " + showing);
127 }
128
129 public static void traceScreenOn() {
130 if (!ENABLED) return;
131 log("screenOn pulsing=" + sPulsing);
132 (sPulsing ? sScreenOnPulsingStats : sScreenOnNotPulsingStats).append();
133 sPulsing = false;
134 }
135
136 public static void traceScreenOff(int why) {
137 if (!ENABLED) return;
138 log("screenOff why=" + why);
139 }
140
141 public static void traceKeyguard(boolean showing) {
142 if (!ENABLED) return;
143 log("keyguard " + showing);
144 if (!showing) {
145 sPulsing = false;
146 }
147 }
148
John Spurlockeab28e62014-11-29 11:33:49 -0500149 public static void traceProximityResult(boolean near, long millis, int pulseReason) {
John Spurlock92b8d412014-10-03 17:12:40 -0400150 if (!ENABLED) return;
John Spurlockeab28e62014-11-29 11:33:49 -0500151 log("proximityResult reason=" + pulseReasonToString(pulseReason) + " near=" + near
152 + " millis=" + millis);
153 sProxStats[pulseReason][near ? 0 : 1].append();
154 }
155
John Spurlockf5d250d2014-12-02 10:41:25 -0500156 public static String pulseReasonToString(int pulseReason) {
John Spurlockeab28e62014-11-29 11:33:49 -0500157 switch (pulseReason) {
158 case PULSE_REASON_INTENT: return "intent";
159 case PULSE_REASON_NOTIFICATION: return "notification";
160 case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion";
161 case PULSE_REASON_SENSOR_PICKUP: return "pickup";
162 default: throw new IllegalArgumentException("bad reason: " + pulseReason);
163 }
John Spurlock92b8d412014-10-03 17:12:40 -0400164 }
165
John Spurlock813552c2014-09-19 08:30:21 -0400166 public static void dump(PrintWriter pw) {
167 synchronized (DozeLog.class) {
168 if (sMessages == null) return;
169 pw.println(" Doze log:");
170 final int start = (sPosition - sCount + SIZE) % SIZE;
171 for (int i = 0; i < sCount; i++) {
172 final int j = (start + i) % SIZE;
173 pw.print(" ");
174 pw.print(FORMAT.format(new Date(sTimes[j])));
175 pw.print(' ');
176 pw.println(sMessages[j]);
177 }
178 pw.print(" Doze summary stats (for ");
179 TimeUtils.formatDuration(System.currentTimeMillis() - sSince, pw);
180 pw.println("):");
181 sPickupPulseNearVibrationStats.dump(pw, "Pickup pulse (near vibration)");
182 sPickupPulseNotNearVibrationStats.dump(pw, "Pickup pulse (not near vibration)");
183 sNotificationPulseStats.dump(pw, "Notification pulse");
184 sScreenOnPulsingStats.dump(pw, "Screen on (pulsing)");
185 sScreenOnNotPulsingStats.dump(pw, "Screen on (not pulsing)");
186 sEmergencyCallStats.dump(pw, "Emergency call");
John Spurlockeab28e62014-11-29 11:33:49 -0500187 for (int i = 0; i < PULSE_REASONS; i++) {
188 final String reason = pulseReasonToString(i);
189 sProxStats[i][0].dump(pw, "Proximity near (" + reason + ")");
190 sProxStats[i][1].dump(pw, "Proximity far (" + reason + ")");
191 }
John Spurlock813552c2014-09-19 08:30:21 -0400192 }
193 }
194
195 private static void log(String msg) {
196 synchronized (DozeLog.class) {
197 if (sMessages == null) return;
198 sTimes[sPosition] = System.currentTimeMillis();
199 sMessages[sPosition] = msg;
200 sPosition = (sPosition + 1) % SIZE;
201 sCount = Math.min(sCount + 1, SIZE);
202 }
203 if (DEBUG) Log.d(TAG, msg);
204 }
205
206 private static class SummaryStats {
207 private int mCount;
208
209 public void append() {
210 mCount++;
211 }
212
213 public void dump(PrintWriter pw, String type) {
John Spurlockeab28e62014-11-29 11:33:49 -0500214 if (mCount == 0) return;
John Spurlock813552c2014-09-19 08:30:21 -0400215 pw.print(" ");
216 pw.print(type);
217 pw.print(": n=");
218 pw.print(mCount);
219 pw.print(" (");
220 final double perHr = (double) mCount / (System.currentTimeMillis() - sSince)
221 * 1000 * 60 * 60;
222 pw.print(perHr);
223 pw.print("/hr)");
224 pw.println();
225 }
226 }
John Spurlockbee3b0a2014-09-29 11:30:12 -0400227
228 private static final KeyguardUpdateMonitorCallback sKeyguardCallback =
229 new KeyguardUpdateMonitorCallback() {
230 @Override
231 public void onEmergencyCallAction() {
232 traceEmergencyCall();
233 }
234
235 @Override
236 public void onKeyguardBouncerChanged(boolean bouncer) {
237 traceKeyguardBouncerChanged(bouncer);
238 }
239
240 @Override
241 public void onScreenTurnedOn() {
242 traceScreenOn();
243 }
244
245 @Override
246 public void onScreenTurnedOff(int why) {
247 traceScreenOff(why);
248 }
249
250 @Override
251 public void onKeyguardVisibilityChanged(boolean showing) {
252 traceKeyguard(showing);
253 }
254 };
John Spurlock813552c2014-09-19 08:30:21 -0400255}