Merge "Change lock-task DPM authorization to packages"

This commit is contained in:
Jason Monk
2014-06-18 13:22:26 +00:00
committed by Android (Google) Code Review
6 changed files with 101 additions and 76 deletions

View File

@@ -5249,7 +5249,7 @@ package android.app.admin {
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();
@@ -5263,7 +5263,7 @@ package android.app.admin {
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);

View File

@@ -18,6 +18,7 @@ package android.app.admin;
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 @@ public class DevicePolicyManager {
}
/**
* 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 @@ public class DevicePolicyManager {
}
/**
* 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 @@ public class DevicePolicyManager {
/**
* 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);
}

View File

@@ -142,9 +142,9 @@ interface IDevicePolicyManager {
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);

View File

@@ -7630,14 +7630,24 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
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();
@@ -7646,6 +7656,9 @@ public final class ActivityManagerService extends ActivityManagerNative
// 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);
}
}
@@ -7656,25 +7669,25 @@ public final class ActivityManagerService extends ActivityManagerNative
@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) {
@@ -7682,24 +7695,27 @@ public final class ActivityManagerService extends ActivityManagerNative
}
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;
}

View File

@@ -251,7 +251,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
/** 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;

View File

@@ -195,7 +195,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
= 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
/**
* 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
/**
* 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;