DevicePolicyManager Authentication for Lock Task
Here we let DevicePolicyManager keep a list of tasks that are
allowed to start the lock task mode. This list can only be set by
a device owner app. The ActivityManager will call
DevicePolicyManager to check whether a given task can start the
lock task mode or not.
Change-Id: I650fdae43fc35bf9fd63452283f4e2bbadd11551
Bug: 14611303
diff --git a/api/current.txt b/api/current.txt
index 302e77e..546e71b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5056,6 +5056,7 @@
method public boolean isActivePasswordSufficient();
method public boolean isAdminActive(android.content.ComponentName);
method public boolean isDeviceOwnerApp(java.lang.String);
+ method public boolean isLockTaskPermitted(android.content.ComponentName);
method public boolean isProfileOwnerApp(java.lang.String);
method public void lockNow();
method public void removeActiveAdmin(android.content.ComponentName);
@@ -5064,6 +5065,7 @@
method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
+ method public void setLockTaskComponents(android.content.ComponentName[]) throws java.lang.SecurityException;
method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
method public void setMaximumTimeToLock(android.content.ComponentName, long);
method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 61ff60a..24bb2cc 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2125,4 +2125,51 @@
return null;
}
+
+ /**
+ * Sets which components may enter lock task mode.
+ *
+ * This function can only be called by the device owner or the profile owner.
+ * @param components The list of components allowed to enter lock task mode
+ */
+ public void setLockTaskComponents(ComponentName[] components) throws SecurityException {
+ if (mService != null) {
+ try {
+ mService.setLockTaskComponents(components);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ }
+
+ /**
+ * This function returns the list of components allowed to start the lock task mode.
+ * @hide
+ */
+ public ComponentName[] getLockTaskComponents() {
+ if (mService != null) {
+ try {
+ return mService.getLockTaskComponents();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * This function lets the caller know whether the given component is allowed to start the
+ * lock task mode.
+ * @param component The component to check
+ */
+ public boolean isLockTaskPermitted(ComponentName component) {
+ if (mService != null) {
+ try {
+ return mService.isLockTaskPermitted(component);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ return false;
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 0096580..03ced0f 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -129,4 +129,8 @@
void setAccountManagementDisabled(in ComponentName who, in String accountType, in boolean disabled);
String[] getAccountTypesWithManagementDisabled();
+
+ void setLockTaskComponents(in ComponentName[] components);
+ ComponentName[] getLockTaskComponents();
+ boolean isLockTaskPermitted(in ComponentName component);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9a9f1c8..4e22b2a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -97,6 +97,7 @@
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
@@ -113,6 +114,8 @@
private static final String DEVICE_POLICIES_XML = "device_policies.xml";
+ private static final String LOCK_TASK_COMPONENTS_XML = "lock-task-component";
+
private static final int REQUEST_EXPIRE_PASSWORD = 5571;
private static final long MS_PER_DAY = 86400 * 1000;
@@ -182,6 +185,9 @@
final ArrayList<ActiveAdmin> mAdminList
= new ArrayList<ActiveAdmin>();
+ // This is the list of component allowed to start lock task mode.
+ final List<ComponentName> mLockTaskComponents = new ArrayList<ComponentName>();
+
public DevicePolicyData(int userHandle) {
mUserHandle = userHandle;
}
@@ -955,6 +961,13 @@
out.endTag(null, "active-password");
}
+ for (int i=0; i<policy.mLockTaskComponents.size(); i++) {
+ ComponentName component = policy.mLockTaskComponents.get(i);
+ out.startTag(null, LOCK_TASK_COMPONENTS_XML);
+ out.attribute(null, "name", component.flattenToString());
+ out.endTag(null, LOCK_TASK_COMPONENTS_XML);
+ }
+
out.endTag(null, "policies");
out.endDocument();
@@ -1004,6 +1017,7 @@
}
type = parser.next();
int outerDepth = parser.getDepth();
+ policy.mLockTaskComponents.clear();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -1056,6 +1070,11 @@
policy.mActivePasswordNonLetter = Integer.parseInt(
parser.getAttributeValue(null, "nonletter"));
XmlUtils.skipCurrentTag(parser);
+ } else if (LOCK_TASK_COMPONENTS_XML.equals(tag)) {
+ policy.mLockTaskComponents.add
+ (ComponentName.unflattenFromString
+ (parser.getAttributeValue(null, "name")));
+ XmlUtils.skipCurrentTag(parser);
} else {
Slog.w(LOG_TAG, "Unknown tag: " + tag);
XmlUtils.skipCurrentTag(parser);
@@ -3344,4 +3363,74 @@
return resultSet.toArray(new String[resultSet.size()]);
}
}
+
+ /**
+ * Sets which componets may enter lock task mode.
+ *
+ * This function can only be called by the device owner or the profile owner.
+ * @param components The list of components allowed to enter lock task mode.
+ */
+ public void setLockTaskComponents(ComponentName[] components) throws SecurityException {
+ // Get the package names of the caller.
+ int uid = Binder.getCallingUid();
+ String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
+
+ // Check whether any of the package name is the device owner or the profile owner.
+ for (int i=0; i<packageNames.length; i++) {
+ String packageName = packageNames[i];
+ int userHandle = UserHandle.getUserId(uid);
+ String profileOwnerPackage = getProfileOwner(userHandle);
+ if (isDeviceOwner(packageName) ||
+ (profileOwnerPackage != null && profileOwnerPackage.equals(packageName))) {
+
+ // If a package name is the device owner or the profile owner,
+ // we update the component list.
+ DevicePolicyData policy = getUserData(userHandle);
+ policy.mLockTaskComponents.clear();
+ if (components != null) {
+ for (int j=0; j<components.length; j++) {
+ ComponentName component = components[j];
+ policy.mLockTaskComponents.add(component);
+ }
+ }
+
+ // Store the settings persistently.
+ saveSettingsLocked(userHandle);
+ return;
+ }
+ }
+ throw new SecurityException();
+ }
+
+ /**
+ * This function returns the list of components allowed to start the task lock mode.
+ */
+ public ComponentName[] getLockTaskComponents() {
+ int userHandle = UserHandle.USER_OWNER;
+ DevicePolicyData policy = getUserData(userHandle);
+ ComponentName[] tempArray = policy.mLockTaskComponents.toArray(new ComponentName[0]);
+ return tempArray;
+ }
+
+ /**
+ * This function lets the caller know whether the given component is allowed to start the
+ * lock task mode.
+ * @param component The component to check
+ */
+ public boolean isLockTaskPermitted(ComponentName component) {
+ // Get current user's devicepolicy
+ int uid = Binder.getCallingUid();
+ int userHandle = UserHandle.getUserId(uid);
+ DevicePolicyData policy = getUserData(userHandle);
+ for (int i=0; i<policy.mLockTaskComponents.size(); i++) {
+ ComponentName lockTaskComponent = policy.mLockTaskComponents.get(i);
+
+ // If the given component equals one of the component stored our device-owner-set
+ // list, we allow this component to start the lock task mode.
+ if (lockTaskComponent.getPackageName().equals(component.getPackageName())) {
+ return true;
+ }
+ }
+ return false;
+ }
}