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

Commit 2b8e0378 authored by Bryce Lee's avatar Bryce Lee
Browse files

Properly remove activity from task on start failure.

When we fail to start an activity, it is removed from its parent task
by the starter. We currently directly ask the task to remove the
child activity. This is incorrect as the stack is unaware of the
movement and cannot cleanup the task if necessary.

This changelist addresses the problem by asking the stack instead to
finish the activity.

Change-Id: I41faa2f4e81873601d45a8ccd1bf22fef9e57033
Fixes: 76679042
Test: atest FrameworksServicesTests:ActivityStarterTests#testTaskModeViolation
parent 312a176a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -764,7 +764,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    /**
     * The controller for all operations related to locktask.
     */
    final LockTaskController mLockTaskController;
    private final LockTaskController mLockTaskController;
    final UserController mUserController;
@@ -12396,6 +12396,10 @@ public class ActivityManagerService extends IActivityManager.Stub
        return mActivityStartController;
    }
    LockTaskController getLockTaskController() {
        return mLockTaskController;
    }
    ClientLifecycleManager getLifecycleManager() {
        return mLifecycleManager;
    }
+8 −2
Original line number Diff line number Diff line
@@ -1590,16 +1590,22 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
    void pauseKeyDispatchingLocked() {
        if (!keysPaused) {
            keysPaused = true;

            if (mWindowContainerController != null) {
                mWindowContainerController.pauseKeyDispatching();
            }
        }
    }

    void resumeKeyDispatchingLocked() {
        if (keysPaused) {
            keysPaused = false;

            if (mWindowContainerController != null) {
                mWindowContainerController.resumeKeyDispatching();
            }
        }
    }

    private void updateTaskDescription(CharSequence description) {
        task.lastDescription = description;
+8 −3
Original line number Diff line number Diff line
@@ -3743,7 +3743,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                }

                if (endTask) {
                    mService.mLockTaskController.clearLockedTask(task);
                    mService.getLockTaskController().clearLockedTask(task);
                }
            } else if (!r.isState(PAUSING)) {
                // If the activity is PAUSING, we will complete the finish once
@@ -4639,7 +4639,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai

        // 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)) {
        if (!mService.getLockTaskController().canMoveTaskToBack(tr)) {
            return false;
        }

@@ -5084,7 +5084,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
            onActivityRemovedFromStack(record);
        }

        mTaskHistory.remove(task);
        final boolean removed = mTaskHistory.remove(task);

        if (removed) {
            EventLog.writeEvent(EventLogTags.AM_REMOVE_TASK, task.taskId, getStackId());
        }

        removeActivitiesFromLRUListLocked(task);
        updateTaskMovement(task, true);

+6 −5
Original line number Diff line number Diff line
@@ -1371,12 +1371,13 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            mService.updateLruProcessLocked(app, true, null);
            mService.updateOomAdjLocked();

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

            try {
@@ -2899,7 +2900,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        if (tr != null) {
            tr.removeTaskActivitiesLocked(pauseImmediately, reason);
            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
            mService.mLockTaskController.clearLockedTask(tr);
            mService.getLockTaskController().clearLockedTask(tr);
            if (tr.isPersistable) {
                mService.notifyTaskPersisterLocked(null, true);
            }
@@ -3813,7 +3814,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        pw.print(mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));

        getKeyguardController().dump(pw, prefix);
        mService.mLockTaskController.dump(pw, prefix);
        mService.getLockTaskController().dump(pw, prefix);
    }

    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+8 −7
Original line number Diff line number Diff line
@@ -1147,9 +1147,10 @@ class ActivityStarter {
            // If we are not able to proceed, disassociate the activity from the task. Leaving an
            // activity in an incomplete state can lead to issues, such as performing operations
            // without a window container.
            if (!ActivityManager.isStartResultSuccessful(result)
                    && mStartActivity.getTask() != null) {
                mStartActivity.getTask().removeActivity(mStartActivity);
            final ActivityStack stack = mStartActivity.getStack();
            if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
                stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                        null /* intentResultData */, "startActivity", true /* oomAdj */);
            }
            mService.mWindowManager.continueSurfaceLayout();
        }
@@ -1199,7 +1200,7 @@ class ActivityStarter {
            // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
            // still needs to be a lock task mode violation since the task gets cleared out and
            // the device would otherwise leave the locked task.
            if (mService.mLockTaskController.isLockTaskModeViolation(reusedActivity.getTask(),
            if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),
                    (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
                Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
@@ -2011,7 +2012,7 @@ class ActivityStarter {
            mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
        }

        if (mService.mLockTaskController.isLockTaskModeViolation(mStartActivity.getTask())) {
        if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
            Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
            return START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }
@@ -2034,7 +2035,7 @@ class ActivityStarter {
    }

    private int setTaskFromSourceRecord() {
        if (mService.mLockTaskController.isLockTaskModeViolation(mSourceRecord.getTask())) {
        if (mService.getLockTaskController().isLockTaskModeViolation(mSourceRecord.getTask())) {
            Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
            return START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }
@@ -2128,7 +2129,7 @@ class ActivityStarter {
    private int setTaskFromInTask() {
        // The caller is asking that the new activity be started in an explicit
        // task it has provided to us.
        if (mService.mLockTaskController.isLockTaskModeViolation(mInTask)) {
        if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
            Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
            return START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }
Loading