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

Commit 432f64ee authored by Craig Mautner's avatar Craig Mautner
Browse files

Avoid resuming activity before launch.

The locktask logic would always bring a locked task to the front and
then resume it when locking. When a task is to be locked at launch that
would cause it to resume immediately before onLaunch was called. Which
would cause havoc because the token was not yet in
ActivityThread.mActivities. This lead to premature finish() calls and
looping restarts.

This change causes the resume to only be called when an app calls
startLockTask. Otherwise the resume call is skipped.

Plus additional locktask debug logging.

Fixes bug 21031298.

Change-Id: I756b0d607827d0ec7a123377db04d9377c41776d
parent aa1cd25d
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -8884,7 +8884,8 @@ public final class ActivityManagerService extends ActivityManagerNative
            throw new SecurityException("updateLockTaskPackage called from non-system process");
        }
        synchronized (this) {
            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + packages);
            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
                    Arrays.toString(packages));
            mLockTaskPackages.put(userId, packages);
            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
        }
@@ -8927,7 +8928,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
                    ActivityManager.LOCK_TASK_MODE_PINNED :
                    ActivityManager.LOCK_TASK_MODE_LOCKED,
                    "startLockTask");
                    "startLockTask", true);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
@@ -8992,7 +8993,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            // Stop lock task
            synchronized (this) {
                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
                        "stopLockTask");
                        "stopLockTask", true);
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
@@ -19433,7 +19434,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
                        "startUser");
                        "startUser", false);
                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
                if (userInfo == null) {
+20 −6
Original line number Diff line number Diff line
@@ -1185,7 +1185,7 @@ public final class ActivityStackSupervisor implements DisplayListener {

        final TaskRecord task = r.task;
        if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
            setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE");
            setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
        }

        final ActivityStack stack = task.stack;
@@ -3675,7 +3675,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
    }

    void removeLockedTaskLocked(final TaskRecord task) {
        if (mLockTaskModeTasks.remove(task) && mLockTaskModeTasks.isEmpty()) {
        if (!mLockTaskModeTasks.remove(task)) {
            return;
        }
        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task);
        if (mLockTaskModeTasks.isEmpty()) {
            // Last one.
            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
                    " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
@@ -3696,7 +3700,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
        }
    }

    void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason) {
    void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason,
            boolean andResume) {
        if (task == null) {
            // Take out of lock task mode if necessary
            final TaskRecord lockedTask = getLockedTaskLocked();
@@ -3745,9 +3750,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
        if (task.mLockTaskUid == -1) {
            task.mLockTaskUid = task.mCallingUid;
        }

        if (andResume) {
            findTaskToMoveToFrontLocked(task, 0, null, reason);
            resumeTopActivitiesLocked();
        }
    }

    boolean isLockTaskModeViolation(TaskRecord task) {
        if (getLockedTaskLocked() == task) {
@@ -3780,6 +3788,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
            lockedTask.setLockTaskAuth();
            if (wasLaunchable && lockedTask.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE) {
                // Lost whitelisting authorization. End it now.
                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
                        lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString());
                removeLockedTaskLocked(lockedTask);
                lockedTask.performClearTaskLocked();
                didSomething = true;
@@ -3797,7 +3807,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
        if (mLockTaskModeTasks.isEmpty() && task != null
                && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
            // This task must have just been authorized.
            setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated");
            if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
                    "onLockTaskPackagesUpdated: starting new locktask task=" + task);
            setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated",
                    false);
            didSomething = true;
        }
        if (didSomething) {
            resumeTopActivitiesLocked();
+16 −12
Original line number Diff line number Diff line
@@ -739,38 +739,40 @@ final class TaskRecord {
        performClearTaskAtIndexLocked(0);
    }

    String lockTaskAuthToString() {
        switch (mLockTaskAuth) {
            case LOCK_TASK_AUTH_DONT_LOCK: return "LOCK_TASK_AUTH_DONT_LOCK";
            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";
            default: return "unknown=" + mLockTaskAuth;
        }
    }

    void setLockTaskAuth() {
        switch (mLockTaskMode) {
            case LOCK_TASK_LAUNCH_MODE_DEFAULT:
                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
                        " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ?
                        "WHITELISTED" : "PINNABLE"));
                mLockTaskAuth = isLockTaskWhitelistedLocked() ?
                    LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
                break;

            case LOCK_TASK_LAUNCH_MODE_NEVER:
                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
                        " mLockTaskAuth=" + (mPrivileged ? "DONT_LOCK" : "PINNABLE"));
                mLockTaskAuth = mPrivileged ?
                        LOCK_TASK_AUTH_DONT_LOCK : LOCK_TASK_AUTH_PINNABLE;
                break;

            case LOCK_TASK_LAUNCH_MODE_ALWAYS:
                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
                        " mLockTaskAuth=" + (mPrivileged ? "LAUNCHABLE" : "PINNABLE"));
                mLockTaskAuth = mPrivileged ?
                        LOCK_TASK_AUTH_LAUNCHABLE: LOCK_TASK_AUTH_PINNABLE;
                break;

            case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
                if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
                        " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ?
                        "LAUNCHABLE" : "PINNABLE"));
                mLockTaskAuth = isLockTaskWhitelistedLocked() ?
                        LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
                break;
        }
        if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
                " mLockTaskAuth=" + lockTaskAuthToString());
    }

    boolean isLockTaskWhitelistedLocked() {
@@ -1173,10 +1175,12 @@ final class TaskRecord {
                    pw.print(" taskType="); pw.print(taskType);
                    pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
        }
        if (rootWasReset || mNeverRelinquishIdentity || mReuseTask) {
        if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
                || mLockTaskAuth != LOCK_TASK_AUTH_PINNABLE) {
            pw.print(prefix); pw.print("rootWasReset="); pw.print(rootWasReset);
                    pw.print(" mNeverRelinquishIdentity="); pw.print(mNeverRelinquishIdentity);
                    pw.print(" mReuseTask="); pw.println(mReuseTask);
                    pw.print(" mReuseTask="); pw.print(mReuseTask);
                    pw.print(" mLockTaskAuth="); pw.println(lockTaskAuthToString());
        }
        if (mAffiliatedTaskId != taskId || mPrevAffiliateTaskId != INVALID_TASK_ID
                || mPrevAffiliate != null || mNextAffiliateTaskId != INVALID_TASK_ID