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

Commit 11e7d7d6 authored by Charles He's avatar Charles He Committed by Android (Google) Code Review
Browse files

Merge "AM: make LockTask truly multi-task-aware."

parents ad5570f5 ff9b4dff
Loading
Loading
Loading
Loading
+25 −25
Original line number Diff line number Diff line
@@ -7304,24 +7304,25 @@ public class Activity extends ContextThemeWrapper
    }

    /**
     * Request to put this Activity in a mode where the user is locked to the
     * current task.
     * Request to put this activity in a mode where the user is locked to a restricted set of
     * applications.
     *
     * This will prevent the user from launching other apps, going to settings, or reaching the
     * home screen. This does not include those apps whose {@link android.R.attr#lockTaskMode}
     * values permit launching while locked.
     * <p>If {@link DevicePolicyManager#isLockTaskPermitted(String)} returns {@code true}
     * for this component, the current task will be launched directly into LockTask mode. Only apps
     * whitelisted by {@link DevicePolicyManager#setLockTaskPackages(ComponentName, String[])} can
     * be launched while LockTask mode is active. The user will not be able to leave this mode
     * until this activity calls {@link #stopLockTask()}. Calling this method while the device is
     * already in LockTask mode has no effect.
     *
     * If {@link DevicePolicyManager#isLockTaskPermitted(String)} returns true or
     * lockTaskMode=lockTaskModeAlways for this component then the app will go directly into
     * Lock Task mode. The user will not be able to exit this mode until
     * {@link Activity#stopLockTask()} is called.
     * <p>Otherwise, the current task will be launched into screen pinning mode. In this case, the
     * system will prompt the user with a dialog requesting permission to use this mode.
     * The user can exit at any time through instructions shown on the request dialog. Calling
     * {@link #stopLockTask()} will also terminate this mode.
     *
     * If {@link DevicePolicyManager#isLockTaskPermitted(String)} returns false
     * then the system will prompt the user with a dialog requesting permission to enter
     * this mode.  When entered through this method the user can exit at any time through
     * an action described by the request dialog.  Calling stopLockTask will also exit the
     * mode.
     * <p><strong>Note:</strong> this method can only be called when the activity is foreground.
     * That is, between {@link #onResume()} and {@link #onPause()}.
     *
     * @see #stopLockTask()
     * @see android.R.attr#lockTaskMode
     */
    public void startLockTask() {
@@ -7332,25 +7333,24 @@ public class Activity extends ContextThemeWrapper
    }

    /**
     * Allow the user to switch away from the current task.
     * Stop the current task from being locked.
     *
     * Called to end the mode started by {@link Activity#startLockTask}. This
     * can only be called by activities that have successfully called
     * startLockTask previously.
     * <p>Called to end the LockTask or screen pinning mode started by {@link #startLockTask()}.
     * This can only be called by activities that have called {@link #startLockTask()} previously.
     *
     * This will allow the user to exit this app and move onto other activities.
     * <p>Note: This method should only be called when the activity is user-facing. That is,
     * between onResume() and onPause().
     * <p>Note: If there are other tasks below this one that are also locked then calling this
     * method will immediately finish this task and resume the previous locked one, remaining in
     * lockTask mode.
     * <p><strong>Note:</strong> If the device is in LockTask mode that is not initially started
     * by this activity, then calling this method will not terminate the LockTask mode, but only
     * finish its own task. The device will remain in LockTask mode, until the activity which
     * started the LockTask mode calls this method, or until its whitelist authorization is revoked
     * by {@link DevicePolicyManager#setLockTaskPackages(ComponentName, String[])}.
     *
     * @see #startLockTask()
     * @see android.R.attr#lockTaskMode
     * @see ActivityManager#getLockTaskModeState()
     */
    public void stopLockTask() {
        try {
            ActivityManager.getService().stopLockTaskMode();
            ActivityManager.getService().stopLockTaskModeByToken(mToken);
        } catch (RemoteException e) {
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -413,7 +413,7 @@ interface IActivityManager {
    String getTagForIntentSender(in IIntentSender sender, in String prefix);
    boolean startUserInBackground(int userid);
    void startLockTaskModeByToken(in IBinder token);
    void stopLockTaskMode();
    void stopLockTaskModeByToken(in IBinder token);
    boolean isInLockTaskMode();
    void setTaskDescription(in IBinder token, in ActivityManager.TaskDescription values);
    int startVoiceActivity(in String callingPackage, int callingPid, int callingUid,
+21 −12
Original line number Diff line number Diff line
@@ -10843,7 +10843,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isAppPinning) {
    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
            return;
@@ -10857,13 +10857,16 @@ public class ActivityManagerService extends IActivityManager.Stub
        // When a task is locked, dismiss the pinned stack if it exists
        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
        // isAppPinning is used to distinguish between locked and pinned mode, as pinned mode
        // is initiated by system after the pinning request was shown and locked mode is initiated
        // by an authorized app directly
        // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
        // system or a specific app.
        // * System-initiated requests will only start the pinned mode (screen pinning)
        // * App-initiated requests
        //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
        //   - will start the pinned mode, otherwise
        final int callingUid = Binder.getCallingUid();
        long ident = Binder.clearCallingIdentity();
        try {
            mLockTaskController.startLockTaskMode(task, isAppPinning, callingUid);
            mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
@@ -10876,7 +10879,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            if (r == null) {
                return;
            }
            startLockTaskModeLocked(r.getTask(), false /* not system initiated */);
            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
        }
    }
@@ -10888,7 +10891,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        try {
            synchronized (this) {
                startLockTaskModeLocked(mStackSupervisor.anyTaskForIdLocked(taskId),
                        true /* system initiated */);
                        true /* isSystemCaller */);
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
@@ -10896,8 +10899,14 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    @Override
    public void stopLockTaskMode() {
        stopLockTaskModeInternal(false /* not system initiated */);
    public void stopLockTaskModeByToken(IBinder token) {
        synchronized (this) {
            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
            if (r == null) {
                return;
            }
            stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
        }
    }
    /**
@@ -10907,15 +10916,15 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void stopSystemLockTaskMode() throws RemoteException {
        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
        stopLockTaskModeInternal(true /* system initiated */);
        stopLockTaskModeInternal(null, true /* isSystemCaller */);
    }
    private void stopLockTaskModeInternal(boolean isSystemRequest) {
    private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
        final int callingUid = Binder.getCallingUid();
        long ident = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
                mLockTaskController.stopLockTaskMode(isSystemRequest, callingUid);
                mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
            }
            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
            // task and jumping straight into a call in the case of emergency call back.
+4 −3
Original line number Diff line number Diff line
@@ -3474,7 +3474,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                }

                if (endTask) {
                    mService.mLockTaskController.removeLockedTask(task);
                    mService.mLockTaskController.clearLockedTask(task);
                }
            } else if (r.state != ActivityState.PAUSING) {
                // If the activity is PAUSING, we will complete the finish once
@@ -4334,8 +4334,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        }
        Slog.i(TAG, "moveTaskToBack: " + tr);

        // If the task is locked, then show the lock task toast
        if (mService.mLockTaskController.checkLockedTask(tr)) {
        // In LockTask mode, moving a locked task to the back of the stack may expose unlocked
        // ones. Therefore we need to check if this operation is allowed.
        if (!mService.mLockTaskController.canMoveTaskToBack(tr)) {
            return false;
        }

+8 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.Manifest.permission.ACTIVITY_EMBEDDING;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.START_ANY_ACTIVITY;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
@@ -83,6 +84,7 @@ import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
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_WHITELISTED;
import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
@@ -1306,8 +1308,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            mService.updateLruProcessLocked(app, true, null);
            mService.updateOomAdjLocked();

            if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
                    task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
            if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
                    || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV
                    || (task.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED
                            && mService.mLockTaskController.getLockTaskModeState()
                            == LOCK_TASK_MODE_LOCKED)) {
                mService.mLockTaskController.startLockTaskMode(task, false, 0 /* blank UID */);
            }

@@ -2769,6 +2774,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        if (tr != null) {
            tr.removeTaskActivitiesLocked(pauseImmediately);
            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
            mService.mLockTaskController.clearLockedTask(tr);
            if (tr.isPersistable) {
                mService.notifyTaskPersisterLocked(null, true);
            }
Loading