Merge "Secondary Lockscreen API: improve documentation and rename onSurfaceReady method." into rvc-dev
diff --git a/api/current.txt b/api/current.txt
index 507603d..0c3281c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6843,7 +6843,7 @@
     ctor public DevicePolicyKeyguardService();
     method @Nullable public void dismiss();
     method @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent);
-    method @Nullable public android.view.SurfaceControlViewHost.SurfacePackage onSurfaceReady(@Nullable android.os.IBinder);
+    method @Nullable public android.view.SurfaceControlViewHost.SurfacePackage onCreateKeyguardSurface(@NonNull android.os.IBinder);
   }
 
   public class DevicePolicyManager {
diff --git a/api/system-current.txt b/api/system-current.txt
index ed2ebdd..ee93225 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -873,7 +873,7 @@
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isDeviceProvisioned();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isDeviceProvisioningConfigApplied();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isManagedKiosk();
-    method public boolean isSecondaryLockscreenEnabled(int);
+    method public boolean isSecondaryLockscreenEnabled(@NonNull android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isUnattendedManagedKiosk();
     method @RequiresPermission("android.permission.NOTIFY_PENDING_SYSTEM_UPDATE") public void notifyPendingSystemUpdate(long);
     method @RequiresPermission("android.permission.NOTIFY_PENDING_SYSTEM_UPDATE") public void notifyPendingSystemUpdate(long, boolean);
diff --git a/core/java/android/app/admin/DevicePolicyKeyguardService.java b/core/java/android/app/admin/DevicePolicyKeyguardService.java
index 2ac5ebf..5b7e387 100644
--- a/core/java/android/app/admin/DevicePolicyKeyguardService.java
+++ b/core/java/android/app/admin/DevicePolicyKeyguardService.java
@@ -16,6 +16,7 @@
 
 package android.app.admin;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Service;
 import android.content.Intent;
@@ -27,7 +28,7 @@
 /**
  * Client interface for providing the SystemUI with secondary lockscreen information.
  *
- * <p>An implementation must be provided by the device admin app when
+ * <p>An implementation must be provided by the Profile Owner when
  * {@link DevicePolicyManager#setSecondaryLockscreenEnabled} is set to true and the service must be
  * declared in the manifest as handling the action
  * {@link DevicePolicyManager#ACTION_BIND_SECONDARY_LOCKSCREEN_SERVICE}, otherwise the keyguard
@@ -41,10 +42,11 @@
 
     private final IKeyguardClient mClient = new IKeyguardClient.Stub() {
         @Override
-        public void onSurfaceReady(@Nullable IBinder hostInputToken, IKeyguardCallback callback) {
+        public void onCreateKeyguardSurface(@Nullable IBinder hostInputToken,
+                IKeyguardCallback callback) {
             mCallback = callback;
             SurfaceControlViewHost.SurfacePackage surfacePackage =
-                    DevicePolicyKeyguardService.this.onSurfaceReady(hostInputToken);
+                    DevicePolicyKeyguardService.this.onCreateKeyguardSurface(hostInputToken);
 
             if (mCallback != null) {
                 try {
@@ -63,13 +65,27 @@
     }
 
     /**
-     * Called by keyguard once the host surface for the secondary lockscreen is ready to display
-     * remote content.
+     * Called by keyguard once the host surface for the secondary lockscreen is created and ready to
+     * display remote content.
+     *
+     * <p>Implementations are expected to create a Surface hierarchy with view elements for the
+     * admin's desired secondary lockscreen UI, and optionally, interactive elements
+     * that will allow the user to dismiss the secondary lockscreen, subject to the implementation's
+     * requirements. The view hierarchy is expected to be embedded via the
+     * {@link SurfaceControlViewHost} APIs, and returned as a SurfacePackage via
+     * {@link SurfaceControlViewHost#getSurfacePackage}for the keyguard to reparent into its
+     * prepared SurfaceView.
+     *
+     * @param hostInputToken Token of the SurfaceView which will hosting the embedded hierarchy,
+     *                       primarily required by {@link SurfaceControlViewHost} for ANR reporting.
+     *                       It will be provided by the keyguard via
+     *                       {@link android.view.SurfaceView#getHostToken}.
      * @return the {@link SurfaceControlViewHost.SurfacePackage} for the Surface the
      *      secondary lockscreen content is attached to.
      */
     @Nullable
-    public SurfaceControlViewHost.SurfacePackage onSurfaceReady(@Nullable IBinder hostInputToken) {
+    public SurfaceControlViewHost.SurfacePackage onCreateKeyguardSurface(
+            @NonNull IBinder hostInputToken) {
         return null;
     }
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 24af5af..4c4afb0 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -8658,11 +8658,11 @@
      * @hide
      */
     @SystemApi
-    public boolean isSecondaryLockscreenEnabled(int userId) {
+    public boolean isSecondaryLockscreenEnabled(@NonNull UserHandle userHandle) {
         throwIfParentInstance("isSecondaryLockscreenEnabled");
         if (mService != null) {
             try {
-                return mService.isSecondaryLockscreenEnabled(userId);
+                return mService.isSecondaryLockscreenEnabled(userHandle);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 514677e..fc1eb0a 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -255,7 +255,7 @@
     String[] getAccountTypesWithManagementDisabledAsUser(int userId, in boolean parent);
 
     void setSecondaryLockscreenEnabled(in ComponentName who, boolean enabled);
-    boolean isSecondaryLockscreenEnabled(int userId);
+    boolean isSecondaryLockscreenEnabled(in UserHandle userHandle);
 
     void setLockTaskPackages(in ComponentName who, in String[] packages);
     String[] getLockTaskPackages(in ComponentName who);
diff --git a/core/java/android/app/admin/IKeyguardClient.aidl b/core/java/android/app/admin/IKeyguardClient.aidl
index 4bfd990..9b2f3f4 100644
--- a/core/java/android/app/admin/IKeyguardClient.aidl
+++ b/core/java/android/app/admin/IKeyguardClient.aidl
@@ -23,5 +23,5 @@
  * @hide
  */
 interface IKeyguardClient {
-    oneway void onSurfaceReady(in IBinder hostInputToken, in IKeyguardCallback keyguardCallback);
+    oneway void onCreateKeyguardSurface(in IBinder hostInputToken, in IKeyguardCallback keyguardCallback);
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java b/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java
index 85724a9..7eb5a8f 100644
--- a/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java
@@ -170,9 +170,15 @@
 
     private void onSurfaceReady() {
         try {
-            mClient.onSurfaceReady(mView.getHostToken(), mCallback);
+            IBinder hostToken = mView.getHostToken();
+            // Should never be null when SurfaceView is attached to window.
+            if (hostToken != null) {
+                mClient.onCreateKeyguardSurface(hostToken, mCallback);
+            } else {
+                hide();
+            }
         } catch (RemoteException e) {
-            Log.e(TAG, "Error in onSurfaceReady", e);
+            Log.e(TAG, "Error in onCreateKeyguardSurface", e);
             dismiss(KeyguardUpdateMonitor.getCurrentUser());
         }
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 90df124..18357a9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -962,18 +962,19 @@
 
     private void updateSecondaryLockscreenRequirement(int userId) {
         Intent oldIntent = mSecondaryLockscreenRequirement.get(userId);
-        boolean enabled = mDevicePolicyManager.isSecondaryLockscreenEnabled(userId);
+        boolean enabled = mDevicePolicyManager.isSecondaryLockscreenEnabled(UserHandle.of(userId));
         boolean changed = false;
 
         if (enabled && (oldIntent == null)) {
-            ResolveInfo resolveInfo =
-                    mContext.getPackageManager().resolveService(
-                            new Intent(
-                                    DevicePolicyManager.ACTION_BIND_SECONDARY_LOCKSCREEN_SERVICE),
-                            0);
+            Intent intent = new Intent(
+                    DevicePolicyManager.ACTION_BIND_SECONDARY_LOCKSCREEN_SERVICE);
+            ComponentName profileOwnerComponent =
+                    mDevicePolicyManager.getProfileOwnerAsUser(userId);
+            intent.setComponent(profileOwnerComponent);
+            ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent, 0);
             if (resolveInfo != null) {
                 Intent newIntent = new Intent();
-                newIntent.setComponent(resolveInfo.serviceInfo.getComponentName());
+                newIntent.setComponent(profileOwnerComponent);
                 mSecondaryLockscreenRequirement.put(userId, newIntent);
                 changed = true;
             }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java
index 0e9a245..cf1299f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java
@@ -105,7 +105,7 @@
             IKeyguardCallback callback = (IKeyguardCallback) invocation.getArguments()[1];
             callback.onRemoteContentReady(mSurfacePackage);
             return null;
-        }).when(mKeyguardClient).onSurfaceReady(any(), any(IKeyguardCallback.class));
+        }).when(mKeyguardClient).onCreateKeyguardSurface(any(), any(IKeyguardCallback.class));
 
         mTestController.show(mServiceIntent);
 
@@ -119,7 +119,7 @@
             IKeyguardCallback callback = (IKeyguardCallback) invocation.getArguments()[1];
             callback.onDismiss();
             return null;
-        }).when(mKeyguardClient).onSurfaceReady(any(), any(IKeyguardCallback.class));
+        }).when(mKeyguardClient).onCreateKeyguardSurface(any(), any(IKeyguardCallback.class));
 
         mTestController.show(mServiceIntent);
 
@@ -133,7 +133,7 @@
             IKeyguardCallback callback = (IKeyguardCallback) invocation.getArguments()[1];
             callback.onRemoteContentReady(mSurfacePackage);
             return null;
-        }).when(mKeyguardClient).onSurfaceReady(any(), any(IKeyguardCallback.class));
+        }).when(mKeyguardClient).onCreateKeyguardSurface(any(), any(IKeyguardCallback.class));
 
         mTestController.show(mServiceIntent);
         SurfaceView v = verifySurfaceReady();
@@ -151,9 +151,9 @@
     }
 
     @Test
-    public void testDismissed_onSurfaceReady_RemoteException() throws Exception {
+    public void testDismissed_onCreateKeyguardSurface_RemoteException() throws Exception {
         doThrow(new RemoteException()).when(mKeyguardClient)
-                .onSurfaceReady(any(), any(IKeyguardCallback.class));
+                .onCreateKeyguardSurface(any(), any(IKeyguardCallback.class));
 
         mTestController.show(mServiceIntent);
 
@@ -161,9 +161,9 @@
     }
 
     @Test
-    public void testDismissed_onSurfaceReady_timeout() throws Exception {
-        // Mocked KeyguardClient never handles the onSurfaceReady, so the operation times out,
-        // resulting in the view being dismissed.
+    public void testDismissed_onCreateKeyguardSurface_timeout() throws Exception {
+        // Mocked KeyguardClient never handles the onCreateKeyguardSurface, so the operation
+        // times out, resulting in the view being dismissed.
         doAnswer(answerVoid(Runnable::run)).when(mHandler)
                 .postDelayed(any(Runnable.class), anyLong());
 
@@ -178,7 +178,7 @@
         verify(mParent).addView(captor.capture());
 
         mTestableLooper.processAllMessages();
-        verify(mKeyguardClient).onSurfaceReady(any(), any(IKeyguardCallback.class));
+        verify(mKeyguardClient).onCreateKeyguardSurface(any(), any(IKeyguardCallback.class));
         return captor.getValue();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index bd50a73..9d9ba1b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -38,6 +38,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.TrustManager;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -567,7 +568,10 @@
         ResolveInfo resolveInfo = new ResolveInfo();
         resolveInfo.serviceInfo = serviceInfo;
         when(mPackageManager.resolveService(any(Intent.class), eq(0))).thenReturn(resolveInfo);
-        when(mDevicePolicyManager.isSecondaryLockscreenEnabled(eq(user))).thenReturn(true, false);
+        when(mDevicePolicyManager.isSecondaryLockscreenEnabled(eq(UserHandle.of(user))))
+                .thenReturn(true, false);
+        when(mDevicePolicyManager.getProfileOwnerAsUser(user))
+                .thenReturn(new ComponentName(packageName, cls));
 
         // Initially null.
         assertThat(mKeyguardUpdateMonitor.getSecondaryLockscreenRequirement(user)).isNull();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6ab5303..ef183a2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11440,9 +11440,9 @@
     }
 
     @Override
-    public boolean isSecondaryLockscreenEnabled(int userId) {
+    public boolean isSecondaryLockscreenEnabled(@NonNull UserHandle userHandle) {
         synchronized (getLockObject()) {
-            return getUserData(userId).mSecondaryLockscreenEnabled;
+            return getUserData(userHandle.getIdentifier()).mSecondaryLockscreenEnabled;
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 5bf0d03..7c6ac17 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -4267,12 +4267,14 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
 
         // Initial state is disabled.
-        assertFalse(dpm.isSecondaryLockscreenEnabled(DpmMockContext.CALLER_USER_HANDLE));
+        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
+                DpmMockContext.CALLER_USER_HANDLE)));
 
         // Profile owner can set enabled state.
         setAsProfileOwner(admin1);
         dpm.setSecondaryLockscreenEnabled(admin1, true);
-        assertTrue(dpm.isSecondaryLockscreenEnabled(DpmMockContext.CALLER_USER_HANDLE));
+        assertTrue(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
+                DpmMockContext.CALLER_USER_HANDLE)));
 
         // Managed profile managed by different package is unaffiliated - cannot set enabled.
         final int managedProfileUserId = 15;
@@ -4289,24 +4291,26 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
 
         // Initial state is disabled.
-        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.USER_SYSTEM));
+        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(UserHandle.USER_SYSTEM)));
 
         // Device owners can set enabled state.
         setupDeviceOwner();
         dpm.setSecondaryLockscreenEnabled(admin1, true);
-        assertTrue(dpm.isSecondaryLockscreenEnabled(UserHandle.USER_SYSTEM));
+        assertTrue(dpm.isSecondaryLockscreenEnabled(UserHandle.of(UserHandle.USER_SYSTEM)));
     }
 
     public void testSecondaryLockscreen_nonOwner() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
 
         // Initial state is disabled.
-        assertFalse(dpm.isSecondaryLockscreenEnabled(DpmMockContext.CALLER_USER_HANDLE));
+        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
+                DpmMockContext.CALLER_USER_HANDLE)));
 
         // Non-DO/PO cannot set enabled state.
         assertExpectException(SecurityException.class, /* messageRegex= */ null,
                 () -> dpm.setSecondaryLockscreenEnabled(admin1, true));
-        assertFalse(dpm.isSecondaryLockscreenEnabled(DpmMockContext.CALLER_USER_HANDLE));
+        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
+                DpmMockContext.CALLER_USER_HANDLE)));
     }
 
     public void testIsDeviceManaged() throws Exception {