Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d168d184 authored by Benjamin Franz's avatar Benjamin Franz Committed by Android (Google) Code Review
Browse files

Merge "Align the behaviour of different lock task modes" into mnc-dev

parents b2af4220 469dd58b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3975,6 +3975,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.
+12 −9
Original line number Diff line number Diff line
@@ -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
+7 −5
Original line number Diff line number Diff line
@@ -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;
@@ -4197,9 +4198,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();
@@ -4361,9 +4362,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;
+11 −6
Original line number Diff line number Diff line
@@ -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());
+14 −6
Original line number Diff line number Diff line
@@ -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: