diff --git a/api/current.txt b/api/current.txt index b8490c4f0fa39..b066cb9ddaed4 100644 --- a/api/current.txt +++ b/api/current.txt @@ -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); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index e80c7616204fb..ae1a4e7428e62 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -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. + * + *
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);
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index a1caa2199b1da..8272c07af031d 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -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);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 61908684cde2c..34c1ecd7b72f2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -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;
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index ed7e5945022c8..9b1d0e33e178b 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 @@ 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;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 4574caf203226..765a33d274919 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
= new ArrayList