DPM.isDeviceOwnerApp() and getDeviceOwner() now check calling user

- Previously on MNC, they would return the same result regardless who
the calling user is.

- Now they properly take DO user-id into account.  Meaning, they'll
always return false and null respectively, if the calling user doesn't
run device owner.

- Note isDeviceOwnerApp() is a public API and getDeviceOwner() is
a system API.  Meaning we're changing the behavior or non-private
APIs.

- Also cleaned up hidden APIs, and gave them explicit suffixes
to avoid confusion.  Bundled code should prefer them for clarity.

Now we have:

* APIs that work cross-users: They all require MANAGE_USERS.
boolean isDeviceOwnerAppOnAnyUser(String packageName)
ComponentName getDeviceOwnerComponentOnAnyUser()

int getDeviceOwnerUserId()
boolean isDeviceOwnedByDeviceOwner()

String getDeviceOwnerNameOnAnyUser()

* APIs that work within user.  No permissions are required.

boolean isDeviceOwnerAppOnCallingUser(String packageName)
ComponentName getDeviceOwnerComponentOnCallingUser()

Bug 24676413

Change-Id: I751a907c7aaf7b019335d67065d183236effaa80
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 1c65c94..9aac170 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -89,6 +89,10 @@
     private final Context mContext;
     private final IDevicePolicyManager mService;
 
+    // TODO Use it everywhere.
+    private static final String REMOTE_EXCEPTION_MESSAGE =
+            "Failed to talk with device policy manager service";
+
     private DevicePolicyManager(Context context) {
         this(context, IDevicePolicyManager.Stub.asInterface(
                         ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)));
@@ -686,7 +690,7 @@
      * extra field. This will invoke a UI to bring the user through adding the profile owner admin
      * to remotely control restrictions on the user.
      *
-     * <p>The intent must be invoked via {@link Activity#startActivityForResult()} to receive the
+     * <p>The intent must be invoked via {@link Activity#startActivityForResult} to receive the
      * result of whether or not the user approved the action. If approved, the result will
      * be {@link Activity#RESULT_OK} and the component will be set as an active admin as well
      * as a profile owner.
@@ -2765,37 +2769,94 @@
      * the setup process.
      * @param packageName the package name of the app, to compare with the registered device owner
      * app, if any.
-     * @return whether or not the package is registered as the device owner app.  Note this method
-     * does *not* check weather the device owner is actually running on the current user.
+     * @return whether or not the package is registered as the device owner app.
      */
     public boolean isDeviceOwnerApp(String packageName) {
+        return isDeviceOwnerAppOnCallingUser(packageName);
+    }
+
+    /**
+     * @return true if a package is registered as device owner, only when it's running on the
+     * calling user.
+     *
+     * <p>Same as {@link #isDeviceOwnerApp}, but bundled code should use it for clarity.
+     * @hide
+     */
+    public boolean isDeviceOwnerAppOnCallingUser(String packageName) {
+        return isDeviceOwnerAppOnAnyUserInner(packageName, /* callingUserOnly =*/ true);
+    }
+
+    /**
+     * @return true if a package is registered as device owner, even if it's running on a different
+     * user.
+     *
+     * <p>Requires the MANAGE_USERS permission.
+     *
+     * @hide
+     */
+    public boolean isDeviceOwnerAppOnAnyUser(String packageName) {
+        return isDeviceOwnerAppOnAnyUserInner(packageName, /* callingUserOnly =*/ false);
+    }
+
+    /**
+     * @return device owner component name, only when it's running on the calling user.
+     *
+     * @hide
+     */
+    public ComponentName getDeviceOwnerComponentOnCallingUser() {
+        return getDeviceOwnerComponentInner(/* callingUserOnly =*/ true);
+    }
+
+    /**
+     * @return device owner component name, even if it's running on a different user.
+     *
+     * <p>Requires the MANAGE_USERS permission.
+     *
+     * @hide
+     */
+    public ComponentName getDeviceOwnerComponentOnAnyUser() {
+        return getDeviceOwnerComponentInner(/* callingUserOnly =*/ false);
+    }
+
+    private boolean isDeviceOwnerAppOnAnyUserInner(String packageName, boolean callingUserOnly) {
         if (packageName == null) {
             return false;
         }
-        final ComponentName deviceOwner = getDeviceOwnerComponent();
+        final ComponentName deviceOwner = getDeviceOwnerComponentInner(callingUserOnly);
         if (deviceOwner == null) {
             return false;
         }
         return packageName.equals(deviceOwner.getPackageName());
     }
 
-    /**
-     * @hide
-     * Redirect to isDeviceOwnerApp.
-     */
-    public boolean isDeviceOwner(String packageName) {
-        return isDeviceOwnerApp(packageName);
+    private ComponentName getDeviceOwnerComponentInner(boolean callingUserOnly) {
+        if (mService != null) {
+            try {
+                return mService.getDeviceOwnerComponent(callingUserOnly);
+            } catch (RemoteException re) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE);
+            }
+        }
+        return null;
     }
 
     /**
-     * Check whether a given component is registered as a device owner.
-     * Note this method does *not* check weather the device owner is actually running on the current
-     * user.
+     * @return ID of the user who runs device owner, or {@link UserHandle#USER_NULL} if there's
+     * no device owner.
+     *
+     * <p>Requires the MANAGE_USERS permission.
      *
      * @hide
      */
-    public boolean isDeviceOwner(ComponentName who) {
-        return (who != null) && who.equals(getDeviceOwner());
+    public int getDeviceOwnerUserId() {
+        if (mService != null) {
+            try {
+                return mService.getDeviceOwnerUserId();
+            } catch (RemoteException re) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE);
+            }
+        }
+        return UserHandle.USER_NULL;
     }
 
     /**
@@ -2818,46 +2879,43 @@
     }
 
     /**
-     * Returns the device owner package name.  Note this method will still return the device owner
-     * package name even if it's running on a different user.
+     * Returns the device owner package name, only if it's running on the calling user.
+     *
+     * <p>Bundled components should use {@code getDeviceOwnerComponentOnCallingUser()} for clarity.
      *
      * @hide
      */
     @SystemApi
     public String getDeviceOwner() {
-        final ComponentName componentName = getDeviceOwnerComponent();
-        return componentName == null ? null : componentName.getPackageName();
+        final ComponentName name = getDeviceOwnerComponentOnCallingUser();
+        return name != null ? name.getPackageName() : null;
     }
 
     /**
-     * Returns the device owner name.  Note this method will still return the device owner
-     * name even if it's running on a different user.
+     * @return true if the device is managed by any device owner.
+     *
+     * <p>Requires the MANAGE_USERS permission.
      *
      * @hide
      */
-    public String getDeviceOwnerName() {
+    public boolean isDeviceManaged() {
+        return getDeviceOwnerComponentOnAnyUser() != null;
+    }
+
+    /**
+     * Returns the device owner name.  Note this method *will* return the device owner
+     * name when it's running on a different user.
+     *
+     * <p>Requires the MANAGE_USERS permission.
+     *
+     * @hide
+     */
+    public String getDeviceOwnerNameOnAnyUser() {
         if (mService != null) {
             try {
                 return mService.getDeviceOwnerName();
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to get device owner");
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the device owner component name.  Note this method will still return the device owner
-     * component name even if it's running on a different user.
-     *
-     * @hide
-     */
-    public ComponentName getDeviceOwnerComponent() {
-        if (mService != null) {
-            try {
-                return mService.getDeviceOwner();
-            } catch (RemoteException re) {
-                Log.w(TAG, "Failed to get device owner");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE);
             }
         }
         return null;
@@ -3130,7 +3188,7 @@
 
     /**
      * @hide
-     * @param user The user for whom to fetch the profile owner name, if any.
+     * @param userId The user for whom to fetch the profile owner name, if any.
      * @return the human readable name of the organisation associated with this profile owner or
      *         null if one is not set.
      * @throws IllegalArgumentException if the userId is invalid.