summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/admin/DevicePolicyKeyguardService.java24
-rw-r--r--packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java33
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java11
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java9
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java3
6 files changed, 80 insertions, 22 deletions
diff --git a/core/java/android/app/admin/DevicePolicyKeyguardService.java b/core/java/android/app/admin/DevicePolicyKeyguardService.java
index db833ec478bd..473725f40cf1 100644
--- a/core/java/android/app/admin/DevicePolicyKeyguardService.java
+++ b/core/java/android/app/admin/DevicePolicyKeyguardService.java
@@ -16,12 +16,15 @@
package android.app.admin;
+import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.SurfaceControlViewHost;
@@ -41,27 +44,34 @@ import android.view.SurfaceControlViewHost;
@SystemApi
public class DevicePolicyKeyguardService extends Service {
private static final String TAG = "DevicePolicyKeyguardService";
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
private IKeyguardCallback mCallback;
private final IKeyguardClient mClient = new IKeyguardClient.Stub() {
+ @MainThread
@Override
public void onCreateKeyguardSurface(@Nullable IBinder hostInputToken,
- IKeyguardCallback callback) {
+ @NonNull IKeyguardCallback callback) {
mCallback = callback;
- SurfaceControlViewHost.SurfacePackage surfacePackage =
- DevicePolicyKeyguardService.this.onCreateKeyguardSurface(hostInputToken);
+ mHandler.post(() -> {
+ SurfaceControlViewHost.SurfacePackage surfacePackage =
+ DevicePolicyKeyguardService.this.onCreateKeyguardSurface(hostInputToken);
- if (mCallback != null) {
try {
mCallback.onRemoteContentReady(surfacePackage);
} catch (RemoteException e) {
Log.e(TAG, "Failed to return created SurfacePackage", e);
}
- }
+ });
}
};
@Override
+ public void onDestroy() {
+ mHandler.removeCallbacksAndMessages(null);
+ }
+
+ @Override
@Nullable
public final IBinder onBind(@Nullable Intent intent) {
return mClient.asBinder();
@@ -97,6 +107,10 @@ public class DevicePolicyKeyguardService extends Service {
*/
@Nullable
public void dismiss() {
+ if (mCallback == null) {
+ Log.w(TAG, "KeyguardCallback was unexpectedly null");
+ return;
+ }
try {
mCallback.onDismiss();
} catch (RemoteException e) {
diff --git a/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java b/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java
index 7eb5a8f2b06c..e99245fa438f 100644
--- a/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java
@@ -34,6 +34,8 @@ import android.view.ViewGroup;
import com.android.internal.annotations.VisibleForTesting;
+import java.util.NoSuchElementException;
+
/**
* Encapsulates all logic for secondary lockscreen state management.
*/
@@ -79,7 +81,9 @@ public class AdminSecondaryLockScreenController {
private final IKeyguardCallback mCallback = new IKeyguardCallback.Stub() {
@Override
public void onDismiss() {
- dismiss(UserHandle.getCallingUserId());
+ mHandler.post(() -> {
+ dismiss(UserHandle.getCallingUserId());
+ });
}
@Override
@@ -91,7 +95,9 @@ public class AdminSecondaryLockScreenController {
if (surfacePackage != null) {
mView.setChildSurfacePackage(surfacePackage);
} else {
- dismiss(KeyguardUpdateMonitor.getCurrentUser());
+ mHandler.post(() -> {
+ dismiss(KeyguardUpdateMonitor.getCurrentUser());
+ });
}
}
};
@@ -122,6 +128,7 @@ public class AdminSecondaryLockScreenController {
// If the remote content is not readied within the timeout period,
// move on without the secondary lockscreen.
dismiss(userId);
+ Log.w(TAG, "Timed out waiting for secondary lockscreen content.");
},
REMOTE_CONTENT_READY_TIMEOUT_MILLIS);
}
@@ -150,8 +157,12 @@ public class AdminSecondaryLockScreenController {
* Displays the Admin security Surface view.
*/
public void show(Intent serviceIntent) {
- mContext.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
- mParent.addView(mView);
+ if (mClient == null) {
+ mContext.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
+ }
+ if (!mView.isAttachedToWindow()) {
+ mParent.addView(mView);
+ }
}
/**
@@ -162,7 +173,11 @@ public class AdminSecondaryLockScreenController {
mParent.removeView(mView);
}
if (mClient != null) {
- mClient.asBinder().unlinkToDeath(mKeyguardClientDeathRecipient, 0);
+ try {
+ mClient.asBinder().unlinkToDeath(mKeyguardClientDeathRecipient, 0);
+ } catch (NoSuchElementException e) {
+ Log.w(TAG, "IKeyguardClient death recipient already released");
+ }
mContext.unbindService(mConnection);
mClient = null;
}
@@ -185,10 +200,12 @@ public class AdminSecondaryLockScreenController {
private void dismiss(int userId) {
mHandler.removeCallbacksAndMessages(null);
- if (mView != null && mView.isAttachedToWindow()
- && userId == KeyguardUpdateMonitor.getCurrentUser()) {
+ if (mView.isAttachedToWindow() && userId == KeyguardUpdateMonitor.getCurrentUser()) {
hide();
- mKeyguardCallback.dismiss(true, userId);
+ if (mKeyguardCallback != null) {
+ mKeyguardCallback.dismiss(/* securityVerified= */ true, userId,
+ /* bypassSecondaryLockScreen= */true);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
index d5a08dda9853..aa2fe3c7f8fc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
@@ -85,7 +85,8 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
// the user proved presence via some other way to the trust agent.
Log.i(TAG, "TrustAgent dismissed Keyguard.");
}
- dismiss(false /* authenticated */, userId);
+ dismiss(false /* authenticated */, userId,
+ /* bypassSecondaryLockScreen */ false);
} else {
mViewMediatorCallback.playTrustedSound();
}
@@ -190,7 +191,7 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
* @return True if the keyguard is done.
*/
public boolean dismiss(int targetUserId) {
- return dismiss(false, targetUserId);
+ return dismiss(false, targetUserId, false);
}
public boolean handleBackKey() {
@@ -206,8 +207,10 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
}
@Override
- public boolean dismiss(boolean authenticated, int targetUserId) {
- return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated, targetUserId);
+ public boolean dismiss(boolean authenticated, int targetUserId,
+ boolean bypassSecondaryLockScreen) {
+ return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated, targetUserId,
+ bypassSecondaryLockScreen);
}
/**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
index 49dcfffb0d72..e38472745234 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
@@ -25,6 +25,15 @@ public interface KeyguardSecurityCallback {
void dismiss(boolean securityVerified, int targetUserId);
/**
+ * Dismiss the given security screen.
+ * @param securityVerified true if the user correctly entered credentials for the given screen.
+ * @param targetUserId a user that needs to be the foreground user at the dismissal completion.
+ * @param bypassSecondaryLockScreen true if the user can bypass the secondary lock screen,
+ * if any, during this dismissal.
+ */
+ void dismiss(boolean securityVerified, int targetUserId, boolean bypassSecondaryLockScreen);
+
+ /**
* Manually report user activity to keep the device awake.
*/
void userActivity();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index ba8a1a945a77..1e1ce4e6d159 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -115,7 +115,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
// Used to notify the container when something interesting happens.
public interface SecurityCallback {
- public boolean dismiss(boolean authenticated, int targetUserId);
+ public boolean dismiss(boolean authenticated, int targetUserId,
+ boolean bypassSecondaryLockScreen);
public void userActivity();
public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput);
@@ -504,9 +505,12 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
* @param authenticated true if the user entered the correct authentication
* @param targetUserId a user that needs to be the foreground user at the finish (if called)
* completion.
+ * @param bypassSecondaryLockScreen true if the user is allowed to bypass the secondary
+ * secondary lock screen requirement, if any.
* @return true if keyguard is done
*/
- boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId) {
+ boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId,
+ boolean bypassSecondaryLockScreen) {
if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
boolean finish = false;
boolean strongAuth = false;
@@ -555,7 +559,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
}
}
// Check for device admin specified additional security measures.
- if (finish) {
+ if (finish && !bypassSecondaryLockScreen) {
Intent secondaryLockscreenIntent =
mUpdateMonitor.getSecondaryLockscreenRequirement(targetUserId);
if (secondaryLockscreenIntent != null) {
@@ -636,8 +640,15 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
mUpdateMonitor.cancelFaceAuth();
}
+ @Override
public void dismiss(boolean authenticated, int targetId) {
- mSecurityCallback.dismiss(authenticated, targetId);
+ dismiss(authenticated, targetId, /* bypassSecondaryLockScreen */ false);
+ }
+
+ @Override
+ public void dismiss(boolean authenticated, int targetId,
+ boolean bypassSecondaryLockScreen) {
+ mSecurityCallback.dismiss(authenticated, targetId, bypassSecondaryLockScreen);
}
public boolean isVerifyUnlockOnly() {
@@ -689,6 +700,9 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
@Override
public void dismiss(boolean securityVerified, int targetUserId) { }
@Override
+ public void dismiss(boolean authenticated, int targetId,
+ boolean bypassSecondaryLockScreen) { }
+ @Override
public void onUserInput() { }
@Override
public void reset() {}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java
index cf1299fc66e0..ce032c94deab 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java
@@ -115,6 +115,7 @@ public class AdminSecondaryLockScreenControllerTest extends SysuiTestCase {
@Test
public void testShow_dismissedByCallback() throws Exception {
+ doAnswer(answerVoid(Runnable::run)).when(mHandler).post(any(Runnable.class));
doAnswer(invocation -> {
IKeyguardCallback callback = (IKeyguardCallback) invocation.getArguments()[1];
callback.onDismiss();
@@ -184,7 +185,7 @@ public class AdminSecondaryLockScreenControllerTest extends SysuiTestCase {
private void verifyViewDismissed(SurfaceView v) throws Exception {
verify(mParent).removeView(v);
- verify(mKeyguardCallback).dismiss(true, TARGET_USER_ID);
+ verify(mKeyguardCallback).dismiss(true, TARGET_USER_ID, true);
assertThat(mContext.isBound(mComponentName)).isFalse();
}
}