When dozing, re-enable falsing threshold and log events.
- Reactivate our configured keyguard falsing swipe threshold for secure keyguards, but only when dozing. - Add DozeLog helper to capture/maintain interesting events about the doze + unlock process, enabled by default, but only on devices that start dozing at least once. - Dump summary counts + logged events to dumpsys output. - Pass notification pulse "instance" as an extra to the scheduled intent, so we can log accordingly. Bug:17496795 Change-Id: I7e88f93bfc967bdc06550cf1fe5e74d535edd774
This commit is contained in:
@@ -146,7 +146,7 @@ public class KeyguardUpdateMonitorCallback {
|
||||
/**
|
||||
* Called when the emergency call button is pressed.
|
||||
*/
|
||||
void onEmergencyCallAction() { }
|
||||
public void onEmergencyCallAction() { }
|
||||
|
||||
/**
|
||||
* Called when the transport background changes.
|
||||
|
||||
211
packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
Normal file
211
packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ public class DozeService extends DreamService {
|
||||
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 @@ public class DozeService extends DreamService {
|
||||
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 @@ public class DozeService extends DreamService {
|
||||
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 @@ public class DozeService extends DreamService {
|
||||
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 @@ public class DozeService extends DreamService {
|
||||
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 @@ public class DozeService extends DreamService {
|
||||
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 @@ public class DozeService extends DreamService {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.view.animation.Interpolator;
|
||||
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 @@ public abstract class PanelView extends FrameLayout {
|
||||
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) {
|
||||
|
||||
@@ -115,6 +115,7 @@ import com.android.systemui.DemoMode;
|
||||
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 class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
|
||||
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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mNotificationPanel.dump(fd, pw, args);
|
||||
}
|
||||
|
||||
DozeLog.dump(pw);
|
||||
|
||||
if (DUMPTRUCK) {
|
||||
synchronized (mNotificationData) {
|
||||
mNotificationData.dump(pw, " ");
|
||||
@@ -4108,6 +4111,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mCurrentDozeService = dozeService;
|
||||
if (!mDozing) {
|
||||
mDozing = true;
|
||||
DozeLog.traceDozing(mContext, mDozing);
|
||||
updateDozingState();
|
||||
}
|
||||
mCurrentDozeService.startDozing();
|
||||
@@ -4125,6 +4129,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
if (mDozing) {
|
||||
mDozing = false;
|
||||
DozeLog.traceDozing(mContext, mDozing);
|
||||
updateDozingState();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.view.animation.DecelerateInterpolator;
|
||||
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 class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
||||
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 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
||||
@Override
|
||||
public void run() {
|
||||
if (DEBUG) Log.d(TAG, "Pulse out finished");
|
||||
DozeLog.tracePulseFinish();
|
||||
mPulseEndTime = 0;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user