diff options
| author | 2016-08-04 14:50:48 -0700 | |
|---|---|---|
| committer | 2016-08-05 00:04:07 +0000 | |
| commit | d88eb2693b6a70af0f5fbc5881ce855e28de33aa (patch) | |
| tree | 37c19a72d654ee73f3eac1cdeeeb4485f8373970 | |
| parent | 88d57db0ad5e97f873a9aa9c40d71895af8e7200 (diff) | |
Keyguard: Refactoring for improving trusted unlock while occluded
- Adds a trusted signal from Keyguard to PhoneWindowManager
- Allows PhoneWindowManager to exempt DISMISS_KEYGUARD windows from force hiding
- Allows PhoneWindowManager to dismiss Keyguard while occluded
Bug: 27410215
Change-Id: I3ad490b64a5805b6f3888a9f37fcfbdd0116395e
10 files changed, 89 insertions, 16 deletions
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 9a8c8a86499a..17d306eb8857 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -136,6 +136,12 @@ public interface WindowManagerPolicy { throws RemoteException; /** + * @return true if windows with FLAG_DISMISS_KEYGUARD should be allowed to show even if + * the keyguard is locked. + */ + boolean canShowDismissingWindowWhileLockedLw(); + + /** * Interface to the Window Manager state associated with a particular * window. You can hold on to an instance of this interface from the call * to prepareAddWindow() until removeWindow(). diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl index 171a264eea8b..83d75fba80f9 100644 --- a/core/java/com/android/internal/policy/IKeyguardService.aidl +++ b/core/java/com/android/internal/policy/IKeyguardService.aidl @@ -34,7 +34,7 @@ oneway interface IKeyguardService { void addStateMonitorCallback(IKeyguardStateCallback callback); void verifyUnlock(IKeyguardExitCallback callback); void keyguardDone(boolean authenticated, boolean wakeup); - void dismiss(); + void dismiss(boolean allowWhileOccluded); void onDreamingStarted(); void onDreamingStopped(); diff --git a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl index db3b40b29903..419b1f8feac7 100644 --- a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl +++ b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl @@ -19,4 +19,5 @@ interface IKeyguardStateCallback { void onShowingStateChanged(boolean showing); void onSimSecureStateChanged(boolean simSecure); void onInputRestrictedStateChanged(boolean inputRestricted); + void onTrustedChanged(boolean trusted); }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index b354a4cd60d5..84901ee67e71 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -98,9 +98,9 @@ public class KeyguardService extends Service { } @Override // Binder interface - public void dismiss() { + public void dismiss(boolean allowWhileOccluded) { checkPermission(); - mKeyguardViewMediator.dismiss(); + mKeyguardViewMediator.dismiss(allowWhileOccluded); } @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 cfa4661d7a06..8915573bdece 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -363,7 +363,7 @@ public class KeyguardViewMediator extends SystemUI { UserInfo info = UserManager.get(mContext).getUserInfo(userId); if (info != null && (info.isGuest() || info.isDemo())) { // If we just switched to a guest, try to dismiss keyguard. - dismiss(); + dismiss(false /* allowWhileOccluded */); } } } @@ -500,6 +500,17 @@ public class KeyguardViewMediator extends SystemUI { userId); } } + + @Override + public void onTrustChanged(int userId) { + if (userId == KeyguardUpdateMonitor.getCurrentUser()) { + synchronized (KeyguardViewMediator.this) { + notifyTrustedChangedLocked(mUpdateMonitor.getUserHasTrust(userId)); + } + } + } + + }; ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() { @@ -1253,15 +1264,16 @@ public class KeyguardViewMediator extends SystemUI { /** * Dismiss the keyguard through the security layers. + * @param allowWhileOccluded if true, dismiss the keyguard even if it's currently occluded. */ - public void handleDismiss() { - if (mShowing && !mOccluded) { + public void handleDismiss(boolean allowWhileOccluded) { + if (mShowing && (allowWhileOccluded || !mOccluded)) { mStatusBarKeyguardViewManager.dismiss(); } } - public void dismiss() { - mHandler.sendEmptyMessage(DISMISS); + public void dismiss(boolean allowWhileOccluded) { + mHandler.obtainMessage(DISMISS, allowWhileOccluded ? 1 : 0, 0).sendToTarget(); } /** @@ -1355,6 +1367,9 @@ public class KeyguardViewMediator extends SystemUI { */ public void setCurrentUser(int newUserId) { KeyguardUpdateMonitor.setCurrentUser(newUserId); + synchronized (this) { + notifyTrustedChangedLocked(mUpdateMonitor.getUserHasTrust(newUserId)); + } } private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @@ -1462,7 +1477,7 @@ public class KeyguardViewMediator extends SystemUI { } break; case DISMISS: - handleDismiss(); + handleDismiss(msg.arg1 == 1 ? true : false /* allowWhileOccluded */); break; case START_KEYGUARD_EXIT_ANIM: Trace.beginSection("KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM"); @@ -1982,6 +1997,20 @@ public class KeyguardViewMediator extends SystemUI { } } + private void notifyTrustedChangedLocked(boolean trusted) { + int size = mKeyguardStateCallbacks.size(); + for (int i = size - 1; i >= 0; i--) { + try { + mKeyguardStateCallbacks.get(i).onTrustedChanged(trusted); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to call notifyTrustedChangedLocked", e); + if (e instanceof DeadObjectException) { + mKeyguardStateCallbacks.remove(i); + } + } + } + } + public void addStateMonitorCallback(IKeyguardStateCallback callback) { synchronized (this) { mKeyguardStateCallbacks.add(callback); @@ -1989,8 +2018,10 @@ public class KeyguardViewMediator extends SystemUI { callback.onSimSecureStateChanged(mUpdateMonitor.isSimPinSecure()); callback.onShowingStateChanged(mShowing); callback.onInputRestrictedStateChanged(mInputRestricted); + callback.onTrustedChanged(mUpdateMonitor.getUserHasTrust( + KeyguardUpdateMonitor.getCurrentUser())); } catch (RemoteException e) { - Slog.w(TAG, "Failed to call onShowingStateChanged or onSimSecureStateChanged or onInputRestrictedStateChanged", e); + Slog.w(TAG, "Failed to call to IKeyguardStateCallback", e); } } } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 09c2b2774f68..b0f7038628e7 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -3560,6 +3560,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + @Override + public boolean canShowDismissingWindowWhileLockedLw() { + return false; + } + private void launchAssistLongPressAction() { performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); @@ -5266,7 +5271,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mHandler.post(new Runnable() { @Override public void run() { - mKeyguardDelegate.dismiss(); + mKeyguardDelegate.dismiss(false /* allowWhileOccluded */); } }); } @@ -6511,7 +6516,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override public void run() { // ask the keyguard to prompt the user to authenticate if necessary - mKeyguardDelegate.dismiss(); + mKeyguardDelegate.dismiss(false /* allowWhileOccluded */); } }); } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java index 7e275584a27d..a3a54f11ba95 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java @@ -194,6 +194,13 @@ public class KeyguardServiceDelegate { return mKeyguardState.showing; } + public boolean isTrusted() { + if (mKeyguardService != null) { + return mKeyguardService.isTrusted(); + } + return false; + } + public boolean isInputRestricted() { if (mKeyguardService != null) { mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted(); @@ -215,14 +222,15 @@ public class KeyguardServiceDelegate { public void setOccluded(boolean isOccluded) { if (mKeyguardService != null) { + if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ")"); mKeyguardService.setOccluded(isOccluded); } mKeyguardState.occluded = isOccluded; } - public void dismiss() { + public void dismiss(boolean allowWhileOccluded) { if (mKeyguardService != null) { - mKeyguardService.dismiss(); + mKeyguardService.dismiss(allowWhileOccluded); } } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java index 57e885797e4c..bea31673a58b 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java @@ -81,9 +81,9 @@ public class KeyguardServiceWrapper implements IKeyguardService { } @Override // Binder interface - public void dismiss() { + public void dismiss(boolean allowWhileOccluded) { try { - mService.dismiss(); + mService.dismiss(allowWhileOccluded); } catch (RemoteException e) { Slog.w(TAG , "Remote Exception", e); } @@ -234,6 +234,10 @@ public class KeyguardServiceWrapper implements IKeyguardService { return mKeyguardStateMonitor.isShowing(); } + public boolean isTrusted() { + return mKeyguardStateMonitor.isTrusted(); + } + public boolean isSecure(int userId) { return mKeyguardStateMonitor.isSecure(userId); } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java index 138f068f38ed..f3238c824104 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java @@ -43,6 +43,7 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { private volatile boolean mIsShowing = true; private volatile boolean mSimSecure = true; private volatile boolean mInputRestricted = true; + private volatile boolean mTrusted = false; private int mCurrentUserId; @@ -70,6 +71,10 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { return mInputRestricted; } + public boolean isTrusted() { + return mTrusted; + } + @Override // Binder interface public void onShowingStateChanged(boolean showing) { mIsShowing = showing; @@ -93,12 +98,18 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { mInputRestricted = inputRestricted; } + @Override // Binder interface + public void onTrustedChanged(boolean trusted) { + mTrusted = trusted; + } + public void dump(String prefix, PrintWriter pw) { pw.println(prefix + TAG); prefix += " "; pw.println(prefix + "mIsShowing=" + mIsShowing); pw.println(prefix + "mSimSecure=" + mSimSecure); pw.println(prefix + "mInputRestricted=" + mInputRestricted); + pw.println(prefix + "mTrusted=" + mTrusted); pw.println(prefix + "mCurrentUserId=" + mCurrentUserId); } }
\ No newline at end of file diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index be060d243404..e5eda0522f92 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; @@ -233,6 +234,12 @@ public class WindowAnimator { || (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0; } + // Allow showing a window that dismisses Keyguard if the policy allows it. This is used for + // when the policy knows that the Keyguard can be dismissed without user interaction to + // provide a smooth transition in that case. + allowWhenLocked |= (win.mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0 + && mPolicy.canShowDismissingWindowWhileLockedLw(); + // Only hide windows if the keyguard is active and not animating away. boolean keyguardOn = mPolicy.isKeyguardShowingOrOccluded() && mForceHiding != KEYGUARD_ANIMATING_OUT; |