diff options
| author | Benjamin Franz <bfranz@google.com> | 2015-06-09 14:24:36 +0100 |
|---|---|---|
| committer | Benjamin Franz <bfranz@google.com> | 2015-06-09 17:17:34 +0100 |
| commit | 469dd58baecb08d8f6daf559595362ada5fbe545 (patch) | |
| tree | 4baca10d9891e3a0620e581300a1deeda5447afb | |
| parent | 7d3b8833df5857f5cc70d6c101abe7501fa22b49 (diff) | |
Align the behaviour of different lock task modes
Currently lock task modes started by the activity flag
android:lockTaskMode behave differently from those started using
startLockTask(). With those changes lock tasks initiated by non-priv
apps cannot finish without calling into stopLockTask. Revoking the
whitelisting on a locked task will also kill that task, independently
of the way the lock task mode was started.
Bug: 21608206
Change-Id: I841abf1103855e2d7218a4a8ca9b43c105630dc9
5 files changed, 47 insertions, 26 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 55eaf272ba77..d00f273354a0 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -3976,6 +3976,9 @@ public class DevicePolicyManager { * <p>Any packages that shares uid with an allowed package will also be allowed * to activate lock task. * + * From {@link android.os.Build.VERSION_CODES#MNC} removing packages from the lock task + * package list results in locked tasks belonging to those packages to be finished. + * * This function can only be called by the device owner. * @param packages The list of packages allowed to enter lock task mode * @param admin Which {@link DeviceAdminReceiver} this request is associated with. diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 470e3455cbbc..f31c1d61d7c5 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1058,18 +1058,20 @@ lockTask mode is disabled. <p>While in lockTask mode with multiple permitted tasks running, each launched task is permitted to finish, transitioning to the previous locked task, until there is only one - task remaining. At that point the last task running is not permitted to finish. --> + task remaining. At that point the last task running is not permitted to finish, unless it + uses the value always. --> <attr name="lockTaskMode"> <!-- This is the default value. Tasks will not launch into lockTask mode but can be placed there by calling {@link android.app.Activity#startLockTask}. If a task with this mode has been whitelisted using {@link - android.app.admin.DevicePolicyManager#setLockTaskPackages} then calling startLockTask - will enter lockTask mode immediately, otherwise the user will be presented with a - dialog to approve entering lockTask mode. + android.app.admin.DevicePolicyManager#setLockTaskPackages} then calling + {@link android.app.Activity#startLockTask} will enter lockTask mode immediately, + otherwise the user will be presented with a dialog to approve entering pinned mode. <p>If the system is already in lockTask mode when a new task rooted at this activity is launched that task will or will not start depending on whether the package of this activity has been whitelisted. - <p>Tasks rooted at this activity can only exit lockTask mode using stopLockTask(). --> + <p>Tasks rooted at this activity can only exit lockTask mode using + {@link android.app.Activity#stopLockTask}. --> <enum name="normal" value="0"/> <!-- Tasks will not launch into lockTask mode and cannot be placed there using {@link android.app.Activity#startLockTask} or be pinned from the Overview screen. @@ -1082,16 +1084,17 @@ <!-- Tasks rooted at this activity will always launch into lockTask mode. If the system is already in lockTask mode when this task is launched then the new task will be launched on top of the current task. Tasks launched in this mode are capable of exiting - lockTask mode using finish(), whereas tasks entering lockTask mode using - startLockTask() must use stopLockTask() to exit. + lockTask mode using {@link android.app.Activity#finish()}. <p>Note: This mode is only available to system and privileged applications. Non-privileged apps with this value will be treated as normal. --> <enum name="always" value="2"/> <!-- If the DevicePolicyManager (DPM) authorizes this package ({@link android.app.admin.DevicePolicyManager#setLockTaskPackages}) then this mode is - identical to always. If the DPM does not authorize this package then this - mode is identical to normal. --> + identical to always, except that the activity needs to call + {@link android.app.Activity#stopLockTask} before being able to finish if it is the last + locked task. + If the DPM does not authorize this package then this mode is identical to normal. --> <enum name="if_whitelisted" value="3"/> </attr> <!-- When set installer will extract native libraries. If set to false diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index efc38e2d3658..992157082f17 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -32,6 +32,7 @@ import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; +import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; @@ -4204,9 +4205,9 @@ public final class ActivityManagerService extends ActivityManagerNative if (rootR == null) { Slog.w(TAG, "Finishing task with all activities already finished"); } - // Do not allow task to finish if last task in lockTask mode. Launchable apps can - // finish themselves. - if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && rootR == r && + // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can + // finish. + if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r && mStackSupervisor.isLastLockedTask(tr)) { Slog.i(TAG, "Not finishing task in lock task mode"); mStackSupervisor.showLockTaskToast(); @@ -4368,9 +4369,10 @@ public final class ActivityManagerService extends ActivityManagerNative return false; } - // Do not allow the last non-launchable task to finish in Lock Task mode. + // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps + // can finish. final TaskRecord task = r.task; - if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && + if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) { mStackSupervisor.showLockTaskToast(); return false; diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 23e62e22eee1..9e33f2a99607 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -35,6 +35,7 @@ import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; import static com.android.server.am.ActivityStack.ActivityState.*; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; +import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED; @@ -1179,7 +1180,8 @@ public final class ActivityStackSupervisor implements DisplayListener { mService.updateOomAdjLocked(); final TaskRecord task = r.task; - if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { + if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE || + task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) { setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false); } @@ -3785,6 +3787,7 @@ public final class ActivityStackSupervisor implements DisplayListener { switch (lockTaskAuth) { case LOCK_TASK_AUTH_DONT_LOCK: return !mLockTaskModeTasks.isEmpty(); + case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: case LOCK_TASK_AUTH_LAUNCHABLE: case LOCK_TASK_AUTH_WHITELISTED: return false; @@ -3801,12 +3804,14 @@ public final class ActivityStackSupervisor implements DisplayListener { boolean didSomething = false; for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx); - if (lockedTask.mLockTaskMode != LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED) { - continue; - } - final boolean wasLaunchable = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE; + final boolean wasWhitelisted = + (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || + (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); lockedTask.setLockTaskAuth(); - if (wasLaunchable && lockedTask.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE) { + final boolean isWhitelisted = + (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || + (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); + if (wasWhitelisted && !isWhitelisted) { // Lost whitelisting authorization. End it now. if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " + lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString()); diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index f966bcf405f8..78f9f181bae0 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -134,12 +134,15 @@ final class TaskRecord { /** Can't be put in lockTask mode. */ final static int LOCK_TASK_AUTH_DONT_LOCK = 0; - /** Can enter lockTask with user approval. Can never start over existing lockTask task. */ + /** Can enter app pinning with user approval. Can never start over existing lockTask task. */ final static int LOCK_TASK_AUTH_PINNABLE = 1; /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */ final static int LOCK_TASK_AUTH_LAUNCHABLE = 2; - /** Can enter lockTask with user approval. Can start over existing lockTask task. */ + /** Can enter lockTask without user approval. Can start over existing lockTask task. */ final static int LOCK_TASK_AUTH_WHITELISTED = 3; + /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing + * lockTask task. */ + final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4; int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE; int mLockTaskUid = -1; // The uid of the application that called startLockTask(). @@ -747,11 +750,18 @@ final class TaskRecord { case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE"; case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE"; case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED"; + case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV"; default: return "unknown=" + mLockTaskAuth; } } void setLockTaskAuth() { + if (!mPrivileged && + (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS || + mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) { + // Non-priv apps are not allowed to use always or never, fall back to default + mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT; + } switch (mLockTaskMode) { case LOCK_TASK_LAUNCH_MODE_DEFAULT: mLockTaskAuth = isLockTaskWhitelistedLocked() ? @@ -759,13 +769,11 @@ final class TaskRecord { break; case LOCK_TASK_LAUNCH_MODE_NEVER: - mLockTaskAuth = mPrivileged ? - LOCK_TASK_AUTH_DONT_LOCK : LOCK_TASK_AUTH_PINNABLE; + mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK; break; case LOCK_TASK_LAUNCH_MODE_ALWAYS: - mLockTaskAuth = mPrivileged ? - LOCK_TASK_AUTH_LAUNCHABLE: LOCK_TASK_AUTH_PINNABLE; + mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV; break; case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED: |
