diff options
Diffstat (limited to 'packages/SystemUI/src/com')
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); } |