Introduce APIs in DPM for setting/getting the device owner info

This information, if set, will be shown in the lock screen instead
of the user owner information and the settings tile will be made readonly
(implementation in following CLs).

Bug: 22547309
Change-Id: Ic826d8049bc67f5e8fcfa6a91aa2017247c93b11
diff --git a/api/current.txt b/api/current.txt
index 5eb08da..6b5c5cf 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5705,6 +5705,7 @@
     method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
     method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
     method public int getCurrentFailedPasswordAttempts();
+    method public java.lang.String getDeviceOwnerLockScreenInfo();
     method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
     method public int getKeyguardDisabledFeatures(android.content.ComponentName);
     method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
@@ -5756,6 +5757,7 @@
     method public void setCameraDisabled(android.content.ComponentName, boolean);
     method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
     method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
+    method public boolean setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.String);
     method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
     method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
     method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
diff --git a/api/system-current.txt b/api/system-current.txt
index dd2e67d..a26a463 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5831,6 +5831,7 @@
     method public deprecated java.lang.String getDeviceInitializerApp();
     method public deprecated android.content.ComponentName getDeviceInitializerComponent();
     method public java.lang.String getDeviceOwner();
+    method public java.lang.String getDeviceOwnerLockScreenInfo();
     method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
     method public int getKeyguardDisabledFeatures(android.content.ComponentName);
     method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
@@ -5888,6 +5889,7 @@
     method public void setCameraDisabled(android.content.ComponentName, boolean);
     method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
     method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
+    method public boolean setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.String);
     method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
     method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
     method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d7ffcc4..2a738ee 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2843,9 +2843,6 @@
      */
     public boolean setProfileOwner(@NonNull ComponentName admin, @Deprecated String ownerName,
             int userHandle) throws IllegalArgumentException {
-        if (admin == null) {
-            throw new NullPointerException("admin cannot be null");
-        }
         if (mService != null) {
             try {
                 if (ownerName == null) {
@@ -2861,6 +2858,42 @@
     }
 
     /**
+     * Sets the device owner information to be shown on the lock screen.
+     *
+     * <p>If the device owner information is {@code null} or empty then the device owner info is
+     * cleared and the user owner info is shown on the lock screen if it is set.
+     *
+     * @param admin The name of the admin component to check.
+     * @param info Device owner information which will be displayed instead of the user
+     * owner info.
+     * @return Whether the device owner information has been set.
+     */
+    public boolean setDeviceOwnerLockScreenInfo(@NonNull ComponentName admin, String info) {
+        if (mService != null) {
+            try {
+                return mService.setDeviceOwnerLockScreenInfo(admin, info);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed talking with device policy service", re);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @return The device owner information. If it is not set returns {@code null}.
+     */
+    public String getDeviceOwnerLockScreenInfo() {
+        if (mService != null) {
+            try {
+                return mService.getDeviceOwnerLockScreenInfo();
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed talking with device policy service", re);
+            }
+        }
+        return null;
+    }
+
+    /**
      * Sets the enabled state of the profile. A profile should be enabled only once it is ready to
      * be used. Only the profile owner can call this.
      *
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index cfa5861..36a48a6 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -127,6 +127,9 @@
     void clearProfileOwner(in ComponentName who);
     boolean hasUserSetupCompleted();
 
+    boolean setDeviceOwnerLockScreenInfo(in ComponentName who, String deviceOwnerInfo);
+    String getDeviceOwnerLockScreenInfo();
+
     boolean installCaCert(in ComponentName admin, in byte[] certBuffer);
     void uninstallCaCerts(in ComponentName admin, in String[] aliases);
     void enforceCanManageCaCerts(in ComponentName admin);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 60ef4a4..889c7b3 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -126,6 +126,8 @@
     private static final String LOCK_SCREEN_OWNER_INFO_ENABLED =
             Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
 
+    private static final String LOCK_SCREEN_DEVICE_OWNER_INFO = "lockscreen.device_owner_info";
+
     private static final String ENABLED_TRUST_AGENTS = "lockscreen.enabledtrustagents";
 
     // Maximum allowed number of repeated or ordered characters in a sequence before we'll
@@ -578,6 +580,29 @@
     }
 
     /**
+     * Sets the device owner information. If the information is {@code null} or empty then the
+     * device owner info is cleared.
+     *
+     * @param info Device owner information which will be displayed instead of the user
+     * owner info.
+     */
+    public void setDeviceOwnerInfo(String info) {
+        if (info != null && info.isEmpty()) {
+            info = null;
+        }
+
+        setString(LOCK_SCREEN_DEVICE_OWNER_INFO, info, UserHandle.USER_SYSTEM);
+    }
+
+    public String getDeviceOwnerInfo() {
+        return getString(LOCK_SCREEN_DEVICE_OWNER_INFO, UserHandle.USER_SYSTEM);
+    }
+
+    public boolean isDeviceOwnerInfoEnabled() {
+        return getDeviceOwnerInfo() != null;
+    }
+
+    /**
      * Compute the password quality from the given password string.
      */
     static public int computePasswordQuality(String password) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 37e46fb..3bab73f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4632,6 +4632,30 @@
         }
     }
 
+    @Override
+    public boolean setDeviceOwnerLockScreenInfo(ComponentName who, String info) {
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        if (!mHasFeature) {
+            return false;
+        }
+
+        synchronized (this) {
+            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+            long token = mInjector.binderClearCallingIdentity();
+            try {
+                new LockPatternUtils(mContext).setDeviceOwnerInfo(info);
+            } finally {
+                mInjector.binderRestoreCallingIdentity(token);
+            }
+            return true;
+        }
+    }
+
+    @Override
+    public String getDeviceOwnerLockScreenInfo() {
+        return new LockPatternUtils(mContext).getDeviceOwnerInfo();
+    }
+
     private void clearUserPoliciesLocked(UserHandle userHandle) {
         int userId = userHandle.getIdentifier();
         // Reset some of the user-specific policies