Merge "Allow clipboard on virtual devices when the default device is locked." into main
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 2d55403..545ba8e 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -26,6 +26,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.annotation.UserIdInt;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManager.PasswordComplexity;
 import android.app.admin.PasswordMetrics;
@@ -736,7 +737,7 @@
      * @see #isKeyguardLocked()
      */
     public boolean isDeviceLocked() {
-        return isDeviceLocked(mContext.getUserId());
+        return isDeviceLocked(mContext.getUserId(), mContext.getDeviceId());
     }
 
     /**
@@ -746,8 +747,17 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public boolean isDeviceLocked(int userId) {
+        return isDeviceLocked(userId, mContext.getDeviceId());
+    }
+
+    /**
+     * Per-user per-device version of {@link #isDeviceLocked()}.
+     *
+     * @hide
+     */
+    public boolean isDeviceLocked(@UserIdInt int userId, int deviceId) {
         try {
-            return mTrustManager.isDeviceLocked(userId, mContext.getAssociatedDisplayId());
+            return mTrustManager.isDeviceLocked(userId, deviceId);
         } catch (RemoteException e) {
             return false;
         }
@@ -769,7 +779,7 @@
      * @see #isKeyguardSecure()
      */
     public boolean isDeviceSecure() {
-        return isDeviceSecure(mContext.getUserId());
+        return isDeviceSecure(mContext.getUserId(), mContext.getDeviceId());
     }
 
     /**
@@ -779,8 +789,17 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public boolean isDeviceSecure(int userId) {
+        return isDeviceSecure(userId, mContext.getDeviceId());
+    }
+
+    /**
+     * Per-user per-device version of {@link #isDeviceSecure()}.
+     *
+     * @hide
+     */
+    public boolean isDeviceSecure(@UserIdInt int userId, int deviceId) {
         try {
-            return mTrustManager.isDeviceSecure(userId, mContext.getAssociatedDisplayId());
+            return mTrustManager.isDeviceSecure(userId, deviceId);
         } catch (RemoteException e) {
             return false;
         }
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index a5e5135..70c25ea 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -34,8 +34,8 @@
     void unregisterTrustListener(in ITrustListener trustListener);
     void reportKeyguardShowingChanged();
     void setDeviceLockedForUser(int userId, boolean locked);
-    boolean isDeviceLocked(int userId, int displayId);
-    boolean isDeviceSecure(int userId, int displayId);
+    boolean isDeviceLocked(int userId, int deviceId);
+    boolean isDeviceSecure(int userId, int deviceId);
     @EnforcePermission("TRUST_LISTENER")
     boolean isTrustUsuallyManaged(int userId);
     void unlockedByBiometricForUser(int userId, in BiometricSourceType source);
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index c29d9bd..f085647 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -108,7 +108,7 @@
         final boolean credentialRequested = Utils.isCredentialRequested(promptInfo);
 
         final boolean credentialAvailable = trustManager.isDeviceSecure(userId,
-                context.getAssociatedDisplayId());
+                context.getDeviceId());
 
         // Assuming that biometric authenticators are listed in priority-order, the rest of this
         // function will attempt to find the first authenticator that's as strong or stronger than
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 76dde54..e3c0cf7 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -646,7 +646,7 @@
                             intendingUid,
                             intendingUserId,
                             intendingDeviceId)
-                    || isDeviceLocked(intendingUserId)) {
+                    || isDeviceLocked(intendingUserId, deviceId)) {
                 return null;
             }
             synchronized (mLock) {
@@ -686,7 +686,7 @@
                             intendingUserId,
                             intendingDeviceId,
                             false)
-                    || isDeviceLocked(intendingUserId)) {
+                    || isDeviceLocked(intendingUserId, deviceId)) {
                 return null;
             }
             synchronized (mLock) {
@@ -710,7 +710,7 @@
                             intendingUserId,
                             intendingDeviceId,
                             false)
-                    || isDeviceLocked(intendingUserId)) {
+                    || isDeviceLocked(intendingUserId, deviceId)) {
                 return false;
             }
             synchronized (mLock) {
@@ -785,7 +785,7 @@
                             intendingUserId,
                             intendingDeviceId,
                             false)
-                    || isDeviceLocked(intendingUserId)) {
+                    || isDeviceLocked(intendingUserId, deviceId)) {
                 return false;
             }
             synchronized (mLock) {
@@ -814,7 +814,7 @@
                             intendingUserId,
                             intendingDeviceId,
                             false)
-                    || isDeviceLocked(intendingUserId)) {
+                    || isDeviceLocked(intendingUserId, deviceId)) {
                 return null;
             }
             synchronized (mLock) {
@@ -1150,12 +1150,12 @@
                 && text.equals(clipboard.primaryClip.getItemAt(0).getText());
     }
 
-    private boolean isDeviceLocked(@UserIdInt int userId) {
+    private boolean isDeviceLocked(@UserIdInt int userId, int deviceId) {
         final long token = Binder.clearCallingIdentity();
         try {
             final KeyguardManager keyguardManager = getContext().getSystemService(
                     KeyguardManager.class);
-            return keyguardManager != null && keyguardManager.isDeviceLocked(userId);
+            return keyguardManager != null && keyguardManager.isDeviceLocked(userId, deviceId);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 635e11b..f82f08b 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -70,7 +70,6 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.Xml;
-import android.view.Display;
 import android.view.IWindowManager;
 import android.view.WindowManagerGlobal;
 
@@ -79,7 +78,6 @@
 import com.android.internal.infra.AndroidFuture;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.widget.LockPatternUtils;
-import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 
@@ -1523,57 +1521,13 @@
             mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
         }
 
-        /**
-         * @param uid: uid of the calling app (obtained via getCallingUid())
-         * @param displayId: the id of a Display
-         * @return Returns true if both of the following conditions hold -
-         * 1) the uid belongs to an app instead of a system core component; and
-         * 2) either the uid is running on a virtual device or the displayId
-         *    is owned by a virtual device
-         */
-        private boolean isAppOrDisplayOnAnyVirtualDevice(int uid, int displayId) {
-            if (UserHandle.isCore(uid)) {
-                return false;
-            }
-
-            if (mVirtualDeviceManager == null) {
-                mVirtualDeviceManager = LocalServices.getService(
-                        VirtualDeviceManagerInternal.class);
-                if (mVirtualDeviceManager == null) {
-                    // VirtualDeviceManager service may not have been published
-                    return false;
-                }
-            }
-
-            switch (displayId) {
-                case Display.INVALID_DISPLAY:
-                    // There is no Display object associated with the Context of the calling app.
-                    if (mVirtualDeviceManager.isAppRunningOnAnyVirtualDevice(uid)) {
-                        return true;
-                    }
-                    break;
-                case Display.DEFAULT_DISPLAY:
-                    // The DEFAULT_DISPLAY is by definition not virtual.
-                    break;
-                default:
-                    // Other display IDs can belong to logical displays created for other purposes.
-                    if (mVirtualDeviceManager.isDisplayOwnedByAnyVirtualDevice(displayId)) {
-                        return true;
-                    }
-                    break;
-            }
-            return false;
-        }
-
         @Override
-        public boolean isDeviceLocked(int userId, int displayId) throws RemoteException {
-            int uid = getCallingUid();
-            if (isAppOrDisplayOnAnyVirtualDevice(uid, displayId)) {
-                // Virtual displays are considered insecure because they may be used for streaming
-                // to other devices.
+        public boolean isDeviceLocked(int userId, int deviceId) throws RemoteException {
+            if (deviceId != Context.DEVICE_ID_DEFAULT) {
+                // Virtual devices are considered insecure.
                 return false;
             }
-            userId = ActivityManager.handleIncomingUser(getCallingPid(), uid, userId,
+            userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
                     false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
 
             final long token = Binder.clearCallingIdentity();
@@ -1588,15 +1542,12 @@
         }
 
         @Override
-        public boolean isDeviceSecure(int userId, int displayId) throws RemoteException {
-            int uid = getCallingUid();
-            if (isAppOrDisplayOnAnyVirtualDevice(uid, displayId)) {
-                // Virtual displays are considered insecure because they may be used for streaming
-                // to other devices.
+        public boolean isDeviceSecure(int userId, int deviceId) throws RemoteException {
+            if (deviceId != Context.DEVICE_ID_DEFAULT) {
+                // Virtual devices are considered insecure.
                 return false;
             }
-
-            userId = ActivityManager.handleIncomingUser(getCallingPid(), uid, userId,
+            userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
                     false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
 
             final long token = Binder.clearCallingIdentity();