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

Commit a89729a2 authored by Louis Chang's avatar Louis Chang
Browse files

Examining if started activity violates lock task mode earlier

The lock task mode violation was used to check on a given task,
so a new task must be created before knowing whether the activity
can be started in lock task mode. If the activity shouldn't be
started, the activity and the task will be removed then.

Instead, this CL allows the lock task mode violation check to be
perform on the activity which is going to be the root activity
of the task which hasn't be created yet, in order to reduce
unnecessary costs if the activity shouldn't be started.

Bug: 171946327
Test: atest LockTaskControllerTest

Change-Id: Ic79368e5197742c34fdde61781d4a0b048540736
parent 7af35b48
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -1687,11 +1687,6 @@ class ActivityStarter {
            final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
            setNewTask(taskToAffiliate);
            if (mService.getLockTaskController().isLockTaskModeViolation(
                    mStartActivity.getTask())) {
                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
        } else if (mAddingToTask) {
            addOrReparentStartingActivity(targetTask, "adding to task");
        }
@@ -1870,11 +1865,18 @@ class ActivityStarter {
        final boolean isNewClearTask =
                (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
        if (!newTask && mService.getLockTaskController().isLockTaskModeViolation(targetTask,
        if (!newTask) {
            if (mService.getLockTaskController().isLockTaskModeViolation(targetTask,
                    isNewClearTask)) {
                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
        } else {
            if (mService.getLockTaskController().isNewTaskLockTaskModeViolation(mStartActivity)) {
                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
        }

        return START_SUCCESS;
    }
+33 −18
Original line number Diff line number Diff line
@@ -274,11 +274,10 @@ public class LockTaskController {
    }

    /**
     * @return whether the requested task is allowed to be locked (either allowlisted, or declares
     * lockTaskMode="always" in the manifest).
     * @return whether the requested task auth is allowed to be locked.
     */
    boolean isTaskAllowlisted(Task task) {
        switch(task.mLockTaskAuth) {
    static boolean isTaskAuthAllowlisted(int lockTaskAuth) {
        switch(lockTaskAuth) {
            case LOCK_TASK_AUTH_ALLOWLISTED:
            case LOCK_TASK_AUTH_LAUNCHABLE:
            case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
@@ -302,7 +301,30 @@ public class LockTaskController {
     * @return whether the requested task is disallowed to be launched.
     */
    boolean isLockTaskModeViolation(Task task, boolean isNewClearTask) {
        if (isLockTaskModeViolationInternal(task, isNewClearTask)) {
        // TODO: Double check what's going on here. If the task is already in lock task mode, it's
        // likely allowlisted, so will return false below.
        if (isTaskLocked(task) && !isNewClearTask) {
            // If the task is already at the top and won't be cleared, then allow the operation
        } else if (isLockTaskModeViolationInternal(task, task.mUserId, task.intent,
                task.mLockTaskAuth)) {
            showLockTaskToast();
            return true;
        }
        return false;
    }

    /**
     * @param activity an activity that is going to be started in a new task as the root activity.
     * @return whether the given activity is allowed to be launched.
     */
    boolean isNewTaskLockTaskModeViolation(ActivityRecord activity) {
        // Use the belong task (if any) to perform the lock task checks
        if (activity.getTask() != null) {
            return isLockTaskModeViolation(activity.getTask());
        }

        int auth = getLockTaskAuth(activity, null /* task */);
        if (isLockTaskModeViolationInternal(activity, activity.mUserId, activity.intent, auth)) {
            showLockTaskToast();
            return true;
        }
@@ -319,25 +341,19 @@ public class LockTaskController {
        return mLockTaskModeTasks.get(0);
    }

    private boolean isLockTaskModeViolationInternal(Task task, boolean isNewClearTask) {
        // TODO: Double check what's going on here. If the task is already in lock task mode, it's
        // likely allowlisted, so will return false below.
        if (isTaskLocked(task) && !isNewClearTask) {
            // If the task is already at the top and won't be cleared, then allow the operation
            return false;
        }

    private boolean isLockTaskModeViolationInternal(WindowContainer wc, int userId,
            Intent intent, int taskAuth) {
        // Allow recents activity if enabled by policy
        if (task.isActivityTypeRecents() && isRecentsAllowed(task.mUserId)) {
        if (wc.isActivityTypeRecents() && isRecentsAllowed(userId)) {
            return false;
        }

        // Allow emergency calling when the device is protected by a locked keyguard
        if (isKeyguardAllowed(task.mUserId) && isEmergencyCallTask(task)) {
        if (isKeyguardAllowed(userId) && isEmergencyCallIntent(intent)) {
            return false;
        }

        return !(isTaskAllowlisted(task) || mLockTaskModeTasks.isEmpty());
        return !(isTaskAuthAllowlisted(taskAuth) || mLockTaskModeTasks.isEmpty());
    }

    private boolean isRecentsAllowed(int userId) {
@@ -369,8 +385,7 @@ public class LockTaskController {
        return isPackageAllowlisted(userId, packageName);
    }

    private boolean isEmergencyCallTask(Task task) {
        final Intent intent = task.intent;
    private boolean isEmergencyCallIntent(Intent intent) {
        if (intent == null) {
            return false;
        }
+2 −2
Original line number Diff line number Diff line
@@ -658,8 +658,8 @@ class RecentTasks {
        }
        for (int i = mTasks.size() - 1; i >= 0; --i) {
            final Task task = mTasks.get(i);
            if (task.mUserId == userId
                    && !mService.getLockTaskController().isTaskAllowlisted(task)) {
            if (task.mUserId == userId && !mService.getLockTaskController().isTaskAuthAllowlisted(
                    task.mLockTaskAuth)) {
                remove(task);
            }
        }
+1 −1
Original line number Diff line number Diff line
@@ -486,7 +486,7 @@ public class ActivityStarterTests extends WindowTestsBase {
        final ActivityStarter starter = prepareStarter(0);

        final LockTaskController lockTaskController = mAtm.getLockTaskController();
        doReturn(true).when(lockTaskController).isLockTaskModeViolation(any());
        doReturn(true).when(lockTaskController).isNewTaskLockTaskModeViolation(any());

        final int result = starter.setReason("testTaskModeViolation").execute();