AMS-stack(一) ActivityStackSupervisor

要想了解AMS这端的stack管理主要有三个类的代码要去分支,包括栈的大管家 ActivityStackSupervisor,,栈结构ActivityStack和task结构TaskRecord

懒得画图。 Android对应用界面的管理分为五个层次
1 多个Display也就是多个屏幕,一般第一个屏幕为内置屏幕,第二个为hdmi,第三个为虚拟屏幕
2 每个Display上面包含多个类型的stack,主要有如下几种类型,这里以对应的id说明 

  • HOME_STACK_ID用于存在luncher中的HomeActivity所在的task或者SystemUI中的RecentActivity ,可以获取焦点
  • FULLSCREEN_WORKSPACE_STACK_ID 可以获取焦点,用于显示全屏应用所在的task.
  • FREEFORM_WORKSPACE_STACK_ID 自由的模式,类似电脑窗口的显示模式,通过bound指定大小
  • DOCKED_STACK_ID 分屏模式所在的stack,可以获取焦点
  • PINNED_STACK_ID 画中画模式,不可获取焦点
  • DYNAMIC_STACK 显示在其他display上面

3 每个stack上有多个task,通过mTaskHistory维护关系,每个task通过mTaskToReturnTo表示返回的task类型,有三种
 APPLICATION_ACTIVITY_TYPE 表示返回到应用task,返回到同一个stack上的其他task
 HOME_ACTIVITY_TYPE 返回到桌面所在的stack/task
 RECENTS_ACTIVITY_TYPE返回到多任务所在的stack/task
4 每个task上有多个Activity,通过集合mActivities维护Activity的顺序,通过int mActivityType表示自己的类型
5 每个Activity在WMS中代表一个AppWindowToken,用allAppWindows维护子window信息,每个AppWindowToken上面可能有一些子window,用WindowToken表示,AppWindowToken是WindowToken的子类。 并且每个Window用WindowState记录状态,对于ams只能看到AppWindowToken信息,看不到子windo

以上五个层级就是对于Activity的管理,严格来说第5个层级不属于ams管理

下面我们思考下对栈的管理都要做哪些工作
1 创建stack
2 创建task
3 移动task到stack
4 移动stack
5 启动activity 
。。。 等等 

我们采用自顶向下分析法,先分析stack大管家ActivityStackSupervisor,ActivityStackSupervisor类实现了DisplayListener借口,包含三个回调函数用于接收display的变化,分别是
void onDisplayAdded(int displayId);  // display添加
void onDisplayRemoved(int displayId); //移除
void onDisplayChanged(int displayId); // 变化

大管家的实现还是比较复杂的,在Android 7.0里面有4500行代码。 我们要想弄清楚它做了哪些事情首先要知道它维护了哪些数据。

private RecentTasks mRecentTasks; //用于管理最近任务
private int mNextFreeStackId = FIRST_DYNAMIC_STACK_ID; //下一个空闲的stackid
//用于管理每个user下的stackId,方便分配下一个stackid
private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20) 
int mCurrentUser //当前user 
ActivityStack mHomeStack  //桌面activity所在的stack
ActivityStack mFocusedStack //当前接收事件或者启动activity的stack
//在stack切换的过程中记录旧的stack,切换完成后mFocusedStack显示后,mLastFocusedStack将被设置成mFocusedStack
private ActivityStack mLastFocusedStack 
//等待一个activity变成可见的activity集合,当activity可见后执行这些activity的stop方法
final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>()
//等待可见的activity,在startActivityMayWait函数中,可能一些activity启动的线程正等在那里等待可见。当可见后调用notify, START_TASK_TO_FRONT的情况
final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>() 
//等待启动一个activity  真正启动activity
final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>() 
//正在关闭的
final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>(); 
//正在finish的
final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>() 
//所在进程休眠
final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>()
//接收分屏通知的
final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>()
//画中画模式的
final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>()
inal ArrayList<UserState> mStartingUsers = new ArrayList<>()//正在启动的用户
boolean mUserLeaving = false //是否需要回调onUserLeaving函数
boolean mSleepTimeout = false  //长时间没有操作,导致超时要进入睡眠
PowerManager.WakeLock mLaunchingActivity //启动activity防止休眠
PowerManager.WakeLock mGoingToSleep //休眠过程中pauseActivity防止休眠的锁
SparseIntArray mUserStackInFront = new SparseIntArray(2) 对战切换时候涉及的两个用户前台stack
//映射(ActivityStack/TaskStack).mStackId状态的容器,主要维护stack信息
private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<>() 
private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>()//维护display信息
ArrayList<TaskRecord> mLockTaskModeTasks = new ArrayList<>();//维护lockmode的task
private int mLockTaskModeState;
private LockTaskNotify mLockTaskNotify;
boolean inResumeTopActivity; //用于防止resumeTopActivityUncheckedLocked函数递归
//resize的时候计算大小
private final Rect tempRect = new Rect();
private final Rect tempRect2 = new Rect();
private final SparseArray<Configuration> mTmpConfigs = new SparseArray<>();
private final SparseArray<Rect> mTmpBounds = new SparseArray<>();
private final SparseArray<Rect> mTmpInsetBounds = new SparseArray<>();
//没有指定task的大小时默认大小
int mDefaultMinSizeOfResizeableTask = -1;
// Whether tasks have moved and we need to rank the tasks before next OOM scoring
private boolean mTaskLayersChanged = true;
final ActivityMetricsLogger mActivityMetricsLogger; //用于日志记录
private final ResizeDockedStackTimeout mResizeDockedStackTimeout; //
//用于寻找复用的task时候使用的变量
private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
boolean mAppVisibilitiesChangedSinceLastPause;
private final ArraySet<Integer> mResizingTasksDuringAnimation = new ArraySet<>();
private boolean mAllowDockedStackResize = true; 
boolean mIsDockMinimized; //docker最小化

PendingActivityLaunch数据结构用于描述不允许切换activity的时候,那些被延迟切换的activity

  • 栈管家初始化过程中比较重要的一步,设置WMS
 void setWindowManager(WindowManagerService wm) {
        synchronized (mService) {
            mWindowManager = wm;

            mDisplayManager =
                    (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
            mDisplayManager.registerDisplayListener(this, null); //注册display变化通知

            Display[] displays = mDisplayManager.getDisplays(); //获取当前的display
            for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
                final int displayId = displays[displayNdx].getDisplayId();
                ActivityDisplay activityDisplay = new ActivityDisplay(displayId); //创建对应的ActivityDisplay,用于描述AMS端看到的Display,在WMS端用DisplayContent描述
                if (activityDisplay.mDisplay == null) {
                    throw new IllegalStateException("Default Display does not exist");
                }
                mActivityDisplays.put(displayId, activityDisplay);
                //计算可变大小的task默认最小化大小(mDefaultMinSizeOfResizeableTask),aosp中是220dp
                calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
            }

            mHomeStack = mFocusedStack = mLastFocusedStack =
                    getStack(HOME_STACK_ID, CREATE_IF_NEEDED, ON_TOP);  //初始化HOME STACK

            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
        }
    }

isFocusedStack函数判断stack是否为焦点stack

boolean isFocusedStack(ActivityStack stack) {
        if (stack == null) {
            return false;
        }
        //子ActivityContainer放在父task的stack中
        final ActivityRecord parent = stack.mActivityContainer.mParentActivity; 
        if (parent != null) {
            stack = parent.task.stack;
        }
        return stack == mFocusedStack; //最终还是判断stack是否等于mFocusedStack
    }
  • isFrontStack函数用于判断一个stack是否在前台,我们后面分析前台stack是什么意思
 boolean isFrontStack(ActivityStack stack) {
        if (stack == null) {
            return false;
        }
        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
        if (parent != null) {
            stack = parent.task.stack;
        }
        return stack == mHomeStack.mStacks.get((mHomeStack.mStacks.size() - 1));
    }
  • 设置焦点stack,焦点stack只能在homeDisplay上,该函数只能在ActivityStack#moveToFront函数调用
 void setFocusStackUnchecked(String reason, ActivityStack focusCandidate) {
        if (!focusCandidate.isFocusable()) {
            // 如果要设置为焦点的stack不能获取焦点,选择下一个有焦点的stack作为焦点stack
            focusCandidate = focusCandidate.getNextFocusableStackLocked();
        }

        if (focusCandidate != mFocusedStack) {
            mLastFocusedStack = mFocusedStack;
            mFocusedStack = focusCandidate; //这里导致focusedStack切换的过程,我们需要分析
        }
        final ActivityRecord r = topRunningActivityLocked();
        if (!mService.mDoingSetFocusedActivity && mService.mFocusedActivity != r) {
          //更新焦点activity
            mService.setFocusedActivityLocked(r, reason + " setFocusStack");
        }
        //说明已经启动完成
        if (mService.mBooting || !mService.mBooted) {
            if (r != null && r.idle) {
                checkFinishBootingLocked();
            }
        }
    }
 void moveHomeStackToFront(String reason) {
        mHomeStack.moveToFront(reason); //将home stack移动到前台我们分析stack的时候分析
    }
  • moveHomeStackTaskToTop函数把home activity移动到前台
 boolean moveHomeStackTaskToTop(int homeStackTaskType, String reason) {
        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
            mWindowManager.showRecentApps(false /* fromHome */);
            return false;
        }

        mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);

        final ActivityRecord top = getHomeActivity();
        if (top == null) {
            return false;
        }
        mService.setFocusedActivityLocked(top, reason);
        return true;
    }
  • anyTaskForIdLocked函数根据给定的task id从stack中找到task, 如果restoreFromRecents为真则recent stack中恢复task,当task中所有的activity都销毁的时候就会从stack中删除,但是在最近任务中还能看见,并且可以恢复,stack id用于指定将task从哪个stack 中恢复
TaskRecord anyTaskForIdLocked(int id, boolean restoreFromRecents, int stackId) {
        int numDisplays = mActivityDisplays.size();
        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {//寻找task过程
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                ActivityStack stack = stacks.get(stackNdx);
                TaskRecord task = stack.taskForIdLocked(id);
                if (task != null) {
                    return task;
                }
            }
        } 
        TaskRecord task = mRecentTasks.taskForIdLocked(id);
        if (task == null) {//没有这个task直接返回
            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
            return null;
        }
        if (!restoreFromRecents) { //不能从最近任务恢复 直接返回
            return task;
        }

        if (!restoreRecentTaskLocked(task, stackId)) {//恢复
            if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
                    "Couldn't restore task id=" + id + " found in recents");
            return null;
        }
        if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents");
        return task;
    }

private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
        if (stackId == INVALID_STACK_ID) {
            stackId = task.getLaunchStackId();
        } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) {//不能改变大小
            stackId = FULLSCREEN_WORKSPACE_STACK_ID;
            //锁屏状态不能恢复在FREEFORM_WORKSPACE_STACK_ID中
        } else if (stackId == FREEFORM_WORKSPACE_STACK_ID 
                && mService.mUserController.shouldConfirmCredentials(task.userId)) {
            stackId = FULLSCREEN_WORKSPACE_STACK_ID;
        }

        if (task.stack != null) {
            // Task has already been restored once. See if we need to do anything more
            if (task.stack.mStackId == stackId) {
                // Nothing else to do since it is already restored in the right stack.
                return true;
            }
            // Remove current stack association, so we can re-associate the task with the
            // right stack below.
            task.stack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING);
        }
        final ActivityStack stack =
                getStack(stackId, CREATE_IF_NEEDED, !ON_TOP); //这里可能触发stack的创建

        if (stack == null) {
            return false;
        }

        stack.addTask(task, false, "restoreRecentTask");
        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
                "Added restored task=" + task + " to stack=" + stack);
        final ArrayList<ActivityRecord> activities = task.mActivities;
        for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
            stack.addConfigOverride(activities.get(activityNdx), task); //设置config
        }
        return true;
    }
  • isUserLockedProfile确定可见的stack的top stack中是否包含给定user的activity,如果有并且需要在keygurd解锁认证的则返回真,否则返回假
boolean isUserLockedProfile(@UserIdInt int userId) 
  • getNextTaskIdForUserLocked用于分配一个taskId
 static int nextTaskIdForUser(int taskId, int userId) {
        int nextTaskId = taskId + 1;
        if (nextTaskId == (userId + 1) * MAX_TASK_IDS_PER_USER) {
            // Wrap around as there will be smaller task ids that are available now.
            nextTaskId -= MAX_TASK_IDS_PER_USER;
        }
        return nextTaskId;
    }
int getNextTaskIdForUserLocked(int userId) {
        final int currentTaskId = mCurTaskIdForUser.get(userId, userId * MAX_TASK_IDS_PER_USER);
        // for a userId u, a taskId can only be in the range
        // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER
        // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on.
        int candidateTaskId = nextTaskIdForUser(currentTaskId, userId);
        while (mRecentTasks.taskIdTakenForUserLocked(candidateTaskId, userId)
                || anyTaskForIdLocked(candidateTaskId, !RESTORE_FROM_RECENTS,
                        INVALID_STACK_ID) != null) {
            candidateTaskId = nextTaskIdForUser(candidateTaskId, userId);
            if (candidateTaskId == currentTaskId) {
                // Something wrong!
                // All MAX_TASK_IDS_PER_USER task ids are taken up by running tasks for this user
                throw new IllegalStateException("Cannot get an available task id."
                        + " Reached limit of " + MAX_TASK_IDS_PER_USER
                        + " running tasks per user.");
            }
        }
        mCurTaskIdForUser.put(userId, candidateTaskId);
        return candidateTaskId;
    }

mCurTaskIdForUser以字典的形式记录user,和当前user分配到的最大的taskid, 第一次分配的时候会返回userId * MAX_TASK_IDS_PER_USER,MAX_TASK_IDS_PER_USER为100000,也就是说一个用户醉倒创建十万个,手下使用nextTaskIdForUser函数进行id的分配,也就是给当前最大id加1,如果超出了十万个则再从头分配. getNextTaskIdForUserLocked的while循环就是处理当十万个id分配完又从头分配的情况. 如果最终没有id可以分配会抛出异常,如果存在没被占用的taskid 则返回新分配好的taskid

  • 函数resumedAppLocked获取当resumed或者即将被显示的activity
ActivityRecord resumedAppLocked() {
        ActivityStack stack = mFocusedStack;
        if (stack == null) {
            return null;
        }
        ActivityRecord resumedActivity = stack.mResumedActivity;
        if (resumedActivity == null || resumedActivity.app == null) {
            resumedActivity = stack.mPausingActivity;
            if (resumedActivity == null || resumedActivity.app == null) {
                resumedActivity = stack.topRunningActivityLocked();
            }
        }
        return resumedActivity;
    }
  • attachApplicationLocked函数将activity绑定到进程上面
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFocusedStack(stack)) {
                    continue;
                }
                ActivityRecord hr = stack.topRunningActivityLocked();
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                  + hr.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
        return didSomething;
    }

函数用于当启动一个activity,但是该activity进程还没有启动的时候,需要等待进程启动,进程启动之后就会调用attachApplicationLocked去启动activity,这里可见一个activity启动的时候会先将ActivityRecord放在task上,然后activity启动后才会设置ActivityRecord.app所对应的ProcessRecord app, 另外只会启动mFocusedStack上的activity,ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS)函数则是用于确保栈上有activity可见,也是app动画的重要一环

  • allResumedActivitiesIdle 函数返回focuse stack上的resume是否进入idle状态
boolean allResumedActivitiesIdle() {
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFocusedStack(stack) || stack.numActivities() == 0) {
                    continue;
                }
                final ActivityRecord resumedActivity = stack.mResumedActivity;
                if (resumedActivity == null || !resumedActivity.idle) {
                    if (DEBUG_STATES) Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack="
                             + stack.mStackId + " " + resumedActivity + " not idle");
                    return false;
                }
            }
        }
        // Send launch end powerhint when idle
        mService.mActivityStarter.sendPowerHintForLaunchEndIfNeeded();
        return true;
    }
  • allResumedActivitiesComplete函数返回所有stack上的mResumedActivity是否都resume完成,这里值得注意的是会设置mLastFocusedStack = mFocusedStack,表明stack切换完成
boolean allResumedActivitiesComplete() {
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (isFocusedStack(stack)) {
                    final ActivityRecord r = stack.mResumedActivity;
                    if (r != null && r.state != RESUMED) {
                        return false;
                    }
                }
            }
        }
        // TODO: Not sure if this should check if all Paused are complete too.
        if (DEBUG_STACK) Slog.d(TAG_STACK,
                "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
                mLastFocusedStack + " to=" + mFocusedStack);
        mLastFocusedStack = mFocusedStack;
        return true;
    }
  • boolean allResumedActivitiesVisible() 返回是否所有栈上的resumed activity可见
  • boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) 函数pause所有非fource stack上的activity,注意在分屏的情况下pause的概念有所变化
  • boolean allPausedActivitiesComplete() 函数返回所有的activity都已经pause完毕
  • void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
    ActivityRecord resuming, boolean dontWait) 这个函数pause所有parent的子activity
  • void cancelInitializingActivities() 函数去掉那些不在栈顶的activity的starting window
  •  通知activity可见,并且唤醒等待进程
void sendWaitingVisibleReportLocked(ActivityRecord r) {
        boolean changed = false;
        for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
            WaitResult w = mWaitingActivityVisible.get(i);
            if (w.who == null) {
                changed = true;
                w.timeout = false;
                if (r != null) {
                    w.who = new ComponentName(r.info.packageName, r.info.name);
                }
                w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
                w.thisTime = w.totalTime;
            }
        }
        if (changed) {
            mService.notifyAll();
        }
    }
  • topRunningActivityLocked返回栈顶可以显示的(两个条件1没有finishing 2 okToShowLocked(针对user))
 ActivityRecord topRunningActivityLocked() {
        final ActivityStack focusedStack = mFocusedStack;
        ActivityRecord r = focusedStack.topRunningActivityLocked();
        if (r != null) {
            return r;
        }

        // Look in other non-focused and non-home stacks.
        final ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (stack != focusedStack && isFrontStack(stack) && stack.isFocusable()) {
                r = stack.topRunningActivityLocked();
                if (r != null) {
                    return r;
                }
            }
        }
        return null;
    }
  • void getTasksLocked(int maxNum, List list, int callingUid, boolean allowed)获取最多maxNum的task,根据lastActiveTime
  • ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags,
    ProfilerInfo profilerInfo) 设置一些调试参数

  • 启动activity的函数realStartActivityLocked

 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {

        if (!allPausedActivitiesComplete()) { //1 所有activity暂停完成再能start
            // While there are activities pausing we skipping starting any new activities until
            // pauses are complete. NOTE: that we also do this for activities that are starting in
            // the paused state because they will first be resumed then paused on the client side.
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "realStartActivityLocked: Skipping start of r=" + r
                    + " some activities pausing...");
            return false;
        }

        if (andResume) {//2需要显示的话 先frozen screen,然后设置activity可见
            r.startFreezingScreenLocked(app, 0);
            mWindowManager.setAppVisibility(r.appToken, true);

            // schedule launch ticks to collect information about slow apps.
            r.startLaunchTickingLocked();
        }

        // Have the window manager re-evaluate the orientation of
        // the screen based on the new activity order.  Note that
        // as a result of this, it can call back into the activity
        // manager with a new orientation.  We don't care about that,
        // because the activity is not currently running so we are
        // just restarting it anyway.
        if (checkConfig) {//3 检查属性是否需要转屏 以后分析
            Configuration config = mWindowManager.updateOrientationFromAppTokens(
                    mService.mConfiguration,
                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
            // Deferring resume here because we're going to launch new activity shortly.
            // We don't want to perform a redundant launch of the same record while ensuring
            // configurations and trying to resume top activity of focused stack.
            mService.updateConfigurationLocked(config, r, false, true /* deferResume */);
        }
     //4 app不为空代表执行启动,后面更新进程信息
        r.app = app;
        app.waitingToKill = null;
        r.launchCount++;
        r.lastLaunchTime = SystemClock.uptimeMillis();

        if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);

        int idx = app.activities.indexOf(r);
        if (idx < 0) {
            app.activities.add(r);
        }
        mService.updateLruProcessLocked(app, true, null);
        mService.updateOomAdjLocked();

     //5 设置logtask mode
        final TaskRecord task = r.task;
        if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||
                task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
            setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
        }

        final ActivityStack stack = task.stack;
        try {
            if (app.thread == null) {
                throw new RemoteException();
            }
            List<ResultInfo> results = null;
            List<ReferrerIntent> newIntents = null;
            if (andResume) {
                results = r.results;
                newIntents = r.newIntents;
            }
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                    "Launching: " + r + " icicle=" + r.icicle + " with results=" + results
                    + " newIntents=" + newIntents + " andResume=" + andResume);
            if (andResume) {
                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
                        r.userId, System.identityHashCode(r),
                        task.taskId, r.shortComponentName);
            }
            if (r.isHomeActivity()) {
                // Home process is the root process of the task.
                mService.mHomeProcess = task.mActivities.get(0).app;
            }
            mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
                                      PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
            r.sleeping = false;
            r.forceNewConfig = false;
            mService.showUnsupportedZoomDialogIfNeededLocked(r);
            mService.showAskCompatModeDialogLocked(r);
            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
            ProfilerInfo profilerInfo = null;
            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
                if (mService.mProfileProc == null || mService.mProfileProc == app) {
                    mService.mProfileProc = app;
                    final String profileFile = mService.mProfileFile;
                    if (profileFile != null) {
                        ParcelFileDescriptor profileFd = mService.mProfileFd;
                        if (profileFd != null) {
                            try {
                                profileFd = profileFd.dup();
                            } catch (IOException e) {
                                if (profileFd != null) {
                                    try {
                                        profileFd.close();
                                    } catch (IOException o) {
                                    }
                                    profileFd = null;
                                }
                            }
                        }

                        profilerInfo = new ProfilerInfo(profileFile, profileFd,
                                mService.mSamplingInterval, mService.mAutoStopProfiler);
                    }
                }
            }

            if (andResume) {
                app.hasShownUi = true;
                app.pendingUiClean = true;
            }
            //6 调用app.thread.scheduleLaunchActivity请求客户端创建activity,这个过程也会执行客户端resume函数
            app.forceProcessStateUpTo(mService.mTopProcessState);
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
            //7 可能更新heavy-weight进程
            if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
                // This may be a heavy-weight process!  Note that the package
                // manager will ensure that only activity can run in the main
                // process of the .apk, which is the only thing that will be
                // considered heavy-weight.
                if (app.processName.equals(app.info.packageName)) {
                    if (mService.mHeavyWeightProcess != null
                            && mService.mHeavyWeightProcess != app) {
                        Slog.w(TAG, "Starting new heavy weight process " + app
                                + " when already running "
                                + mService.mHeavyWeightProcess);
                    }
                    mService.mHeavyWeightProcess = app;
                    Message msg = mService.mHandler.obtainMessage(
                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
                    msg.obj = r;
                    mService.mHandler.sendMessage(msg);
                }
            }

        } catch (RemoteException e) {
            if (r.launchFailed) {
                // This is the second time we failed -- finish activity
                // and give up.
                Slog.e(TAG, "Second failure launching "
                      + r.intent.getComponent().flattenToShortString()
                      + ", giving up", e);
                mService.appDiedLocked(app);
                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                        "2nd-crash", false);
                return false;
            }

            // This is the first time we failed -- restart process and
            // retry.
            app.activities.remove(r);
            throw e;
        }

        r.launchFailed = false;
        if (stack.updateLRUListLocked(r)) {
            Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
        }

        if (andResume) {// 8 更新为resume状态
            // As part of the process of launching, ActivityThread also performs
            // a resume.
            stack.minimalResumeActivityLocked(r);
        } else { //9 pause状态
            // This activity is not starting in the resumed state... which should look like we asked
            // it to pause+stop (but remain visible), and it has done so and reported back the
            // current icicle and other state.
            if (DEBUG_STATES) Slog.v(TAG_STATES,
                    "Moving to PAUSED: " + r + " (starting in paused state)");
            r.state = PAUSED;
        }

        // 10 检查是否启动steup应用
        // Launch the new version setup screen if needed.  We do this -after-
        // launching the initial activity (that is, home), so that it can have
        // a chance to initialize itself while in the background, making the
        // switch back to it faster and look better.
        if (isFocusedStack(stack)) {
            mService.startSetupActivityLocked();
        }
     //11 更新bind service信息
        // Update any services we are bound to that might care about whether
        // their client may have activities.
        if (r.app != null) {
            mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
        }

        return true;
    }
  • boolean moveActivityStackToFront(ActivityRecord r, String reason) 把ActivityRecord所在task放在stack前台
  • Activity idle检查
 // Checked.
    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
            Configuration config) {
        if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);

        ArrayList<ActivityRecord> finishes = null;
        ArrayList<UserState> startingUsers = null;
        int NS = 0;
        int NF = 0;
        boolean booting = false;
        boolean activityRemoved = false;

        ActivityRecord r = ActivityRecord.forTokenLocked(token);
        if (r != null) {
            if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
                    + Debug.getCallers(4));
            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
            r.finishLaunchTickingLocked();
            if (fromTimeout) {
                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
            }

            // This is a hack to semi-deal with a race condition
            // in the client where it can be constructed with a
            // newer configuration from when we asked it to launch.
            // We'll update with whatever configuration it now says
            // it used to launch.
            if (config != null) {
                r.configuration = config;
            }

            // We are now idle.  If someone is waiting for a thumbnail from
            // us, we can now deliver.
            r.idle = true; // 1 进入idle状态

            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
            if (isFocusedStack(r.task.stack) || fromTimeout) {
                booting = checkFinishBootingLocked();
            }
        }

        if (allResumedActivitiesIdle()) { //2所有ResumedActivity进入idle状态,执行gc
            if (r != null) {
                mService.scheduleAppGcsLocked();
            }

            if (mLaunchingActivity.isHeld()) {
                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
                if (VALIDATE_WAKE_LOCK_CALLER &&
                        Binder.getCallingUid() != Process.myUid()) {
                    throw new IllegalStateException("Calling must be system uid");
                }
                mLaunchingActivity.release();
            }
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }

        // Atomically retrieve all of the other things to do.
        final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(true);
        NS = stops != null ? stops.size() : 0;
        if ((NF = mFinishingActivities.size()) > 0) {
            finishes = new ArrayList<>(mFinishingActivities);
            mFinishingActivities.clear();
        }

        if (mStartingUsers.size() > 0) {
            startingUsers = new ArrayList<>(mStartingUsers);
            mStartingUsers.clear();
        }

        // Stop any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NS; i++) {
            r = stops.get(i);
            final ActivityStack stack = r.task.stack;
            if (stack != null) {
                if (r.finishing) {
                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
                } else {
                    stack.stopActivityLocked(r);
                }
            }
        }

        // Finish any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NF; i++) {
            r = finishes.get(i);
            final ActivityStack stack = r.task.stack;
            if (stack != null) {
                activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
            }
        }

        if (!booting) {
            // Complete user switch
            if (startingUsers != null) {
                for (int i = 0; i < startingUsers.size(); i++) {
                    mService.mUserController.finishUserSwitch(startingUsers.get(i));
                }
            }
        }

        mService.trimApplications();
        //dump();
        //mWindowManager.dump();

        if (activityRemoved) {
            resumeFocusedStackTopActivityLocked();
        }

        return r;
    }
  • void closeSystemDialogsLocked()
  • boolean handleAppDiedLocked(ProcessRecord app )处理进程死亡
  • void removeUserLocked(int userId)删除账户 
  • void updateUserStackLocked(int userId, ActivityStack stack) 维护user和front stack的关系
  • boolean finishDisabledPackageActivitiesLocked(String packageName, Set filterByClasses,
    boolean doit, boolean evenPersistent, int userId)  关闭disable的package下的activity
  • void updatePreviousProcessLocked(ActivityRecord r)  更新前一个前台进程的记录
  • boolean resumeFocusedStackTopActivityLocked() 恢复焦点stack顶部activity可见
boolean resumeFocusedStackTopActivityLocked() {
        return resumeFocusedStackTopActivityLocked(null, null, null);
    }
  • resumeFocusedStackTopActivityLocked函数是上面resumeFocusedStackTopActivityLocked函数的重载
 boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        }
        return false;
    }

函数的参数targetStack为目标stack,target指要恢复的activity,targetOptions为启动过程的参数, 函数实现如果targetStack是该焦点的stack,就在指定的stack上resume 指定的activity,否则的话在焦点上resume activit,注意这里判断 r.state != RESUMED可以减少函数调用,返回值也是比较讲究的

  • getStack 系列函数
 ActivityStack getStack(int stackId) {
        return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
    }

    ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) {
        ActivityContainer activityContainer = mActivityContainers.get(stackId);
        if (activityContainer != null) {
            return activityContainer.mStack;
        }
        if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) {
            return null;
        }
        return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop);
    }

    ArrayList<ActivityStack> getStacks() {
        ArrayList<ActivityStack> allStacks = new ArrayList<>();
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks);
        }
        return allStacks;
    }
  • void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds,
    boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) 重新设置stack大小
void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds,
            boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) {
        if (stackId == DOCKED_STACK_ID) { //1 重新设置dock stack大小
            resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null,
                    preserveWindows, deferResume);
            return;
        }
        final ActivityStack stack = getStack(stackId);
        if (stack == null) { //2 不存在stack直接返回
            Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
            return;
        }
       // 3 不允许dock mode 重新设置大小
        if (!allowResizeInDockedMode && getStack(DOCKED_STACK_ID) != null) {
            // If the docked stack exist we don't allow resizes of stacks not caused by the docked
            // stack size changing so things don't get out of sync.
            return;
        }

        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId);
        mWindowManager.deferSurfaceLayout();
        try {// 4 重新设置栈大小
            resizeStackUncheckedLocked(stack, bounds, tempTaskBounds, tempTaskInsetBounds);
            if (!deferResume) {
                stack.ensureVisibleActivitiesConfigurationLocked(
                        stack.topRunningActivityLocked(), preserveWindows);
            }
        } finally {
            mWindowManager.continueSurfaceLayout();
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }          
  • notifyAppTransitionDone app切换动画执行完成
 void notifyAppTransitionDone() {
        continueUpdateBounds(HOME_STACK_ID);
        for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
            final int taskId = mResizingTasksDuringAnimation.valueAt(i);
            if (anyTaskForIdLocked(taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID) != null) {
                mWindowManager.setTaskDockedResizing(taskId, false);
            }
        }
        mResizingTasksDuringAnimation.clear();
    }

执行拖拽Dock stack设置大小操作
重置大小系列函数

//先介绍下参数, dockedBounds当前dock大小位置,tempDockedTaskBounds为DockedTask的大小位置,tempDockedTaskInsetBounds docktask的inset,  tempOtherTaskBounds下面的task大小位置,tempOtherTaskInsetBounds 另外一个tack的inset
 void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
            Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds,
            boolean preserveWindows) {
        resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds,
                tempOtherTaskBounds, tempOtherTaskInsetBounds, preserveWindows,
                false /* deferResume */);
    }

 void resizeStackUncheckedLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds,
            Rect tempTaskInsetBounds) {
        bounds = TaskRecord.validateBounds(bounds); //1 校验边界是否可用

        if (!stack.updateBoundsAllowed(bounds, tempTaskBounds, tempTaskInsetBounds)) {//2是否可以马上更新
            return;
        }

        mTmpBounds.clear();
        mTmpConfigs.clear();
        mTmpInsetBounds.clear();
        final ArrayList<TaskRecord> tasks = stack.getAllTasks();
        final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds;
        final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds;
        for (int i = tasks.size() - 1; i >= 0; i--) {
            final TaskRecord task = tasks.get(i);
            if (task.isResizeable()) { //1 stack 可以修改大小
                if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
                    // For freeform stack we don't adjust the size of the tasks to match that
                    // of the stack, but we do try to make sure the tasks are still contained
                    // with the bounds of the stack.
                     //2 对于FREEFORM stack,不重新计算task大小以适应stack,但是尽量保证边界在stack内 
                    tempRect2.set(task.mBounds);
                    fitWithinBounds(tempRect2, bounds);
                    task.updateOverrideConfiguration(tempRect2);
                } else {
                  // 3 更新大小
                    task.updateOverrideConfiguration(taskBounds, insetBounds);
                }
            }

            mTmpConfigs.put(task.taskId, task.mOverrideConfig);
            mTmpBounds.put(task.taskId, task.mBounds);
            if (tempTaskInsetBounds != null) {
                mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds);
            }
        }

     //4 准备冻结屏幕
        // We might trigger a configuration change. Save the current task bounds for freezing.
        mWindowManager.prepareFreezingTaskBounds(stack.mStackId);
        //5 wms改变窗口大小
        stack.mFullscreen = mWindowManager.resizeStack(stack.mStackId, bounds, mTmpConfigs,
                mTmpBounds, mTmpInsetBounds);
        //6 更新stack 大小
        stack.setBounds(bounds);
    }

   // docker stack关闭的时候移动dock stack上的task到全屏的stack上
    void moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop) {
        final ActivityStack stack = getStack(fromStackId); //1 检查stack不存在不做操作
        if (stack == null) {
            return;
        }

        mWindowManager.deferSurfaceLayout();
        try {
            if (fromStackId == DOCKED_STACK_ID) { 

                // We are moving all tasks from the docked stack to the fullscreen stack,
                // which is dismissing the docked stack, so resize all other stacks to
                // fullscreen here already so we don't end up with resize trashing.
                for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {// 2 先改变其他stack大小,在resizeDockedStackLocked函数中也有调用
                    if (StackId.isResizeableByDockedStack(i)) {
                        ActivityStack otherStack = getStack(i);
                        if (otherStack != null) {
                            resizeStackLocked(i, null, null, null, PRESERVE_WINDOWS,
                                    true /* allowResizeInDockedMode */, DEFER_RESUME);
                        }
                    }
                }

                // Also disable docked stack resizing since we have manually adjusted the
                // size of other stacks above and we don't want to trigger a docked stack
                // resize when we remove task from it below and it is detached from the
                // display because it no longer contains any tasks.
                mAllowDockedStackResize = false;
            }
            final ArrayList<TaskRecord> tasks = stack.getAllTasks();
            final int size = tasks.size();
            if (onTop) {
                for (int i = 0; i < size; i++) { //4 移动task到其他stack顶部
                    moveTaskToStackLocked(tasks.get(i).taskId,
                            FULLSCREEN_WORKSPACE_STACK_ID, onTop, onTop /*forceFocus*/,
                            "moveTasksToFullscreenStack", ANIMATE, DEFER_RESUME);
                }

                ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
                resumeFocusedStackTopActivityLocked();//5 这时候可能有了新的栈顶,重新可见它
            } else {
                for (int i = size - 1; i >= 0; i--) { //6 放到FULLSCREEN_WORKSPACE_STACK_ID 底部
                    positionTaskInStackLocked(tasks.get(i).taskId,
                            FULLSCREEN_WORKSPACE_STACK_ID, 0);
                }
            }
        } finally {
            mAllowDockedStackResize = true;
            mWindowManager.continueSurfaceLayout();
        }
    }

    /** 把user下的activity移动到FULLSCREEN_WORKSPACE_STACK_ID对应的stack的底部
     * TODO: remove the need for this method. (b/30693465)
     *
     * @param userId user handle for the locked managed profile. Freeform tasks for this user will
     *        be moved to another stack, so they are not shown in the background.
     */
    void moveProfileTasksFromFreeformToFullscreenStackLocked(@UserIdInt int userId) {
        final ActivityStack stack = getStack(FREEFORM_WORKSPACE_STACK_ID);
        if (stack == null) {
            return;
        }
        mWindowManager.deferSurfaceLayout();
        try {
            final ArrayList<TaskRecord> tasks = stack.getAllTasks();
            final int size = tasks.size();
            for (int i = size - 1; i >= 0; i--) {
                if (taskContainsActivityFromUser(tasks.get(i), userId)) {
                    positionTaskInStackLocked(tasks.get(i).taskId, FULLSCREEN_WORKSPACE_STACK_ID,
                            /* position */ 0);
                }
            }
        } finally {
            mWindowManager.continueSurfaceLayout();
        }
    }

    void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
            Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds,
            boolean preserveWindows) {
        resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds,
                tempOtherTaskBounds, tempOtherTaskInsetBounds, preserveWindows,
                false /* deferResume */);
    }


    void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
            Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds,
            boolean preserveWindows, boolean deferResume) {

        if (!mAllowDockedStackResize) { //1不允许改变大小直接返回
            // Docked stack resize currently disabled.
            return;
        }

        final ActivityStack stack = getStack(DOCKED_STACK_ID);
        if (stack == null) { //2 dock stack 不存在直接返回
            Slog.w(TAG, "resizeDockedStackLocked: docked stack not found");
            return;
        }

        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack");
        mWindowManager.deferSurfaceLayout(); //3 禁止WMS执行新的layout
        try {
            // Don't allow re-entry while resizing. E.g. due to docked stack detaching.
            mAllowDockedStackResize = false; // 4 在执行resize的时候不允许再次进入
            ActivityRecord r = stack.topRunningActivityLocked(); 
            resizeStackUncheckedLocked(stack, dockedBounds, tempDockedTaskBounds,
                    tempDockedTaskInsetBounds); //5重新计算dock stack大小

            // TODO: Checking for isAttached might not be needed as if the user passes in null
            // dockedBounds then they want the docked stack to be dismissed.
            if (stack.mFullscreen || (dockedBounds == null && !stack.isAttached())) {
                // The dock stack either was dismissed or went fullscreen, which is kinda the same.
                // In this case we make all other static stacks fullscreen and move all
                // docked stack tasks to the fullscreen stack.
                // 6 Dock stack 变成全屏或者被销毁的时候移动所有task到全屏task
                moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, ON_TOP);

                // stack shouldn't contain anymore activities, so nothing to resume.
                r = null;
            } else {
                // Docked stacks occupy a dedicated region on screen so the size of all other
                // static stacks need to be adjusted so they don't overlap with the docked stack.
                // We get the bounds to use from window manager which has been adjusted for any
                // screen controls and is also the same for all stacks.
                //7 docker大小该表,修改其他stack的大小防止重叠
                mWindowManager.getStackDockedModeBounds(
                        HOME_STACK_ID, tempRect, true /* ignoreVisibility */);
                for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
                    if (StackId.isResizeableByDockedStack(i) && getStack(i) != null) {
                        resizeStackLocked(i, tempRect, tempOtherTaskBounds,
                                tempOtherTaskInsetBounds, preserveWindows,
                                true /* allowResizeInDockedMode */, deferResume);
                    }
                }
            }
            if (!deferResume) {
                stack.ensureVisibleActivitiesConfigurationLocked(r, preserveWindows);
            }
        } finally {
            mAllowDockedStackResize = true; //8 允许执行resize 和 新的layout
            mWindowManager.continueSurfaceLayout();
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }

        mResizeDockedStackTimeout.notifyResizing(dockedBounds,
                tempDockedTaskBounds != null
                || tempDockedTaskInsetBounds != null
                || tempOtherTaskBounds != null
                || tempOtherTaskInsetBounds != null); //9 发送一个10s没有处理的超时操作
    }

  // 改变画中画所在的stack大小
    void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
        final ActivityStack stack = getStack(PINNED_STACK_ID);
        if (stack == null) {
            Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found");
            return;
        }
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack");
        mWindowManager.deferSurfaceLayout();
        try {
            ActivityRecord r = stack.topRunningActivityLocked();
            resizeStackUncheckedLocked(stack, pinnedBounds, tempPinnedTaskBounds,
                    null);
            stack.ensureVisibleActivitiesConfigurationLocked(r, false);
        } finally {
            mWindowManager.continueSurfaceLayout();
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

    boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow,
            boolean deferResume) {
        if (!task.isResizeable()) { //1 不允许改变task大小直接返回
            Slog.w(TAG, "resizeTask: task " + task + " not resizeable.");
            return true;
        }

        // If this is a forced resize, let it go through even if the bounds is not changing,
        // as we might need a relayout due to surface size change (to/from fullscreen).
        final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
        if (Objects.equals(task.mBounds, bounds) && !forced) { //2 大小没有改变
            // Nothing to do here...
            return true;
        }
        bounds = TaskRecord.validateBounds(bounds); 

        if (!mWindowManager.isValidTaskId(task.taskId)) {//3 更新taskbounds属性
            // Task doesn't exist in window manager yet (e.g. was restored from recents).
            // All we can do for now is update the bounds so it can be used when the task is
            // added to window manager.
            task.updateOverrideConfiguration(bounds);
            if (task.stack != null && task.stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
                // re-restore the task so it can have the proper stack association.
                restoreRecentTaskLocked(task, FREEFORM_WORKSPACE_STACK_ID);
            }
            return true;
        }

        // Do not move the task to another stack here.
        // This method assumes that the task is already placed in the right stack.
        // we do not mess with that decision and we only do the resize!

        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + task.taskId);

        final Configuration overrideConfig =  task.updateOverrideConfiguration(bounds);
        // This variable holds information whether the configuration didn't change in a significant
        // way and the activity was kept the way it was. If it's false, it means the activity had
        // to be relaunched due to configuration change.
        boolean kept = true;
        if (overrideConfig != null) {
            final ActivityRecord r = task.topRunningActivityLocked();
            if (r != null) {
                final ActivityStack stack = task.stack;
                kept = stack.ensureActivityConfigurationLocked(r, 0, preserveWindow);

                if (!deferResume) {//4 由于属性变化重新启动activity

                    // All other activities must be made visible with their correct configuration.
                    ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS);
                    if (!kept) {
                        resumeFocusedStackTopActivityLocked();
                    }
                }
            }
        }
        //5 WMS改变窗口大小
        mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, kept, forced);

        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        return kept;
    }
  • fitWithinBounds修复task的大小,在freedom模式下不需要修改task大小来适应stack,但是要尽量保证task在stack边界内部
    参数bounds为task的边界,stackBounds为stack的边界
private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
        // 1 全屏stack和stack的边界包含task边界时候直接返回,不需要操作
        if (stackBounds == null || stackBounds.contains(bounds)) {
            return;
        }

        if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {//2向左边或者向右边移动task,使task显示更多
            final int maxRight = stackBounds.right
                    - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
            int horizontalDiff = stackBounds.left - bounds.left;
            if ((horizontalDiff < 0 && bounds.left >= maxRight)
                    || (bounds.left + horizontalDiff >= maxRight)) {
                horizontalDiff = maxRight - bounds.left;
            }
            bounds.left += horizontalDiff;
            bounds.right += horizontalDiff;
        }

        if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
            final int maxBottom = stackBounds.bottom
                    - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
            int verticalDiff = stackBounds.top - bounds.top;
            if ((verticalDiff < 0 && bounds.top >= maxBottom)
                    || (bounds.top + verticalDiff >= maxBottom)) {
                verticalDiff = maxBottom - bounds.top;
            }
            bounds.top += verticalDiff;
            bounds.bottom += verticalDiff;
        }
    }

通过这一系列函数可以看出使用task.updateOverrideConfiguration(taskBounds, insetBounds);函数去设置stack中的task大小,WMS的操作主要是 mWindowManager.setTaskDockedResizing(taskId, false); 设置状态。
mWindowManager.prepareFreezingTaskBounds(stack.mStackId);
stack.mFullscreen = mWindowManager.resizeStack(stack.mStackId, bounds, mTmpConfigs,
mTmpBounds, mTmpInsetBounds);
mWindowManager.getStackDockedModeBounds(
HOME_STACK_ID, tempRect, true /* ignoreVisibility */);
mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, kept, forced);

  • createStackOnDisplay 创建stack的过程 这里面和wms结合的比较紧密
  ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) {
        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
        if (activityDisplay == null) { //1 指定的display不存在 返回null
            return null;
        }

        ActivityContainer activityContainer = new ActivityContainer(stackId); //2 创建
        mActivityContainers.put(stackId, activityContainer);
        activityContainer.attachToDisplayLocked(activityDisplay, onTop); //3 attach
        return activityContainer.mStack;
    }
  • int getNextStackId() 创建一个动态的stack id
  • 恢复最近任务
 /**
     * Restores a recent task to a stack
     * @param task The recent task to be restored.
     * @param stackId The stack to restore the task to (default launch stack will be used
     *                if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}).
     * @return true if the task has been restored successfully.
     */
    private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
        if (stackId == INVALID_STACK_ID) {//1没指定stack根据task类型返回
            stackId = task.getLaunchStackId();
        } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) {//2 task不能进入dock stack返回FULLSCREEN_WORKSPACE_STACK_ID
            // Preferred stack is the docked stack, but the task can't go in the docked stack.
            // Put it in the fullscreen stack.
            stackId = FULLSCREEN_WORKSPACE_STACK_ID;
        } else if (stackId == FREEFORM_WORKSPACE_STACK_ID
                && mService.mUserController.shouldConfirmCredentials(task.userId)) {
            //3这个用户不允许进入freeform stack,放到fullscrenn stack
            // Task is barred from the freeform stack. Put it in the fullscreen stack.
            stackId = FULLSCREEN_WORKSPACE_STACK_ID;
        }

        if (task.stack != null) {
            // Task has already been restored once. See if we need to do anything more
            if (task.stack.mStackId == stackId) { // 4 不需要做啥
                // Nothing else to do since it is already restored in the right stack.
                return true;
            }
            // Remove current stack association, so we can re-associate the task with the
            // right stack below. //5 从原来的stack移除
            task.stack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING);
        }

        final ActivityStack stack =
                getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);

        if (stack == null) {
            // What does this mean??? Not sure how we would get here...
            if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
                    "Unable to find/create stack to restore recent task=" + task);
            return false;
        }

        stack.addTask(task, false, "restoreRecentTask"); //6 添加task到stack底部,放到底部会改变stack属性
        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
                "Added restored task=" + task + " to stack=" + stack);
        final ArrayList<ActivityRecord> activities = task.mActivities;
        for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
            stack.addConfigOverride(activities.get(activityNdx), task);
        }
        return true;
    }

下面的一系列函数则是移动task,stack和activity的操作,涉及到task移动的场景其实就是分屏等操作

   /**
     * Moves the specified task record to the input stack id.
     * WARNING: This method performs an unchecked/raw move of the task and
     * can leave the system in an unstable state if used incorrectly.
     * Use {@link #moveTaskToStackLocked} to perform safe task movement to a stack.
     * @param task Task to move.
     * @param stackId Id of stack to move task to.
     * @param toTop True if the task should be placed at the top of the stack.
     * @param forceFocus if focus should be moved to the new stack
     * @param reason Reason the task is been moved.
     * @return The stack the task was moved to.
     */
    ActivityStack moveTaskToStackUncheckedLocked(
            TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) {
        //1 不支持分屏直接返回
        if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) {
            throw new IllegalStateException("moveTaskToStackUncheckedLocked: Device doesn't "
                    + "support multi-window task=" + task + " to stackId=" + stackId);
        }

        final ActivityRecord r = task.topRunningActivityLocked();
        final ActivityStack prevStack = task.stack;
        final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r);
        final boolean wasResumed = prevStack.mResumedActivity == r;
        // In some cases the focused stack isn't the front stack. E.g. pinned stack.
        // Whenever we are moving the top activity from the front stack we want to make sure to move
        // the stack to the front.
        final boolean wasFront = isFrontStack(prevStack)
                && (prevStack.topRunningActivityLocked() == r);

        if (stackId == DOCKED_STACK_ID && !task.isResizeable()) {
        //2不允许改变大小的task,还放到原来的stack或者放到FULLSCREEN_WORKSPACE_STACK
            // We don't allow moving a unresizeable task to the docked stack since the docked
            // stack is used for split-screen mode and will cause things like the docked divider to
            // show up. We instead leave the task in its current stack or move it to the fullscreen
            // stack if it isn't currently in a stack.
            stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID;
            Slog.w(TAG, "Can not move unresizeable task=" + task
                    + " to docked stack. Moving to stackId=" + stackId + " instead.");
        }
        if (stackId == FREEFORM_WORKSPACE_STACK_ID
        //3 user认证不通过的 
            stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID;
            Slog.w(TAG, "Can not move locked profile task=" + task
                    + " to freeform stack. Moving to stackId=" + stackId + " instead.");
        }

        // Temporarily disable resizeablility of task we are moving. We don't want it to be resized
        // if a docked stack is created below which will lead to the stack we are moving from and
        // its resizeable tasks being resized.
        task.mTemporarilyUnresizable = true; 
        final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop);
        task.mTemporarilyUnresizable = false;
        //4 wms移动task到stack上
        mWindowManager.moveTaskToStack(task.taskId, stack.mStackId, toTop);
        stack.addTask(task, toTop, reason);//5AMS端移动

        // If the task had focus before (or we're requested to move focus),
        // move focus to the new stack by moving the stack to the front.
        //5 如果移动的task带有焦点,或者之前在前台,移动stack到前台
        stack.moveToFrontAndResumeStateIfNeeded(
                r, forceFocus || wasFocused || wasFront, wasResumed, reason);

        return stack;
    }

   
    boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
            String reason, boolean animate) {
        return moveTaskToStackLocked(taskId, stackId, toTop, forceFocus, reason, animate,
                false /* deferResume */);
    }
  //moveTaskToStackUncheckedLocked 的上一级函数,做一些必要的检查
    boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
            String reason, boolean animate, boolean deferResume) {
        final TaskRecord task = anyTaskForIdLocked(taskId); //1 获取task record ,不存在退出
        if (task == null) {
            Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
            return false;
        }

        if (task.stack != null && task.stack.mStackId == stackId) {//2不需要移动返回
            // You are already in the right stack silly...
            Slog.i(TAG, "moveTaskToStack: taskId=" + taskId + " already in stackId=" + stackId);
            return true;
        }
     //3 不允许REEFORM抛出异常
        if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {
            throw new IllegalArgumentException("moveTaskToStack:"
                    + "Attempt to move task " + taskId + " to unsupported freeform stack");
        }

        final ActivityRecord topActivity = task.getTopActivity();
        final int sourceStackId = task.stack != null ? task.stack.mStackId : INVALID_STACK_ID;
        //从FREEFORM窗口移动要替换原来的窗口,要重新启动activity
        final boolean mightReplaceWindow =
                StackId.replaceWindowsOnTaskMove(sourceStackId, stackId) && topActivity != null;
        if (mightReplaceWindow) {
            // We are about to relaunch the activity because its configuration changed due to
            // being maximized, i.e. size change. The activity will first remove the old window
            // and then add a new one. This call will tell window manager about this, so it can
            // preserve the old window until the new one is drawn. This prevents having a gap
            // between the removal and addition, in which no window is visible. We also want the
            // entrance of the new window to be properly animated.
            // Note here we always set the replacing window first, as the flags might be needed
            // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
            //4通知WMS移动窗口
            mWindowManager.setReplacingWindow(topActivity.appToken, animate);
        }

        mWindowManager.deferSurfaceLayout();
        final int preferredLaunchStackId = stackId;
        boolean kept = true;
        try {
           //5 真正的移动task到stack,主要是使用stack的一些函数进行操作
            final ActivityStack stack = moveTaskToStackUncheckedLocked(
                    task, stackId, toTop, forceFocus, reason + " moveTaskToStack");
            stackId = stack.mStackId;

            if (!animate) {
                stack.mNoAnimActivities.add(topActivity);
            }

            // We might trigger a configuration change. Save the current task bounds for freezing.
            mWindowManager.prepareFreezingTaskBounds(stack.mStackId);

            // Make sure the task has the appropriate bounds/size for the stack it is in.
            if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) {
              //6 改变stack大小,因为task移动到stack上有可能改变stack的属性大小,这里改变大小
                kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM,
                        !mightReplaceWindow, deferResume);
            } else if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
                Rect bounds = task.getLaunchBounds();
                if (bounds == null) {
                    stack.layoutTaskInStack(task, null); //7 根据stack计算task大小
                    bounds = task.mBounds;
                }
                //8reize task
                kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow,
                        deferResume);
            } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) {
            //9 确保大小
                kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM,
                        !mightReplaceWindow, deferResume);
            }
        } finally {
            mWindowManager.continueSurfaceLayout();
        }

        if (mightReplaceWindow) {
            // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
            // window), we need to clear the replace window settings. Otherwise, we schedule a
            // timeout to remove the old window if the replacing window is not coming in time.
            mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept);
        }

        if (!deferResume) {

            // The task might have already been running and its visibility needs to be synchronized with
            // the visibility of the stack / windows.
            ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
            //10 resume,这里只是确保有可见的activity
            resumeFocusedStackTopActivityLocked();
        }

        handleNonResizableTaskIfNeeded(task, preferredLaunchStackId, stackId);

        return (preferredLaunchStackId == stackId);
    }
    //把stack上的top activity移动到画中画所在的stack上
    boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect bounds) {
        final ActivityStack stack = getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
        if (stack == null) { //1 stack不存在直接抛出异常
            throw new IllegalArgumentException(
                    "moveTopStackActivityToPinnedStackLocked: Unknown stackId=" + stackId);
        }

        final ActivityRecord r = stack.topRunningActivityLocked();
        if (r == null) {//2 不存在running的activity也是返回false
            Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: No top running activity"
                    + " in stack=" + stack);
            return false;
        }
        //3  不支持画中画返回false
        if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
            Slog.w(TAG,
                    "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for "
                            + " r=" + r);
            return false;
        }
        //4 做完检查和找到top activity直接执行
        moveActivityToPinnedStackLocked(r, "moveTopActivityToPinnedStack", bounds);
        return true;
    }

    void moveActivityToPinnedStackLocked(ActivityRecord r, String reason, Rect bounds) {
        mWindowManager.deferSurfaceLayout();
        try {
            final TaskRecord task = r.task;

            if (r == task.stack.getVisibleBehindActivity()) {
                // An activity can't be pinned and visible behind at the same time. Go ahead and
                // release it from been visible behind before pinning.
                requestVisibleBehindLocked(r, false);
            }
            //5获取或者创建pinned stack
            // Need to make sure the pinned stack exist so we can resize it below...
            final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);

            //6 调整pinned stack大小为即将要移动进来的activity的大小
            // Resize the pinned stack to match the current size of the task the activity we are
            // going to be moving is currently contained in. We do this to have the right starting
            // animation bounds for the pinned stack to the desired bounds the caller wants.
            resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */,
                    null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
                    true /* allowResizeInDockedMode */, !DEFER_RESUME);

            if (task.mActivities.size() == 1) {
            //7 task中只有一个activity的情况把task移动到stack上
                // There is only one activity in the task. So, we can just move the task over to
                // the stack without re-parenting the activity in a different task.
                if (task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
                    // Move the home stack forward if the task we just moved to the pinned stack
                    // was launched from home so home should be visible behind it.
                    moveHomeStackToFront(reason);
                }
                moveTaskToStackLocked(
                        task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE);
            } else {
               //8 移动activity到stack
                stack.moveActivityToStack(r);
            }
        } finally {
            mWindowManager.continueSurfaceLayout();
        }

        // The task might have already been running and its visibility needs to be synchronized
        // with the visibility of the stack / windows.
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        resumeFocusedStackTopActivityLocked(); //9 可见焦点activity

        //10 执行动画
        mWindowManager.animateResizePinnedStack(bounds, -1);
        mService.notifyActivityPinnedLocked();
    }
  // 把task放到stack指定的位置(position)
    void positionTaskInStackLocked(int taskId, int stackId, int position) {
        final TaskRecord task = anyTaskForIdLocked(taskId);
        if (task == null) { //1不存在task直接返回
            Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId);
            return;
        }
        //2 获得stack
        final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, !ON_TOP);
        //3 更新config
        task.updateOverrideConfigurationForStack(stack);
        //4 更新wms端的stack和配置
        mWindowManager.positionTaskInStack(
                taskId, stackId, position, task.mBounds, task.mOverrideConfig);
        //5 添加到ams中stack对应位置
        stack.positionTask(task, position);
        // The task might have already been running and its visibility needs to be synchronized with
        // the visibility of the stack / windows.
        stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        resumeFocusedStackTopActivityLocked();  //6可见activity
    }
    // 根据activity找到task
    ActivityRecord findTaskLocked(ActivityRecord r) {
        mTmpFindTaskResult.r = null;
        mTmpFindTaskResult.matchedByRootAffinity = false;
        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!r.isApplicationActivity() && !stack.isHomeStack()) {//不从home stack中找
                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack);
                    continue;
                }
                if (!stack.mActivityContainer.isEligibleForNewTasks()) {
                    if (DEBUG_TASKS) Slog.d(TAG_TASKS,
                            "Skipping stack: (new task not allowed) " + stack);
                    continue;
                }
                //最主要函数在stack中找task
                stack.findTaskLocked(r, mTmpFindTaskResult);
                // It is possible to have task in multiple stacks with the same root affinity.
                // If the match we found was based on root affinity we keep on looking to see if
                // there is a better match in another stack. We eventually return the match based
                // on root affinity if we don't find a better match.
                if (mTmpFindTaskResult.r != null && !mTmpFindTaskResult.matchedByRootAffinity) {
                    return mTmpFindTaskResult.r;
                }
            }
        }
        if (DEBUG_TASKS && mTmpFindTaskResult.r == null) Slog.d(TAG_TASKS, "No task found");
        return mTmpFindTaskResult.r;
    }
    //找activity
    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info,
                                      boolean compareIntentFilters) {
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityRecord ar = stacks.get(stackNdx) 
                        .findActivityLocked(intent, info, compareIntentFilters);
                if (ar != null) {
                    return ar;
                }
            }
        }
        return null;
    }

休眠和开关机相关的函数

//goingToSleepLocked函数很简单,首先发出一个五秒超时的消息,然后获取mGoingToSleep的weak log,
//防止cpu过早休眠,之后释放mLaunchingActivity weak log,移除LAUNCH_TIMEOUT_MSG消息,
void goingToSleepLocked() {
        scheduleSleepTimeout();
        if (!mGoingToSleep.isHeld()) {
            mGoingToSleep.acquire();
            if (mLaunchingActivity.isHeld()) {
                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
                    throw new IllegalStateException("Calling must be system uid");
                }
                mLaunchingActivity.release();
                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
            }
        }
        // 检查是否准备好休眠
        checkReadyForSleepLocked();
    }

    boolean shutdownLocked(int timeout) {
        goingToSleepLocked();//1 先进入休眠流程善后

        boolean timedout = false;
        final long endTime = System.currentTimeMillis() + timeout;
        while (true) {
            boolean cantShutdown = false;
            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                    cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked();
                }
            }
            if (cantShutdown) {//2 stack还没有准备好等待超时时间
                long timeRemaining = endTime - System.currentTimeMillis();
                if (timeRemaining > 0) {
                    try {
                        mService.wait(timeRemaining);
                    } catch (InterruptedException e) {
                    }
                } else {
                    Slog.w(TAG, "Activity manager shutdown timed out");
                    //3 超时
                    timedout = true;
                    break;
                }
            } else {
                break;
            }
        }
     
        // Force checkReadyForSleep to complete.
        mSleepTimeout = true;
        //3 再次检查超时,强制进行sleep状态 
        checkReadyForSleepLocked();
        return timedout;
    }
  //走出休眠状态唤醒,这里直接清除掉mGoingToSleepActivities,只有休眠超时的时候一些activity才会进入sleep状态
    void comeOutOfSleepIfNeededLocked() {
        removeSleepTimeouts();
        if (mGoingToSleep.isHeld()) {
            mGoingToSleep.release();
        }
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                stack.awakeFromSleepingLocked();
                if (isFocusedStack(stack)) {
                    resumeFocusedStackTopActivityLocked();
                }
            }
        }
        mGoingToSleepActivities.clear();
    }
    //客户端执行完activity休眠所做的操作
    void activitySleptLocked(ActivityRecord r) {
        mGoingToSleepActivities.remove(r);
        checkReadyForSleepLocked();
    }

    void checkReadyForSleepLocked() {
      // 1处于关机状态或者还没有计入休眠什么都不需要做
        if (!mService.isSleepingOrShuttingDownLocked()) {
            // Do not care.
            return;
        }
        //2 没有超时的情况(goingToSleepLocked函数会发送一个检查超时的消息,超时后该值设置为真)
        if (!mSleepTimeout) { 
            boolean dontSleep = false;
            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                   //3 检查每一个stack是否都准备好了进入休眠状态,也就是检查stack上还有没有resume activity和
                   //Pausing Activity(正在执行pause的),如果有不允许进入休眠
                    dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked();
                }
            }
            //4 如果有些activity还需要进入stoping状态,则还不能进入休眠
            if (mStoppingActivities.size() > 0) {
                // Still need to tell some activities to stop; can't sleep yet.
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
                        + mStoppingActivities.size() + " activities");
                //发送一个IDLE_NOW_MSG使activity进入休眠。这个消息在
                //activityIdleInternal()函数中处理我们前面已经分析过了,会对mStoppingActivities和
                // mFinishingActivities的activity执行相应的生命周期函数
                scheduleIdleLocked();
                dontSleep = true;
            }
       //5 还有些需要通知客户端进行休眠的activity,也不能进入休眠状态
       // 请观察ActivityThread.scheduleSleeping(appToken, _sleeping)
            if (mGoingToSleepActivities.size() > 0) {
                // Still need to tell some activities to sleep; can't sleep yet.
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
                        + mGoingToSleepActivities.size() + " activities");
                dontSleep = true;
            }
            //6 不能休眠直接返回
            if (dontSleep) {
                return;
            }
        }

        // Send launch end powerhint before going sleep
        mService.mActivityStarter.sendPowerHintForLaunchEndIfNeeded();
        //7 设置每个正在stop pause的并且可见的activity进入休眠状态,也是为了执行Activity的stop函数
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                stacks.get(stackNdx).goToSleep();
            }
        }
        //8 移除超时消息
        removeSleepTimeouts();
        //9 释放休眠锁,可见mGoingToSleep这把weak lock只是用于执行睡眠过程中的善后操作防止休眠用的
        if (mGoingToSleep.isHeld()) {
            mGoingToSleep.release();
        }
        if (mService.mShuttingDown) {
            mService.notifyAll();
        }
    }

所以从上面可以看出进入休眠之前要使所有activity进入到stop状态(也就是idle状态),会执行stacks.get(stackNdx).goToSleep()函数使activity执行stop函数。

  • reportResumedActivityLocked Activity执行resume完成后会执行这个函数,并且会出发app 动画执行
  • void handleAppCrashLocked(ProcessRecord app) app崩溃时候对上面的activity做善后处理
  • processStoppingActivitiesLocked 处理stopping 状态的activity
 //TODO
 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
        ArrayList<ActivityRecord> stops = null;

        final boolean nowVisible = allResumedActivitiesVisible();
        for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
            ActivityRecord s = mStoppingActivities.get(activityNdx);
            // TODO: Remove mWaitingVisibleActivities list and just remove activity from
            // mStoppingActivities when something else comes up.
            boolean waitingVisible = mWaitingVisibleActivities.contains(s);
            if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
                    + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
            if (waitingVisible && nowVisible) {
                mWaitingVisibleActivities.remove(s);
                waitingVisible = false;
                if (s.finishing) {
                    // If this activity is finishing, it is sitting on top of
                    // everyone else but we now know it is no longer needed...
                    // so get rid of it.  Otherwise, we need to go through the
                    // normal flow and hide it once we determine that it is
                    // hidden by the activities in front of it.
                    if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
                    //1 如果activity正在关闭状态,设置不可见
                    mWindowManager.setAppVisibility(s.appToken, false);
                }
            }
            //2 不需要等待可见或者进入睡眠状态的,收集到stops集合中,外层函数做处理
            if ((!waitingVisible || mService.isSleepingOrShuttingDownLocked()) && remove) {
                if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
                if (stops == null) {
                    stops = new ArrayList<>();
                }
                stops.add(s);
                mStoppingActivities.remove(activityNdx);
            }
        }

        return stops;
    }

这里可以看到mStoppingActivities中包含一些等待可见的activity(mWaitingVisibleActivities),在WMS通知activity可见或者idle的时候调用processStoppingActivitiesLocked 函数处理。

  • validateTopActivitiesLocked打印top activity状态
  • display相关的处理
private void handleDisplayAdded(int displayId) {
        boolean newDisplay;
        synchronized (mService) {
            newDisplay = mActivityDisplays.get(displayId) == null;
            if (newDisplay) {//1创建新的display
                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
                if (activityDisplay.mDisplay == null) {
                    Slog.w(TAG, "Display " + displayId + " gone before initialization complete");
                    return;
                }
                mActivityDisplays.put(displayId, activityDisplay);
                //2 计算最小化task的大小,现在的值不和dispaly关联
                calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
            }
        }
        if (newDisplay) {//3 通知WMS添加displaycontent
            mWindowManager.onDisplayAdded(displayId);
        }
    }
  • handler的处理在AMS的mainHandler上,ActivityStackSupervisorHandler
  private final class ActivityStackSupervisorHandler extends Handler {

        public ActivityStackSupervisorHandler(Looper looper) {
            super(looper);
        }

        void activityIdleInternal(ActivityRecord r) {
            synchronized (mService) {
                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
            }
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
                    synchronized (mService) {
                       //分屏模式改变
                        for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
                            final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
                            //调用app.thread.scheduleMultiWindowModeChanged(appToken, !task.mFullscreen);
                            r.scheduleMultiWindowModeChanged();
                        }
                    }
                } break;
                case REPORT_PIP_MODE_CHANGED_MSG: {
                //画中画模式改变
                    synchronized (mService) {
                        for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
                            final ActivityRecord r = mPipModeChangedActivities.remove(i);
                            //调用 app.thread.schedulePictureInPictureModeChanged(
                            //appToken, task.stack.mStackId == PINNED_STACK_ID)
                            r.schedulePictureInPictureModeChanged();
                        }
                    }
                } break;
                case IDLE_TIMEOUT_MSG: {
                    if (DEBUG_IDLE) Slog.d(TAG_IDLE,
                            "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
                    if (mService.mDidDexOpt) { //正在执行dex->oat延迟进入idle
                        mService.mDidDexOpt = false;
                        Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
                        nmsg.obj = msg.obj;
                        mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
                        return;
                    }
                    // We don't at this point know if the activity is fullscreen,
                    // so we need to be conservative and assume it isn't.
                    //IDLE处理
                    activityIdleInternal((ActivityRecord)msg.obj);
                } break;
                case IDLE_NOW_MSG: {
                    if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
                    // 马上idle ,忽略dex2oat
                    activityIdleInternal((ActivityRecord)msg.obj);
                } break;
                case RESUME_TOP_ACTIVITY_MSG: {
                    synchronized (mService) {
                        resumeFocusedStackTopActivityLocked();
                    }
                } break;
                case SLEEP_TIMEOUT_MSG: { //进入休眠超时
                    synchronized (mService) {
                        if (mService.isSleepingOrShuttingDownLocked()) {
                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
                            mSleepTimeout = true;
                            checkReadyForSleepLocked();
                        }
                    }
                } break;
                case LAUNCH_TIMEOUT_MSG: {
                // 启动超时的处理,防止启动过程中wak log持有时间太长
                    if (mService.mDidDexOpt) {
                        mService.mDidDexOpt = false;
                        mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
                        return;
                    }
                    synchronized (mService) {
                        if (mLaunchingActivity.isHeld()) {
                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
                            if (VALIDATE_WAKE_LOCK_CALLER
                                    && Binder.getCallingUid() != Process.myUid()) {
                                throw new IllegalStateException("Calling must be system uid");
                            }
                            mLaunchingActivity.release();
                        }
                    }
                } break;
                case HANDLE_DISPLAY_ADDED: {
                    handleDisplayAdded(msg.arg1);
                } break;
                case HANDLE_DISPLAY_CHANGED: {
                    handleDisplayChanged(msg.arg1);
                } break;
                case HANDLE_DISPLAY_REMOVED: {
                    handleDisplayRemoved(msg.arg1);
                } break;
                case CONTAINER_CALLBACK_VISIBILITY: {
                    final ActivityContainer container = (ActivityContainer) msg.obj;
                    final IActivityContainerCallback callback = container.mCallback;
                    if (callback != null) {
                        try {
                            callback.setVisible(container.asBinder(), msg.arg1 == 1);
                        } catch (RemoteException e) {
                        }
                    }
                } break;
                case LOCK_TASK_START_MSG: {
                    // When lock task starts, we disable the status bars.
                    try {
                        if (mLockTaskNotify == null) {
                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
                        }
                        mLockTaskNotify.show(true);
                        mLockTaskModeState = msg.arg2;
                        if (getStatusBarService() != null) {
                            int flags = 0;
                            if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
                                flags = StatusBarManager.DISABLE_MASK
                                        & (~StatusBarManager.DISABLE_BACK);
                            } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
                                flags = StatusBarManager.DISABLE_MASK
                                        & (~StatusBarManager.DISABLE_BACK)
                                        & (~StatusBarManager.DISABLE_HOME)
                                        & (~StatusBarManager.DISABLE_RECENT);
                            }
                            getStatusBarService().disable(flags, mToken,
                                    mService.mContext.getPackageName());
                        }
                        mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
                        if (getDevicePolicyManager() != null) {
                            getDevicePolicyManager().notifyLockTaskModeChanged(true,
                                    (String)msg.obj, msg.arg1);
                        }
                    } catch (RemoteException ex) {
                        throw new RuntimeException(ex);
                    }
                } break;
                case LOCK_TASK_END_MSG: {
                    // When lock task ends, we enable the status bars.
                    try {
                        if (getStatusBarService() != null) {
                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
                                    mService.mContext.getPackageName());
                        }
                        mWindowManager.reenableKeyguard(mToken);
                        if (getDevicePolicyManager() != null) {
                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
                                    msg.arg1);
                        }
                        if (mLockTaskNotify == null) {
                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
                        }
                        mLockTaskNotify.show(false);
                        try {
                            boolean shouldLockKeyguard = Settings.Secure.getInt(
                                    mService.mContext.getContentResolver(),
                                    Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0;
                            if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) {
                                mWindowManager.lockNow(null);
                                mWindowManager.dismissKeyguard();
                                new LockPatternUtils(mService.mContext)
                                        .requireCredentialEntry(UserHandle.USER_ALL);
                            }
                        } catch (SettingNotFoundException e) {
                            // No setting, don't lock.
                        }
                    } catch (RemoteException ex) {
                        throw new RuntimeException(ex);
                    } finally {
                        mLockTaskModeState = LOCK_TASK_MODE_NONE;
                    }
                } break;
                case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: {
                    if (mLockTaskNotify == null) {
                        mLockTaskNotify = new LockTaskNotify(mService.mContext);
                    }
                    mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED);
                } break;
                case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
                    final ActivityContainer container = (ActivityContainer) msg.obj;
                    final IActivityContainerCallback callback = container.mCallback;
                    if (callback != null) {
                        try {
                            callback.onAllActivitiesComplete(container.asBinder());
                        } catch (RemoteException e) {
                        }
                    }
                } break;
                case LAUNCH_TASK_BEHIND_COMPLETE: {
                    synchronized (mService) {
                        ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
                        if (r != null) {
                            handleLaunchTaskBehindCompleteLocked(r);
                        }
                    }
                } break;

            }
        }
    }
  • startActivityFromRecentsInner从recent启动,在最近任务中选择一个task启动就是这种情况,taskid 随参数传递,而stack则随bOptions参数传递
final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
        final TaskRecord task;
        final int callingUid;
        final String callingPackage;
        final Intent intent;
        final int userId;
        //1 获取stackid 并进行检查
        final ActivityOptions activityOptions = (bOptions != null)
                ? new ActivityOptions(bOptions) : null;
        final int launchStackId = (activityOptions != null)
                ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
        if (launchStackId == HOME_STACK_ID) {
            throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
                    + taskId + " can't be launch in the home stack.");
        }

        if (launchStackId == DOCKED_STACK_ID) {
            mWindowManager.setDockedStackCreateState(
                    activityOptions.getDockCreateMode(), null /* initialBounds */);

            // Defer updating the stack in which recents is until the app transition is done, to
            // not run into issues where we still need to draw the task in recents but the
            // docked stack is already created.
            deferUpdateBounds(HOME_STACK_ID);
            mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
        }
     //2 获取或者恢复task
        task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
        if (task == null) {
            continueUpdateBounds(HOME_STACK_ID);
            mWindowManager.executeAppTransition();
            throw new IllegalArgumentException(
                    "startActivityFromRecentsInner: Task " + taskId + " not found.");
        }

        // Since we don't have an actual source record here, we assume that the currently focused
        // activity was the source.
        final ActivityStack focusedStack = getFocusedStack();
        final ActivityRecord sourceRecord =
                focusedStack != null ? focusedStack.topActivity() : null;

        if (launchStackId != INVALID_STACK_ID) {
            if (task.stack.mStackId != launchStackId) {//3移动task到正确的stack
                moveTaskToStackLocked(
                        taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
                        ANIMATE);
            }
        }

        // If the user must confirm credentials (e.g. when first launching a work app and the
        // Work Challenge is present) let startActivityInPackage handle the intercepting.
        if (!mService.mUserController.shouldConfirmCredentials(task.userId)
                && task.getRootActivity() != null) {
            mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */);
            mActivityMetricsLogger.notifyActivityLaunching();
            //4 移动task到前台,最关键一步,这里task包含activity,所以直接移动到前台就可以了
            mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
            mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
                    task.getTopActivity());

            // If we are launching the task in the docked stack, put it into resizing mode so
            // the window renders full-screen with the background filling the void. Also only
            // call this at the end to make sure that tasks exists on the window manager side.
            if (launchStackId == DOCKED_STACK_ID) {
                setResizingDuringAnimation(taskId); //5 执行动画
            }

            mService.mActivityStarter.postStartActivityUncheckedProcessing(task.getTopActivity(),
                    ActivityManager.START_TASK_TO_FRONT,
                    sourceRecord != null ? sourceRecord.task.stack.mStackId : INVALID_STACK_ID,
                    sourceRecord, task.stack);
            return ActivityManager.START_TASK_TO_FRONT;
        }
        callingUid = task.mCallingUid;
        callingPackage = task.mCallingPackage;
        intent = task.intent;
        intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
        userId = task.userId;
        //6 启动activity
        int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
                null, null, 0, 0, bOptions, userId, null, task);
        if (launchStackId == DOCKED_STACK_ID) {
            setResizingDuringAnimation(task.taskId);
        }
        return result;
    }

    /**
     * @return a list of activities which are the top ones in each visible stack. The first
     * entry will be the focused activity.
     */
    public List<IBinder> getTopVisibleActivities() {
        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
        if (display == null) {
            return Collections.EMPTY_LIST;
        }
        ArrayList<IBinder> topActivityTokens = new ArrayList<>();
        final ArrayList<ActivityStack> stacks = display.mStacks;
        for (int i = stacks.size() - 1; i >= 0; i--) {
            ActivityStack stack = stacks.get(i);
            if (stack.getStackVisibilityLocked(null) == ActivityStack.STACK_VISIBLE) {
                ActivityRecord top = stack.topActivity();
                if (top != null) {
                    if (stack == mFocusedStack) {
                        topActivityTokens.add(0, top.appToken);
                    } else {
                        topActivityTokens.add(top.appToken);
                    }
                }
            }
        }
        return topActivityTokens;
    }

猜你喜欢

转载自blog.csdn.net/woai110120130/article/details/79889738