Change lock-task DPM authorization to packages
Switch the DPM lock-task authorization to be controlled by a package
rather than a component.
Change-Id: Ife9bed068f31ff2449b4451ab69d3586a3f09d89
diff --git a/api/current.txt b/api/current.txt
index a09a853..e931331 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5229,7 +5229,7 @@
method public boolean isAdminActive(android.content.ComponentName);
method public boolean isApplicationBlocked(android.content.ComponentName, java.lang.String);
method public boolean isDeviceOwnerApp(java.lang.String);
- method public boolean isLockTaskPermitted(android.content.ComponentName);
+ method public boolean isLockTaskPermitted(java.lang.String);
method public boolean isMasterVolumeMuted(android.content.ComponentName);
method public boolean isProfileOwnerApp(java.lang.String);
method public void lockNow();
@@ -5243,7 +5243,7 @@
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
- method public void setLockTaskComponents(android.content.ComponentName[]) throws java.lang.SecurityException;
+ method public void setLockTaskPackages(java.lang.String[]) throws java.lang.SecurityException;
method public void setMasterVolumeMuted(android.content.ComponentName, boolean);
method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
method public void setMaximumTimeToLock(android.content.ComponentName, long);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e80c761..ae1a4e7 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -18,6 +18,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -2340,15 +2341,20 @@
}
/**
- * Sets which components may enter lock task mode.
+ * Sets which packages may enter lock task mode.
+ *
+ * <p>Any packages that shares uid with an allowed package will also be allowed
+ * to activate lock task.
*
* 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
+ * @param packages The list of packages allowed to enter lock task mode
+ *
+ * @see Activity#startLockTask()
*/
- public void setLockTaskComponents(ComponentName[] components) throws SecurityException {
+ public void setLockTaskPackages(String[] packages) throws SecurityException {
if (mService != null) {
try {
- mService.setLockTaskComponents(components);
+ mService.setLockTaskPackages(packages);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2356,13 +2362,13 @@
}
/**
- * This function returns the list of components allowed to start the lock task mode.
+ * This function returns the list of packages allowed to start the lock task mode.
* @hide
*/
- public ComponentName[] getLockTaskComponents() {
+ public String[] getLockTaskPackages() {
if (mService != null) {
try {
- return mService.getLockTaskComponents();
+ return mService.getLockTaskPackages();
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -2373,12 +2379,12 @@
/**
* This function lets the caller know whether the given component is allowed to start the
* lock task mode.
- * @param component The component to check
+ * @param pkg The package to check
*/
- public boolean isLockTaskPermitted(ComponentName component) {
+ public boolean isLockTaskPermitted(String pkg) {
if (mService != null) {
try {
- return mService.isLockTaskPermitted(component);
+ return mService.isLockTaskPermitted(pkg);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index a1caa21..8272c07 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -142,9 +142,9 @@
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);
+ void setLockTaskPackages(in String[] packages);
+ String[] getLockTaskPackages();
+ boolean isLockTaskPermitted(in String pkg);
void setGlobalSetting(in ComponentName who, in String setting, in String value);
void setSecureSetting(in ComponentName who, in String setting, in String value);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 697e1f2..1d9cf5b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7625,14 +7625,24 @@
}
}
- private boolean isLockTaskAuthorized(ComponentName name) {
+ private boolean isLockTaskAuthorized(String pkg) {
final DevicePolicyManager dpm = (DevicePolicyManager)
mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- return dpm != null && dpm.isLockTaskPermitted(name);
+ try {
+ int uid = mContext.getPackageManager().getPackageUid(pkg,
+ Binder.getCallingUserHandle().getIdentifier());
+ return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
+ } catch (NameNotFoundException e) {
+ return false;
+ }
}
private void startLockTaskMode(TaskRecord task) {
- if (!isLockTaskAuthorized(task.intent.getComponent())) {
+ final String pkg;
+ synchronized (this) {
+ pkg = task.intent.getComponent().getPackageName();
+ }
+ if (!isLockTaskAuthorized(pkg)) {
return;
}
long ident = Binder.clearCallingIdentity();
@@ -7641,6 +7651,9 @@
// Since we lost lock on task, make sure it is still there.
task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
if (task != null) {
+ if ((mFocusedActivity == null) || (task != mFocusedActivity.task)) {
+ throw new IllegalArgumentException("Invalid task, not in foreground");
+ }
mStackSupervisor.setLockTaskModeLocked(task);
}
}
@@ -7651,25 +7664,25 @@
@Override
public void startLockTaskMode(int taskId) {
+ final TaskRecord task;
long ident = Binder.clearCallingIdentity();
try {
- final TaskRecord task;
synchronized (this) {
task = mStackSupervisor.anyTaskForIdLocked(taskId);
}
- if (task != null) {
- startLockTaskMode(task);
- }
} finally {
Binder.restoreCallingIdentity(ident);
}
+ if (task != null) {
+ startLockTaskMode(task);
+ }
}
@Override
public void startLockTaskMode(IBinder token) {
+ final TaskRecord task;
long ident = Binder.clearCallingIdentity();
try {
- final TaskRecord task;
synchronized (this) {
final ActivityRecord r = ActivityRecord.forToken(token);
if (r == null) {
@@ -7677,24 +7690,27 @@
}
task = r.task;
}
- if (task != null) {
- startLockTaskMode(task);
- }
} finally {
Binder.restoreCallingIdentity(ident);
}
+ if (task != null) {
+ startLockTaskMode(task);
+ }
}
@Override
public void stopLockTaskMode() {
- // Check if the calling task is eligible to use lock task
- final int uid = Binder.getCallingUid();
+ // Verify that the user matches the package of the intent for the TaskRecord
+ // we are locked to. This will ensure the same caller for startLockTaskMode and
+ // stopLockTaskMode.
try {
- final String name = AppGlobals.getPackageManager().getNameForUid(uid);
- if (!isLockTaskAuthorized(new ComponentName(name, name))) {
- return;
+ String pkg = mStackSupervisor.mLockTaskModeTask.intent.getPackage();
+ int uid = mContext.getPackageManager().getPackageUid(pkg,
+ Binder.getCallingUserHandle().getIdentifier());
+ if (uid != Binder.getCallingUid()) {
+ throw new SecurityException("Invalid uid, expected " + uid);
}
- } catch (RemoteException e) {
+ } catch (NameNotFoundException e) {
Log.d(TAG, "stopLockTaskMode " + e);
return;
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 66e9eb3..278fa3e 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -251,7 +251,7 @@
/** If non-null then the task specified remains in front and no other tasks may be started
* until the task exits or #stopLockTaskMode() is called. */
- private TaskRecord mLockTaskModeTask;
+ TaskRecord mLockTaskModeTask;
public ActivityStackSupervisor(ActivityManagerService service) {
mService = service;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 4574caf..765a33d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -195,7 +195,7 @@
= new ArrayList<ActiveAdmin>();
// This is the list of component allowed to start lock task mode.
- final List<ComponentName> mLockTaskComponents = new ArrayList<ComponentName>();
+ final List<String> mLockTaskPackages = new ArrayList<String>();
ComponentName mRestrictionsProvider;
@@ -1014,10 +1014,10 @@
out.endTag(null, "active-password");
}
- for (int i=0; i<policy.mLockTaskComponents.size(); i++) {
- ComponentName component = policy.mLockTaskComponents.get(i);
+ for (int i=0; i<policy.mLockTaskPackages.size(); i++) {
+ String component = policy.mLockTaskPackages.get(i);
out.startTag(null, LOCK_TASK_COMPONENTS_XML);
- out.attribute(null, "name", component.flattenToString());
+ out.attribute(null, "name", component);
out.endTag(null, LOCK_TASK_COMPONENTS_XML);
}
@@ -1077,7 +1077,7 @@
type = parser.next();
int outerDepth = parser.getDepth();
- policy.mLockTaskComponents.clear();
+ policy.mLockTaskPackages.clear();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -1131,9 +1131,7 @@
parser.getAttributeValue(null, "nonletter"));
XmlUtils.skipCurrentTag(parser);
} else if (LOCK_TASK_COMPONENTS_XML.equals(tag)) {
- policy.mLockTaskComponents.add
- (ComponentName.unflattenFromString
- (parser.getAttributeValue(null, "name")));
+ policy.mLockTaskPackages.add(parser.getAttributeValue(null, "name"));
XmlUtils.skipCurrentTag(parser);
} else {
Slog.w(LOG_TAG, "Unknown tag: " + tag);
@@ -3723,38 +3721,40 @@
}
/**
- * Sets which componets may enter lock task mode.
+ * Sets which packages 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 {
+ public void setLockTaskPackages(String[] packages) 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))) {
+ synchronized (this) {
+ // 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);
+ // If a package name is the device owner or the profile owner,
+ // we update the component list.
+ DevicePolicyData policy = getUserData(userHandle);
+ policy.mLockTaskPackages.clear();
+ if (packages != null) {
+ for (int j = 0; j < packages.length; j++) {
+ String pkg = packages[j];
+ policy.mLockTaskPackages.add(pkg);
+ }
}
- }
- // Store the settings persistently.
- saveSettingsLocked(userHandle);
- return;
+ // Store the settings persistently.
+ saveSettingsLocked(userHandle);
+ return;
+ }
}
}
throw new SecurityException();
@@ -3763,30 +3763,33 @@
/**
* 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;
+ public String[] getLockTaskPackages() {
+ synchronized (this) {
+ int userHandle = UserHandle.USER_OWNER;
+ DevicePolicyData policy = getUserData(userHandle);
+ return policy.mLockTaskPackages.toArray(new String[0]);
+ }
}
/**
- * This function lets the caller know whether the given component is allowed to start the
+ * This function lets the caller know whether the given package is allowed to start the
* lock task mode.
- * @param component The component to check
+ * @param pkg The package to check
*/
- public boolean isLockTaskPermitted(ComponentName component) {
+ public boolean isLockTaskPermitted(String pkg) {
// 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);
+ synchronized (this) {
+ for (int i = 0; i < policy.mLockTaskPackages.size(); i++) {
+ String lockTaskPackage = policy.mLockTaskPackages.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;
+ // If the given package equals one of the packages stored our list,
+ // we allow this package to start lock task mode.
+ if (lockTaskPackage.equals(pkg)) {
+ return true;
+ }
}
}
return false;