am 933e8411: Merge "When dozing, re-enable falsing threshold and log events." into lmp-dev

* commit '933e841121f91329bd4273cbffe1ed510db76314':
  When dozing, re-enable falsing threshold and log events.
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 33cab8f..2b40903 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -146,7 +146,7 @@
     /**
      * Called when the emergency call button is pressed.
      */
-    void onEmergencyCallAction() { }
+    public void onEmergencyCallAction() { }
 
     /**
      * Called when the transport background changes.
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
new file mode 100644
index 0000000..3bf86a0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2014 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.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 java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DozeLog {
+    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;
+    private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+
+    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;
+
+    public static void tracePickupPulse(boolean withinVibrationThreshold) {
+        if (!ENABLED) return;
+        log("pickupPulse withinVibrationThreshold=" + withinVibrationThreshold);
+        (withinVibrationThreshold ? sPickupPulseNearVibrationStats
+                : sPickupPulseNotNearVibrationStats).append();
+    }
+
+    public static void tracePulseStart() {
+        if (!ENABLED) return;
+        sPulsing = true;
+        log("pulseStart");
+    }
+
+    public static void tracePulseFinish() {
+        if (!ENABLED) return;
+        sPulsing = false;
+        log("pulseFinish");
+    }
+
+    public static void traceNotificationPulse(long instance) {
+        if (!ENABLED) return;
+        log("notificationPulse instance=" + instance);
+        sNotificationPulseStats.append();
+    }
+
+    public static void traceDozing(Context context, boolean dozing) {
+        if (!ENABLED) return;
+        sPulsing = false;
+        synchronized (DozeLog.class) {
+            if (dozing && 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();
+                log("init");
+                KeyguardUpdateMonitor.getInstance(context)
+                        .registerCallback(new KeyguardUpdateMonitorCallback() {
+                    @Override
+                    public void onEmergencyCallAction() {
+                        traceEmergencyCall();
+                    }
+                    @Override
+                    public void onKeyguardBouncerChanged(boolean bouncer) {
+                        traceKeyguardBouncerChanged(bouncer);
+                    }
+                    @Override
+                    public void onScreenTurnedOn() {
+                        traceScreenOn();
+                    }
+                    @Override
+                    public void onScreenTurnedOff(int why) {
+                        traceScreenOff(why);
+                    }
+                    @Override
+                    public void onKeyguardVisibilityChanged(boolean showing) {
+                        traceKeyguard(showing);
+                    }
+                });
+            }
+        }
+        log("dozing " + dozing);
+    }
+
+    public static void traceFling(boolean expand, boolean aboveThreshold, boolean thresholdNeeded) {
+        if (!ENABLED) return;
+        log("fling expand=" + expand + " aboveThreshold=" + aboveThreshold + " thresholdNeeded="
+                + thresholdNeeded);
+    }
+
+    public static void traceEmergencyCall() {
+        if (!ENABLED) return;
+        log("emergencyCall");
+    }
+
+    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 traceKeyguard(boolean showing) {
+        if (!ENABLED) return;
+        log("keyguard " + showing);
+        if (!showing) {
+            sPulsing = false;
+        }
+    }
+
+    public static 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]);
+            }
+            pw.print("  Doze summary stats (for ");
+            TimeUtils.formatDuration(System.currentTimeMillis() - sSince, 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");
+        }
+    }
+
+    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 static class SummaryStats {
+        private int mCount;
+
+        public void append() {
+            mCount++;
+        }
+
+        public void dump(PrintWriter pw, String type) {
+            pw.print("    ");
+            pw.print(type);
+            pw.print(": n=");
+            pw.print(mCount);
+            pw.print(" (");
+            final double perHr = (double) mCount / (System.currentTimeMillis() - sSince)
+                    * 1000 * 60 * 60;
+            pw.print(perHr);
+            pw.print("/hr)");
+            pw.println();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index e2c8ff9..e429801 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -49,6 +49,7 @@
     private static final String ACTION_BASE = "com.android.systemui.doze";
     private static final String PULSE_ACTION = ACTION_BASE + ".pulse";
     private static final String NOTIFICATION_PULSE_ACTION = ACTION_BASE + ".notification_pulse";
+    private static final String EXTRA_INSTANCE = "instance";
 
     private final String mTag = String.format(TAG + ".%08x", hashCode());
     private final Context mContext = this;
@@ -67,7 +68,6 @@
     private boolean mDisplayStateSupported;
     private int mDisplayStateWhenOn;
     private boolean mNotificationLightOn;
-    private PendingIntent mNotificationPulseIntent;
     private boolean mPowerSaveActive;
     private long mNotificationPulseTime;
     private int mScheduleResetsRemaining;
@@ -115,9 +115,6 @@
         mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         mDisplayStateSupported = mDozeParameters.getDisplayStateSupported();
-        mNotificationPulseIntent = PendingIntent.getBroadcast(mContext, 0,
-                new Intent(NOTIFICATION_PULSE_ACTION).setPackage(getPackageName()),
-                PendingIntent.FLAG_UPDATE_CURRENT);
         mDisplayStateWhenOn = mDisplayStateSupported ? Display.STATE_DOZE : Display.STATE_ON;
         mDisplayOff.run();
     }
@@ -257,9 +254,17 @@
         rescheduleNotificationPulse(true /*predicate*/);
     }
 
+    private PendingIntent notificationPulseIntent(long instance) {
+        return PendingIntent.getBroadcast(mContext, 0,
+                new Intent(NOTIFICATION_PULSE_ACTION).setPackage(getPackageName())
+                        .putExtra(EXTRA_INSTANCE, instance),
+                PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+
     private void rescheduleNotificationPulse(boolean predicate) {
         if (DEBUG) Log.d(TAG, "rescheduleNotificationPulse predicate=" + predicate);
-        mAlarmManager.cancel(mNotificationPulseIntent);
+        final PendingIntent notificationPulseIntent = notificationPulseIntent(0);
+        mAlarmManager.cancel(notificationPulseIntent);
         if (!predicate) {
             if (DEBUG) Log.d(TAG, "  don't reschedule: predicate is false");
             return;
@@ -280,8 +285,10 @@
             if (DEBUG) Log.d(TAG, "  don't reschedule: delta is " + delta);
             return;
         }
-        if (DEBUG) Log.d(TAG, "Scheduling pulse in " + delta + "ms for " + new Date(time));
-        mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent);
+        final long instance = time - mNotificationPulseTime;
+        if (DEBUG) Log.d(TAG, "Scheduling pulse " + instance + " in " + delta + "ms for "
+                + new Date(time));
+        mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, notificationPulseIntent(instance));
     }
 
     private static String triggerEventToString(TriggerEvent event) {
@@ -313,7 +320,9 @@
                 requestPulse();
             }
             if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) {
-                if (DEBUG) Log.d(mTag, "Received notification pulse intent");
+                final long instance = intent.getLongExtra(EXTRA_INSTANCE, -1);
+                if (DEBUG) Log.d(mTag, "Received notification pulse intent instance=" + instance);
+                DozeLog.traceNotificationPulse(instance);
                 requestPulse();
                 rescheduleNotificationPulse(mNotificationLightOn);
             }
@@ -415,11 +424,16 @@
             // reset the notification pulse schedule, but only if we think we were not triggered
             // by a notification-related vibration
             final long timeSinceNotification = System.currentTimeMillis() - mNotificationPulseTime;
-            if (timeSinceNotification < mDozeParameters.getPickupVibrationThreshold()) {
+            final boolean withinVibrationThreshold =
+                    timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
+            if (withinVibrationThreshold) {
                if (DEBUG) Log.d(mTag, "Not resetting schedule, recent notification");
             } else {
                 resetNotificationResets();
             }
+            if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
+                DozeLog.tracePickupPulse(withinVibrationThreshold);
+            }
         }
     }
 }
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 873d528..67c7723 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -33,6 +33,7 @@
 import android.widget.FrameLayout;
 
 import com.android.systemui.R;
+import com.android.systemui.doze.DozeLog;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.StatusBarState;
 
@@ -347,6 +348,8 @@
                     if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
                         Log.i(TAG, "Flinging: expand=" + expand);
                     }
+                    DozeLog.traceFling(expand, mTouchAboveFalsingThreshold,
+                            mStatusBar.isFalsingThresholdNeeded());
                     fling(vel, expand);
                     mUpdateFlingOnLayout = expand && mPanelClosedOnDown && !mHasLayoutedSinceDown;
                     if (mUpdateFlingOnLayout) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 353c887..624fea5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -115,6 +115,7 @@
 import com.android.systemui.EventLogTags;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
+import com.android.systemui.doze.DozeLog;
 import com.android.systemui.doze.DozeService;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.qs.QSPanel;
@@ -2101,8 +2102,8 @@
 
     public boolean isFalsingThresholdNeeded() {
         boolean onKeyguard = getBarState() == StatusBarState.KEYGUARD;
-        boolean isMethodInSecure = mUnlockMethodCache.isMethodInsecure();
-        return onKeyguard && isMethodInSecure;
+        boolean isMethodInsecure = mUnlockMethodCache.isMethodInsecure();
+        return onKeyguard && (isMethodInsecure || mDozing);
     }
 
     @Override  // NotificationData.Environment
@@ -2874,6 +2875,8 @@
             mNotificationPanel.dump(fd, pw, args);
         }
 
+        DozeLog.dump(pw);
+
         if (DUMPTRUCK) {
             synchronized (mNotificationData) {
                 mNotificationData.dump(pw, "  ");
@@ -4108,6 +4111,7 @@
             mCurrentDozeService = dozeService;
             if (!mDozing) {
                 mDozing = true;
+                DozeLog.traceDozing(mContext, mDozing);
                 updateDozingState();
             }
             mCurrentDozeService.startDozing();
@@ -4125,6 +4129,7 @@
             }
             if (mDozing) {
                 mDozing = false;
+                DozeLog.traceDozing(mContext, mDozing);
                 updateDozingState();
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 3ff11d2..ddb03e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -30,6 +30,7 @@
 import android.view.animation.Interpolator;
 
 import com.android.systemui.R;
+import com.android.systemui.doze.DozeLog;
 
 /**
  * Controls both the scrim behind the notifications and in front of the notifications (when a
@@ -309,6 +310,7 @@
         public void run() {
             if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing);
             if (!mDozing) return;
+            DozeLog.tracePulseStart();
             mDurationOverride = mDozeParameters.getPulseInDuration();
             mAnimationDelay = 0;
             mAnimateChange = true;
@@ -343,6 +345,7 @@
         @Override
         public void run() {
             if (DEBUG) Log.d(TAG, "Pulse out finished");
+            DozeLog.tracePulseFinish();
             mPulseEndTime = 0;
         }
     };