• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.systemui.doze;
18 
19 import android.annotation.IntDef;
20 import android.util.TimeUtils;
21 
22 import androidx.annotation.NonNull;
23 
24 import com.android.keyguard.KeyguardUpdateMonitor;
25 import com.android.keyguard.KeyguardUpdateMonitorCallback;
26 import com.android.systemui.Dumpable;
27 import com.android.systemui.dagger.SysUISingleton;
28 import com.android.systemui.dump.DumpManager;
29 
30 import java.io.FileDescriptor;
31 import java.io.PrintWriter;
32 import java.lang.annotation.Retention;
33 import java.lang.annotation.RetentionPolicy;
34 
35 import javax.inject.Inject;
36 
37 /**
38  * Logs doze events for debugging and triaging purposes. Logs are dumped in bugreports or on demand:
39  *      adb shell dumpsys activity service com.android.systemui/.SystemUIService \
40  *      dependency DumpController DozeLog,DozeStats
41  */
42 @SysUISingleton
43 public class DozeLog implements Dumpable {
44     private final DozeLogger mLogger;
45 
46     private boolean mPulsing;
47     private long mSince;
48     private SummaryStats mPickupPulseNearVibrationStats;
49     private SummaryStats mPickupPulseNotNearVibrationStats;
50     private SummaryStats mNotificationPulseStats;
51     private SummaryStats mScreenOnPulsingStats;
52     private SummaryStats mScreenOnNotPulsingStats;
53     private SummaryStats mEmergencyCallStats;
54     private SummaryStats[][] mProxStats; // [reason][near/far]
55 
56     @Inject
DozeLog( KeyguardUpdateMonitor keyguardUpdateMonitor, DumpManager dumpManager, DozeLogger logger)57     public DozeLog(
58             KeyguardUpdateMonitor keyguardUpdateMonitor,
59             DumpManager dumpManager,
60             DozeLogger logger) {
61         mLogger = logger;
62         mSince = System.currentTimeMillis();
63         mPickupPulseNearVibrationStats = new SummaryStats();
64         mPickupPulseNotNearVibrationStats = new SummaryStats();
65         mNotificationPulseStats = new SummaryStats();
66         mScreenOnPulsingStats = new SummaryStats();
67         mScreenOnNotPulsingStats = new SummaryStats();
68         mEmergencyCallStats = new SummaryStats();
69         mProxStats = new SummaryStats[TOTAL_REASONS][2];
70         for (int i = 0; i < TOTAL_REASONS; i++) {
71             mProxStats[i][0] = new SummaryStats();
72             mProxStats[i][1] = new SummaryStats();
73         }
74 
75         if (keyguardUpdateMonitor != null) {
76             keyguardUpdateMonitor.registerCallback(mKeyguardCallback);
77         }
78 
79         dumpManager.registerDumpable("DumpStats", this);
80     }
81 
82     /**
83      * Appends pickup wakeup event to the logs
84      */
tracePickupWakeUp(boolean withinVibrationThreshold)85     public void tracePickupWakeUp(boolean withinVibrationThreshold) {
86         mLogger.logPickupWakeup(withinVibrationThreshold);
87         (withinVibrationThreshold ? mPickupPulseNearVibrationStats
88                 : mPickupPulseNotNearVibrationStats).append();
89     }
90 
91     /**
92      * Appends pulse started event to the logs.
93      * @param reason why the pulse started
94      */
tracePulseStart(@eason int reason)95     public void tracePulseStart(@Reason int reason) {
96         mLogger.logPulseStart(reason);
97         mPulsing = true;
98     }
99 
100     /**
101      * Appends pulse finished event to the logs
102      */
tracePulseFinish()103     public void tracePulseFinish() {
104         mLogger.logPulseFinish();
105         mPulsing = false;
106     }
107 
108     /**
109      * Appends pulse event to the logs
110      */
traceNotificationPulse()111     public void traceNotificationPulse() {
112         mLogger.logNotificationPulse();
113         mNotificationPulseStats.append();
114     }
115 
116     /**
117      * Appends dozing event to the logs
118      * @param dozing true if dozing, else false
119      */
traceDozing(boolean dozing)120     public void traceDozing(boolean dozing) {
121         mLogger.logDozing(dozing);
122         mPulsing = false;
123     }
124 
125     /**
126      * Appends dozing event to the logs
127      * @param suppressed true if dozing is suppressed
128      */
traceDozingSuppressed(boolean suppressed)129     public void traceDozingSuppressed(boolean suppressed) {
130         mLogger.logDozingSuppressed(suppressed);
131     }
132 
133     /**
134      * Appends fling event to the logs
135      */
traceFling(boolean expand, boolean aboveThreshold, boolean thresholdNeeded, boolean screenOnFromTouch)136     public void traceFling(boolean expand, boolean aboveThreshold, boolean thresholdNeeded,
137             boolean screenOnFromTouch) {
138         mLogger.logFling(expand, aboveThreshold, thresholdNeeded, screenOnFromTouch);
139     }
140 
141     /**
142      * Appends emergency call event to the logs
143      */
traceEmergencyCall()144     public void traceEmergencyCall() {
145         mLogger.logEmergencyCall();
146         mEmergencyCallStats.append();
147     }
148 
149     /**
150      * Appends keyguard bouncer changed event to the logs
151      * @param showing true if the keyguard bouncer is showing, else false
152      */
traceKeyguardBouncerChanged(boolean showing)153     public void traceKeyguardBouncerChanged(boolean showing) {
154         mLogger.logKeyguardBouncerChanged(showing);
155     }
156 
157     /**
158      * Appends screen-on event to the logs
159      */
traceScreenOn()160     public void traceScreenOn() {
161         mLogger.logScreenOn(mPulsing);
162         (mPulsing ? mScreenOnPulsingStats : mScreenOnNotPulsingStats).append();
163         mPulsing = false;
164     }
165 
166     /**
167      * Appends screen-off event to the logs
168      * @param why reason the screen is off
169      */
traceScreenOff(int why)170     public void traceScreenOff(int why) {
171         mLogger.logScreenOff(why);
172     }
173 
174     /**
175      * Appends missed tick event to the logs
176      * @param delay of the missed tick
177      */
traceMissedTick(String delay)178     public void traceMissedTick(String delay) {
179         mLogger.logMissedTick(delay);
180     }
181 
182     /**
183      * Appends time tick scheduled event to the logs
184      * @param when time tick scheduled at
185      * @param triggerAt time tick trigger at
186      */
traceTimeTickScheduled(long when, long triggerAt)187     public void traceTimeTickScheduled(long when, long triggerAt) {
188         mLogger.logTimeTickScheduled(when, triggerAt);
189     }
190 
191     /**
192      * Appends keyguard visibility change event to the logs
193      * @param showing whether the keyguard is now showing
194      */
traceKeyguard(boolean showing)195     public void traceKeyguard(boolean showing) {
196         mLogger.logKeyguardVisibilityChange(showing);
197         if (!showing) mPulsing = false;
198     }
199 
200     /**
201      * Appends doze state changed event to the logs
202      * @param state new DozeMachine state
203      */
traceState(DozeMachine.State state)204     public void traceState(DozeMachine.State state) {
205         mLogger.logDozeStateChanged(state);
206     }
207 
208     /**
209      * Appends doze state changed sent to all DozeMachine parts event to the logs
210      * @param state new DozeMachine state
211      */
traceDozeStateSendComplete(DozeMachine.State state)212     public void traceDozeStateSendComplete(DozeMachine.State state) {
213         mLogger.logStateChangedSent(state);
214     }
215 
216     /**
217      * Appends display state changed event to the logs
218      * @param displayState new DozeMachine state
219      */
traceDisplayState(int displayState)220     public void traceDisplayState(int displayState) {
221         mLogger.logDisplayStateChanged(displayState);
222     }
223 
224     /**
225      * Appends wake-display event to the logs.
226      * @param wake if we're waking up or sleeping.
227      */
traceWakeDisplay(boolean wake, @Reason int reason)228     public void traceWakeDisplay(boolean wake, @Reason int reason) {
229         mLogger.logWakeDisplay(wake, reason);
230     }
231 
232     /**
233      * Appends proximity result event to the logs
234      * @param near true if near, else false
235      * @param reason why proximity result was triggered
236      */
traceProximityResult(boolean near, long millis, @Reason int reason)237     public void traceProximityResult(boolean near, long millis, @Reason int reason) {
238         mLogger.logProximityResult(near, millis, reason);
239         mProxStats[reason][near ? 0 : 1].append();
240     }
241 
242     @Override
dump(@onNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args)243     public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
244         synchronized (DozeLog.class) {
245             pw.print("  Doze summary stats (for ");
246             TimeUtils.formatDuration(System.currentTimeMillis() - mSince, pw);
247             pw.println("):");
248             mPickupPulseNearVibrationStats.dump(pw, "Pickup pulse (near vibration)");
249             mPickupPulseNotNearVibrationStats.dump(pw, "Pickup pulse (not near vibration)");
250             mNotificationPulseStats.dump(pw, "Notification pulse");
251             mScreenOnPulsingStats.dump(pw, "Screen on (pulsing)");
252             mScreenOnNotPulsingStats.dump(pw, "Screen on (not pulsing)");
253             mEmergencyCallStats.dump(pw, "Emergency call");
254             for (int i = 0; i < TOTAL_REASONS; i++) {
255                 final String reason = reasonToString(i);
256                 mProxStats[i][0].dump(pw, "Proximity near (" + reason + ")");
257                 mProxStats[i][1].dump(pw, "Proximity far (" + reason + ")");
258             }
259         }
260     }
261 
262     /**
263      * Appends pulse dropped event to logs
264      */
tracePulseDropped(boolean pulsePending, DozeMachine.State state, boolean blocked)265     public void tracePulseDropped(boolean pulsePending, DozeMachine.State state, boolean blocked) {
266         mLogger.logPulseDropped(pulsePending, state, blocked);
267     }
268 
269     /**
270      * Appends pulse dropped event to logs
271      * @param reason why the pulse was dropped
272      */
tracePulseDropped(String reason)273     public void tracePulseDropped(String reason) {
274         mLogger.logPulseDropped(reason);
275     }
276 
277     /**
278      * Appends pulse touch displayed by prox sensor event to logs
279      * @param disabled
280      */
tracePulseTouchDisabledByProx(boolean disabled)281     public void tracePulseTouchDisabledByProx(boolean disabled) {
282         mLogger.logPulseTouchDisabledByProx(disabled);
283     }
284 
285     /**
286      * Appends sensor triggered event to logs
287      * @param reason why the sensor was triggered
288      */
traceSensor(@eason int reason)289     public void traceSensor(@Reason int reason) {
290         mLogger.logSensorTriggered(reason);
291     }
292 
293     /**
294      * Appends doze suppressed event to the logs
295      * @param suppressedState The {@link DozeMachine.State} that was suppressed
296      */
traceDozeSuppressed(DozeMachine.State suppressedState)297     public void traceDozeSuppressed(DozeMachine.State suppressedState) {
298         mLogger.logDozeSuppressed(suppressedState);
299     }
300 
301     /**
302      * Appends new AOD sreen brightness to logs
303      * @param brightness display brightness setting
304      */
traceDozeScreenBrightness(int brightness)305     public void traceDozeScreenBrightness(int brightness) {
306         mLogger.logDozeScreenBrightness(brightness);
307     }
308 
309     /**
310     * Appends new AOD dimming scrim opacity to logs
311     * @param scrimOpacity
312      */
traceSetAodDimmingScrim(float scrimOpacity)313     public void traceSetAodDimmingScrim(float scrimOpacity) {
314         mLogger.logSetAodDimmingScrim((long) scrimOpacity);
315     }
316 
317     private class SummaryStats {
318         private int mCount;
319 
append()320         public void append() {
321             mCount++;
322         }
323 
dump(PrintWriter pw, String type)324         public void dump(PrintWriter pw, String type) {
325             if (mCount == 0) return;
326             pw.print("    ");
327             pw.print(type);
328             pw.print(": n=");
329             pw.print(mCount);
330             pw.print(" (");
331             final double perHr = (double) mCount / (System.currentTimeMillis() - mSince)
332                     * 1000 * 60 * 60;
333             pw.print(perHr);
334             pw.print("/hr)");
335             pw.println();
336         }
337     }
338 
339     private final KeyguardUpdateMonitorCallback mKeyguardCallback =
340             new KeyguardUpdateMonitorCallback() {
341         @Override
342         public void onEmergencyCallAction() {
343             traceEmergencyCall();
344         }
345 
346         @Override
347         public void onKeyguardBouncerChanged(boolean bouncer) {
348             traceKeyguardBouncerChanged(bouncer);
349         }
350 
351         @Override
352         public void onStartedWakingUp() {
353             traceScreenOn();
354         }
355 
356         @Override
357         public void onFinishedGoingToSleep(int why) {
358             traceScreenOff(why);
359         }
360 
361         @Override
362         public void onKeyguardVisibilityChanged(boolean showing) {
363             traceKeyguard(showing);
364         }
365     };
366 
367     /**
368      * Converts the reason (integer) to a user-readable string
369      */
reasonToString(@eason int pulseReason)370     public static String reasonToString(@Reason int pulseReason) {
371         switch (pulseReason) {
372             case PULSE_REASON_INTENT: return "intent";
373             case PULSE_REASON_NOTIFICATION: return "notification";
374             case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion";
375             case REASON_SENSOR_PICKUP: return "pickup";
376             case REASON_SENSOR_DOUBLE_TAP: return "doubletap";
377             case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
378             case PULSE_REASON_DOCKING: return "docking";
379             case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "reach-wakelockscreen";
380             case REASON_SENSOR_WAKE_UP: return "presence-wakeup";
381             case REASON_SENSOR_TAP: return "tap";
382             case REASON_SENSOR_UDFPS_LONG_PRESS: return "udfps";
383             case REASON_SENSOR_QUICK_PICKUP: return "quickPickup";
384             default: throw new IllegalArgumentException("invalid reason: " + pulseReason);
385         }
386     }
387 
388     @Retention(RetentionPolicy.SOURCE)
389     @IntDef({PULSE_REASON_NONE, PULSE_REASON_INTENT, PULSE_REASON_NOTIFICATION,
390             PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP,
391             PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP,
392             PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP,
393             REASON_SENSOR_UDFPS_LONG_PRESS, REASON_SENSOR_QUICK_PICKUP})
394     public @interface Reason {}
395     public static final int PULSE_REASON_NONE = -1;
396     public static final int PULSE_REASON_INTENT = 0;
397     public static final int PULSE_REASON_NOTIFICATION = 1;
398     public static final int PULSE_REASON_SENSOR_SIGMOTION = 2;
399     public static final int REASON_SENSOR_PICKUP = 3;
400     public static final int REASON_SENSOR_DOUBLE_TAP = 4;
401     public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
402     public static final int PULSE_REASON_DOCKING = 6;
403     public static final int REASON_SENSOR_WAKE_UP = 7;
404     public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8;
405     public static final int REASON_SENSOR_TAP = 9;
406     public static final int REASON_SENSOR_UDFPS_LONG_PRESS = 10;
407     public static final int REASON_SENSOR_QUICK_PICKUP = 11;
408 
409     public static final int TOTAL_REASONS = 12;
410 }
411