Merge "DozeLog uses new SysuiLog"
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
index 1d7e9ea..419fd62 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
@@ -82,7 +82,7 @@
 
     private void requestPulse(State dozeState) {
         if (!mDozeHost.isPulsingBlocked() && dozeState.canPulse()) {
-            mMachine.requestPulse(DozeLog.PULSE_REASON_DOCKING);
+            mMachine.requestPulse(DozeEvent.PULSE_REASON_DOCKING);
         }
         mPulsePending = false;
     }
@@ -91,7 +91,7 @@
         if (dozeState == State.DOZE_REQUEST_PULSE || dozeState == State.DOZE_PULSING
                 || dozeState == State.DOZE_PULSING_BRIGHT) {
             final int pulseReason = mMachine.getPulseReason();
-            if (pulseReason == DozeLog.PULSE_REASON_DOCKING) {
+            if (pulseReason == DozeEvent.PULSE_REASON_DOCKING) {
                 mDozeHost.stopPulsing();
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java b/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java
new file mode 100644
index 0000000..ea1def0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.doze;
+
+import android.annotation.IntDef;
+
+import com.android.systemui.log.RichEvent;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An event related to dozing. {@link DozeLog} stores and prints these events for debugging
+ * and triaging purposes.
+ */
+public class DozeEvent extends RichEvent {
+    public static final int TOTAL_EVENT_TYPES = 19;
+
+    public DozeEvent(int logLevel, int type, String reason) {
+        super(logLevel, type, reason);
+    }
+
+    /**
+     * Event labels for each doze event
+     * Index corresponds to the integer associated with each {@link EventType}
+     */
+    @Override
+    public String[] getEventLabels() {
+        final String[] events = new String[]{
+                "PickupWakeup",
+                "PulseStart",
+                "PulseFinish",
+                "NotificationPulse",
+                "Dozing",
+                "Fling",
+                "EmergencyCall",
+                "KeyguardBouncerChanged",
+                "ScreenOn",
+                "ScreenOff",
+                "MissedTick",
+                "TimeTickScheduled",
+                "KeyguardVisibilityChanged",
+                "DozeStateChanged",
+                "WakeDisplay",
+                "ProximityResult",
+                "PulseDropped",
+                "PulseDisabledByProx",
+                "SensorTriggered"
+        };
+
+        if (events.length != TOTAL_EVENT_TYPES) {
+            throw new IllegalStateException("DozeEvent events.length should match TOTAL_EVENT_TYPES"
+                    + " events.length=" + events.length
+                    + " TOTAL_EVENT_LENGTH=" + TOTAL_EVENT_TYPES);
+        }
+        return events;
+    }
+
+    /**
+     * Converts the reason (integer) to a user-readable string
+     */
+    public static String reasonToString(@Reason int pulseReason) {
+        switch (pulseReason) {
+            case PULSE_REASON_INTENT: return "intent";
+            case PULSE_REASON_NOTIFICATION: return "notification";
+            case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion";
+            case REASON_SENSOR_PICKUP: return "pickup";
+            case REASON_SENSOR_DOUBLE_TAP: return "doubletap";
+            case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
+            case PULSE_REASON_DOCKING: return "docking";
+            case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "wakelockscreen";
+            case REASON_SENSOR_WAKE_UP: return "wakeup";
+            case REASON_SENSOR_TAP: return "tap";
+            default: throw new IllegalArgumentException("invalid reason: " + pulseReason);
+        }
+    }
+
+    /**
+     * Builds a DozeEvent.
+     */
+    public static class DozeEventBuilder extends RichEvent.Builder<DozeEventBuilder> {
+        @Override
+        public DozeEventBuilder getBuilder() {
+            return this;
+        }
+
+        @Override
+        public RichEvent build() {
+            return new DozeEvent(mLogLevel, mType, mReason);
+        }
+    }
+
+    @IntDef({PICKUP_WAKEUP, PULSE_START, PULSE_FINISH, NOTIFICATION_PULSE, DOZING, FLING,
+            EMERGENCY_CALL, KEYGUARD_BOUNCER_CHANGED, SCREEN_ON, SCREEN_OFF, MISSED_TICK,
+            TIME_TICK_SCHEDULED, KEYGUARD_VISIBILITY_CHANGE, DOZE_STATE_CHANGED, WAKE_DISPLAY,
+            PROXIMITY_RESULT, PULSE_DROPPED, PULSE_DISABLED_BY_PROX, SENSOR_TRIGGERED})
+    /**
+     * Types of DozeEvents
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EventType {}
+    public static final int PICKUP_WAKEUP = 0;
+    public static final int PULSE_START = 1;
+    public static final int PULSE_FINISH = 2;
+    public static final int NOTIFICATION_PULSE = 3;
+    public static final int DOZING = 4;
+    public static final int FLING = 5;
+    public static final int EMERGENCY_CALL = 6;
+    public static final int KEYGUARD_BOUNCER_CHANGED = 7;
+    public static final int SCREEN_ON = 8;
+    public static final int SCREEN_OFF = 9;
+    public static final int MISSED_TICK = 10;
+    public static final int TIME_TICK_SCHEDULED = 11;
+    public static final int KEYGUARD_VISIBILITY_CHANGE = 12;
+    public static final int DOZE_STATE_CHANGED = 13;
+    public static final int WAKE_DISPLAY = 14;
+    public static final int PROXIMITY_RESULT = 15;
+    public static final int PULSE_DROPPED = 16;
+    public static final int PULSE_DISABLED_BY_PROX = 17;
+    public static final int SENSOR_TRIGGERED = 18;
+
+    public static final int TOTAL_REASONS = 10;
+    @IntDef({PULSE_REASON_NONE, PULSE_REASON_INTENT, PULSE_REASON_NOTIFICATION,
+            PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP,
+            PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP,
+            PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Reason {}
+    public static final int PULSE_REASON_NONE = -1;
+    public static final int PULSE_REASON_INTENT = 0;
+    public static final int PULSE_REASON_NOTIFICATION = 1;
+    public static final int PULSE_REASON_SENSOR_SIGMOTION = 2;
+    public static final int REASON_SENSOR_PICKUP = 3;
+    public static final int REASON_SENSOR_DOUBLE_TAP = 4;
+    public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
+    public static final int PULSE_REASON_DOCKING = 6;
+    public static final int REASON_SENSOR_WAKE_UP = 7;
+    public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8;
+    public static final int REASON_SENSOR_TAP = 9;
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 4d3dc70..2bbe775 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -44,7 +44,8 @@
     }
 
     /** Creates a DozeMachine with its parts for {@code dozeService}. */
-    public DozeMachine assembleMachine(DozeService dozeService, FalsingManager falsingManager) {
+    public DozeMachine assembleMachine(DozeService dozeService, FalsingManager falsingManager,
+            DozeLog dozeLog) {
         Context context = dozeService;
         AsyncSensorManager sensorManager = Dependency.get(AsyncSensorManager.class);
         AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
@@ -65,13 +66,14 @@
                 params);
 
         DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock,
-                wakefulnessLifecycle);
+                wakefulnessLifecycle, dozeLog);
         machine.setParts(new DozeMachine.Part[]{
                 new DozePauser(handler, machine, alarmManager, params.getPolicy()),
                 new DozeFalsingManagerAdapter(falsingManager),
                 createDozeTriggers(context, sensorManager, host, alarmManager, config, params,
-                        handler, wakeLock, machine, dockManager),
-                createDozeUi(context, host, wakeLock, machine, handler, alarmManager, params),
+                        handler, wakeLock, machine, dockManager, dozeLog),
+                createDozeUi(context, host, wakeLock, machine, handler, alarmManager, params,
+                        dozeLog),
                 new DozeScreenState(wrappedService, handler, params, wakeLock),
                 createDozeScreenBrightness(context, wrappedService, sensorManager, host, params,
                         handler),
@@ -95,18 +97,19 @@
     private DozeTriggers createDozeTriggers(Context context, AsyncSensorManager sensorManager,
             DozeHost host, AlarmManager alarmManager, AmbientDisplayConfiguration config,
             DozeParameters params, Handler handler, WakeLock wakeLock, DozeMachine machine,
-            DockManager dockManager) {
+            DockManager dockManager, DozeLog dozeLog) {
         boolean allowPulseTriggers = true;
         return new DozeTriggers(context, machine, host, alarmManager, config, params,
                 sensorManager, handler, wakeLock, allowPulseTriggers, dockManager,
-                new ProximitySensor(context, sensorManager));
+                new ProximitySensor(context, sensorManager), dozeLog);
+
     }
 
     private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock,
             DozeMachine machine, Handler handler, AlarmManager alarmManager,
-            DozeParameters params) {
+            DozeParameters params, DozeLog dozeLog) {
         return new DozeUi(context, alarmManager, machine, wakeLock, host, handler, params,
-                Dependency.get(KeyguardUpdateMonitor.class));
+                Dependency.get(KeyguardUpdateMonitor.class), dozeLog);
     }
 
     public static DozeHost getHost(DozeService service) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 8fe9f92..2e4466d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -16,282 +16,284 @@
 
 package com.android.systemui.doze;
 
-import android.content.Context;
-import android.os.Build;
-import android.util.Log;
 import android.util.TimeUtils;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.Dependency;
+import com.android.systemui.DumpController;
+import com.android.systemui.log.SysuiLog;
 
 import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
 import java.util.Date;
 
-public class DozeLog {
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Logs doze events for debugging and triaging purposes. Logs are dumped in bugreports or on demand:
+ *      adb shell dumpsys activity service com.android.systemui/.SystemUIService \
+ *      dependency DumpController DozeLog
+ */
+@Singleton
+public class DozeLog extends SysuiLog {
     private static final String TAG = "DozeLog";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean ENABLED = true;
-    private static final int SIZE = Build.IS_DEBUGGABLE ? 400 : 50;
-    static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
 
-    public static final int REASONS = 10;
+    private boolean mPulsing;
+    private long mSince;
+    private SummaryStats mPickupPulseNearVibrationStats;
+    private SummaryStats mPickupPulseNotNearVibrationStats;
+    private SummaryStats mNotificationPulseStats;
+    private SummaryStats mScreenOnPulsingStats;
+    private SummaryStats mScreenOnNotPulsingStats;
+    private SummaryStats mEmergencyCallStats;
+    private SummaryStats[][] mProxStats; // [reason][near/far]
 
-    public static final int PULSE_REASON_NONE = -1;
-    public static final int PULSE_REASON_INTENT = 0;
-    public static final int PULSE_REASON_NOTIFICATION = 1;
-    public static final int PULSE_REASON_SENSOR_SIGMOTION = 2;
-    public static final int REASON_SENSOR_PICKUP = 3;
-    public static final int REASON_SENSOR_DOUBLE_TAP = 4;
-    public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
-    public static final int PULSE_REASON_DOCKING = 6;
-    public static final int REASON_SENSOR_WAKE_UP = 7;
-    public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8;
-    public static final int REASON_SENSOR_TAP = 9;
+    @Inject
+    public DozeLog(KeyguardUpdateMonitor keyguardUpdateMonitor, DumpController dumpController) {
+        super(dumpController, TAG, MAX_DOZE_DEBUG_LOGS, MAX_DOZE_LOGS);
+        mSince = System.currentTimeMillis();
+        mPickupPulseNearVibrationStats = new SummaryStats();
+        mPickupPulseNotNearVibrationStats = new SummaryStats();
+        mNotificationPulseStats = new SummaryStats();
+        mScreenOnPulsingStats = new SummaryStats();
+        mScreenOnNotPulsingStats = new SummaryStats();
+        mEmergencyCallStats = new SummaryStats();
+        mProxStats = new SummaryStats[DozeEvent.TOTAL_REASONS][2];
+        for (int i = 0; i < DozeEvent.TOTAL_REASONS; i++) {
+            mProxStats[i][0] = new SummaryStats();
+            mProxStats[i][1] = new SummaryStats();
+        }
 
-    private static boolean sRegisterKeyguardCallback = true;
-
-    private static long[] sTimes;
-    private static String[] sMessages;
-    private static int sPosition;
-    private static int sCount;
-    private static boolean sPulsing;
-
-    private static long sSince;
-    private static SummaryStats sPickupPulseNearVibrationStats;
-    private static SummaryStats sPickupPulseNotNearVibrationStats;
-    private static SummaryStats sNotificationPulseStats;
-    private static SummaryStats sScreenOnPulsingStats;
-    private static SummaryStats sScreenOnNotPulsingStats;
-    private static SummaryStats sEmergencyCallStats;
-    private static SummaryStats[][] sProxStats; // [reason][near/far]
-
-    public static void tracePickupWakeUp(Context context, boolean withinVibrationThreshold) {
-        if (!ENABLED) return;
-        init(context);
-        log("pickupWakeUp withinVibrationThreshold=" + withinVibrationThreshold);
-        (withinVibrationThreshold ? sPickupPulseNearVibrationStats
-                : sPickupPulseNotNearVibrationStats).append();
-    }
-
-    public static void tracePulseStart(int reason) {
-        if (!ENABLED) return;
-        sPulsing = true;
-        log("pulseStart reason=" + reasonToString(reason));
-    }
-
-    public static void tracePulseFinish() {
-        if (!ENABLED) return;
-        sPulsing = false;
-        log("pulseFinish");
-    }
-
-    public static void traceNotificationPulse(Context context) {
-        if (!ENABLED) return;
-        init(context);
-        log("notificationPulse");
-        sNotificationPulseStats.append();
-    }
-
-    private static void init(Context context) {
-        synchronized (DozeLog.class) {
-            if (sMessages == null) {
-                sTimes = new long[SIZE];
-                sMessages = new String[SIZE];
-                sSince = System.currentTimeMillis();
-                sPickupPulseNearVibrationStats = new SummaryStats();
-                sPickupPulseNotNearVibrationStats = new SummaryStats();
-                sNotificationPulseStats = new SummaryStats();
-                sScreenOnPulsingStats = new SummaryStats();
-                sScreenOnNotPulsingStats = new SummaryStats();
-                sEmergencyCallStats = new SummaryStats();
-                sProxStats = new SummaryStats[REASONS][2];
-                for (int i = 0; i < REASONS; i++) {
-                    sProxStats[i][0] = new SummaryStats();
-                    sProxStats[i][1] = new SummaryStats();
-                }
-                log("init");
-                if (sRegisterKeyguardCallback) {
-                    Dependency.get(KeyguardUpdateMonitor.class).registerCallback(sKeyguardCallback);
-                }
-            }
+        if (keyguardUpdateMonitor != null) {
+            keyguardUpdateMonitor.registerCallback(mKeyguardCallback);
         }
     }
 
-    public static void traceDozing(Context context, boolean dozing) {
-        if (!ENABLED) return;
-        sPulsing = false;
-        init(context);
-        log("dozing " + dozing);
+    /**
+     * Appends pickup wakeup event to the logs
+     */
+    public void tracePickupWakeUp(boolean withinVibrationThreshold) {
+        if (log(DozeEvent.PICKUP_WAKEUP,
+                "withinVibrationThreshold=" + withinVibrationThreshold)) {
+            (withinVibrationThreshold ? mPickupPulseNearVibrationStats
+                    : mPickupPulseNotNearVibrationStats).append();
+        }
     }
 
-    public static void traceFling(boolean expand, boolean aboveThreshold, boolean thresholdNeeded,
+    /**
+     * Appends pulse started event to the logs.
+     * @param reason why the pulse started
+     */
+    public void tracePulseStart(@DozeEvent.Reason int reason) {
+        if (log(DozeEvent.PULSE_START, DozeEvent.reasonToString(reason))) {
+            mPulsing = true;
+        }
+    }
+
+    /**
+     * Appends pulse finished event to the logs
+     */
+    public void tracePulseFinish() {
+        if (log(DozeEvent.PULSE_FINISH)) {
+            mPulsing = false;
+        }
+    }
+
+    /**
+     * Appends pulse event to the logs
+     */
+    public void traceNotificationPulse() {
+        if (log(DozeEvent.NOTIFICATION_PULSE)) {
+            mNotificationPulseStats.append();
+        }
+    }
+
+    /**
+     * Appends dozing event to the logs
+     * @param dozing true if dozing, else false
+     */
+    public void traceDozing(boolean dozing) {
+        if (log(DozeEvent.DOZING, "dozing=" + dozing)) {
+            mPulsing = false;
+        }
+    }
+
+    /**
+     * Appends fling event to the logs
+     */
+    public void traceFling(boolean expand, boolean aboveThreshold, boolean thresholdNeeded,
             boolean screenOnFromTouch) {
-        if (!ENABLED) return;
-        log("fling expand=" + expand + " aboveThreshold=" + aboveThreshold + " thresholdNeeded="
-                + thresholdNeeded + " screenOnFromTouch=" + screenOnFromTouch);
+        log(DozeEvent.FLING, "expand=" + expand
+                + " aboveThreshold=" + aboveThreshold
+                + " thresholdNeeded=" + thresholdNeeded
+                + " screenOnFromTouch=" + screenOnFromTouch);
     }
 
-    public static void traceEmergencyCall() {
-        if (!ENABLED) return;
-        log("emergencyCall");
-        sEmergencyCallStats.append();
-    }
-
-    public static void traceKeyguardBouncerChanged(boolean showing) {
-        if (!ENABLED) return;
-        log("bouncer " + showing);
-    }
-
-    public static void traceScreenOn() {
-        if (!ENABLED) return;
-        log("screenOn pulsing=" + sPulsing);
-        (sPulsing ? sScreenOnPulsingStats : sScreenOnNotPulsingStats).append();
-        sPulsing = false;
-    }
-
-    public static void traceScreenOff(int why) {
-        if (!ENABLED) return;
-        log("screenOff why=" + why);
-    }
-
-    public static void traceMissedTick(String delay) {
-        if (!ENABLED) return;
-        log("missedTick by=" + delay);
-    }
-
-    public static void traceTimeTickScheduled(long when, long triggerAt) {
-        if (!ENABLED) return;
-        log("timeTickScheduled at=" + FORMAT.format(new Date(when)) + " triggerAt="
-                + FORMAT.format(new Date(triggerAt)));
-    }
-
-    public static void traceKeyguard(boolean showing) {
-        if (!ENABLED) return;
-        log("keyguard " + showing);
-        if (!showing) {
-            sPulsing = false;
+    /**
+     * Appends emergency call event to the logs
+     */
+    public void traceEmergencyCall() {
+        if (log(DozeEvent.EMERGENCY_CALL)) {
+            mEmergencyCallStats.append();
         }
     }
 
-    public static void traceState(DozeMachine.State state) {
-        if (!ENABLED) return;
-        log("state " + state);
+    /**
+     * Appends keyguard bouncer changed event to the logs
+     * @param showing true if the keyguard bouncer is showing, else false
+     */
+    public void traceKeyguardBouncerChanged(boolean showing) {
+        log(DozeEvent.KEYGUARD_BOUNCER_CHANGED, "showing=" + showing);
+    }
+
+    /**
+     * Appends screen-on event to the logs
+     */
+    public void traceScreenOn() {
+        if (log(DozeEvent.SCREEN_ON, "pulsing=" + mPulsing)) {
+            (mPulsing ? mScreenOnPulsingStats : mScreenOnNotPulsingStats).append();
+            mPulsing = false;
+        }
+    }
+
+    /**
+     * Appends screen-off event to the logs
+     * @param why reason the screen is off
+     */
+    public void traceScreenOff(int why) {
+        log(DozeEvent.SCREEN_OFF, "why=" + why);
+    }
+
+    /**
+     * Appends missed tick event to the logs
+     * @param delay of the missed tick
+     */
+    public void traceMissedTick(String delay) {
+        log(DozeEvent.MISSED_TICK, "delay=" + delay);
+    }
+
+    /**
+     * Appends time tick scheduled event to the logs
+     * @param when time tick scheduled at
+     * @param triggerAt time tick trigger at
+     */
+    public void traceTimeTickScheduled(long when, long triggerAt) {
+        log(DozeEvent.TIME_TICK_SCHEDULED,
+                "scheduledAt=" + DATE_FORMAT.format(new Date(when))
+                + " triggerAt=" + DATE_FORMAT.format(new Date(triggerAt)));
+    }
+
+    /**
+     * Appends keyguard visibility change event to the logs
+     * @param showing whether the keyguard is now showing
+     */
+    public void traceKeyguard(boolean showing) {
+        if (log(DozeEvent.KEYGUARD_VISIBILITY_CHANGE, "showing=" + showing)
+                && !showing) {
+            mPulsing = false;
+        }
+    }
+
+    /**
+     * Appends doze state changed event to the logs
+     * @param state new DozeMachine state
+     */
+    public void traceState(DozeMachine.State state) {
+        log(DozeEvent.DOZE_STATE_CHANGED, state.name());
     }
 
     /**
      * Appends wake-display event to the logs.
      * @param wake if we're waking up or sleeping.
      */
-    public static void traceWakeDisplay(boolean wake) {
-        if (!ENABLED) return;
-        log("wakeDisplay " + wake);
+    public void traceWakeDisplay(boolean wake) {
+        log(DozeEvent.WAKE_DISPLAY, "wake=" + wake);
     }
 
-    public static void traceProximityResult(Context context, boolean near, long millis,
-            int reason) {
-        if (!ENABLED) return;
-        init(context);
-        log("proximityResult reason=" + reasonToString(reason) + " near=" + near
-                + " millis=" + millis);
-        sProxStats[reason][near ? 0 : 1].append();
-    }
-
-    public static String reasonToString(int pulseReason) {
-        switch (pulseReason) {
-            case PULSE_REASON_INTENT: return "intent";
-            case PULSE_REASON_NOTIFICATION: return "notification";
-            case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion";
-            case REASON_SENSOR_PICKUP: return "pickup";
-            case REASON_SENSOR_DOUBLE_TAP: return "doubletap";
-            case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
-            case PULSE_REASON_DOCKING: return "docking";
-            case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "wakelockscreen";
-            case REASON_SENSOR_WAKE_UP: return "wakeup";
-            case REASON_SENSOR_TAP: return "tap";
-            default: throw new IllegalArgumentException("bad reason: " + pulseReason);
+    /**
+     * Appends proximity result event to the logs
+     * @param near true if near, else false
+     * @param millis
+     * @param reason why proximity result was triggered
+     */
+    public void traceProximityResult(boolean near, long millis, @DozeEvent.Reason int reason) {
+        if (log(DozeEvent.PROXIMITY_RESULT,
+                " reason=" + DozeEvent.reasonToString(reason)
+                + " near=" + near
+                + " millis=" + millis)) {
+            mProxStats[reason][near ? 0 : 1].append();
         }
     }
 
-    public static void dump(PrintWriter pw) {
+    /**
+     * Prints doze log timeline and consolidated stats
+     * @param pw
+     */
+    public void dump(PrintWriter pw) {
         synchronized (DozeLog.class) {
-            if (sMessages == null) return;
-            pw.println("  Doze log:");
-            final int start = (sPosition - sCount + SIZE) % SIZE;
-            for (int i = 0; i < sCount; i++) {
-                final int j = (start + i) % SIZE;
-                pw.print("    ");
-                pw.print(FORMAT.format(new Date(sTimes[j])));
-                pw.print(' ');
-                pw.println(sMessages[j]);
-            }
+            super.dump(null, pw, null); // prints timeline
+
             pw.print("  Doze summary stats (for ");
-            TimeUtils.formatDuration(System.currentTimeMillis() - sSince, pw);
+            TimeUtils.formatDuration(System.currentTimeMillis() - mSince, pw);
             pw.println("):");
-            sPickupPulseNearVibrationStats.dump(pw, "Pickup pulse (near vibration)");
-            sPickupPulseNotNearVibrationStats.dump(pw, "Pickup pulse (not near vibration)");
-            sNotificationPulseStats.dump(pw, "Notification pulse");
-            sScreenOnPulsingStats.dump(pw, "Screen on (pulsing)");
-            sScreenOnNotPulsingStats.dump(pw, "Screen on (not pulsing)");
-            sEmergencyCallStats.dump(pw, "Emergency call");
-            for (int i = 0; i < REASONS; i++) {
-                final String reason = reasonToString(i);
-                sProxStats[i][0].dump(pw, "Proximity near (" + reason + ")");
-                sProxStats[i][1].dump(pw, "Proximity far (" + reason + ")");
+            mPickupPulseNearVibrationStats.dump(pw, "Pickup pulse (near vibration)");
+            mPickupPulseNotNearVibrationStats.dump(pw, "Pickup pulse (not near vibration)");
+            mNotificationPulseStats.dump(pw, "Notification pulse");
+            mScreenOnPulsingStats.dump(pw, "Screen on (pulsing)");
+            mScreenOnNotPulsingStats.dump(pw, "Screen on (not pulsing)");
+            mEmergencyCallStats.dump(pw, "Emergency call");
+            for (int i = 0; i < DozeEvent.TOTAL_REASONS; i++) {
+                final String reason = DozeEvent.reasonToString(i);
+                mProxStats[i][0].dump(pw, "Proximity near (" + reason + ")");
+                mProxStats[i][1].dump(pw, "Proximity far (" + reason + ")");
             }
         }
     }
 
-    private static void log(String msg) {
-        synchronized (DozeLog.class) {
-            if (sMessages == null) return;
-            sTimes[sPosition] = System.currentTimeMillis();
-            sMessages[sPosition] = msg;
-            sPosition = (sPosition + 1) % SIZE;
-            sCount = Math.min(sCount + 1, SIZE);
-        }
-        if (DEBUG) Log.d(TAG, msg);
+    private boolean log(@DozeEvent.EventType int eventType) {
+        return log(eventType, "");
     }
 
-    public static void tracePulseDropped(Context context, boolean pulsePending,
-            DozeMachine.State state, boolean blocked) {
-        if (!ENABLED) return;
-        init(context);
-        log("pulseDropped pulsePending=" + pulsePending + " state="
-                + state + " blocked=" + blocked);
+    private boolean log(@DozeEvent.EventType int eventType, String msg) {
+        return super.log(new DozeEvent.DozeEventBuilder()
+                .setType(eventType)
+                .setReason(msg)
+                .build());
     }
 
-    public static void tracePulseDropped(Context context, String why) {
-        if (!ENABLED) return;
-        init(context);
-        log("pulseDropped why=" + why);
+    /**
+     * Appends pulse dropped event to logs
+     */
+    public void tracePulseDropped(boolean pulsePending, DozeMachine.State state, boolean blocked) {
+        log(DozeEvent.PULSE_DROPPED, "pulsePending=" + pulsePending + " state="
+                + state.name() + " blocked=" + blocked);
     }
 
-    public static void tracePulseTouchDisabledByProx(Context context, boolean disabled) {
-        if (!ENABLED) return;
-        init(context);
-        log("pulseTouchDisabledByProx " + disabled);
+    /**
+     * Appends pulse dropped event to logs
+     * @param reason why the pulse was dropped
+     */
+    public void tracePulseDropped(String reason) {
+        log(DozeEvent.PULSE_DROPPED, "why=" + reason);
     }
 
-    public static void setRegisterKeyguardCallback(boolean registerKeyguardCallback) {
-        if (!ENABLED) return;
-        synchronized (DozeLog.class) {
-            if (sRegisterKeyguardCallback != registerKeyguardCallback && sMessages != null) {
-                throw new IllegalStateException("Cannot change setRegisterKeyguardCallback "
-                        + "after init()");
-            }
-            sRegisterKeyguardCallback = registerKeyguardCallback;
-        }
+    /**
+     * Appends pulse touch displayed by prox sensor event to logs
+     * @param disabled
+     */
+    public void tracePulseTouchDisabledByProx(boolean disabled) {
+        log(DozeEvent.PULSE_DISABLED_BY_PROX, "disabled=" + disabled);
     }
 
-    public static void traceSensor(Context context, int reason) {
-        if (!ENABLED) return;
-        init(context);
-        log("sensor type=" + reasonToString(reason));
+    /**
+     * Appends sensor triggered event to logs
+     * @param reason why the sensor was triggered
+     */
+    public void traceSensor(@DozeEvent.Reason int reason) {
+        log(DozeEvent.SENSOR_TRIGGERED, "type=" + DozeEvent.reasonToString(reason));
     }
 
-    private static class SummaryStats {
+    private class SummaryStats {
         private int mCount;
 
         public void append() {
@@ -305,7 +307,7 @@
             pw.print(": n=");
             pw.print(mCount);
             pw.print(" (");
-            final double perHr = (double) mCount / (System.currentTimeMillis() - sSince)
+            final double perHr = (double) mCount / (System.currentTimeMillis() - mSince)
                     * 1000 * 60 * 60;
             pw.print(perHr);
             pw.print("/hr)");
@@ -313,7 +315,7 @@
         }
     }
 
-    private static final KeyguardUpdateMonitorCallback sKeyguardCallback =
+    private final KeyguardUpdateMonitorCallback mKeyguardCallback =
             new KeyguardUpdateMonitorCallback() {
         @Override
         public void onEmergencyCallAction() {
@@ -340,4 +342,7 @@
             traceKeyguard(showing);
         }
     };
+
+    private static final int MAX_DOZE_DEBUG_LOGS = 400;
+    private static final int MAX_DOZE_LOGS = 50;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 93a51cc..ba81d2f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -45,6 +45,7 @@
 
     static final String TAG = "DozeMachine";
     static final boolean DEBUG = DozeService.DEBUG;
+    private final DozeLog mDozeLog;
     private static final String REASON_CHANGE_STATE = "DozeMachine#requestState";
     private static final String REASON_HELD_FOR_STATE = "DozeMachine#heldForState";
 
@@ -129,11 +130,12 @@
     private boolean mWakeLockHeldForCurrentState = false;
 
     public DozeMachine(Service service, AmbientDisplayConfiguration config,
-            WakeLock wakeLock, WakefulnessLifecycle wakefulnessLifecycle) {
+            WakeLock wakeLock, WakefulnessLifecycle wakefulnessLifecycle, DozeLog dozeLog) {
         mDozeService = service;
         mConfig = config;
         mWakefulnessLifecycle = wakefulnessLifecycle;
         mWakeLock = wakeLock;
+        mDozeLog = dozeLog;
     }
 
     /** Initializes the set of {@link Part}s. Must be called exactly once after construction. */
@@ -155,7 +157,7 @@
     @MainThread
     public void requestState(State requestedState) {
         Preconditions.checkArgument(requestedState != State.DOZE_REQUEST_PULSE);
-        requestState(requestedState, DozeLog.PULSE_REASON_NONE);
+        requestState(requestedState, DozeEvent.PULSE_REASON_NONE);
     }
 
     @MainThread
@@ -243,7 +245,7 @@
         State oldState = mState;
         mState = newState;
 
-        DozeLog.traceState(newState);
+        mDozeLog.traceState(newState);
         Trace.traceCounter(Trace.TRACE_TAG_APP, "doze_machine_state", newState.ordinal());
 
         updatePulseReason(newState, oldState, pulseReason);
@@ -257,7 +259,7 @@
         if (newState == State.DOZE_REQUEST_PULSE) {
             mPulseReason = pulseReason;
         } else if (oldState == State.DOZE_PULSE_DONE) {
-            mPulseReason = DozeLog.PULSE_REASON_NONE;
+            mPulseReason = DozeEvent.PULSE_REASON_NONE;
         }
     }
 
@@ -349,7 +351,7 @@
                     nextState = State.DOZE;
                 }
 
-                transitionTo(nextState, DozeLog.PULSE_REASON_NONE);
+                transitionTo(nextState, DozeEvent.PULSE_REASON_NONE);
                 break;
             default:
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index a201400..7d86028 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -80,7 +80,8 @@
 
     public DozeSensors(Context context, AlarmManager alarmManager, AsyncSensorManager sensorManager,
             DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
-            Callback callback, Consumer<Boolean> proxCallback, AlwaysOnDisplayPolicy policy) {
+            Callback callback, Consumer<Boolean> proxCallback, AlwaysOnDisplayPolicy policy,
+            DozeLog dozeLog) {
         mContext = context;
         mAlarmManager = alarmManager;
         mSensorManager = sensorManager;
@@ -97,52 +98,59 @@
                         mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
                         null /* setting */,
                         dozeParameters.getPulseOnSigMotion(),
-                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
-                        false /* touchscreen */),
+                        DozeEvent.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
+                        false /* touchscreen */, dozeLog),
                 mPickupSensor = new TriggerSensor(
                         mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
                         Settings.Secure.DOZE_PICK_UP_GESTURE,
                         true /* settingDef */,
                         config.dozePickupSensorAvailable(),
-                        DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */,
+                        DozeEvent.REASON_SENSOR_PICKUP, false /* touchCoords */,
                         false /* touchscreen */,
-                        false /* ignoresSetting */),
+                        false /* ignoresSetting */,
+                        dozeLog),
                 new TriggerSensor(
                         findSensorWithType(config.doubleTapSensorType()),
                         Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
                         true /* configured */,
-                        DozeLog.REASON_SENSOR_DOUBLE_TAP,
+                        DozeEvent.REASON_SENSOR_DOUBLE_TAP,
                         dozeParameters.doubleTapReportsTouchCoordinates(),
-                        true /* touchscreen */),
+                        true /* touchscreen */,
+                        dozeLog),
                 new TriggerSensor(
                         findSensorWithType(config.tapSensorType()),
                         Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
                         true /* configured */,
-                        DozeLog.REASON_SENSOR_TAP,
+                        DozeEvent.REASON_SENSOR_TAP,
                         false /* reports touch coordinates */,
-                        true /* touchscreen */),
+                        true /* touchscreen */,
+                        dozeLog),
                 new TriggerSensor(
                         findSensorWithType(config.longPressSensorType()),
                         Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
                         false /* settingDef */,
                         true /* configured */,
-                        DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
+                        DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS,
                         true /* reports touch coordinates */,
-                        true /* touchscreen */),
+                        true /* touchscreen */,
+                        dozeLog),
                 new PluginSensor(
                         new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
                         Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
                         mConfig.wakeScreenGestureAvailable() && alwaysOn,
-                        DozeLog.REASON_SENSOR_WAKE_UP,
+                        DozeEvent.REASON_SENSOR_WAKE_UP,
                         false /* reports touch coordinates */,
-                        false /* touchscreen */),
+                        false /* touchscreen */,
+                        dozeLog),
                 new PluginSensor(
                         new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN),
                         Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
                         mConfig.wakeScreenGestureAvailable(),
-                        DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
+                        DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
                         false /* reports touch coordinates */,
-                        false /* touchscreen */, mConfig.getWakeLockScreenDebounce()),
+                        false /* touchscreen */,
+                        mConfig.getWakeLockScreenDebounce(),
+                        dozeLog),
         };
 
         mProximitySensor = new ProximitySensor(context, sensorManager);
@@ -306,23 +314,24 @@
         protected boolean mRegistered;
         protected boolean mDisabled;
         protected boolean mIgnoresSetting;
+        protected final DozeLog mDozeLog;
 
         public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason,
-                boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
+                boolean reportsTouchCoordinates, boolean requiresTouchscreen, DozeLog dozeLog) {
             this(sensor, setting, true /* settingDef */, configured, pulseReason,
-                    reportsTouchCoordinates, requiresTouchscreen);
+                    reportsTouchCoordinates, requiresTouchscreen, dozeLog);
         }
 
         public TriggerSensor(Sensor sensor, String setting, boolean settingDef,
                 boolean configured, int pulseReason, boolean reportsTouchCoordinates,
-                boolean requiresTouchscreen) {
+                boolean requiresTouchscreen, DozeLog dozeLog) {
             this(sensor, setting, settingDef, configured, pulseReason, reportsTouchCoordinates,
-                    requiresTouchscreen, false /* ignoresSetting */);
+                    requiresTouchscreen, false /* ignoresSetting */, dozeLog);
         }
 
         private TriggerSensor(Sensor sensor, String setting, boolean settingDef,
                 boolean configured, int pulseReason, boolean reportsTouchCoordinates,
-                boolean requiresTouchscreen, boolean ignoresSetting) {
+                boolean requiresTouchscreen, boolean ignoresSetting, DozeLog dozeLog) {
             mSensor = sensor;
             mSetting = setting;
             mSettingDefault = settingDef;
@@ -331,6 +340,7 @@
             mReportsTouchCoordinates = reportsTouchCoordinates;
             mRequiresTouchscreen = requiresTouchscreen;
             mIgnoresSetting = ignoresSetting;
+            mDozeLog = dozeLog;
         }
 
         public void setListening(boolean listen) {
@@ -387,7 +397,7 @@
         @Override
         @AnyThread
         public void onTrigger(TriggerEvent event) {
-            DozeLog.traceSensor(mContext, mPulseReason);
+            mDozeLog.traceSensor(mPulseReason);
             mHandler.post(mWakeLock.wrap(() -> {
                 if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
                 if (mSensor != null && mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
@@ -443,16 +453,17 @@
         private long mDebounce;
 
         PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
-                int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
+                int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen,
+                DozeLog dozeLog) {
             this(sensor, setting, configured, pulseReason, reportsTouchCoordinates,
-                    requiresTouchscreen, 0L /* debounce */);
+                    requiresTouchscreen, 0L /* debounce */, dozeLog);
         }
 
         PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
                 int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen,
-                long debounce) {
+                long debounce, DozeLog dozeLog) {
             super(null, setting, configured, pulseReason, reportsTouchCoordinates,
-                    requiresTouchscreen);
+                    requiresTouchscreen, dozeLog);
             mPluginSensor = sensor;
             mDebounce = debounce;
         }
@@ -498,7 +509,7 @@
 
         @Override
         public void onSensorChanged(SensorManagerPlugin.SensorEvent event) {
-            DozeLog.traceSensor(mContext, mPulseReason);
+            mDozeLog.traceSensor(mPulseReason);
             mHandler.post(mWakeLock.wrap(() -> {
                 final long now = SystemClock.uptimeMillis();
                 if (now < mDebounceFrom + mDebounce) {
@@ -515,7 +526,7 @@
 
         /**
          * Called when a sensor requests a pulse
-         * @param pulseReason Requesting sensor, e.g. {@link DozeLog#REASON_SENSOR_PICKUP}
+         * @param pulseReason Requesting sensor, e.g. {@link DozeEvent#REASON_SENSOR_PICKUP}
          * @param screenX the location on the screen where the sensor fired or -1
          *                if the sensor doesn't support reporting screen locations.
          * @param screenY the location on the screen where the sensor fired or -1
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index e92acfc..17559c9 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -39,15 +39,17 @@
     private static final String TAG = "DozeService";
     static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private final FalsingManager mFalsingManager;
+    private final DozeLog mDozeLog;
 
     private DozeMachine mDozeMachine;
     private DozeServicePlugin mDozePlugin;
     private PluginManager mPluginManager;
 
     @Inject
-    public DozeService(FalsingManager falsingManager) {
+    public DozeService(FalsingManager falsingManager, DozeLog dozeLog) {
         setDebug(DEBUG);
         mFalsingManager = falsingManager;
+        mDozeLog = dozeLog;
     }
 
     @Override
@@ -62,7 +64,7 @@
         }
         mPluginManager = Dependency.get(PluginManager.class);
         mPluginManager.addPluginListener(this, DozeServicePlugin.class, false /* allowMultiple */);
-        mDozeMachine = new DozeFactory().assembleMachine(this, mFalsingManager);
+        mDozeMachine = new DozeFactory().assembleMachine(this, mFalsingManager, mDozeLog);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 8eed71c..74dec35 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -67,6 +67,7 @@
 
     private final Context mContext;
     private final DozeMachine mMachine;
+    private final DozeLog mDozeLog;
     private final DozeSensors mDozeSensors;
     private final DozeHost mDozeHost;
     private final AmbientDisplayConfiguration mConfig;
@@ -89,7 +90,8 @@
             AlarmManager alarmManager, AmbientDisplayConfiguration config,
             DozeParameters dozeParameters, AsyncSensorManager sensorManager, Handler handler,
             WakeLock wakeLock, boolean allowPulseTriggers, DockManager dockManager,
-            ProximitySensor proximitySensor) {
+            ProximitySensor proximitySensor,
+            DozeLog dozeLog) {
         mContext = context;
         mMachine = machine;
         mDozeHost = dozeHost;
@@ -100,10 +102,11 @@
         mAllowPulseTriggers = allowPulseTriggers;
         mDozeSensors = new DozeSensors(context, alarmManager, mSensorManager, dozeParameters,
                 config, wakeLock, this::onSensor, this::onProximityFar,
-                dozeParameters.getPolicy());
+                dozeParameters.getPolicy(), dozeLog);
         mUiModeManager = mContext.getSystemService(UiModeManager.class);
         mDockManager = dockManager;
         mProxCheck = new ProximitySensor.ProximityCheck(proximitySensor, handler);
+        mDozeLog = dozeLog;
     }
 
     private void onNotification(Runnable onPulseSuppressedListener) {
@@ -113,18 +116,18 @@
         if (!sWakeDisplaySensorState) {
             Log.d(TAG, "Wake display false. Pulse denied.");
             runIfNotNull(onPulseSuppressedListener);
-            DozeLog.tracePulseDropped(mContext, "wakeDisplaySensor");
+            mDozeLog.tracePulseDropped("wakeDisplaySensor");
             return;
         }
         mNotificationPulseTime = SystemClock.elapsedRealtime();
         if (!mConfig.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) {
             runIfNotNull(onPulseSuppressedListener);
-            DozeLog.tracePulseDropped(mContext, "pulseOnNotificationsDisabled");
+            mDozeLog.tracePulseDropped("pulseOnNotificationsDisabled");
             return;
         }
-        requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */,
+        requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */,
                 onPulseSuppressedListener);
-        DozeLog.traceNotificationPulse(mContext);
+        mDozeLog.traceNotificationPulse();
     }
 
     private static void runIfNotNull(Runnable runnable) {
@@ -145,8 +148,7 @@
             final long start = SystemClock.uptimeMillis();
             mProxCheck.check(PROXIMITY_TIMEOUT_DELAY_MS, near -> {
                 final long end = SystemClock.uptimeMillis();
-                DozeLog.traceProximityResult(
-                        mContext,
+                mDozeLog.traceProximityResult(
                         near == null ? false : near,
                         end - start,
                         reason);
@@ -159,12 +161,12 @@
 
     @VisibleForTesting
     void onSensor(int pulseReason, float screenX, float screenY, float[] rawValues) {
-        boolean isDoubleTap = pulseReason == DozeLog.REASON_SENSOR_DOUBLE_TAP;
-        boolean isTap = pulseReason == DozeLog.REASON_SENSOR_TAP;
-        boolean isPickup = pulseReason == DozeLog.REASON_SENSOR_PICKUP;
-        boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS;
-        boolean isWakeDisplay = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP;
-        boolean isWakeLockScreen = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
+        boolean isDoubleTap = pulseReason == DozeEvent.REASON_SENSOR_DOUBLE_TAP;
+        boolean isTap = pulseReason == DozeEvent.REASON_SENSOR_TAP;
+        boolean isPickup = pulseReason == DozeEvent.REASON_SENSOR_PICKUP;
+        boolean isLongPress = pulseReason == DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS;
+        boolean isWakeDisplay = pulseReason == DozeEvent.REASON_SENSOR_WAKE_UP;
+        boolean isWakeLockScreen = pulseReason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
         boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0;
 
         if (isWakeDisplay) {
@@ -201,7 +203,7 @@
                     SystemClock.elapsedRealtime() - mNotificationPulseTime;
             final boolean withinVibrationThreshold =
                     timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
-            DozeLog.tracePickupWakeUp(mContext, withinVibrationThreshold);
+            mDozeLog.tracePickupWakeUp(withinVibrationThreshold);
         }
     }
 
@@ -263,7 +265,7 @@
      *              transitions.
      */
     private void onWakeScreen(boolean wake, @Nullable DozeMachine.State state) {
-        DozeLog.traceWakeDisplay(wake);
+        mDozeLog.traceWakeDisplay(wake);
         sWakeDisplaySensorState = wake;
 
         if (wake) {
@@ -277,9 +279,9 @@
                     // Logs AOD open due to sensor wake up.
                     mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
                             .setType(MetricsEvent.TYPE_OPEN)
-                            .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP));
+                            .setSubtype(DozeEvent.REASON_SENSOR_WAKE_UP));
                 }
-            }, true /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP);
+            }, true /* alreadyPerformedProxCheck */, DozeEvent.REASON_SENSOR_WAKE_UP);
         } else {
             boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
             boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
@@ -288,7 +290,7 @@
                 // Logs AOD close due to sensor wake up.
                 mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
                         .setType(MetricsEvent.TYPE_CLOSE)
-                        .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP));
+                        .setSubtype(DozeEvent.REASON_SENSOR_WAKE_UP));
             }
         }
     }
@@ -361,14 +363,14 @@
         // When already pulsing we're allowed to show the wallpaper directly without
         // requesting a new pulse.
         if (mMachine.getState() == DozeMachine.State.DOZE_PULSING
-                && reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
+                && reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
             mMachine.requestState(DozeMachine.State.DOZE_PULSING_BRIGHT);
             return;
         }
 
         if (mPulsePending || !mAllowPulseTriggers || !canPulse()) {
             if (mAllowPulseTriggers) {
-                DozeLog.tracePulseDropped(mContext, mPulsePending, mMachine.getState(),
+                mDozeLog.tracePulseDropped(mPulsePending, mMachine.getState(),
                         mDozeHost.isPulsingBlocked());
             }
             runIfNotNull(onPulseSuppressedListener);
@@ -379,7 +381,7 @@
         proximityCheckThenCall((result) -> {
             if (result != null && result) {
                 // in pocket, abort pulse
-                DozeLog.tracePulseDropped(mContext, "inPocket");
+                mDozeLog.tracePulseDropped("inPocket");
                 mPulsePending = false;
                 runIfNotNull(onPulseSuppressedListener);
             } else {
@@ -401,7 +403,7 @@
     private void continuePulseRequest(int reason) {
         mPulsePending = false;
         if (mDozeHost.isPulsingBlocked() || !canPulse()) {
-            DozeLog.tracePulseDropped(mContext, mPulsePending, mMachine.getState(),
+            mDozeLog.tracePulseDropped(mPulsePending, mMachine.getState(),
                     mDozeHost.isPulsingBlocked());
             return;
         }
@@ -425,7 +427,7 @@
         public void onReceive(Context context, Intent intent) {
             if (PULSE_ACTION.equals(intent.getAction())) {
                 if (DozeMachine.DEBUG) Log.d(TAG, "Received pulse intent");
-                requestPulse(DozeLog.PULSE_REASON_INTENT, false, /* performedProxCheck */
+                requestPulse(DozeEvent.PULSE_REASON_INTENT, false, /* performedProxCheck */
                         null /* onPulseSupressedListener */);
             }
             if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 1f33af8..1cfe517 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -49,6 +49,7 @@
     private final AlarmTimeout mTimeTicker;
     private final boolean mCanAnimateTransition;
     private final DozeParameters mDozeParameters;
+    private final DozeLog mDozeLog;
 
     private boolean mKeyguardShowing;
     private final KeyguardUpdateMonitorCallback mKeyguardVisibilityCallback =
@@ -65,7 +66,8 @@
 
     public DozeUi(Context context, AlarmManager alarmManager, DozeMachine machine,
             WakeLock wakeLock, DozeHost host, Handler handler,
-            DozeParameters params, KeyguardUpdateMonitor keyguardUpdateMonitor) {
+            DozeParameters params, KeyguardUpdateMonitor keyguardUpdateMonitor,
+            DozeLog dozeLog) {
         mContext = context;
         mMachine = machine;
         mWakeLock = wakeLock;
@@ -75,6 +77,7 @@
         mDozeParameters = params;
         mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler);
         keyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
+        mDozeLog = dozeLog;
     }
 
     /**
@@ -96,7 +99,7 @@
                     public void onPulseStarted() {
                         try {
                             mMachine.requestState(
-                                    reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
+                                    reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
                                             ? DozeMachine.State.DOZE_PULSING_BRIGHT
                                             : DozeMachine.State.DOZE_PULSING);
                         } catch (IllegalStateException e) {
@@ -175,7 +178,7 @@
         long delta = roundToNextMinute(time) - System.currentTimeMillis();
         boolean scheduled = mTimeTicker.schedule(delta, AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
         if (scheduled) {
-            DozeLog.traceTimeTickScheduled(time, time + delta);
+            mDozeLog.traceTimeTickScheduled(time, time + delta);
         }
         mLastTimeTickElapsed = SystemClock.elapsedRealtime();
     }
@@ -192,7 +195,7 @@
         long millisSinceLastTick = SystemClock.elapsedRealtime() - mLastTimeTickElapsed;
         if (millisSinceLastTick > TIME_TICK_DEADLINE_MILLIS) {
             String delay = Formatter.formatShortElapsedTime(mContext, millisSinceLastTick);
-            DozeLog.traceMissedTick(delay);
+            mDozeLog.traceMissedTick(delay);
             Log.e(DozeMachine.TAG, "Missed AOD time tick by " + delay);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 60e381a..fe3c04e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -22,11 +22,14 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Dependency;
+import com.android.systemui.doze.DozeEvent;
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 
+import javax.inject.Inject;
+
 /**
  * Controller which handles all the doze animations of the scrims.
  */
@@ -34,6 +37,7 @@
     private static final String TAG = "DozeScrimController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
+    private final DozeLog mDozeLog;
     private final DozeParameters mDozeParameters;
     private final Handler mHandler = new Handler();
 
@@ -47,7 +51,7 @@
         public void onDisplayBlanked() {
             if (DEBUG) {
                 Log.d(TAG, "Pulse in, mDozing=" + mDozing + " mPulseReason="
-                        + DozeLog.reasonToString(mPulseReason));
+                        + DozeEvent.reasonToString(mPulseReason));
             }
             if (!mDozing) {
                 return;
@@ -68,8 +72,8 @@
             // Notifications should time out on their own.  Pulses due to notifications should
             // instead be managed externally based off the notification's lifetime.
             // Dock also controls the time out by self.
-            if (mPulseReason != DozeLog.PULSE_REASON_NOTIFICATION
-                    && mPulseReason != DozeLog.PULSE_REASON_DOCKING) {
+            if (mPulseReason != DozeEvent.PULSE_REASON_NOTIFICATION
+                    && mPulseReason != DozeEvent.PULSE_REASON_DOCKING) {
                 mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
                 mHandler.postDelayed(mPulseOutExtended,
                         mDozeParameters.getPulseVisibleDurationExtended());
@@ -90,14 +94,16 @@
          */
         @Override
         public boolean shouldTimeoutWallpaper() {
-            return mPulseReason == DozeLog.PULSE_REASON_DOCKING;
+            return mPulseReason == DozeEvent.PULSE_REASON_DOCKING;
         }
     };
 
-    public DozeScrimController(DozeParameters dozeParameters) {
+    @Inject
+    public DozeScrimController(DozeParameters dozeParameters, DozeLog dozeLog) {
         mDozeParameters = dozeParameters;
         //Never expected to be destroyed
         Dependency.get(StatusBarStateController.class).addCallback(this);
+        mDozeLog = dozeLog;
     }
 
     @VisibleForTesting
@@ -168,14 +174,14 @@
     }
 
     private void pulseStarted() {
-        DozeLog.tracePulseStart(mPulseReason);
+        mDozeLog.tracePulseStart(mPulseReason);
         if (mPulseCallback != null) {
             mPulseCallback.onPulseStarted();
         }
     }
 
     private void pulseFinished() {
-        DozeLog.tracePulseFinish();
+        mDozeLog.tracePulseFinish();
         if (mPulseCallback != null) {
             mPulseCallback.onPulseFinished();
             mPulseCallback = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 353a538..cee1d5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -68,6 +68,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.doze.DozeLog;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.FalsingManager;
@@ -459,8 +460,9 @@
             DynamicPrivacyController dynamicPrivacyController,
             KeyguardBypassController bypassController,
             FalsingManager falsingManager,
-            PluginManager pluginManager) {
-        super(context, attrs);
+            PluginManager pluginManager,
+            DozeLog dozeLog) {
+        super(context, attrs, falsingManager, dozeLog);
         setWillNotDraw(!DEBUG);
         mInjectionInflationController = injectionInflationController;
         mFalsingManager = falsingManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index ffaf3d5..432d636 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -111,6 +111,7 @@
     private FlingAnimationUtils mFlingAnimationUtilsClosing;
     private FlingAnimationUtils mFlingAnimationUtilsDismissing;
     private final FalsingManager mFalsingManager;
+    private final DozeLog mDozeLog;
     private final VibratorHelper mVibratorHelper;
 
     /**
@@ -204,7 +205,8 @@
         mJustPeeked = true;
     }
 
-    public PanelView(Context context, AttributeSet attrs) {
+    public PanelView(Context context, AttributeSet attrs, FalsingManager falsingManager,
+            DozeLog dozeLog) {
         super(context, attrs);
         mFlingAnimationUtils = new FlingAnimationUtils(context, 0.6f /* maxLengthSeconds */,
                 0.6f /* speedUpFactor */);
@@ -214,7 +216,8 @@
                 0.5f /* maxLengthSeconds */, 0.2f /* speedUpFactor */, 0.6f /* x2 */,
                 0.84f /* y2 */);
         mBounceInterpolator = new BounceInterpolator();
-        mFalsingManager = Dependency.get(FalsingManager.class);  // TODO: inject into a controller.
+        mFalsingManager = falsingManager;
+        mDozeLog = dozeLog;
         mNotificationsDragEnabled =
                 getResources().getBoolean(R.bool.config_enableNotificationShadeDrag);
         mVibratorHelper = Dependency.get(VibratorHelper.class);
@@ -477,7 +480,7 @@
             boolean expand = flingExpands(vel, vectorVel, x, y)
                     || event.getActionMasked() == MotionEvent.ACTION_CANCEL
                     || forceCancel;
-            DozeLog.traceFling(expand, mTouchAboveFalsingThreshold,
+            mDozeLog.traceFling(expand, mTouchAboveFalsingThreshold,
                     mStatusBar.isFalsingThresholdNeeded(),
                     mStatusBar.isWakeUpComingFromTouch());
                     // Log collapse gesture if on lock screen.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 7bab7f1..8150161 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -152,6 +152,7 @@
 import com.android.systemui.charging.WirelessChargingAnimation;
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.doze.DozeEvent;
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.doze.DozeReceiver;
@@ -370,6 +371,8 @@
 
     protected StatusBarIconController mIconController;
     @Inject
+    DozeLog mDozeLog;
+    @Inject
     InjectionInflationController mInjectionInflater;
     @Inject
     PulseExpansionHandler mPulseExpansionHandler;
@@ -968,7 +971,8 @@
                 mKeyguardStateController);
         mNotificationPanel.initDependencies(this, mGroupManager, mNotificationShelf,
                 mHeadsUpManager, mNotificationIconAreaController, mScrimController);
-        mDozeScrimController = new DozeScrimController(DozeParameters.getInstance(context));
+        mDozeScrimController = new DozeScrimController(DozeParameters.getInstance(context),
+                mDozeLog);
 
         BackDropView backdrop = mStatusBarWindow.findViewById(R.id.backdrop);
         mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
@@ -2377,7 +2381,7 @@
         final boolean lightWpTheme = mContext.getThemeResId() == R.style.Theme_SystemUI_Light;
         pw.println("    light wallpaper theme: " + lightWpTheme);
 
-        DozeLog.dump(pw);
+        mDozeLog.dump(pw);
 
         if (mBiometricUnlockController != null) {
             mBiometricUnlockController.dump(pw);
@@ -4003,7 +4007,7 @@
         public void startDozing() {
             if (!mDozingRequested) {
                 mDozingRequested = true;
-                DozeLog.traceDozing(mContext, mDozing);
+                mDozeLog.traceDozing(mDozing);
                 updateDozing();
                 updateIsKeyguard();
             }
@@ -4011,22 +4015,22 @@
 
         @Override
         public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
-            if (reason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS) {
+            if (reason == DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS) {
                 mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
                         "com.android.systemui:LONG_PRESS");
                 startAssist(new Bundle());
                 return;
             }
 
-            if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
+            if (reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
                 mScrimController.setWakeLockScreenSensorActive(true);
             }
 
-            if (reason == DozeLog.PULSE_REASON_DOCKING && mStatusBarWindow != null) {
+            if (reason == DozeEvent.PULSE_REASON_DOCKING && mStatusBarWindow != null) {
                 mStatusBarWindow.suppressWakeUpGesture(true);
             }
 
-            boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
+            boolean passiveAuthInterrupt = reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
                             && mWakeLockScreenPerformsAuth;
             // Set the state to pulsing, so ScrimController will know what to do once we ask it to
             // execute the transition. The pulse callback will then be invoked when the scrims
@@ -4077,7 +4081,7 @@
         public void stopDozing() {
             if (mDozingRequested) {
                 mDozingRequested = false;
-                DozeLog.traceDozing(mContext, mDozing);
+                mDozeLog.traceDozing(mDozing);
                 updateDozing();
             }
         }
@@ -4085,7 +4089,7 @@
         @Override
         public void onIgnoreTouchWhilePulsing(boolean ignore) {
             if (ignore != mIgnoreTouchWhilePulsing) {
-                DozeLog.tracePulseTouchDisabledByProx(mContext, ignore);
+                mDozeLog.tracePulseTouchDisabledByProx(ignore);
             }
             mIgnoreTouchWhilePulsing = ignore;
             if (isDozing() && ignore) {
@@ -4129,7 +4133,7 @@
 
         @Override
         public void extendPulse(int reason) {
-            if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
+            if (reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
                 mScrimController.setWakeLockScreenSensorActive(true);
             }
             if (mDozeScrimController.isPulsing() && mHeadsUpManager.hasNotifications()) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
index af2de1b..1ce0172 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
@@ -43,7 +43,6 @@
 import com.android.systemui.doze.DozeMachine.State;
 
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -58,12 +57,6 @@
     private Instrumentation mInstrumentation;
     private DockManagerFake mDockManagerFake;
 
-    @BeforeClass
-    public static void setupSuite() {
-        // We can't use KeyguardUpdateMonitor from tests.
-        DozeLog.setRegisterKeyguardCallback(false);
-    }
-
     @Before
     public void setUp() throws Exception {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
@@ -95,7 +88,7 @@
 
         mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED);
 
-        verify(mMachine).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING));
+        verify(mMachine).requestPulse(eq(DozeEvent.PULSE_REASON_DOCKING));
     }
 
     @Test
@@ -105,14 +98,14 @@
 
         mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED);
 
-        verify(mMachine).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING));
+        verify(mMachine).requestPulse(eq(DozeEvent.PULSE_REASON_DOCKING));
     }
 
     @Test
     public void testOnEvent_dockedHideWhenPulsing_requestPulseOut() {
         mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
         when(mMachine.getState()).thenReturn(State.DOZE_PULSING);
-        when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_DOCKING);
+        when(mMachine.getPulseReason()).thenReturn(DozeEvent.PULSE_REASON_DOCKING);
 
         mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED_HIDE);
 
@@ -123,7 +116,7 @@
     public void testOnEvent_undockedWhenPulsing_requestPulseOut() {
         mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
         when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_PULSING);
-        when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_DOCKING);
+        when(mMachine.getPulseReason()).thenReturn(DozeEvent.PULSE_REASON_DOCKING);
 
         mDockManagerFake.setDockEvent(DockManager.STATE_NONE);
 
@@ -161,7 +154,7 @@
 
         TestableLooper.get(this).processAllMessages();
 
-        verify(mMachine).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING));
+        verify(mMachine).requestPulse(eq(DozeEvent.PULSE_REASON_DOCKING));
     }
 
     @Test
@@ -174,7 +167,7 @@
 
         TestableLooper.get(this).processAllMessages();
 
-        verify(mMachine).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING));
+        verify(mMachine).requestPulse(eq(DozeEvent.PULSE_REASON_DOCKING));
     }
 
     @Test
@@ -186,7 +179,7 @@
 
         mDockHandler.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
 
-        verify(mMachine, never()).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING));
+        verify(mMachine, never()).requestPulse(eq(DozeEvent.PULSE_REASON_DOCKING));
     }
 
     @Test
@@ -205,7 +198,7 @@
     public void testTransitionToPulsing_whenDockedHide_requestPulseOut() {
         mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
         when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_PULSING);
-        when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_DOCKING);
+        when(mMachine.getPulseReason()).thenReturn(DozeEvent.PULSE_REASON_DOCKING);
         mDockManagerFake.setDockEvent(DockManager.STATE_DOCKED_HIDE);
 
         mDockHandler.transitionTo(DozeMachine.State.INITIALIZED, State.DOZE_PULSING);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 1e18e51..9d42b75 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -63,6 +63,8 @@
 
     @Mock
     private WakefulnessLifecycle mWakefulnessLifecycle;
+    @Mock
+    private DozeLog mDozeLog;
     private DozeServiceFake mServiceFake;
     private WakeLockFake mWakeLockFake;
     private AmbientDisplayConfiguration mConfigMock;
@@ -76,7 +78,9 @@
         mConfigMock = mock(AmbientDisplayConfiguration.class);
         mPartMock = mock(DozeMachine.Part.class);
 
-        mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake, mWakefulnessLifecycle);
+        mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake,
+                mWakefulnessLifecycle,
+                mDozeLog);
 
         mMachine.setParts(new DozeMachine.Part[]{mPartMock});
     }
@@ -112,7 +116,7 @@
     public void testPulseDone_goesToDoze() {
         when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
         mMachine.requestState(INITIALIZED);
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+        mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
         mMachine.requestState(DOZE_PULSING);
 
         mMachine.requestState(DOZE_PULSE_DONE);
@@ -125,7 +129,7 @@
     public void testPulseDone_goesToAoD() {
         when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
         mMachine.requestState(INITIALIZED);
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+        mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
         mMachine.requestState(DOZE_PULSING);
 
         mMachine.requestState(DOZE_PULSE_DONE);
@@ -169,7 +173,7 @@
     public void testWakeLock_heldInPulseStates() {
         mMachine.requestState(INITIALIZED);
 
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+        mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
         assertTrue(mWakeLockFake.isHeld());
 
         mMachine.requestState(DOZE_PULSING);
@@ -192,7 +196,7 @@
         mMachine.requestState(INITIALIZED);
 
         mMachine.requestState(DOZE);
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+        mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
         mMachine.requestState(DOZE_PULSING);
         mMachine.requestState(DOZE_PULSE_DONE);
 
@@ -204,9 +208,9 @@
         mMachine.requestState(INITIALIZED);
 
         mMachine.requestState(DOZE);
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+        mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
         mMachine.requestState(DOZE_PULSING);
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+        mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
         mMachine.requestState(DOZE_PULSE_DONE);
     }
 
@@ -215,7 +219,7 @@
         mMachine.requestState(INITIALIZED);
 
         mMachine.requestState(DOZE);
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+        mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
         mMachine.requestState(DOZE_PULSE_DONE);
     }
 
@@ -228,7 +232,7 @@
             return null;
         }).when(mPartMock).transitionTo(any(), eq(DOZE_REQUEST_PULSE));
 
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+        mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
 
         assertEquals(DOZE_PULSING, mMachine.getState());
     }
@@ -237,9 +241,9 @@
     public void testPulseReason_getMatchesRequest() {
         mMachine.requestState(INITIALIZED);
         mMachine.requestState(DOZE);
-        mMachine.requestPulse(DozeLog.REASON_SENSOR_DOUBLE_TAP);
+        mMachine.requestPulse(DozeEvent.REASON_SENSOR_DOUBLE_TAP);
 
-        assertEquals(DozeLog.REASON_SENSOR_DOUBLE_TAP, mMachine.getPulseReason());
+        assertEquals(DozeEvent.REASON_SENSOR_DOUBLE_TAP, mMachine.getPulseReason());
     }
 
     @Test
@@ -251,7 +255,7 @@
             if (newState == DOZE_REQUEST_PULSE
                     || newState == DOZE_PULSING
                     || newState == DOZE_PULSE_DONE) {
-                assertEquals(DozeLog.PULSE_REASON_NOTIFICATION, mMachine.getPulseReason());
+                assertEquals(DozeEvent.PULSE_REASON_NOTIFICATION, mMachine.getPulseReason());
             } else {
                 assertTrue("unexpected state " + newState,
                         newState == DOZE || newState == DOZE_AOD);
@@ -259,7 +263,7 @@
             return null;
         }).when(mPartMock).transitionTo(any(), any());
 
-        mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+        mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION);
         mMachine.requestState(DOZE_PULSING);
         mMachine.requestState(DOZE_PULSE_DONE);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index ddd1685..f2665ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -78,6 +78,8 @@
     private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy;
     @Mock
     private TriggerSensor mTriggerSensor;
+    @Mock
+    private DozeLog mDozeLog;
     private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener;
     private TestableLooper mTestableLooper;
     private DozeSensors mDozeSensors;
@@ -101,14 +103,14 @@
 
         mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class));
         mTestableLooper.processAllMessages();
-        verify(mCallback).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN),
+        verify(mCallback).onSensorPulse(eq(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN),
                 anyFloat(), anyFloat(), eq(null));
 
         mDozeSensors.requestTemporaryDisable();
         reset(mCallback);
         mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class));
         mTestableLooper.processAllMessages();
-        verify(mCallback, never()).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN),
+        verify(mCallback, never()).onSensorPulse(eq(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN),
                 anyFloat(), anyFloat(), eq(null));
     }
 
@@ -146,7 +148,7 @@
         TestableDozeSensors() {
             super(getContext(), mAlarmManager, mSensorManager, mDozeParameters,
                     mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback,
-                    mAlwaysOnDisplayPolicy);
+                    mAlwaysOnDisplayPolicy, mDozeLog);
             for (TriggerSensor sensor : mSensors) {
                 if (sensor instanceof PluginSensor
                         && ((PluginSensor) sensor).mPluginSensor.getType()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index b0e3969..e5ae6d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -48,7 +48,6 @@
 import com.android.systemui.util.wakelock.WakeLockFake;
 
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -64,12 +63,6 @@
     private DockManager mDockManagerFake;
     private FakeProximitySensor mProximitySensor;
 
-    @BeforeClass
-    public static void setupSuite() {
-        // We can't use KeyguardUpdateMonitor from tests.
-        DozeLog.setRegisterKeyguardCallback(false);
-    }
-
     @Before
     public void setUp() throws Exception {
         mMachine = mock(DozeMachine.class);
@@ -87,7 +80,7 @@
 
         mTriggers = new DozeTriggers(mContext, mMachine, mHost, alarmManager, config, parameters,
                 asyncSensorManager, Handler.createAsync(Looper.myLooper()), wakeLock, true,
-                mDockManagerFake, mProximitySensor);
+                mDockManagerFake, mProximitySensor, mock(DozeLog.class));
         waitForSensorManager();
     }
 
@@ -148,9 +141,10 @@
     @Test
     public void testProximitySensorNotAvailablel() {
         mProximitySensor.setSensorAvailable(false);
-        mTriggers.onSensor(DozeLog.PULSE_REASON_SENSOR_LONG_PRESS, 100, 100, null);
-        mTriggers.onSensor(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, 100, 100, new float[]{1});
-        mTriggers.onSensor(DozeLog.REASON_SENSOR_TAP, 100, 100, null);
+        mTriggers.onSensor(DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS, 100, 100, null);
+        mTriggers.onSensor(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, 100, 100,
+                new float[]{1});
+        mTriggers.onSensor(DozeEvent.REASON_SENSOR_TAP, 100, 100, null);
     }
 
     private void waitForSensorManager() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
index 25231bc..c5bddc1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
@@ -65,6 +65,8 @@
     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock
     private DozeHost mHost;
+    @Mock
+    private DozeLog mDozeLog;
     private WakeLockFake mWakeLock;
     private Handler mHandler;
     private HandlerThread mHandlerThread;
@@ -80,7 +82,7 @@
         mHandler = mHandlerThread.getThreadHandler();
 
         mDozeUi = new DozeUi(mContext, mAlarmManager, mMachine, mWakeLock, mHost, mHandler,
-                mDozeParameters, mKeyguardUpdateMonitor);
+                mDozeParameters, mKeyguardUpdateMonitor, mDozeLog);
     }
 
     @After
@@ -135,7 +137,7 @@
         reset(mHost);
         when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(true);
         mDozeUi = new DozeUi(mContext, mAlarmManager, mMachine, mWakeLock, mHost, mHandler,
-                mDozeParameters, mKeyguardUpdateMonitor);
+                mDozeParameters, mKeyguardUpdateMonitor, mDozeLog);
 
         // Never animate if display doesn't support it.
         mDozeUi.getKeyguardCallback().onKeyguardVisibilityChanged(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
index 20c739f..1ce336e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeScrimControllerTest.java
@@ -27,6 +27,7 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.doze.DozeHost;
+import com.android.systemui.doze.DozeLog;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -41,12 +42,14 @@
 
     @Mock
     private DozeParameters mDozeParameters;
+    @Mock
+    private DozeLog mDozeLog;
     private DozeScrimController mDozeScrimController;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        mDozeScrimController = new DozeScrimController(mDozeParameters);
+        mDozeScrimController = new DozeScrimController(mDozeParameters, mDozeLog);
         mDozeScrimController.setDozing(true);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 219aef1..b5ef716 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -40,6 +40,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.doze.DozeLog;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.plugins.PluginManager;
@@ -216,7 +217,7 @@
                             SystemUIFactory.getInstance().getRootComponent()),
                     coordinator, expansionHandler, mock(DynamicPrivacyController.class),
                     bypassController,
-                    mFalsingManager, mock(PluginManager.class));
+                    mFalsingManager, mock(PluginManager.class), mock(DozeLog.class));
             mNotificationStackScroller = mNotificationStackScrollLayout;
             mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
             mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index b75cb8c..9932a14 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -80,8 +80,8 @@
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.doze.DozeEvent;
 import com.android.systemui.doze.DozeHost;
-import com.android.systemui.doze.DozeLog;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
@@ -230,7 +230,6 @@
                 mExpansionStateLogger);
         mNotificationLogger.setVisibilityReporter(mock(Runnable.class));
         mDependency.injectTestDependency(NotificationLogger.class, mNotificationLogger);
-        DozeLog.traceDozing(mContext, false /* dozing */);
 
         mCommandQueue = mock(CommandQueue.class);
         when(mCommandQueue.asBinder()).thenReturn(new Binder());
@@ -652,7 +651,7 @@
 
         // Starting a pulse should change the scrim controller to the pulsing state
         mStatusBar.mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class),
-                DozeLog.PULSE_REASON_NOTIFICATION);
+                DozeEvent.PULSE_REASON_NOTIFICATION);
         verify(mScrimController).transitionTo(eq(ScrimState.PULSING), any());
 
         // Ending a pulse should take it back to keyguard state
@@ -663,21 +662,21 @@
     @Test
     public void testPulseWhileDozing_notifyAuthInterrupt() {
         HashSet<Integer> reasonsWantingAuth = new HashSet<>(
-                Collections.singletonList(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN));
+                Collections.singletonList(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN));
         HashSet<Integer> reasonsSkippingAuth = new HashSet<>(
-                Arrays.asList(DozeLog.PULSE_REASON_INTENT,
-                        DozeLog.PULSE_REASON_NOTIFICATION,
-                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION,
-                        DozeLog.REASON_SENSOR_PICKUP,
-                        DozeLog.REASON_SENSOR_DOUBLE_TAP,
-                        DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
-                        DozeLog.PULSE_REASON_DOCKING,
-                        DozeLog.REASON_SENSOR_WAKE_UP,
-                        DozeLog.REASON_SENSOR_TAP));
+                Arrays.asList(DozeEvent.PULSE_REASON_INTENT,
+                        DozeEvent.PULSE_REASON_NOTIFICATION,
+                        DozeEvent.PULSE_REASON_SENSOR_SIGMOTION,
+                        DozeEvent.REASON_SENSOR_PICKUP,
+                        DozeEvent.REASON_SENSOR_DOUBLE_TAP,
+                        DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS,
+                        DozeEvent.PULSE_REASON_DOCKING,
+                        DozeEvent.REASON_SENSOR_WAKE_UP,
+                        DozeEvent.REASON_SENSOR_TAP));
         HashSet<Integer> reasonsThatDontPulse = new HashSet<>(
-                Arrays.asList(DozeLog.REASON_SENSOR_PICKUP,
-                        DozeLog.REASON_SENSOR_DOUBLE_TAP,
-                        DozeLog.REASON_SENSOR_TAP));
+                Arrays.asList(DozeEvent.REASON_SENSOR_PICKUP,
+                        DozeEvent.REASON_SENSOR_DOUBLE_TAP,
+                        DozeEvent.REASON_SENSOR_TAP));
 
         doAnswer(invocation -> {
             DozeHost.PulseCallback callback = invocation.getArgument(0);
@@ -686,7 +685,7 @@
         }).when(mDozeScrimController).pulse(any(), anyInt());
 
         mStatusBar.mDozeServiceHost.mWakeLockScreenPerformsAuth = true;
-        for (int i = 0; i < DozeLog.REASONS; i++) {
+        for (int i = 0; i < DozeEvent.TOTAL_REASONS; i++) {
             reset(mKeyguardUpdateMonitor);
             mStatusBar.mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class), i);
             if (reasonsWantingAuth.contains(i)) {
@@ -711,7 +710,7 @@
 
         // Starting a pulse while docking should suppress wakeup gesture
         mStatusBar.mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class),
-                DozeLog.PULSE_REASON_DOCKING);
+                DozeEvent.PULSE_REASON_DOCKING);
         verify(mStatusBarWindowView).suppressWakeUpGesture(eq(true));
 
         // Ending a pulse should restore wakeup gesture