Add profile policy to set work challenge background color
Adding a policy for profile owners to set the background color of the
confirm credential screen for the managed profile.
Bug: 26638631
Change-Id: Iea36b94c5a42b6ae12cc36921ec5f840306e81a1
diff --git a/api/current.txt b/api/current.txt
index 0f3b099..56d3326 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5806,6 +5806,7 @@
method public java.lang.String getLongSupportMessage(android.content.ComponentName);
method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
method public long getMaximumTimeToLock(android.content.ComponentName);
+ method public int getOrganizationColor(android.content.ComponentName);
method public boolean getPackageSuspended(android.content.ComponentName, java.lang.String);
method public android.app.admin.DevicePolicyManager getParentProfileInstance(android.content.ComponentName);
method public long getPasswordExpiration(android.content.ComponentName);
@@ -5874,6 +5875,7 @@
method public void setMasterVolumeMuted(android.content.ComponentName, boolean);
method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
method public void setMaximumTimeToLock(android.content.ComponentName, long);
+ method public void setOrganizationColor(android.content.ComponentName, int);
method public boolean setPackageSuspended(android.content.ComponentName, java.lang.String, boolean);
method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
method public void setPasswordHistoryLength(android.content.ComponentName, int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 360a40b..940d3b3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5943,6 +5943,7 @@
method public java.lang.String getLongSupportMessage(android.content.ComponentName);
method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
method public long getMaximumTimeToLock(android.content.ComponentName);
+ method public int getOrganizationColor(android.content.ComponentName);
method public boolean getPackageSuspended(android.content.ComponentName, java.lang.String);
method public android.app.admin.DevicePolicyManager getParentProfileInstance(android.content.ComponentName);
method public long getPasswordExpiration(android.content.ComponentName);
@@ -6017,6 +6018,7 @@
method public void setMasterVolumeMuted(android.content.ComponentName, boolean);
method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
method public void setMaximumTimeToLock(android.content.ComponentName, long);
+ method public void setOrganizationColor(android.content.ComponentName, int);
method public boolean setPackageSuspended(android.content.ComponentName, java.lang.String, boolean);
method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
method public void setPasswordHistoryLength(android.content.ComponentName, int);
diff --git a/api/test-current.txt b/api/test-current.txt
index fb11fcc..9a7750f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5808,6 +5808,7 @@
method public java.lang.String getLongSupportMessage(android.content.ComponentName);
method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
method public long getMaximumTimeToLock(android.content.ComponentName);
+ method public int getOrganizationColor(android.content.ComponentName);
method public boolean getPackageSuspended(android.content.ComponentName, java.lang.String);
method public android.app.admin.DevicePolicyManager getParentProfileInstance(android.content.ComponentName);
method public long getPasswordExpiration(android.content.ComponentName);
@@ -5876,6 +5877,7 @@
method public void setMasterVolumeMuted(android.content.ComponentName, boolean);
method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
method public void setMaximumTimeToLock(android.content.ComponentName, long);
+ method public void setOrganizationColor(android.content.ComponentName, int);
method public boolean setPackageSuspended(android.content.ComponentName, java.lang.String, boolean);
method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
method public void setPasswordHistoryLength(android.content.ComponentName, int);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9e39a5f..e3959a0 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -5129,4 +5129,55 @@
return null;
}
}
+
+ /**
+ * Called by a profile owner of a managed profile to set the color used for customization.
+ * This color is used as background color of the confirm credentials screen for that user.
+ * The default color is {@link android.graphics.Color#GRAY}.
+ *
+ * <p>The confirm credentials screen can be created using
+ * {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent}.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param color The 32bit representation of the color to be used.
+ */
+ public void setOrganizationColor(@NonNull ComponentName admin, int color) {
+ try {
+ mService.setOrganizationColor(admin, color);
+ } catch (RemoteException re) {
+ Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
+ }
+ }
+
+ /**
+ * Called by a profile owner of a managed profile to retrieve the color used for customization.
+ * This color is used as background color of the confirm credentials screen for that user.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @return The 32bit representation of the color to be used.
+ */
+ public int getOrganizationColor(@NonNull ComponentName admin) {
+ try {
+ return mService.getOrganizationColor(admin);
+ } catch (RemoteException re) {
+ Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
+ return 0;
+ }
+ }
+
+ /**
+ * @hide
+ * Retrieve the customization color for a given user.
+ *
+ * @param userHandle The user id of the user we're interested in.
+ * @return The 32bit representation of the color to be used.
+ */
+ public int getOrganizationColorForUser(int userHandle) {
+ try {
+ return mService.getOrganizationColorForUser(userHandle);
+ } catch (RemoteException re) {
+ Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
+ return 0;
+ }
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 08cab88..82115a2 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -263,4 +263,8 @@
String getLongSupportMessageForUser(in ComponentName admin, int userHandle);
boolean isSeparateProfileChallengeAllowed(int userHandle);
+
+ void setOrganizationColor(in ComponentName admin, in int color);
+ int getOrganizationColor(in ComponentName admin);
+ int getOrganizationColorForUser(int userHandle);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 1ada0ac..a9b3fc9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -67,6 +67,7 @@
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.graphics.Bitmap;
+import android.graphics.Color;
import android.media.AudioManager;
import android.media.IAudioService;
import android.net.ConnectivityManager;
@@ -487,6 +488,7 @@
private static final String TAG_SHORT_SUPPORT_MESSAGE = "short-support-message";
private static final String TAG_LONG_SUPPORT_MESSAGE = "long-support-message";
private static final String TAG_PARENT_ADMIN = "parent-admin";
+ private static final String TAG_ORGANIZATION_COLOR = "organization-color";
final DeviceAdminInfo info;
@@ -580,6 +582,10 @@
String shortSupportMessage = null;
String longSupportMessage = null;
+ // Background color of confirm credentials screen. Default: gray.
+ static final int DEF_ORGANIZATION_COLOR = Color.GRAY;
+ int organizationColor = DEF_ORGANIZATION_COLOR;
+
ActiveAdmin(DeviceAdminInfo _info, boolean parent) {
info = _info;
isParent = parent;
@@ -787,6 +793,11 @@
parentAdmin.writeToXml(out);
out.endTag(null, TAG_PARENT_ADMIN);
}
+ if (organizationColor != DEF_ORGANIZATION_COLOR) {
+ out.startTag(null, TAG_ORGANIZATION_COLOR);
+ out.attribute(null, ATTR_VALUE, Integer.toString(organizationColor));
+ out.endTag(null, TAG_ORGANIZATION_COLOR);
+ }
}
void writePackageListToXml(XmlSerializer out, String outerTag,
@@ -920,6 +931,9 @@
} else if (TAG_PARENT_ADMIN.equals(tag)) {
parentAdmin = new ActiveAdmin(info, /* parent */ true);
parentAdmin.readFromXml(parser);
+ } else if (TAG_ORGANIZATION_COLOR.equals(tag)) {
+ organizationColor = Integer.parseInt(
+ parser.getAttributeValue(null, ATTR_VALUE));
} else {
Slog.w(LOG_TAG, "Unknown admin tag: " + tag);
XmlUtils.skipCurrentTag(parser);
@@ -7681,4 +7695,46 @@
}
return null;
}
+
+ @Override
+ public void setOrganizationColor(@NonNull ComponentName who, int color) {
+ final int userHandle = mInjector.userHandleGetCallingUserId();
+ if (!mHasFeature || !isManagedProfile(userHandle)) {
+ return;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ synchronized (this) {
+ ActiveAdmin admin = getActiveAdminForCallerLocked(who,
+ DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ admin.organizationColor = color;
+ saveSettingsLocked(userHandle);
+ }
+ }
+
+ @Override
+ public int getOrganizationColor(@NonNull ComponentName who) {
+ final int userHandle = mInjector.userHandleGetCallingUserId();
+ if (!mHasFeature || !isManagedProfile(userHandle)) {
+ return ActiveAdmin.DEF_ORGANIZATION_COLOR;
+ }
+ synchronized (this) {
+ ActiveAdmin admin = getActiveAdminForCallerLocked(who,
+ DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ return admin.organizationColor;
+ }
+ }
+
+ @Override
+ public int getOrganizationColorForUser(int userHandle) {
+ if (!mHasFeature || !isManagedProfile(userHandle)) {
+ return ActiveAdmin.DEF_ORGANIZATION_COLOR;
+ }
+ enforceCrossUsersPermission(userHandle);
+ synchronized (this) {
+ ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userHandle);
+ return (profileOwner != null)
+ ? profileOwner.organizationColor
+ : ActiveAdmin.DEF_ORGANIZATION_COLOR;
+ }
+ }
}