summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Matt Pietal <mpietal@google.com> 2021-10-01 11:03:16 -0400
committer Matt Pietal <mpietal@google.com> 2022-02-11 20:23:48 +0000
commit21e48cf26bbcd7f13a623e22a25dbc0340c4e4eb (patch)
treea4fe4e4b08ed20f511a5ed8010e8ffc498068e36
parent66460c8ff45eec1a015a6b50e8785b355af08bde (diff)
[DO NOT MERGE] Keyguard - Treat messsages to lock with priority
When switching users and attempting to lock the device, the sysui main thread becomes overwhelmed with events, creating a significant lag between the time a message is posted and processed on the main thread. This can be dangerous when these events are critical for security, such as calls coming from PhoneWindowManager#lockNow() that call KeyguardViewMediator#doKeyguardTimeout(). On older devices with slower CPUs and less memory, the delay in processing can be significant (15 - 30s). The result of not prioritizing these events leads to a window of time where a guest user can switch back to the owner, and gain access to the owner's homescreen without needing to unlock the device with the owner's credentials. As a mitigation, prioritize two events originating in two specific methods to make sure the device locks as soon as possible as well as have the system server preemptively update its local cache. Bug: 151095871 Test: Very manual race condition - follow steps listed in bug Change-Id: I7585a0a5eeb308e0e32a4f77f581556d883b5cda Merged-In: I7585a0a5eeb308e0e32a4f77f581556d883b5cda (cherry picked from commit 28c53ab8bca26af58b45625c1ebba8b9051c107d)
-rw-r--r--core/java/com/android/internal/policy/IKeyguardStateCallback.aidl2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java16
-rw-r--r--services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java6
-rw-r--r--services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java8
4 files changed, 25 insertions, 7 deletions
diff --git a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
index 8e454db4cb04..a8003a1169e9 100644
--- a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
@@ -16,7 +16,7 @@
package com.android.internal.policy;
interface IKeyguardStateCallback {
- void onShowingStateChanged(boolean showing);
+ void onShowingStateChanged(boolean showing, int userId);
void onSimSecureStateChanged(boolean simSecure);
void onInputRestrictedStateChanged(boolean inputRestricted);
void onTrustedChanged(boolean trusted);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 75f4809d752f..d8eda2c1ecc5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1310,7 +1310,9 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
public void doKeyguardTimeout(Bundle options) {
mHandler.removeMessages(KEYGUARD_TIMEOUT);
Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT, options);
- mHandler.sendMessage(msg);
+ // Treat these messages with priority - A call to timeout means the device should lock
+ // as soon as possible and not wait for other messages on the thread to process first.
+ mHandler.sendMessageAtFrontOfQueue(msg);
}
/**
@@ -1497,12 +1499,15 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
* @see #handleShow
*/
private void showLocked(Bundle options) {
- Trace.beginSection("KeyguardViewMediator#showLocked aqcuiring mShowKeyguardWakeLock");
+ Trace.beginSection("KeyguardViewMediator#showLocked acquiring mShowKeyguardWakeLock");
if (DEBUG) Log.d(TAG, "showLocked");
// ensure we stay awake until we are finished displaying the keyguard
mShowKeyguardWakeLock.acquire();
Message msg = mHandler.obtainMessage(SHOW, options);
- mHandler.sendMessage(msg);
+ // Treat these messages with priority - This call can originate from #doKeyguardTimeout,
+ // meaning the device should lock as soon as possible and not wait for other messages on
+ // the thread to process first.
+ mHandler.sendMessageAtFrontOfQueue(msg);
Trace.endSection();
}
@@ -1664,6 +1669,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
case KEYGUARD_TIMEOUT:
synchronized (KeyguardViewMediator.this) {
doKeyguardLocked((Bundle) msg.obj);
+ notifyDefaultDisplayCallbacks(mShowing);
}
break;
case DISMISS:
@@ -2293,7 +2299,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
for (int i = size - 1; i >= 0; i--) {
IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
try {
- callback.onShowingStateChanged(showing);
+ callback.onShowingStateChanged(showing, KeyguardUpdateMonitor.getCurrentUser());
} catch (RemoteException e) {
Slog.w(TAG, "Failed to call onShowingStateChanged", e);
if (e instanceof DeadObjectException) {
@@ -2342,7 +2348,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
mKeyguardStateCallbacks.add(callback);
try {
callback.onSimSecureStateChanged(mUpdateMonitor.isSimPinSecure());
- callback.onShowingStateChanged(mShowing);
+ callback.onShowingStateChanged(mShowing, KeyguardUpdateMonitor.getCurrentUser());
callback.onInputRestrictedStateChanged(mInputRestricted);
callback.onTrustedChanged(mUpdateMonitor.getUserHasTrust(
KeyguardUpdateMonitor.getCurrentUser()));
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 4e848686254a..cf5c587e0494 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -192,6 +192,12 @@ public class KeyguardServiceWrapper implements IKeyguardService {
@Override // Binder interface
public void doKeyguardTimeout(Bundle options) {
+ int userId = mKeyguardStateMonitor.getCurrentUser();
+ if (mKeyguardStateMonitor.isSecure(userId)) {
+ // Preemptively inform the cache that the keyguard will soon be showing, as calls to
+ // doKeyguardTimeout are a signal to lock the device as soon as possible.
+ mKeyguardStateMonitor.onShowingStateChanged(true, userId);
+ }
try {
mService.doKeyguardTimeout(options);
} catch (RemoteException e) {
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 add0b01f1879..f0f62edf8779 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -83,8 +83,14 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
return mHasLockscreenWallpaper;
}
+ public int getCurrentUser() {
+ return mCurrentUserId;
+ }
+
@Override // Binder interface
- public void onShowingStateChanged(boolean showing) {
+ public void onShowingStateChanged(boolean showing, int userId) {
+ if (userId != mCurrentUserId) return;
+
mIsShowing = showing;
mCallback.onShowingChanged();