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

Commit ac6f843c authored by Craig Mautner's avatar Craig Mautner
Browse files

Fix home activity and user switch interactions.

- Make sure Home activity goes in the correct task and on the correct
stack.
- Do not allow different users to be in the same task.
- Do not set stacks aside for each user.

Fixes bug 9775492.

Change-Id: I0e7954e917aac8482a1015a36923e02914e2b692
parent 350503fb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ interface IWindowManager
    void addWindowToken(IBinder token, int type);
    void removeWindowToken(IBinder token);
    void addAppToken(int addPos, IApplicationToken token, int groupId, int stackId,
            int requestedOrientation, boolean fullscreen, boolean showWhenLocked);
            int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId);
    void setAppGroupId(IBinder token, int groupId);
    void setAppOrientation(IApplicationToken token, int requestedOrientation);
    int getAppOrientation(IApplicationToken token);
+16 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.util.ArrayMap;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.ResolverActivity;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.ProcessStats;
@@ -2056,7 +2057,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    final void setFocusedActivityLocked(ActivityRecord r) {
        if (mFocusedActivity != r) {
            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivitiyLocked: r=" + r);
            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
            mFocusedActivity = r;
            mStackSupervisor.setFocusedStack(r);
            if (r != null) {
@@ -2493,6 +2494,20 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
    }
    String getHomePackageName() {
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        intent.addCategory(Intent.CATEGORY_HOME);
        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, mCurrentUserId);
        if (aInfo != null) {
            final String homePackageName = aInfo.applicationInfo.packageName;
            if (!ResolverActivity.class.getName().equals(homePackageName)) {
                return homePackageName;
            }
        }
        return null;
    }
    boolean startHomeActivityLocked(int userId) {
        if (mHeadless) {
            // Added because none of the other calls to ensureBootCompleted seem to fire
+12 −7
Original line number Diff line number Diff line
@@ -339,6 +339,10 @@ final class ActivityRecord {
        }
    }

    boolean isNotResolverActivity() {
        return !ResolverActivity.class.getName().equals(realActivity.getClassName());
    }

    ActivityRecord(ActivityManagerService _service, ProcessRecord _caller,
            int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
            ActivityInfo aInfo, Configuration _configuration,
@@ -442,21 +446,22 @@ final class ActivityRecord {

            // If we know the system has determined the component, then
            // we can consider this to be a home activity...
            // Note the last check is so we don't count the resolver
            // activity as being home...  really, we don't care about
            // doing anything special with something that comes from
            // the core framework package.
            if ((!_componentSpecified || _launchedFromUid == Process.myUid()
            String homePackageName = supervisor.getHomePackageName();
            if (homePackageName != null && homePackageName.equals(packageName)) {
                mActivityType = HOME_ACTIVITY_TYPE;
            } else if ((!_componentSpecified || _launchedFromUid == Process.myUid()
                    || _launchedFromUid == 0) &&
                    Intent.ACTION_MAIN.equals(_intent.getAction()) &&
                    _intent.hasCategory(Intent.CATEGORY_HOME) &&
                    _intent.getCategories().size() == 1 &&
                    _intent.getData() == null &&
                    _intent.getType() == null &&
                    (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
                    !ResolverActivity.class.getName().equals(realActivity.getClassName())) {
                    (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
                // This sure looks like a home activity!
                mActivityType = HOME_ACTIVITY_TYPE;
                if (isNotResolverActivity()) {
                    supervisor.setHomePackageName(userId, packageName);
                }
            } else if (realActivity.getClassName().contains("com.android.systemui.recent")) {
                mActivityType = RECENTS_ACTIVITY_TYPE;
            } else {
+50 −23
Original line number Diff line number Diff line
@@ -465,7 +465,9 @@ final class ActivityStack {
     * Returns the top activity in any existing task matching the given
     * Intent.  Returns null if no such task is found.
     */
    ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) {
    ActivityRecord findTaskLocked(ActivityRecord target) {
        Intent intent = target.intent;
        ActivityInfo info = target.info;
        ComponentName cls = intent.getComponent();
        if (info.targetActivity != null) {
            cls = new ComponentName(info.packageName, info.targetActivity);
@@ -474,6 +476,10 @@ final class ActivityStack {

        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            final TaskRecord task = mTaskHistory.get(taskNdx);
            if (task.userId != userId) {
                // Looking for a different task.
                continue;
            }
            final ActivityRecord r = task.getTopActivity();
            if (r == null || r.finishing || r.userId != userId ||
                    r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
@@ -518,7 +524,11 @@ final class ActivityStack {
        final int userId = UserHandle.getUserId(info.applicationInfo.uid);

        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
            TaskRecord task = mTaskHistory.get(taskNdx);
            if (task.userId != mCurrentUser) {
                return null;
            }
            final ArrayList<ActivityRecord> activities = task.mActivities;
            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                ActivityRecord r = activities.get(activityNdx);
                if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId == userId) {
@@ -534,8 +544,7 @@ final class ActivityStack {
    }

    /*
     * Move the activities around in the stack to bring a user to the foreground. This only
     * matters on the home stack. All other stacks are single user.
     * Move the activities around in the stack to bring a user to the foreground.
     * @return whether there are any activities for the specified user.
     */
    final boolean switchUserLocked(int userId) {
@@ -1172,6 +1181,7 @@ final class ActivityStack {
            // There are no more activities!  Let's just start up the
            // Launcher...
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return mStackSupervisor.resumeHomeActivity(prev);
        }
@@ -1186,6 +1196,7 @@ final class ActivityStack {
            mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Top activity resumed " + next);
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
@@ -1213,6 +1224,7 @@ final class ActivityStack {
                final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
                mTaskHistory.get(taskNdx).mActivities.get(0).mLaunchHomeTaskNext = true;
            } else {
                if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Launching home next");
                return mStackSupervisor.resumeHomeActivity(prev);
            }
        }
@@ -1227,6 +1239,7 @@ final class ActivityStack {
            mWindowManager.executeAppTransition();
            mNoAnimActivities.clear();
            ActivityOptions.abort(options);
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Going to sleep and all paused");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
@@ -1255,7 +1268,8 @@ final class ActivityStack {
        // If we are currently pausing an activity, then don't do anything
        // until that is done.
        if (!mStackSupervisor.allPausedActivitiesComplete()) {
            if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG, "Skip resume: some activity pausing");
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG,
                    "resumeTopActivityLocked: Skip resume: some activity pausing.");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
@@ -1295,9 +1309,11 @@ final class ActivityStack {
        if (mResumedActivity != null) {
            pausing = true;
            startPausingLocked(userLeaving, false);
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
        }
        if (pausing) {
            if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing");
            if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,
                    "resumeTopActivityLocked: Skip resume: need to start pausing");
            // At this point we want to put the upcoming activity's process
            // at the top of the LRU list, since we know we will be needing it
            // very soon and it would be a waste to let it get killed if it
@@ -1459,7 +1475,7 @@ final class ActivityStack {
                // is still at the top and schedule another run if something
                // weird happened.
                ActivityRecord nextNext = topRunningActivityLocked(null);
                if (DEBUG_SWITCH) Slog.i(TAG,
                if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG,
                        "Activity config changed during resume: " + next
                        + ", new next: " + nextNext);
                if (nextNext != next) {
@@ -1505,6 +1521,7 @@ final class ActivityStack {

                mStackSupervisor.checkReadyForSleepLocked();

                if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Resumed " + next);
            } catch (Exception e) {
                // Whoops, need to restart this activity!
                if (DEBUG_STATES) Slog.v(TAG, "Resume failed; resetting state to "
@@ -1561,6 +1578,7 @@ final class ActivityStack {
                }
                if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);
            }
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

@@ -1568,6 +1586,21 @@ final class ActivityStack {
        return true;
    }

    private void insertTaskAtTop(TaskRecord task) {
        mTaskHistory.remove(task);
        // Now put task at top.
        int stackNdx = mTaskHistory.size();
        if (task.userId != mCurrentUser) {
            // Put non-current user tasks below current user tasks.
            while (--stackNdx >= 0) {
                if (mTaskHistory.get(stackNdx).userId != mCurrentUser) {
                    break;
                }
            }
            ++stackNdx;
        }
        mTaskHistory.add(stackNdx, task);
    }

    final void startActivityLocked(ActivityRecord r, boolean newTask,
            boolean doResume, boolean keepCurTransition, Bundle options) {
@@ -1577,9 +1610,7 @@ final class ActivityStack {
            // Last activity in task had been removed or ActivityManagerService is reusing task.
            // Insert or replace.
            // Might not even be in.
            mTaskHistory.remove(rTask);
            // Now put task at top.
            mTaskHistory.add(rTask);
            insertTaskAtTop(rTask);
            mWindowManager.moveTaskToTop(taskId);
        }
        TaskRecord task = null;
@@ -1599,7 +1630,8 @@ final class ActivityStack {
                        r.putInHistory();
                        mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                                r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                                (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
                                (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
                                r.userId);
                        if (VALIDATE_TOKENS) {
                            validateAppTokensLocked();
                        }
@@ -1660,7 +1692,7 @@ final class ActivityStack {
            r.updateOptionsLocked(options);
            mWindowManager.addAppToken(task.mActivities.indexOf(r),
                    r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId);
            boolean doShow = true;
            if (newTask) {
                // Even though this activity is starting fresh, we still need
@@ -1703,7 +1735,7 @@ final class ActivityStack {
            // because there is nothing for it to animate on top of.
            mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                    r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId);
            ActivityOptions.abort(options);
        }
        if (VALIDATE_TOKENS) {
@@ -2897,8 +2929,7 @@ final class ActivityStack {

        // Shift all activities with this task up to the top
        // of the stack, keeping them in the same internal order.
        mTaskHistory.remove(tr);
        mTaskHistory.add(tr);
        insertTaskAtTop(tr);

        if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to front transition: task=" + tr);
        if (reason != null &&
@@ -3380,7 +3411,7 @@ final class ActivityStack {
            printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw,
                    mTaskHistory.get(taskNdx).mActivities, "    ", "Hist", true, !dumpAll,
                    dumpClient, dumpPackage, needSep, header,
                    "    Task " + taskNdx + ": id #" + task.taskId);
                    "    Task id #" + task.taskId);
            if (printed) {
                header = null;
            }
@@ -3448,12 +3479,8 @@ final class ActivityStack {
    }

    TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, boolean toTop) {
        TaskRecord task = new TaskRecord(taskId, info, intent, this);
        if (toTop) {
            mTaskHistory.add(task);
        } else {
            mTaskHistory.add(0, task);
        }
        TaskRecord task = new TaskRecord(taskId, info, intent);
        addTask(task, toTop);
        return task;
    }

@@ -3464,7 +3491,7 @@ final class ActivityStack {
    void addTask(final TaskRecord task, final boolean toTop) {
        task.stack = this;
        if (toTop) {
            mTaskHistory.add(task);
            insertTaskAtTop(task);
        } else {
            mTaskHistory.add(0, task);
        }
+84 −61

File changed.

Preview size limit exceeded, changes collapsed.

Loading