summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src/com')
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeHost.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeService.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java75
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/Recents.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java126
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java272
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java182
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java59
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java111
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java14
35 files changed, 891 insertions, 296 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 89a2c74..82a1bfe 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -29,6 +29,7 @@ public interface DozeHost {
void stopDozing();
boolean isPowerSaveActive();
boolean isNotificationLightOn();
+ boolean isPulsingBlocked();
public interface Callback {
void onNewNotifications();
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 887391c..630d735 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -255,6 +255,11 @@ public class DozeService extends DreamService {
}
private void continuePulsing(int reason) {
+ if (mHost.isPulsingBlocked()) {
+ mPulsing = false;
+ mWakeLock.release();
+ return;
+ }
mHost.pulseWhileDozing(new DozeHost.PulseCallback() {
@Override
public void onPulseStarted() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index d78800f..d2c60ef 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -80,7 +80,8 @@ public class KeyguardService extends Service {
@Override // Binder interface
public void keyguardDone(boolean authenticated, boolean wakeup) {
checkPermission();
- mKeyguardViewMediator.keyguardDone(authenticated, wakeup);
+ // TODO: Remove wakeup
+ mKeyguardViewMediator.keyguardDone(authenticated);
}
@Override // Binder interface
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index a1c8b1a..647b272 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -68,6 +68,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.SystemUI;
+import com.android.systemui.statusbar.phone.FingerprintUnlockController;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -176,11 +177,6 @@ public class KeyguardViewMediator extends SystemUI {
*/
private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics";
- /**
- * How much faster we collapse the lockscreen when authenticating with fingerprint.
- */
- private static final float FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR = 1.3f;
-
/** The stream type that the lock sounds are tied to. */
private int mUiSoundsStreamType;
@@ -458,30 +454,6 @@ public class KeyguardViewMediator extends SystemUI {
break;
}
}
-
- @Override
- public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
- boolean unlockingWithFingerprintAllowed =
- mUpdateMonitor.isUnlockingWithFingerprintAllowed();
- if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
- if (unlockingWithFingerprintAllowed) {
- mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated();
- }
- } else {
- if (wakeAndUnlocking && mShowing && unlockingWithFingerprintAllowed) {
- mWakeAndUnlocking = true;
- mStatusBarKeyguardViewManager.setWakeAndUnlocking();
- keyguardDone(true, true);
- } else if (mShowing && mDeviceInteractive) {
- if (wakeAndUnlocking) {
- mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
- }
- mStatusBarKeyguardViewManager.animateCollapsePanels(
- FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
- }
- }
- };
-
};
ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
@@ -490,9 +462,12 @@ public class KeyguardViewMediator extends SystemUI {
KeyguardViewMediator.this.userActivity();
}
- public void keyguardDone(boolean authenticated) {
+ public void keyguardDone(boolean strongAuth) {
if (!mKeyguardDonePending) {
- KeyguardViewMediator.this.keyguardDone(authenticated, true);
+ KeyguardViewMediator.this.keyguardDone(true /* authenticated */);
+ }
+ if (strongAuth) {
+ mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
}
}
@@ -506,12 +481,15 @@ public class KeyguardViewMediator extends SystemUI {
}
@Override
- public void keyguardDonePending() {
+ public void keyguardDonePending(boolean strongAuth) {
mKeyguardDonePending = true;
mHideAnimationRun = true;
mStatusBarKeyguardViewManager.startPreHideAnimation(null /* finishRunnable */);
mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT,
KEYGUARD_DONE_PENDING_TIMEOUT_MS);
+ if (strongAuth) {
+ mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
+ }
}
@Override
@@ -524,7 +502,7 @@ public class KeyguardViewMediator extends SystemUI {
if (mKeyguardDonePending) {
// Somebody has called keyguardDonePending before, which means that we are
// authenticated
- KeyguardViewMediator.this.keyguardDone(true /* authenticated */, true /* wakeUp */);
+ KeyguardViewMediator.this.keyguardDone(true /* authenticated */);
}
}
@@ -552,9 +530,12 @@ public class KeyguardViewMediator extends SystemUI {
public int getBouncerPromptReason() {
int currentUser = ActivityManager.getCurrentUser();
if ((mUpdateMonitor.getUserTrustIsManaged(currentUser)
- || mUpdateMonitor.isUnlockWithFingerPrintPossible(currentUser))
- && !mTrustManager.hasUserAuthenticatedSinceBoot(currentUser)) {
+ || mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser))
+ && !mUpdateMonitor.getStrongAuthTracker().hasUserAuthenticatedSinceBoot()) {
return KeyguardSecurityView.PROMPT_REASON_RESTART;
+ } else if (mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser)
+ && mUpdateMonitor.hasFingerprintUnlockTimedOut(currentUser)) {
+ return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
}
return KeyguardSecurityView.PROMPT_REASON_NONE;
}
@@ -1189,10 +1170,10 @@ public class KeyguardViewMediator extends SystemUI {
}
};
- public void keyguardDone(boolean authenticated, boolean wakeup) {
- if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")");
+ public void keyguardDone(boolean authenticated) {
+ if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated +")");
EventLog.writeEvent(70000, 2);
- Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0, wakeup ? 1 : 0);
+ Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0);
mHandler.sendMessage(msg);
}
@@ -1235,14 +1216,11 @@ public class KeyguardViewMediator extends SystemUI {
handleNotifyStartedWakingUp();
break;
case KEYGUARD_DONE:
- handleKeyguardDone(msg.arg1 != 0, msg.arg2 != 0);
+ handleKeyguardDone(msg.arg1 != 0);
break;
case KEYGUARD_DONE_DRAWING:
handleKeyguardDoneDrawing();
break;
- case KEYGUARD_DONE_AUTHENTICATING:
- keyguardDone(true, true);
- break;
case SET_OCCLUDED:
handleSetOccluded(msg.arg1 != 0);
break;
@@ -1272,7 +1250,7 @@ public class KeyguardViewMediator extends SystemUI {
* @see #keyguardDone
* @see #KEYGUARD_DONE
*/
- private void handleKeyguardDone(boolean authenticated, boolean wakeup) {
+ private void handleKeyguardDone(boolean authenticated) {
if (DEBUG) Log.d(TAG, "handleKeyguardDone");
synchronized (this) {
resetKeyguardDonePendingLocked();
@@ -1586,6 +1564,7 @@ public class KeyguardViewMediator extends SystemUI {
synchronized (this) {
if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOff");
mStatusBarKeyguardViewManager.onScreenTurnedOff();
+ mWakeAndUnlocking = false;
}
}
@@ -1612,11 +1591,17 @@ public class KeyguardViewMediator extends SystemUI {
}
}
+ public void onWakeAndUnlocking() {
+ mWakeAndUnlocking = true;
+ keyguardDone(true /* authenticated */);
+ }
+
public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar,
ViewGroup container, StatusBarWindowManager statusBarWindowManager,
- ScrimController scrimController) {
+ ScrimController scrimController,
+ FingerprintUnlockController fingerprintUnlockController) {
mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container,
- statusBarWindowManager, scrimController);
+ statusBarWindowManager, scrimController, fingerprintUnlockController);
return mStatusBarKeyguardViewManager;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java b/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java
index f36019b..e64f6a0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java
@@ -21,7 +21,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SharedPreferences;
import com.android.systemui.Prefs;
import com.android.systemui.R;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 8c2ac88..f1550a0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -20,7 +20,6 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ITaskStackListener;
-import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index b47fb30..d0876fa 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -33,7 +33,6 @@ import android.view.View;
import android.view.ViewStub;
import android.widget.Toast;
-import com.android.internal.logging.MetricsConstants;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Prefs;
import com.android.systemui.R;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 298a1cc..d5c9253 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -20,10 +20,8 @@ import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.AppGlobals;
-import android.app.IActivityContainer;
import android.app.IActivityManager;
import android.app.ITaskStackListener;
-import android.app.SearchManager;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
@@ -54,15 +52,12 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
-import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
import android.util.MutableBoolean;
import android.util.Pair;
import android.util.SparseArray;
import android.view.Display;
-import android.view.DisplayInfo;
-import android.view.SurfaceControl;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -71,7 +66,6 @@ import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsAppWidgetHost;
import java.io.IOException;
import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 403af70..7f17885 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -350,6 +350,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
} else {
updateBackground();
}
+ setOutlineAlpha(dark ? 0f : 1f);
}
public void setShowingLegacyBackground(boolean showing) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 7065343..c14f215 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -90,6 +90,7 @@ import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.util.NotificationColorUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.DejankUtils;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SwipeHelper;
@@ -167,13 +168,7 @@ public abstract class BaseStatusBar extends SystemUI implements
// on-screen navigation buttons
protected NavigationBarView mNavigationBarView = null;
- protected Boolean mScreenOn;
-
- // The second field is a bit different from the first one because it only listens to screen on/
- // screen of events from Keyguard. We need this so we don't have a race condition with the
- // broadcast. In the future, we should remove the first field altogether and rename the second
- // field.
- protected boolean mScreenOnFromKeyguard;
+ protected boolean mDeviceInteractive;
protected boolean mVisible;
@@ -1512,6 +1507,15 @@ public abstract class BaseStatusBar extends SystemUI implements
final PendingIntent intent = sbn.getNotification().contentIntent;
final String notificationKey = sbn.getKey();
+ // Mark notification for one frame.
+ row.setJustClicked(true);
+ DejankUtils.postAfterTraversal(new Runnable() {
+ @Override
+ public void run() {
+ row.setJustClicked(false);
+ }
+ });
+
if (NOTIFICATION_CLICK_DEBUG) {
Log.d(TAG, "Clicked on content of " + notificationKey);
}
@@ -1619,7 +1623,7 @@ public abstract class BaseStatusBar extends SystemUI implements
protected void updateVisibleToUser() {
boolean oldVisibleToUser = mVisibleToUser;
- mVisibleToUser = mVisible && mScreenOnFromKeyguard;
+ mVisibleToUser = mVisible && mDeviceInteractive;
if (oldVisibleToUser != mVisibleToUser) {
handleVisibleToUserChanged(mVisibleToUser);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index b88e5ca..5f01306 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -24,6 +24,7 @@ import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.RippleDrawable;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -110,6 +111,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
}
};
+ private boolean mJustClicked;
+
public NotificationContentView getPrivateLayout() {
return mPrivateLayout;
}
@@ -301,6 +304,21 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
return mHeadsUpHeight;
}
+ /**
+ * Mark whether this notification was just clicked, i.e. the user has just clicked this
+ * notification in this frame.
+ */
+ public void setJustClicked(boolean justClicked) {
+ mJustClicked = justClicked;
+ }
+
+ /**
+ * @return true if this notification has been clicked in this frame, false otherwise
+ */
+ public boolean wasJustClicked() {
+ return mJustClicked;
+ }
+
public interface ExpansionLogger {
public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index d77e050..a6fc4bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -34,6 +34,7 @@ public abstract class ExpandableOutlineView extends ExpandableView {
private final Rect mOutlineRect = new Rect();
protected final int mRoundedRectCornerRadius;
private boolean mCustomOutline;
+ private float mOutlineAlpha = 1f;
public ExpandableOutlineView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -50,6 +51,7 @@ public abstract class ExpandableOutlineView extends ExpandableView {
} else {
outline.setRoundRect(mOutlineRect, mRoundedRectCornerRadius);
}
+ outline.setAlpha(mOutlineAlpha);
}
});
}
@@ -66,6 +68,11 @@ public abstract class ExpandableOutlineView extends ExpandableView {
invalidateOutline();
}
+ protected void setOutlineAlpha(float alpha) {
+ mOutlineAlpha = alpha;
+ invalidateOutline();
+ }
+
protected void setOutlineRect(RectF rect) {
if (rect != null) {
setOutlineRect(rect.left, rect.top, rect.right, rect.bottom);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 07a055c..54f91da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -16,17 +16,13 @@
package com.android.systemui.statusbar;
-import com.android.internal.app.IBatteryStats;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Resources;
import android.graphics.Color;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.Handler;
@@ -39,19 +35,35 @@ import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
+import com.android.internal.app.IBatteryStats;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
+import com.android.systemui.statusbar.phone.LockIcon;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+
/**
- * Controls the little text indicator on the keyguard.
+ * Controls the indications and error messages shown on the Keyguard
*/
public class KeyguardIndicationController {
private static final String TAG = "KeyguardIndicationController";
+ private static final boolean DEBUG_CHARGING_CURRENT = false;
private static final int MSG_HIDE_TRANSIENT = 1;
+ private static final int MSG_CLEAR_FP_MSG = 2;
+ private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
private final Context mContext;
private final KeyguardIndicationTextView mTextView;
private final IBatteryStats mBatteryInfo;
+ private final int mSlowThreshold;
+ private final int mFastThreshold;
+ private final LockIcon mLockIcon;
+ private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+
private String mRestingIndication;
private String mTransientIndication;
private int mTransientTextColor;
@@ -59,10 +71,20 @@ public class KeyguardIndicationController {
private boolean mPowerPluggedIn;
private boolean mPowerCharged;
+ private int mChargingSpeed;
+ private int mChargingCurrent;
+ private String mMessageToShowOnScreenOn;
- public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView) {
+ public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView,
+ LockIcon lockIcon) {
mContext = context;
mTextView = textView;
+ mLockIcon = lockIcon;
+
+ Resources res = context.getResources();
+ mSlowThreshold = res.getInteger(R.integer.config_chargingSlowlyThreshold);
+ mFastThreshold = res.getInteger(R.integer.config_chargingFastThreshold);
+
mBatteryInfo = IBatteryStats.Stub.asInterface(
ServiceManager.getService(BatteryStats.SERVICE_NAME));
@@ -150,7 +172,11 @@ public class KeyguardIndicationController {
return mTransientIndication;
}
if (mPowerPluggedIn) {
- return computePowerIndication();
+ String indication = computePowerIndication();
+ if (DEBUG_CHARGING_CURRENT) {
+ indication += ", " + (mChargingCurrent / 1000) + " mA";
+ }
+ return indication;
}
return mRestingIndication;
}
@@ -174,7 +200,19 @@ public class KeyguardIndicationController {
}
// Fall back to simple charging label.
- return mContext.getResources().getString(R.string.keyguard_plugged_in);
+ int chargingId;
+ switch (mChargingSpeed) {
+ case KeyguardUpdateMonitor.BatteryStatus.CHARGING_FAST:
+ chargingId = R.string.keyguard_plugged_in_charging_fast;
+ break;
+ case KeyguardUpdateMonitor.BatteryStatus.CHARGING_SLOWLY:
+ chargingId = R.string.keyguard_plugged_in_charging_slowly;
+ break;
+ default:
+ chargingId = R.string.keyguard_plugged_in;
+ break;
+ }
+ return mContext.getResources().getString(chargingId);
}
KeyguardUpdateMonitorCallback mUpdateMonitor = new KeyguardUpdateMonitorCallback() {
@@ -184,8 +222,68 @@ public class KeyguardIndicationController {
|| status.status == BatteryManager.BATTERY_STATUS_FULL;
mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
mPowerCharged = status.isCharged();
+ mChargingCurrent = status.maxChargingCurrent;
+ mChargingSpeed = status.getChargingSpeed(mSlowThreshold, mFastThreshold);
updateIndication();
}
+
+ @Override
+ public void onFingerprintHelp(int msgId, String helpString) {
+ KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+ if (!updateMonitor.isUnlockingWithFingerprintAllowed()) {
+ return;
+ }
+ int errorColor = mContext.getResources().getColor(R.color.system_warning_color, null);
+ if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+ mStatusBarKeyguardViewManager.showBouncerMessage(helpString, errorColor);
+ } else if (updateMonitor.isDeviceInteractive()) {
+ mLockIcon.setTransientFpError(true);
+ showTransientIndication(helpString, errorColor);
+ mHandler.removeMessages(MSG_CLEAR_FP_MSG);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_FP_MSG),
+ TRANSIENT_FP_ERROR_TIMEOUT);
+ }
+ }
+
+ @Override
+ public void onFingerprintError(int msgId, String errString) {
+ KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+ if (!updateMonitor.isUnlockingWithFingerprintAllowed()
+ || msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
+ return;
+ }
+ int errorColor = mContext.getResources().getColor(R.color.system_warning_color, null);
+ if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+ mStatusBarKeyguardViewManager.showBouncerMessage(errString, errorColor);
+ } else if (updateMonitor.isDeviceInteractive()) {
+ showTransientIndication(errString, errorColor);
+ // We want to keep this message around in case the screen was off
+ mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+ hideTransientIndicationDelayed(5000);
+ } else {
+ mMessageToShowOnScreenOn = errString;
+ }
+ }
+
+ @Override
+ public void onScreenTurnedOn() {
+ if (mMessageToShowOnScreenOn != null) {
+ int errorColor = mContext.getResources().getColor(R.color.system_warning_color,
+ null);
+ showTransientIndication(mMessageToShowOnScreenOn, errorColor);
+ // We want to keep this message around in case the screen was off
+ mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+ hideTransientIndicationDelayed(5000);
+ mMessageToShowOnScreenOn = null;
+ }
+ }
+
+ @Override
+ public void onFingerprintRunningStateChanged(boolean running) {
+ if (running) {
+ mMessageToShowOnScreenOn = null;
+ }
+ }
};
BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -203,7 +301,15 @@ public class KeyguardIndicationController {
if (msg.what == MSG_HIDE_TRANSIENT && mTransientIndication != null) {
mTransientIndication = null;
updateIndication();
+ } else if (msg.what == MSG_CLEAR_FP_MSG) {
+ mLockIcon.setTransientFpError(false);
+ hideTransientIndication();
}
}
};
+
+ public void setStatusBarKeyguardViewManager(
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+ mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
index 01aa8d1..8688c28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
@@ -86,6 +86,9 @@ public class NotificationBackgroundView extends View {
if (mBackground != null) {
mBackground.setCallback(this);
}
+ if (mBackground instanceof RippleDrawable) {
+ ((RippleDrawable) mBackground).setForceSoftware(true);
+ }
invalidate();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 6b167b4..5a2fa3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -50,8 +50,6 @@ public class DozeParameters {
pw.print(" getPulseDuration(pickup=true): "); pw.println(getPulseDuration(true));
pw.print(" getPulseInDuration(pickup=false): "); pw.println(getPulseInDuration(false));
pw.print(" getPulseInDuration(pickup=true): "); pw.println(getPulseInDuration(true));
- pw.print(" getPulseInDelay(pickup=false): "); pw.println(getPulseInDelay(false));
- pw.print(" getPulseInDelay(pickup=true): "); pw.println(getPulseInDelay(true));
pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration());
pw.print(" getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion());
@@ -80,12 +78,6 @@ public class DozeParameters {
: getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
}
- public int getPulseInDelay(boolean pickup) {
- return pickup
- ? getInt("doze.pulse.delay.in.pickup", R.integer.doze_pulse_delay_in_pickup)
- : getInt("doze.pulse.delay.in", R.integer.doze_pulse_delay_in);
- }
-
public int getPulseVisibleDuration() {
return getInt("doze.pulse.duration.visible", R.integer.doze_pulse_duration_visible);
}
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 3e17328..3ff69c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -100,10 +100,35 @@ public class DozeScrimController {
mHandler.post(mPulseIn);
}
+ /**
+ * Aborts pulsing immediately.
+ */
+ public void abortPulsing() {
+ cancelPulsing();
+ if (mDozing) {
+ mScrimController.setDozeBehindAlpha(1f);
+ mScrimController.setDozeInFrontAlpha(1f);
+ }
+ }
+
+ public void onScreenTurnedOn() {
+ if (isPulsing()) {
+ final boolean pickup = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
+ startScrimAnimation(true /* inFront */, 0f,
+ mDozeParameters.getPulseInDuration(pickup),
+ pickup ? mPulseInInterpolatorPickup : mPulseInInterpolator,
+ mPulseInFinished);
+ }
+ }
+
public boolean isPulsing() {
return mPulseCallback != null;
}
+ public boolean isDozing() {
+ return mDozing;
+ }
+
private void cancelPulsing() {
if (DEBUG) Log.d(TAG, "Cancel pulsing");
@@ -138,12 +163,11 @@ public class DozeScrimController {
private void startScrimAnimation(final boolean inFront, float target, long duration,
Interpolator interpolator) {
- startScrimAnimation(inFront, target, duration, interpolator, 0 /* delay */,
- null /* endRunnable */);
+ startScrimAnimation(inFront, target, duration, interpolator, null /* endRunnable */);
}
private void startScrimAnimation(final boolean inFront, float target, long duration,
- Interpolator interpolator, long delay, final Runnable endRunnable) {
+ Interpolator interpolator, final Runnable endRunnable) {
Animator current = getCurrentAnimator(inFront);
if (current != null) {
float currentTarget = getCurrentTarget(inFront);
@@ -162,7 +186,6 @@ public class DozeScrimController {
});
anim.setInterpolator(interpolator);
anim.setDuration(duration);
- anim.setStartDelay(delay);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -222,12 +245,6 @@ public class DozeScrimController {
+ DozeLog.pulseReasonToString(mPulseReason));
if (!mDozing) return;
DozeLog.tracePulseStart(mPulseReason);
- final boolean pickup = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
- startScrimAnimation(true /* inFront */, 0f,
- mDozeParameters.getPulseInDuration(pickup),
- pickup ? mPulseInInterpolatorPickup : mPulseInInterpolator,
- mDozeParameters.getPulseInDelay(pickup),
- mPulseInFinished);
// Signal that the pulse is ready to turn the screen on and draw.
pulseStarted();
@@ -249,7 +266,7 @@ public class DozeScrimController {
if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
if (!mDozing) return;
startScrimAnimation(true /* inFront */, 1f, mDozeParameters.getPulseOutDuration(),
- mPulseOutInterpolator, 0 /* delay */, mPulseOutFinished);
+ mPulseOutInterpolator, mPulseOutFinished);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
new file mode 100644
index 0000000..4e69999
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2015 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.statusbar.phone;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.keyguard.KeyguardConstants;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.keyguard.KeyguardViewMediator;
+
+/**
+ * Controller which coordinates all the fingerprint unlocking actions with the UI.
+ */
+public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback {
+
+ private static final String TAG = "FingerprintController";
+ private static final boolean DEBUG_FP_WAKELOCK = KeyguardConstants.DEBUG_FP_WAKELOCK;
+ private static final long FINGERPRINT_WAKELOCK_TIMEOUT_MS = 15 * 1000;
+ private static final String FINGERPRINT_WAKE_LOCK_NAME = "wake-and-unlock wakelock";
+
+ /**
+ * Mode in which we don't need to wake up the device when we get a fingerprint.
+ */
+ public static final int MODE_NONE = 0;
+
+ /**
+ * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire
+ * a fingerprint while the screen is off and the device was sleeping.
+ */
+ public static final int MODE_WAKE_AND_UNLOCK = 1;
+
+ /**
+ * Mode in which we wake the device up, and fade out the Keyguard contents because they were
+ * already visible while pulsing in doze mode.
+ */
+ public static final int MODE_WAKE_AND_UNLOCK_PULSING = 2;
+
+ /**
+ * Mode in which we wake up the device, but play the normal dismiss animation. Active when we
+ * acquire a fingerprint pulsing in doze mode.
+ */
+ public static final int MODE_SHOW_BOUNCER = 3;
+
+ /**
+ * Mode in which we only wake up the device, and keyguard was not showing when we acquired a
+ * fingerprint.
+ * */
+ public static final int MODE_ONLY_WAKE = 4;
+
+ /**
+ * Mode in which fingerprint unlocks the device.
+ */
+ public static final int MODE_UNLOCK = 5;
+
+ /**
+ * Mode in which fingerprint brings up the bouncer because fingerprint unlocking is currently
+ * not allowed.
+ */
+ public static final int MODE_DISMISS_BOUNCER = 6;
+
+ /**
+ * How much faster we collapse the lockscreen when authenticating with fingerprint.
+ */
+ private static final float FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR = 1.3f;
+
+ private PowerManager mPowerManager;
+ private Handler mHandler = new Handler();
+ private PowerManager.WakeLock mWakeLock;
+ private KeyguardUpdateMonitor mUpdateMonitor;
+ private int mMode;
+ private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private StatusBarWindowManager mStatusBarWindowManager;
+ private DozeScrimController mDozeScrimController;
+ private KeyguardViewMediator mKeyguardViewMediator;
+ private ScrimController mScrimController;
+ private PhoneStatusBar mPhoneStatusBar;
+
+ public FingerprintUnlockController(Context context,
+ StatusBarWindowManager statusBarWindowManager,
+ DozeScrimController dozeScrimController,
+ KeyguardViewMediator keyguardViewMediator,
+ ScrimController scrimController,
+ PhoneStatusBar phoneStatusBar) {
+ mPowerManager = context.getSystemService(PowerManager.class);
+ mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
+ mUpdateMonitor.registerCallback(this);
+ mStatusBarWindowManager = statusBarWindowManager;
+ mDozeScrimController = dozeScrimController;
+ mKeyguardViewMediator = keyguardViewMediator;
+ mScrimController = scrimController;
+ mPhoneStatusBar = phoneStatusBar;
+ }
+
+ public void setStatusBarKeyguardViewManager(
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+ mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+ }
+
+ private final Runnable mReleaseFingerprintWakeLockRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "fp wakelock: TIMEOUT!!");
+ }
+ releaseFingerprintWakeLock();
+ }
+ };
+
+ private void releaseFingerprintWakeLock() {
+ if (mWakeLock != null) {
+ mHandler.removeCallbacks(mReleaseFingerprintWakeLockRunnable);
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "releasing fp wakelock");
+ }
+ mWakeLock.release();
+ mWakeLock = null;
+ }
+ }
+
+ @Override
+ public void onFingerprintAcquired() {
+ releaseFingerprintWakeLock();
+ if (!mUpdateMonitor.isDeviceInteractive()) {
+ mWakeLock = mPowerManager.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, FINGERPRINT_WAKE_LOCK_NAME);
+ mWakeLock.acquire();
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "fingerprint acquired, grabbing fp wakelock");
+ }
+ mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable,
+ FINGERPRINT_WAKELOCK_TIMEOUT_MS);
+ if (mDozeScrimController.isPulsing()) {
+
+ // If we are waking the device up while we are pulsing the clock and the
+ // notifications would light up first, creating an unpleasant animation.
+ // Defer changing the screen brightness by forcing doze brightness on our window
+ // until the clock and the notifications are faded out.
+ mStatusBarWindowManager.setForceDozeBrightness(true);
+ }
+ }
+ }
+
+ @Override
+ public void onFingerprintAuthenticated(int userId) {
+ boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
+ mMode = calculateMode();
+ if (!wasDeviceInteractive) {
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "fp wakelock: Authenticated, waking up...");
+ }
+ mPowerManager.wakeUp(SystemClock.uptimeMillis());
+ }
+ releaseFingerprintWakeLock();
+ switch (mMode) {
+ case MODE_DISMISS_BOUNCER:
+ mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(
+ false /* strongAuth */);
+ break;
+ case MODE_UNLOCK:
+ case MODE_SHOW_BOUNCER:
+ if (!wasDeviceInteractive) {
+ mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
+ }
+ mStatusBarKeyguardViewManager.animateCollapsePanels(
+ FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
+ break;
+ case MODE_WAKE_AND_UNLOCK_PULSING:
+ mPhoneStatusBar.updateMediaMetaData(false /* metaDataChanged */);
+ // Fall through.
+ case MODE_WAKE_AND_UNLOCK:
+ mStatusBarWindowManager.setStatusBarFocusable(false);
+ mDozeScrimController.abortPulsing();
+ mKeyguardViewMediator.onWakeAndUnlocking();
+ mScrimController.setWakeAndUnlocking();
+ if (mPhoneStatusBar.getNavigationBarView() != null) {
+ mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
+ }
+ break;
+ case MODE_ONLY_WAKE:
+ case MODE_NONE:
+ break;
+ }
+ if (mMode != MODE_WAKE_AND_UNLOCK_PULSING) {
+ mStatusBarWindowManager.setForceDozeBrightness(false);
+ }
+ mPhoneStatusBar.notifyFpAuthModeChanged();
+ }
+
+ public int getMode() {
+ return mMode;
+ }
+
+ private int calculateMode() {
+ boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithFingerprintAllowed();
+ if (!mUpdateMonitor.isDeviceInteractive()) {
+ if (!mStatusBarKeyguardViewManager.isShowing()) {
+ return MODE_ONLY_WAKE;
+ } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
+ return MODE_WAKE_AND_UNLOCK_PULSING;
+ } else if (unlockingAllowed) {
+ return MODE_WAKE_AND_UNLOCK;
+ } else {
+ return MODE_SHOW_BOUNCER;
+ }
+ }
+ if (mStatusBarKeyguardViewManager.isShowing()) {
+ if (mStatusBarKeyguardViewManager.isBouncerShowing() && unlockingAllowed) {
+ return MODE_DISMISS_BOUNCER;
+ } else if (unlockingAllowed) {
+ return MODE_UNLOCK;
+ } else {
+ return MODE_SHOW_BOUNCER;
+ }
+ }
+ return MODE_NONE;
+ }
+
+ @Override
+ public void onFingerprintAuthFailed() {
+ cleanup();
+ }
+
+ @Override
+ public void onFingerprintError(int msgId, String errString) {
+ cleanup();
+ }
+
+ private void cleanup() {
+ mMode = MODE_NONE;
+ releaseFingerprintWakeLock();
+ mStatusBarWindowManager.setForceDozeBrightness(false);
+ mPhoneStatusBar.notifyFpAuthModeChanged();
+ }
+
+ public void startKeyguardFadingAway() {
+
+ // Disable brightness override when the ambient contents are fully invisible.
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mStatusBarWindowManager.setForceDozeBrightness(false);
+ }
+ }, PhoneStatusBar.FADE_KEYGUARD_DURATION_PULSING);
+ }
+
+ public void finishKeyguardFadingAway() {
+ mMode = MODE_NONE;
+ if (mPhoneStatusBar.getNavigationBarView() != null) {
+ mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(false);
+ }
+ mPhoneStatusBar.notifyFpAuthModeChanged();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 1a2fa97..579889d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -29,7 +29,6 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
-import android.hardware.fingerprint.FingerprintManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
@@ -86,7 +85,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
- private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
private KeyguardAffordanceView mCameraImageView;
private KeyguardAffordanceView mLeftAffordanceView;
@@ -528,7 +526,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
return mCameraPreview;
}
- public KeyguardAffordanceView getLockIcon() {
+ public LockIcon getLockIcon() {
return mLockIcon;
}
@@ -613,21 +611,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
};
- private final Runnable mTransientFpErrorClearRunnable = new Runnable() {
- @Override
- public void run() {
- mLockIcon.setTransientFpError(false);
- mIndicationController.hideTransientIndication();
- }
- };
-
- private final Runnable mHideTransientIndicationRunnable = new Runnable() {
- @Override
- public void run() {
- mIndicationController.hideTransientIndication();
- }
- };
-
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
@@ -646,42 +629,28 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
@Override
- public void onKeyguardVisibilityChanged(boolean showing) {
- mLockIcon.update();
+ public void onScreenTurnedOn() {
+ mLockIcon.setScreenOn(true);
}
@Override
- public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
+ public void onScreenTurnedOff() {
+ mLockIcon.setScreenOn(false);
}
@Override
- public void onFingerprintRunningStateChanged(boolean running) {
+ public void onKeyguardVisibilityChanged(boolean showing) {
mLockIcon.update();
}
@Override
- public void onFingerprintHelp(int msgId, String helpString) {
- if (!KeyguardUpdateMonitor.getInstance(mContext).isUnlockingWithFingerprintAllowed()) {
- return;
- }
- mLockIcon.setTransientFpError(true);
- mIndicationController.showTransientIndication(helpString,
- getResources().getColor(R.color.system_warning_color, null));
- removeCallbacks(mTransientFpErrorClearRunnable);
- postDelayed(mTransientFpErrorClearRunnable, TRANSIENT_FP_ERROR_TIMEOUT);
+ public void onFingerprintRunningStateChanged(boolean running) {
+ mLockIcon.update();
}
@Override
- public void onFingerprintError(int msgId, String errString) {
- if (!KeyguardUpdateMonitor.getInstance(mContext).isUnlockingWithFingerprintAllowed()
- || msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
- return;
- }
- // TODO: Go to bouncer if this is "too many attempts" (lockout) error.
- mIndicationController.showTransientIndication(errString,
- getResources().getColor(R.color.system_warning_color, null));
- removeCallbacks(mHideTransientIndicationRunnable);
- postDelayed(mHideTransientIndicationRunnable, 5000);
+ public void onStrongAuthStateChanged(int userId) {
+ mLockIcon.update();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index e9b2c61..893b352 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
-import android.view.Choreographer;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -27,6 +26,8 @@ import android.view.accessibility.AccessibilityEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardHostView;
import com.android.keyguard.KeyguardSecurityView;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.R;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.DejankUtils;
@@ -48,6 +49,13 @@ public class KeyguardBouncer {
private ViewGroup mRoot;
private boolean mShowingSoon;
private int mBouncerPromptReason;
+ private KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onStrongAuthStateChanged(int userId) {
+ mBouncerPromptReason = mCallback.getBouncerPromptReason();
+ }
+ };
public KeyguardBouncer(Context context, ViewMediatorCallback callback,
LockPatternUtils lockPatternUtils, StatusBarWindowManager windowManager,
@@ -57,6 +65,7 @@ public class KeyguardBouncer {
mLockPatternUtils = lockPatternUtils;
mContainer = container;
mWindowManager = windowManager;
+ KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
}
public void show(boolean resetSecuritySelection) {
@@ -103,6 +112,10 @@ public class KeyguardBouncer {
mKeyguardView.showPromptReason(reason);
}
+ public void showMessage(String message, int color) {
+ mKeyguardView.showMessage(message, color);
+ }
+
private void cancelShowRunnable() {
DejankUtils.removeCallbacks(mShowRunnable);
mShowingSoon = false;
@@ -244,8 +257,8 @@ public class KeyguardBouncer {
return mKeyguardView.interceptMediaKey(event);
}
- public void notifyKeyguardAuthenticated() {
+ public void notifyKeyguardAuthenticated(boolean strongAuth) {
ensureView();
- mKeyguardView.finish();
+ mKeyguardView.finish(strongAuth);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 06d2fca..463abfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -34,12 +34,6 @@ import com.android.systemui.statusbar.policy.AccessibilityController;
*/
public class LockIcon extends KeyguardAffordanceView {
- /**
- * Delay animations a bit when the screen just turned on as a heuristic to start them after
- * the screen has actually turned on.
- */
- private static final long ANIM_DELAY_AFTER_SCREEN_ON = 250;
-
private static final int STATE_LOCKED = 0;
private static final int STATE_LOCK_OPEN = 1;
private static final int STATE_FACE_UNLOCK = 2;
@@ -50,6 +44,8 @@ public class LockIcon extends KeyguardAffordanceView {
private boolean mLastDeviceInteractive;
private boolean mTransientFpError;
private boolean mDeviceInteractive;
+ private boolean mScreenOn;
+ private boolean mLastScreenOn;
private final TrustDrawable mTrustDrawable;
private final UnlockMethodCache mUnlockMethodCache;
private AccessibilityController mAccessibilityController;
@@ -88,6 +84,11 @@ public class LockIcon extends KeyguardAffordanceView {
update();
}
+ public void setScreenOn(boolean screenOn) {
+ mScreenOn = screenOn;
+ update();
+ }
+
public void update() {
boolean visible = isShown()
&& KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
@@ -96,20 +97,20 @@ public class LockIcon extends KeyguardAffordanceView {
} else {
mTrustDrawable.stop();
}
- if (!visible) {
- return;
- }
// TODO: Real icon for facelock.
int state = getState();
boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
- if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive) {
+ if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive
+ || mScreenOn != mLastScreenOn) {
+ boolean isAnim = true;
int iconRes = getAnimationResForTransition(mLastState, state, mLastDeviceInteractive,
- mDeviceInteractive);
+ mDeviceInteractive, mLastScreenOn, mScreenOn);
if (iconRes == R.drawable.lockscreen_fingerprint_draw_off_animation) {
anyFingerprintIcon = true;
}
if (iconRes == -1) {
- iconRes = getIconForState(state);
+ iconRes = getIconForState(state, mScreenOn, mDeviceInteractive);
+ isAnim = false;
}
Drawable icon = mContext.getDrawable(iconRes);
final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
@@ -135,23 +136,12 @@ public class LockIcon extends KeyguardAffordanceView {
: R.string.accessibility_unlock_button);
setContentDescription(contentDescription);
mHasFingerPrintIcon = anyFingerprintIcon;
- if (animation != null) {
-
- // If we play the draw on animation, delay it by one frame when the screen is
- // actually turned on.
- if (iconRes == R.drawable.lockscreen_fingerprint_draw_on_animation) {
- postOnAnimationDelayed(new Runnable() {
- @Override
- public void run() {
- animation.start();
- }
- }, ANIM_DELAY_AFTER_SCREEN_ON);
- } else {
- animation.start();
- }
+ if (animation != null && isAnim) {
+ animation.start();
}
mLastState = state;
mLastDeviceInteractive = mDeviceInteractive;
+ mLastScreenOn = mScreenOn;
}
// Hide trust circle when fingerprint is running.
@@ -192,7 +182,7 @@ public class LockIcon extends KeyguardAffordanceView {
mAccessibilityController = accessibilityController;
}
- private int getIconForState(int state) {
+ private int getIconForState(int state, boolean screenOn, boolean deviceInteractive) {
switch (state) {
case STATE_LOCKED:
return R.drawable.ic_lock_24dp;
@@ -201,7 +191,11 @@ public class LockIcon extends KeyguardAffordanceView {
case STATE_FACE_UNLOCK:
return com.android.internal.R.drawable.ic_account_circle;
case STATE_FINGERPRINT:
- return R.drawable.ic_fingerprint;
+ // If screen is off and device asleep, use the draw on animation so the first frame
+ // gets drawn.
+ return screenOn && deviceInteractive
+ ? R.drawable.ic_fingerprint
+ : R.drawable.lockscreen_fingerprint_draw_on_animation;
case STATE_FINGERPRINT_ERROR:
return R.drawable.ic_fingerprint_error;
default:
@@ -209,8 +203,9 @@ public class LockIcon extends KeyguardAffordanceView {
}
}
- private int getAnimationResForTransition(int oldState, int newState, boolean oldScreenOn,
- boolean screenOn) {
+ private int getAnimationResForTransition(int oldState, int newState,
+ boolean oldDeviceInteractive, boolean deviceInteractive,
+ boolean oldScreenOn, boolean screenOn) {
if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
return R.drawable.lockscreen_fingerprint_fp_to_error_state_animation;
} else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
@@ -218,7 +213,8 @@ public class LockIcon extends KeyguardAffordanceView {
} else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN
&& !mUnlockMethodCache.isTrusted()) {
return R.drawable.lockscreen_fingerprint_draw_off_animation;
- } else if (newState == STATE_FINGERPRINT && !oldScreenOn && screenOn) {
+ } else if (newState == STATE_FINGERPRINT && (!oldScreenOn && screenOn && deviceInteractive
+ || screenOn && !oldDeviceInteractive && deviceInteractive)) {
return R.drawable.lockscreen_fingerprint_draw_on_animation;
} else {
return -1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 059ecee..cc31476 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -91,7 +91,8 @@ public class NavigationBarView extends LinearLayout {
private OnVerticalChangedListener mOnVerticalChangedListener;
private boolean mIsLayoutRtl;
- private boolean mLayoutTransitionsEnabled;
+ private boolean mLayoutTransitionsEnabled = true;
+ private boolean mWakeAndUnlocking;
private class NavTransitionListener implements TransitionListener {
private boolean mBackTransitioning;
@@ -361,13 +362,19 @@ public class NavigationBarView extends LinearLayout {
}
}
+ public void setLayoutTransitionsEnabled(boolean enabled) {
+ mLayoutTransitionsEnabled = enabled;
+ updateLayoutTransitionsEnabled();
+ }
+
public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
setUseFadingAnimations(wakeAndUnlocking);
- setLayoutTransitionsEnabled(!wakeAndUnlocking);
+ mWakeAndUnlocking = wakeAndUnlocking;
+ updateLayoutTransitionsEnabled();
}
- private void setLayoutTransitionsEnabled(boolean enabled) {
- mLayoutTransitionsEnabled = enabled;
+ private void updateLayoutTransitionsEnabled() {
+ boolean enabled = !mWakeAndUnlocking && mLayoutTransitionsEnabled;
ViewGroup navButtons = (ViewGroup) mCurrentView.findViewById(R.id.nav_buttons);
LayoutTransition lt = navButtons.getLayoutTransition();
if (lt != null) {
@@ -459,7 +466,7 @@ public class NavigationBarView extends LinearLayout {
}
mCurrentView = mRotatedViews[rot];
mCurrentView.setVisibility(View.VISIBLE);
- setLayoutTransitionsEnabled(mLayoutTransitionsEnabled);
+ updateLayoutTransitionsEnabled();
getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
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 373abe5..5be768d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -918,7 +918,7 @@ public class NotificationPanelView extends PanelView implements
}
private int getFalsingThreshold() {
- float factor = mStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+ float factor = mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
return (int) (mQsFalsingThreshold * factor);
}
@@ -2075,7 +2075,7 @@ public class NotificationPanelView extends PanelView implements
@Override
public float getAffordanceFalsingFactor() {
- return mStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+ return mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
}
@Override
@@ -2388,4 +2388,9 @@ public class NotificationPanelView extends PanelView implements
protected boolean isPanelVisibleBecauseOfHeadsUp() {
return mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway;
}
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return !mDozing;
+ }
}
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 8b25e08..c6743e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -382,7 +382,7 @@ public abstract class PanelView extends FrameLayout {
|| forceCancel;
DozeLog.traceFling(expand, mTouchAboveFalsingThreshold,
mStatusBar.isFalsingThresholdNeeded(),
- mStatusBar.isScreenOnComingFromTouch());
+ mStatusBar.isWakeUpComingFromTouch());
// Log collapse gesture if on lock screen.
if (!expand && mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
float displayDensity = mStatusBar.getDisplayDensity();
@@ -411,7 +411,7 @@ public abstract class PanelView extends FrameLayout {
}
private int getFalsingThreshold() {
- float factor = mStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+ float factor = mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
return (int) (mUnlockFalsingThreshold * factor);
}
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 18cf95b..d5825de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -99,6 +99,7 @@ import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.DemoMode;
@@ -153,6 +154,7 @@ import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
+import com.android.systemui.statusbar.stack.StackStateAnimator;
import com.android.systemui.statusbar.stack.StackViewState;
import com.android.systemui.volume.VolumeComponent;
@@ -230,6 +232,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public static final int FADE_KEYGUARD_START_DELAY = 100;
public static final int FADE_KEYGUARD_DURATION = 300;
+ public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
/** Allow some time inbetween the long press for back and recents. */
private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
@@ -270,6 +273,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
KeyguardMonitor mKeyguardMonitor;
BrightnessMirrorController mBrightnessMirrorController;
AccessibilityController mAccessibilityController;
+ FingerprintUnlockController mFingerprintUnlockController;
int mNaturalBarHeight = -1;
@@ -282,8 +286,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private StatusBarWindowManager mStatusBarWindowManager;
private UnlockMethodCache mUnlockMethodCache;
private DozeServiceHost mDozeServiceHost;
- private boolean mScreenOnComingFromTouch;
- private PointF mScreenOnTouchLocation;
+ private boolean mWakeUpComingFromTouch;
+ private PointF mWakeUpTouchLocation;
int mPixelFormat;
Object mQueueLock = new Object();
@@ -621,6 +625,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
startKeyguard();
mDozeServiceHost = new DozeServiceHost();
+ KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mDozeServiceHost);
putComponent(DozeHost.class, mDozeServiceHost);
putComponent(PhoneStatusBar.class, this);
@@ -780,7 +785,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mKeyguardBottomArea.setAssistManager(mAssistManager);
mKeyguardIndicationController = new KeyguardIndicationController(mContext,
(KeyguardIndicationTextView) mStatusBarWindow.findViewById(
- R.id.keyguard_indication_text));
+ R.id.keyguard_indication_text),
+ mKeyguardBottomArea.getLockIcon());
mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
// set the inital view visibility
@@ -1009,8 +1015,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private void startKeyguard() {
KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
+ mFingerprintUnlockController = new FingerprintUnlockController(mContext,
+ mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator,
+ mScrimController, this);
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
- mStatusBarWindow, mStatusBarWindowManager, mScrimController);
+ mStatusBarWindow, mStatusBarWindowManager, mScrimController,
+ mFingerprintUnlockController);
+ mKeyguardIndicationController.setStatusBarKeyguardViewManager(
+ mStatusBarKeyguardViewManager);
+ mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
}
@@ -1681,7 +1694,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
final boolean hasArtwork = artworkBitmap != null;
if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
- && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
+ && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
+ && mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
// time to show some art!
if (mBackdrop.getVisibility() != View.VISIBLE) {
mBackdrop.setVisibility(View.VISIBLE);
@@ -1736,31 +1751,40 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
}
- mBackdrop.animate()
- // Never let the alpha become zero - otherwise the RenderNode
- // won't draw anything and uninitialized memory will show through
- // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in libhwui.
- .alpha(0.002f)
- .setInterpolator(mBackdropInterpolator)
- .setDuration(300)
- .setStartDelay(0)
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- mBackdrop.setVisibility(View.GONE);
- mBackdropFront.animate().cancel();
- mBackdropBack.animate().cancel();
- mHandler.post(mHideBackdropFront);
- }
- });
- if (mKeyguardFadingAway) {
- mBackdrop.animate()
+ if (mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
- // Make it disappear faster, as the focus should be on the activity behind.
- .setDuration(mKeyguardFadingAwayDuration / 2)
- .setStartDelay(mKeyguardFadingAwayDelay)
- .setInterpolator(mLinearInterpolator)
- .start();
+ // We are unlocking directly - no animation!
+ mBackdrop.setVisibility(View.GONE);
+ } else {
+ mBackdrop.animate()
+ // Never let the alpha become zero - otherwise the RenderNode
+ // won't draw anything and uninitialized memory will show through
+ // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
+ // libhwui.
+ .alpha(0.002f)
+ .setInterpolator(mBackdropInterpolator)
+ .setDuration(300)
+ .setStartDelay(0)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ mBackdrop.setVisibility(View.GONE);
+ mBackdropFront.animate().cancel();
+ mBackdropBack.animate().cancel();
+ mHandler.post(mHideBackdropFront);
+ }
+ });
+ if (mKeyguardFadingAway) {
+ mBackdrop.animate()
+
+ // Make it disappear faster, as the focus should be on the activity
+ // behind.
+ .setDuration(mKeyguardFadingAwayDuration / 2)
+ .setStartDelay(mKeyguardFadingAwayDelay)
+ .setInterpolator(mLinearInterpolator)
+ .start();
+ }
}
}
}
@@ -1910,8 +1934,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return mNotificationPanel.isQsExpanded();
}
- public boolean isScreenOnComingFromTouch() {
- return mScreenOnComingFromTouch;
+ public boolean isWakeUpComingFromTouch() {
+ return mWakeUpComingFromTouch;
}
public boolean isFalsingThresholdNeeded() {
@@ -2423,8 +2447,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|| mStatusBarMode == MODE_LIGHTS_OUT_TRANSPARENT);
boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave();
boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
-
- mIconController.setIconsDark(allowLight && light);
+ boolean animate = mFingerprintUnlockController == null
+ || (mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
+ && mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK);
+ mIconController.setIconsDark(allowLight && light, animate);
}
// restore the recents bit
if (wasRecentsVisible) {
@@ -2471,7 +2499,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private void checkBarMode(int mode, int windowState, BarTransitions transitions,
boolean noAnimation) {
final boolean powerSave = mBatteryController.isPowerSave();
- final boolean anim = !noAnimation && (mScreenOn == null || mScreenOn)
+ final boolean anim = !noAnimation && mDeviceInteractive
&& windowState != WINDOW_STATE_HIDDEN && !powerSave;
if (powerSave && getBarState() == StatusBarState.SHADE) {
mode = MODE_WARNING;
@@ -2879,14 +2907,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
- mScreenOn = false;
notifyNavigationBarScreenOn(false);
notifyHeadsUpScreenOff();
finishBarAnimations();
resetUserExpandedStates();
}
else if (Intent.ACTION_SCREEN_ON.equals(action)) {
- mScreenOn = true;
notifyNavigationBarScreenOn(true);
}
}
@@ -3340,7 +3366,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
setBarState(StatusBarState.KEYGUARD);
updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
- if (!mScreenOnFromKeyguard) {
+ if (!mDeviceInteractive) {
// If the screen is off already, we need to disable touch events because these might
// collapse the panel after we expanded it, and thus we would end up with a blank
@@ -3422,6 +3448,19 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
/**
+ * Fades the content of the Keyguard while we are dozing and makes it invisible when finished
+ * fading.
+ */
+ public void fadeKeyguardWhilePulsing() {
+ mNotificationPanel.animate()
+ .alpha(0f)
+ .setStartDelay(0)
+ .setDuration(FADE_KEYGUARD_DURATION_PULSING)
+ .setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR)
+ .start();
+ }
+
+ /**
* Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
* Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
* because the launched app crashed or something else went wrong.
@@ -3455,11 +3494,24 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
setBarState(StatusBarState.SHADE);
if (mLeaveOpenOnKeyguardHide) {
mLeaveOpenOnKeyguardHide = false;
- mNotificationPanel.animateToFullShade(calculateGoingToFullShadeDelay());
+ long delay = calculateGoingToFullShadeDelay();
+ mNotificationPanel.animateToFullShade(delay);
if (mDraggedDownRow != null) {
mDraggedDownRow.setUserLocked(false);
mDraggedDownRow = null;
}
+
+ // Disable layout transitions in navbar for this transition because the load is just
+ // too heavy for the CPU and GPU on any device.
+ if (mNavigationBarView != null) {
+ mNavigationBarView.setLayoutTransitionsEnabled(false);
+ mNavigationBarView.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mNavigationBarView.setLayoutTransitionsEnabled(true);
+ }
+ }, delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
+ }
} else {
instantCollapseNotificationPanel();
}
@@ -3471,6 +3523,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mQSPanel.refreshAllTiles();
}
mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
+ mNotificationPanel.setAlpha(1f);
return staying;
}
@@ -3560,9 +3613,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private void updateDozingState() {
boolean animate = !mDozing && mDozeScrimController.isPulsing();
mNotificationPanel.setDozing(mDozing, animate);
- mStackScroller.setDark(mDozing, animate, mScreenOnTouchLocation);
+ mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
mScrimController.setDozing(mDozing);
- mDozeScrimController.setDozing(mDozing, animate);
+
+ // Immediately abort the dozing from the doze scrim controller in case of wake-and-unlock
+ // for pulsing so the Keyguard fade-out animation scrim can take over.
+ mDozeScrimController.setDozing(mDozing &&
+ mFingerprintUnlockController.getMode()
+ != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate);
}
public void updateStackScrollerState(boolean goingToFullShade) {
@@ -3613,7 +3671,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
public boolean onSpacePressed() {
- if (mScreenOn != null && mScreenOn
+ if (mDeviceInteractive
&& (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
animateCollapsePanels(
CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);
@@ -3823,16 +3881,16 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
}
- public void onScreenTurnedOff() {
- mScreenOnFromKeyguard = false;
- mScreenOnComingFromTouch = false;
- mScreenOnTouchLocation = null;
+ public void onFinishedGoingToSleep() {
+ mDeviceInteractive = false;
+ mWakeUpComingFromTouch = false;
+ mWakeUpTouchLocation = null;
mStackScroller.setAnimationsEnabled(false);
updateVisibleToUser();
}
- public void onScreenTurnedOn() {
- mScreenOnFromKeyguard = true;
+ public void onStartedWakingUp() {
+ mDeviceInteractive = true;
mStackScroller.setAnimationsEnabled(true);
mNotificationPanel.setTouchDisabled(false);
updateVisibleToUser();
@@ -3842,6 +3900,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mNotificationPanel.onScreenTurningOn();
}
+ public void onScreenTurnedOn() {
+ mDozeScrimController.onScreenTurnedOn();
+ }
+
/**
* This handles long-press of both back and recents. They are
* handled together to capture them both being long-pressed
@@ -3956,8 +4018,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (mDozing && mDozeScrimController.isPulsing()) {
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
pm.wakeUp(time, "com.android.systemui:NODOZE");
- mScreenOnComingFromTouch = true;
- mScreenOnTouchLocation = new PointF(event.getX(), event.getY());
+ mWakeUpComingFromTouch = true;
+ mWakeUpTouchLocation = new PointF(event.getX(), event.getY());
mNotificationPanel.setTouchDisabled(false);
mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
}
@@ -3982,8 +4044,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void appTransitionStarting(long startTime, long duration) {
// Use own timings when Keyguard is going away, see keyguardGoingAway and
- // setKeyguardFadingAway
- if (!mKeyguardFadingAway) {
+ // setKeyguardFadingAway. When duration is 0, skip this one because no animation is really
+ // playing.
+ if (!mKeyguardFadingAway && duration > 0) {
mIconController.appTransitionStarting(startTime, duration);
}
if (mIconPolicy != null) {
@@ -3991,8 +4054,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
+ public void notifyFpAuthModeChanged() {
+ updateDozing();
+ }
+
private void updateDozing() {
- mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD;
+ // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
+ mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD
+ || mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
updateDozingState();
}
@@ -4022,7 +4092,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
- private final class DozeServiceHost implements DozeHost {
+ private final class DozeServiceHost extends KeyguardUpdateMonitorCallback implements DozeHost {
// Amount of time to allow to update the time shown on the screen before releasing
// the wakelock. This timeout is design to compensate for the fact that we don't
// currently have a way to know when time display contents have actually been
@@ -4096,6 +4166,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
@Override
+ public boolean isPulsingBlocked() {
+ return mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
+ }
+
+ @Override
public boolean isNotificationLightOn() {
return mNotificationLightOn;
}
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 1a35500..cc6f396 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -22,7 +22,6 @@ import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
-import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.DecelerateInterpolator;
@@ -44,12 +43,15 @@ import com.android.systemui.statusbar.stack.StackStateAnimator;
public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
HeadsUpManager.OnHeadsUpChangedListener {
public static final long ANIMATION_DURATION = 220;
+ public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR
+ = new PathInterpolator(0f, 0, 0.7f, 1f);
private static final float SCRIM_BEHIND_ALPHA = 0.62f;
private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f;
private static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
private static final int TAG_KEY_ANIM = R.id.scrim;
+ private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
private static final int TAG_HUN_START_ALPHA = R.id.hun_scrim_alpha_start;
private static final int TAG_HUN_END_ALPHA = R.id.hun_scrim_alpha_end;
@@ -71,9 +73,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
private long mDurationOverride = -1;
private long mAnimationDelay;
private Runnable mOnAnimationFinished;
- private boolean mAnimationStarted;
private final Interpolator mInterpolator = new DecelerateInterpolator();
- private final Interpolator mKeyguardFadeOutInterpolator = new PathInterpolator(0f, 0, 0.7f, 1f);
private BackDropView mBackDropView;
private boolean mScrimSrcEnabled;
private boolean mDozing;
@@ -86,6 +86,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
private float mTopHeadsUpDragAmount;
private View mDraggedHeadsUpView;
private boolean mForceHideScrims;
+ private boolean mSkipFirstFrame;
public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
boolean scrimSrcEnabled) {
@@ -133,19 +134,25 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
scheduleUpdate();
}
- public void animateKeyguardFadingOut(long delay, long duration, Runnable onAnimationFinished) {
+ public void animateKeyguardFadingOut(long delay, long duration, Runnable onAnimationFinished,
+ boolean skipFirstFrame) {
mWakeAndUnlocking = false;
mAnimateKeyguardFadingOut = true;
mDurationOverride = duration;
mAnimationDelay = delay;
mAnimateChange = true;
+ mSkipFirstFrame = skipFirstFrame;
mOnAnimationFinished = onAnimationFinished;
scheduleUpdate();
+
+ // No need to wait for the next frame to be drawn for this case - onPreDraw will execute
+ // the changes we just scheduled.
+ onPreDraw();
}
public void abortKeyguardFadingOut() {
if (mAnimateKeyguardFadingOut) {
- endAnimateKeyguardFadingOut();
+ endAnimateKeyguardFadingOut(true /* force */);
}
}
@@ -198,8 +205,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
// During wake and unlock, we first hide everything behind a black scrim, which then
// gets faded out from animateKeyguardFadingOut.
- setScrimInFrontColor(1f);
- setScrimBehindColor(0f);
+ if (mDozing) {
+ setScrimInFrontColor(0f);
+ setScrimBehindColor(1f);
+ } else {
+ setScrimInFrontColor(1f);
+ setScrimBehindColor(0f);
+ }
} else if (!mKeyguardShowing && !mBouncerShowing) {
updateScrimNormal();
setScrimInFrontColor(0);
@@ -258,10 +270,14 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
}
private void setScrimColor(View scrim, float alpha) {
- Object runningAnim = scrim.getTag(TAG_KEY_ANIM);
- if (runningAnim instanceof ValueAnimator) {
- ((ValueAnimator) runningAnim).cancel();
- scrim.setTag(TAG_KEY_ANIM, null);
+ ValueAnimator runningAnim = (ValueAnimator) scrim.getTag(TAG_KEY_ANIM);
+ Float target = (Float) scrim.getTag(TAG_KEY_ANIM_TARGET);
+ if (runningAnim != null && target != null) {
+ if (alpha != target) {
+ runningAnim.cancel();
+ } else {
+ return;
+ }
}
if (mAnimateChange) {
startScrimAnimation(scrim, alpha);
@@ -325,15 +341,19 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
mOnAnimationFinished = null;
}
scrim.setTag(TAG_KEY_ANIM, null);
+ scrim.setTag(TAG_KEY_ANIM_TARGET, null);
}
});
anim.start();
+ if (mSkipFirstFrame) {
+ anim.setCurrentPlayTime(16);
+ }
scrim.setTag(TAG_KEY_ANIM, anim);
- mAnimationStarted = true;
+ scrim.setTag(TAG_KEY_ANIM_TARGET, target);
}
private Interpolator getInterpolator() {
- return mAnimateKeyguardFadingOut ? mKeyguardFadeOutInterpolator : mInterpolator;
+ return mAnimateKeyguardFadingOut ? KEYGUARD_FADE_OUT_INTERPOLATOR : mInterpolator;
}
@Override
@@ -343,21 +363,26 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
updateScrims();
mDurationOverride = -1;
mAnimationDelay = 0;
+ mSkipFirstFrame = false;
// Make sure that we always call the listener even if we didn't start an animation.
- endAnimateKeyguardFadingOut();
- mAnimationStarted = false;
+ endAnimateKeyguardFadingOut(false /* force */);
return true;
}
- private void endAnimateKeyguardFadingOut() {
+ private void endAnimateKeyguardFadingOut(boolean force) {
mAnimateKeyguardFadingOut = false;
- if (!mAnimationStarted && mOnAnimationFinished != null) {
+ if ((force || (!isAnimating(mScrimInFront) && !isAnimating(mScrimBehind)))
+ && mOnAnimationFinished != null) {
mOnAnimationFinished.run();
mOnAnimationFinished = null;
}
}
+ private boolean isAnimating(View scrim) {
+ return scrim.getTag(TAG_KEY_ANIM) != null;
+ }
+
public void setBackDropView(BackDropView backDropView) {
mBackDropView = backDropView;
mBackDropView.setOnVisibilityChangedRunnable(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
index a1e9ece..18db5b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
@@ -19,6 +19,7 @@ import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.graphics.drawable.RippleDrawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 7ee47df..e9c4e49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -26,6 +26,7 @@ import android.graphics.Outline;
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.util.TypedValue;
@@ -184,6 +185,12 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
}
});
requestCaptureValues();
+
+ // RenderThread is doing more harm than good when touching the header (to expand quick
+ // settings), so disable it for this view
+ ((RippleDrawable) getBackground()).setForceSoftware(true);
+ ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true);
+ ((RippleDrawable) mSystemIconsSuperContainer.getBackground()).setForceSoftware(true);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 067e50e..5de1c13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -335,8 +335,10 @@ public class StatusBarIconController implements Tunable {
}
}
- public void setIconsDark(boolean dark) {
- if (mTransitionPending) {
+ public void setIconsDark(boolean dark, boolean animate) {
+ if (!animate) {
+ setIconTintInternal(dark ? 1.0f : 0.0f);
+ } else if (mTransitionPending) {
deferIconTintChange(dark ? 1.0f : 0.0f);
} else if (mTransitionDeferring) {
animateIconTint(dark ? 1.0f : 0.0f,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 7dd3e7c..59ee5c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -48,6 +48,8 @@ public class StatusBarKeyguardViewManager {
// with the appear animations of the PIN/pattern/password views.
private static final long NAV_BAR_SHOW_DELAY_BOUNCER = 320;
+ private static final long WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS = 200;
+
private static String TAG = "StatusBarKeyguardViewManager";
private final Context mContext;
@@ -56,6 +58,7 @@ public class StatusBarKeyguardViewManager {
private ViewMediatorCallback mViewMediatorCallback;
private PhoneStatusBar mPhoneStatusBar;
private ScrimController mScrimController;
+ private FingerprintUnlockController mFingerprintUnlockController;
private ViewGroup mContainer;
private StatusBarWindowManager mStatusBarWindowManager;
@@ -71,10 +74,8 @@ public class StatusBarKeyguardViewManager {
private boolean mLastOccluded;
private boolean mLastBouncerShowing;
private boolean mLastBouncerDismissible;
- private boolean mLastDeferScrimFadeOut;
private OnDismissAction mAfterKeyguardGoneAction;
private boolean mDeviceWillWakeUp;
- private boolean mWakeAndUnlocking;
private boolean mDeferScrimFadeOut;
public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback,
@@ -86,11 +87,13 @@ public class StatusBarKeyguardViewManager {
public void registerStatusBar(PhoneStatusBar phoneStatusBar,
ViewGroup container, StatusBarWindowManager statusBarWindowManager,
- ScrimController scrimController) {
+ ScrimController scrimController,
+ FingerprintUnlockController fingerprintUnlockController) {
mPhoneStatusBar = phoneStatusBar;
mContainer = container;
mStatusBarWindowManager = statusBarWindowManager;
mScrimController = scrimController;
+ mFingerprintUnlockController = fingerprintUnlockController;
mBouncer = new KeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils,
mStatusBarWindowManager, container);
}
@@ -162,14 +165,14 @@ public class StatusBarKeyguardViewManager {
public void onFinishedGoingToSleep() {
mDeviceInteractive = false;
- mPhoneStatusBar.onScreenTurnedOff();
+ mPhoneStatusBar.onFinishedGoingToSleep();
mBouncer.onScreenTurnedOff();
}
public void onStartedWakingUp() {
mDeviceInteractive = true;
mDeviceWillWakeUp = false;
- mPhoneStatusBar.onScreenTurnedOn();
+ mPhoneStatusBar.onStartedWakingUp();
}
public void onScreenTurningOn() {
@@ -178,12 +181,13 @@ public class StatusBarKeyguardViewManager {
public void onScreenTurnedOn() {
mScreenTurnedOn = true;
- mWakeAndUnlocking = false;
if (mDeferScrimFadeOut) {
mDeferScrimFadeOut = false;
- animateScrimControllerKeyguardFadingOut(0, 200);
+ animateScrimControllerKeyguardFadingOut(0, WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS,
+ true /* skipFirstFrame */);
updateStates();
}
+ mPhoneStatusBar.onScreenTurnedOn();
}
public void onScreenTurnedOff() {
@@ -260,7 +264,8 @@ public class StatusBarKeyguardViewManager {
updateStates();
mScrimController.animateKeyguardFadingOut(
PhoneStatusBar.FADE_KEYGUARD_START_DELAY,
- PhoneStatusBar.FADE_KEYGUARD_DURATION, null);
+ PhoneStatusBar.FADE_KEYGUARD_DURATION, null,
+ false /* skipFirstFrame */);
}
}, new Runnable() {
@Override
@@ -272,18 +277,43 @@ public class StatusBarKeyguardViewManager {
}
});
} else {
- mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
- boolean staying = mPhoneStatusBar.hideKeyguard();
- if (!staying) {
+ if (mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
+ mFingerprintUnlockController.startKeyguardFadingAway();
+ mPhoneStatusBar.setKeyguardFadingAway(startTime, 0, 240);
mStatusBarWindowManager.setKeyguardFadingAway(true);
- if (mWakeAndUnlocking && !mScreenTurnedOn) {
- mDeferScrimFadeOut = true;
+ mPhoneStatusBar.fadeKeyguardWhilePulsing();
+ animateScrimControllerKeyguardFadingOut(0, 240, new Runnable() {
+ @Override
+ public void run() {
+ mPhoneStatusBar.hideKeyguard();
+ }
+ }, false /* skipFirstFrame */);
+ } else {
+ mFingerprintUnlockController.startKeyguardFadingAway();
+ mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
+ boolean staying = mPhoneStatusBar.hideKeyguard();
+ if (!staying) {
+ mStatusBarWindowManager.setKeyguardFadingAway(true);
+ if (mFingerprintUnlockController.getMode()
+ == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK) {
+ if (!mScreenTurnedOn) {
+ mDeferScrimFadeOut = true;
+ } else {
+
+ // Screen is already on, don't defer with fading out.
+ animateScrimControllerKeyguardFadingOut(0,
+ WAKE_AND_UNLOCK_SCRIM_FADEOUT_DURATION_MS,
+ true /* skipFirstFrame */);
+ }
+ } else {
+ animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration,
+ false /* skipFirstFrame */);
+ }
} else {
- animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration);
+ mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
+ mPhoneStatusBar.finishKeyguardFadingAway();
}
- } else {
- mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
- mPhoneStatusBar.finishKeyguardFadingAway();
}
mStatusBarWindowManager.setKeyguardShowing(false);
mBouncer.hide(true /* destroyView */);
@@ -291,24 +321,31 @@ public class StatusBarKeyguardViewManager {
executeAfterKeyguardGoneAction();
updateStates();
}
+ }
+ private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
+ boolean skipFirstFrame) {
+ animateScrimControllerKeyguardFadingOut(delay, duration, null /* endRunnable */,
+ skipFirstFrame);
}
- private void animateScrimControllerKeyguardFadingOut(long delay, long duration) {
+ private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
+ final Runnable endRunnable, boolean skipFirstFrame) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "Fading out", 0);
mScrimController.animateKeyguardFadingOut(delay, duration, new Runnable() {
@Override
public void run() {
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
mStatusBarWindowManager.setKeyguardFadingAway(false);
mPhoneStatusBar.finishKeyguardFadingAway();
- if (mPhoneStatusBar.getNavigationBarView() != null) {
- mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(false);
- }
+ mFingerprintUnlockController.finishKeyguardFadingAway();
WindowManagerGlobal.getInstance().trimMemory(
ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "Fading out", 0);
}
- });
+ }, skipFirstFrame);
}
private void executeAfterKeyguardGoneAction() {
@@ -382,7 +419,6 @@ public class StatusBarKeyguardViewManager {
boolean occluded = mOccluded;
boolean bouncerShowing = mBouncer.isShowing();
boolean bouncerDismissible = !mBouncer.isFullscreenBouncer();
- boolean deferScrimFadeOut = mDeferScrimFadeOut;
if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing)
|| mFirstUpdate) {
@@ -393,16 +429,18 @@ public class StatusBarKeyguardViewManager {
}
}
- // Hide navigation bar on Keyguard but not on bouncer and also if we are deferring a scrim
- // fade out, i.e. we are waiting for the screen to have turned on.
- boolean navBarVisible = !deferScrimFadeOut && (!(showing && !occluded) || bouncerShowing);
- boolean lastNavBarVisible = !mLastDeferScrimFadeOut && (!(mLastShowing && !mLastOccluded)
- || mLastBouncerShowing);
+ boolean navBarVisible = (!(showing && !occluded) || bouncerShowing);
+ boolean lastNavBarVisible = (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing);
if (navBarVisible != lastNavBarVisible || mFirstUpdate) {
if (mPhoneStatusBar.getNavigationBarView() != null) {
if (navBarVisible) {
- mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable,
- getNavBarShowDelay());
+ long delay = getNavBarShowDelay();
+ if (delay == 0) {
+ mMakeNavigationBarVisibleRunnable.run();
+ } else {
+ mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable,
+ delay);
+ }
} else {
mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable);
mPhoneStatusBar.getNavigationBarView().setVisibility(View.GONE);
@@ -427,7 +465,6 @@ public class StatusBarKeyguardViewManager {
mFirstUpdate = false;
mLastShowing = showing;
mLastOccluded = occluded;
- mLastDeferScrimFadeOut = deferScrimFadeOut;
mLastBouncerShowing = bouncerShowing;
mLastBouncerDismissible = bouncerDismissible;
@@ -484,15 +521,11 @@ public class StatusBarKeyguardViewManager {
* Notifies that the user has authenticated by other means than using the bouncer, for example,
* fingerprint.
*/
- public void notifyKeyguardAuthenticated() {
- mBouncer.notifyKeyguardAuthenticated();
+ public void notifyKeyguardAuthenticated(boolean strongAuth) {
+ mBouncer.notifyKeyguardAuthenticated(strongAuth);
}
- public void setWakeAndUnlocking() {
- mWakeAndUnlocking = true;
- mScrimController.setWakeAndUnlocking();
- if (mPhoneStatusBar.getNavigationBarView() != null) {
- mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
- }
+ public void showBouncerMessage(String message, int color) {
+ mBouncer.showMessage(message, color);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 038fefb..ccfa0dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -24,6 +24,7 @@ import android.os.SystemProperties;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
+import android.view.Window;
import android.view.WindowManager;
import com.android.keyguard.R;
@@ -47,13 +48,15 @@ public class StatusBarWindowManager {
private WindowManager.LayoutParams mLpChanged;
private int mBarHeight;
private final boolean mKeyguardScreenRotation;
-
+ private final float mScreenBrightnessDoze;
private final State mCurrentState = new State();
public StatusBarWindowManager(Context context) {
mContext = context;
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
+ mScreenBrightnessDoze = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_screenBrightnessDoze) / 255f;
}
private boolean shouldEnableKeyguardScreenRotation() {
@@ -182,6 +185,7 @@ public class StatusBarWindowManager {
applyInputFeatures(state);
applyFitsSystemWindows(state);
applyModalFlag(state);
+ applyBrightness(state);
if (mLp.copyFrom(mLpChanged) != 0) {
mWindowManager.updateViewLayout(mStatusBarView, mLp);
}
@@ -205,6 +209,14 @@ public class StatusBarWindowManager {
}
}
+ private void applyBrightness(State state) {
+ if (state.forceDozeBrightness) {
+ mLpChanged.screenBrightness = mScreenBrightnessDoze;
+ } else {
+ mLpChanged.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
+ }
+ }
+
public void setKeyguardShowing(boolean showing) {
mCurrentState.keyguardShowing = showing;
apply(mCurrentState);
@@ -279,6 +291,15 @@ public class StatusBarWindowManager {
apply(mCurrentState);
}
+ /**
+ * Set whether the screen brightness is forced to the value we use for doze mode by the status
+ * bar window.
+ */
+ public void setForceDozeBrightness(boolean forceDozeBrightness) {
+ mCurrentState.forceDozeBrightness = forceDozeBrightness;
+ apply(mCurrentState);
+ }
+
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("StatusBarWindowManager state:");
pw.println(mCurrentState);
@@ -297,6 +318,7 @@ public class StatusBarWindowManager {
boolean headsUpShowing;
boolean forceStatusBarVisible;
boolean forceCollapsed;
+ boolean forceDozeBrightness;
/**
* The {@link BaseStatusBar} state from the status bar.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index bd537f7..a91cd51 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -132,7 +132,7 @@ public class UnlockMethodCache {
}
@Override
- public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
+ public void onFingerprintAuthenticated(int userId) {
if (!mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()) {
return;
}
@@ -143,6 +143,11 @@ public class UnlockMethodCache {
public void onFaceUnlockStateChanged(boolean running, int userId) {
update(false /* updateAlways */);
}
+
+ @Override
+ public void onStrongAuthStateChanged(int userId) {
+ update(false /* updateAlways */);
+ }
};
public boolean isTrustManaged() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
index 753a7f7..56f6564 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
@@ -34,6 +34,7 @@ public class AnimationFilter {
boolean hasDelays;
boolean hasGoToFullShadeEvent;
boolean hasDarkEvent;
+ boolean hasHeadsUpDisappearClickEvent;
int darkAnimationOriginIndex;
public AnimationFilter animateAlpha() {
@@ -106,6 +107,10 @@ public class AnimationFilter {
hasDarkEvent = true;
darkAnimationOriginIndex = ev.darkAnimationOriginIndex;
}
+ if (ev.animationType == NotificationStackScrollLayout.AnimationEvent
+ .ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) {
+ hasHeadsUpDisappearClickEvent = true;
+ }
}
}
@@ -135,6 +140,7 @@ public class AnimationFilter {
hasDelays = false;
hasGoToFullShadeEvent = false;
hasDarkEvent = false;
+ hasHeadsUpDisappearClickEvent = false;
darkAnimationOriginIndex =
NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 23d9b9f..a7fe71e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -653,7 +653,7 @@ public class NotificationStackScrollLayout extends ViewGroup
@Override
public float getFalsingThresholdFactor() {
- return mPhoneStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+ return mPhoneStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
}
public View getChildAtPosition(MotionEvent ev) {
@@ -1915,7 +1915,9 @@ public class NotificationStackScrollLayout extends ViewGroup
boolean onBottom = false;
boolean pinnedAndClosed = row.isPinned() && !mIsExpanded;
if (!mIsExpanded && !isHeadsUp) {
- type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
+ type = row.wasJustClicked()
+ ? AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
+ : AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
} else {
StackViewState viewState = mCurrentStackScrollState.getViewStateForView(row);
if (viewState == null) {
@@ -3016,6 +3018,15 @@ public class NotificationStackScrollLayout extends ViewGroup
.animateY()
.animateZ(),
+ // ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
+ new AnimationFilter()
+ .animateAlpha()
+ .animateHeight()
+ .animateTopInset()
+ .animateY()
+ .animateZ()
+ .hasDelays(),
+
// ANIMATION_TYPE_HEADS_UP_OTHER
new AnimationFilter()
.animateAlpha()
@@ -3087,6 +3098,9 @@ public class NotificationStackScrollLayout extends ViewGroup
// ANIMATION_TYPE_HEADS_UP_DISAPPEAR
StackStateAnimator.ANIMATION_DURATION_HEADS_UP_DISAPPEAR,
+ // ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
+ StackStateAnimator.ANIMATION_DURATION_HEADS_UP_DISAPPEAR,
+
// ANIMATION_TYPE_HEADS_UP_OTHER
StackStateAnimator.ANIMATION_DURATION_STANDARD,
@@ -3110,8 +3124,9 @@ public class NotificationStackScrollLayout extends ViewGroup
static final int ANIMATION_TYPE_GROUP_EXPANSION_CHANGED = 13;
static final int ANIMATION_TYPE_HEADS_UP_APPEAR = 14;
static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR = 15;
- static final int ANIMATION_TYPE_HEADS_UP_OTHER = 16;
- static final int ANIMATION_TYPE_EVERYTHING = 17;
+ static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK = 16;
+ static final int ANIMATION_TYPE_HEADS_UP_OTHER = 17;
+ static final int ANIMATION_TYPE_EVERYTHING = 18;
static final int DARK_ANIMATION_ORIGIN_INDEX_ABOVE = -1;
static final int DARK_ANIMATION_ORIGIN_INDEX_BELOW = -2;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 82064a7..cf696a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -127,7 +127,7 @@ public class StackScrollAlgorithm {
mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize(
R.dimen.notification_collapse_second_card_padding);
mScaleDimmed = context.getResources().getDisplayMetrics().densityDpi
- >= DisplayMetrics.DENSITY_XXHIGH;
+ >= DisplayMetrics.DENSITY_420;
}
public boolean shouldScaleDimmed() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 97c7d30..b4ab48a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -54,6 +54,7 @@ public class StackStateAnimator {
public static final int ANIMATION_DELAY_PER_ELEMENT_DARK = 24;
public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2;
public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE_CHILDREN = 3;
+ public static final int ANIMATION_DELAY_HEADS_UP = 120;
private static final int TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag;
private static final int TAG_ANIMATOR_TRANSLATION_Z = R.id.translation_z_animator_tag;
@@ -320,6 +321,9 @@ public class StackStateAnimator {
if (mAnimationFilter.hasGoToFullShadeEvent) {
return calculateDelayGoToFullShade(viewState);
}
+ if (mAnimationFilter.hasHeadsUpDisappearClickEvent) {
+ return ANIMATION_DELAY_HEADS_UP;
+ }
long minDelay = 0;
for (NotificationStackScrollLayout.AnimationEvent event : mNewEvents) {
long delayPerElement = ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING;
@@ -890,7 +894,9 @@ public class StackStateAnimator {
mHeadsUpAppearChildren.add(changingView);
finalState.applyState(changingView, mTmpState);
} else if (event.animationType == NotificationStackScrollLayout
- .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR) {
+ .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR ||
+ event.animationType == NotificationStackScrollLayout
+ .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) {
mHeadsUpDisappearChildren.add(changingView);
if (mHostLayout.indexOfChild(changingView) == -1) {
// This notification was actually removed, so we need to add it to the overlay
@@ -900,7 +906,11 @@ public class StackStateAnimator {
// We temporarily enable Y animations, the real filter will be combined
// afterwards anyway
mAnimationFilter.animateY = true;
- startViewAnimations(changingView, mTmpState, 0,
+ startViewAnimations(changingView, mTmpState,
+ event.animationType == NotificationStackScrollLayout
+ .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
+ ? ANIMATION_DELAY_HEADS_UP
+ : 0,
ANIMATION_DURATION_HEADS_UP_DISAPPEAR);
mChildrenToClearFromOverlay.add(changingView);
}