Android之AMS和WMS数据对应关系(基于Android9.0)

本文主要是讲述activity启动过程中ams和wms的数据是怎么关联起来的

ActivityStack和TaskStack

1:在Activity启动过程中,首先会创建ActivityRecord对象,在ActivityRecord的构造方法中会创建一个Token对象,Token继承于IApplicationToken.Stub,appToken会保存在app应用程序段,ams和wms端在

ActivityStarter::startActivity
    ActivityRecord(ActivityManagerService _service, ProcessRecord _caller, int _launchedFromPid,
            int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
            ActivityInfo aInfo, Configuration _configuration,
            ActivityRecord _resultTo, String _resultWho, int _reqCode,
            boolean _componentSpecified, boolean _rootVoiceInteraction,
            ActivityStackSupervisor supervisor, ActivityOptions options,
            ActivityRecord sourceRecord) {
        service = _service;
        appToken = new Token(this, _intent);
        setState(INITIALIZING, "ActivityRecord ctor");
    }

2:创建完ActivityRecord之后,会创建ActivityStack,在ActivityStack的构造方法中会创建StackWindowController,android是支持多屏显示的,ActivityStack是由ActivityDisplay负责创建,ActivityStack可以根据stackid来区分,DisplayContent表示的一块独立的显示屏幕,在StackWindowController的构造方法中会根据当前activity所属于的DisplayContent来创建一个TaskStack,TaskStack的stackId和前面的stackId是完全一致的
3:StackWindowController作为ActivityStack的成员变量mWindowContainerController,DisplayContent通过调用creatStack函数会将StackWindowController传递给TaskStack,TaskStack继承于WindowContainer,在TaskStack的构造方法中调用了父类的setController将传递过来的StackWindowController对象设置成自己的StackWindowController

@VisibleForTesting
public StackWindowController(int stackId, StackWindowListener listener,
        int displayId, boolean onTop, Rect outBounds, WindowManagerService service) {
    super(listener, service);
    mStackId = stackId;
    mHandler = new H(new WeakReference<>(this), service.mH.getLooper());

    synchronized (mWindowMap) {
        final DisplayContent dc = mRoot.getDisplayContent(displayId);
        if (dc == null) {
            throw new IllegalArgumentException("Trying to add stackId=" + stackId
                    + " to unknown displayId=" + displayId);
        }

        dc.createStack(stackId, onTop, this);------------->this表示的就是StackWindowController
        getRawBounds(outBounds);
    }
}
TaskStack createStack(int stackId, boolean onTop, StackWindowController controller) {
    if (DEBUG_STACK) Slog.d(TAG_WM, "Create new stackId=" + stackId + " on displayId="
            + mDisplayId);
    final TaskStack stack = new TaskStack(mService, stackId, controller);
    mTaskStackContainers.addStackToDisplay(stack, onTop);
    return stack;
}
TaskStack(WindowManagerService service, int stackId, StackWindowController controller) {
    super(service);
    mStackId = stackId;
    setController(controller);
    mDockedStackMinimizeThickness = service.mContext.getResources().getDimensionPixelSize(
            com.android.internal.R.dimen.docked_stack_minimize_thickness);
    EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId);
}

这样ActivityStack便通过StatckWindowController和TaskStack关联起来
1:ActivityStackSuperVisor管理ActivityStack,ActivityStackSuperVisor的成员变量
private final SparseArray mActivityDisplays = new SparseArray<>();维护当前设备上的所有ActivityDisplay
2:ActivityDisplay的成员变量private final ArrayList mStacks = new ArrayList<>();管理着当前的ActivityStack
3:在wms端RootWindowContainer持有WindowList列表,维护着所有的DisplayContent,DisplayContent代表的是一块显示屏幕
4:DisplayContent的静态内部类TaskStackContainers持有WindowList列表,维护着所有的TaskStack

TaskRecord和Task

1:创建完ActivityStack之后便需要创建一个TaskRecord,是否创建一个新的TaskRecord取决于应用设置的flag和taskAffnity,是否需要创建一个新的task是在startActivityUnchecked方法中

    boolean newTask = false;
    final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
            ? mSourceRecord.getTask() : null;
    // Should this be considered a new task?
    int result = START_SUCCESS;
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        newTask = true;
        result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);--->新建一个task
    } else if (mSourceRecord != null) {
        result = setTaskFromSourceRecord();
    } else if (mInTask != null) {
        result = setTaskFromInTask();
    } else {
        // This not being started from an existing activity, and not part of a new task...
        // just put it in the top task, though these days this case should never happen.
        setTaskToCurrentTopOrCreateNewTask();
    }
    if (result != START_SUCCESS) {
        return result;
    }

private int setTaskFromReuseOrCreateNewTask(
        TaskRecord taskToAffiliate, ActivityStack topStack) {
    mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
    // Do no move the target stack to front yet, as we might bail if
    // isLockTaskModeViolation fails below.
    if (mReuseTask == null) {
        final TaskRecord task = mTargetStack.createTaskRecord(
                mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
                mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
                mOptions);
        addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
        updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);

        if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
                + " in new task " + mStartActivity.getTask());
    } else {
    ...........................................
    return START_SUCCESS;

2:ActivityStack负责创建Task并且管理task,task创建完毕之后会将其移到其所在Stack的栈顶,并且调用createWindowContainer创建一个TaskWindowContainerController,TaskRecord持有mWindowContainerController对象,在TaskWindowContainerController的构造方法中会创建一个Task对象,将创建好的Task至于之前创建的TaskStack的栈顶,同时将mWindowContainerController设置为task的windowContainer对象,这样TaskRecord和Task通过TaskWindowContainerController关联起来了

    TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            boolean toTop, ActivityRecord activity, ActivityRecord source,
            ActivityOptions options) {
        final TaskRecord task = TaskRecord.create(
                mService, taskId, info, intent, voiceSession, voiceInteractor);
        // add the task to stack first, mTaskPositioner might need the stack association
        addTask(task, toTop, "createTaskRecord");------------->至于stack的栈顶
        final int displayId = mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY;
        final boolean isLockscreenShown = mService.mStackSupervisor.getKeyguardController()
                .isKeyguardOrAodShowing(displayId);
        if (!mStackSupervisor.getLaunchParamsController()
                .layoutTask(task, info.windowLayout, activity, source, options)
                && !matchParentBounds() && task.isResizeable() && !isLockscreenShown) {
            task.updateOverrideConfiguration(getOverrideBounds());
        }
        task.createWindowContainer(toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);----->创建WindowContainer
        return task;
    }
    void createWindowContainer(boolean onTop, boolean showForAllUsers) {
        if (mWindowContainerController != null) {
            throw new IllegalArgumentException("Window container=" + mWindowContainerController
                    + " already created for task=" + this);
        }
        final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
        setWindowContainerController(new TaskWindowContainerController(taskId, this,
                getStack().getWindowContainerController(), userId, bounds,
                mResizeMode, mSupportsPictureInPicture, onTop,
                showForAllUsers, lastTaskDescription));--------------------->创建TaskWindowContainerController
    }
    public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
            StackWindowController stackController, int userId, Rect bounds, int resizeMode,
            boolean supportsPictureInPicture, boolean toTop, boolean showForAllUsers,
            TaskDescription taskDescription, WindowManagerService service) {
        super(listener, service);
        mTaskId = taskId;
        mHandler = new H(new WeakReference<>(this), service.mH.getLooper());
        synchronized(mWindowMap) {
            if (DEBUG_STACK) Slog.i(TAG_WM, "TaskWindowContainerController: taskId=" + taskId
                    + " stack=" + stackController + " bounds=" + bounds);
            final TaskStack stack = stackController.mContainer;
            if (stack == null) {
                throw new IllegalArgumentException("TaskWindowContainerController: invalid stack="
                        + stackController);
            }
            EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
            final Task task = createTask(taskId, stack, userId, resizeMode,
                    supportsPictureInPicture, taskDescription);
            final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
            // We only want to move the parents to the parents if we are creating this task at the
            // top of its stack.
            stack.addTask(task, position, showForAllUsers, toTop /* moveParents */);
        }
    
    Task(int taskId, TaskStack stack, int userId, WindowManagerService service, int resizeMode,
            boolean supportsPictureInPicture, TaskDescription taskDescription,
            TaskWindowContainerController controller) {
        super(service);
        mTaskId = taskId;
        mStack = stack;
        mUserId = userId;
        mResizeMode = resizeMode;
        mSupportsPictureInPicture = supportsPictureInPicture;
        setController(controller);
        setBounds(getOverrideBounds());
        mTaskDescription = taskDescription;

        // Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED).
        setOrientation(SCREEN_ORIENTATION_UNSET);
    }

1:TaskRecord内部有一个成员变量:final ArrayList mActivities;来管理当前task的activity
2:一个Activity在ams中可能有多个ActivityRecord,但是是不同的对象
在wms端
1:Task持有WindowList对象
2:AppWindowToken继承WindowContainer,AppWindowToken持有WindowList,表明AppWindowToken关联着一组WindowState

ActivityRecord和AppWindowToken(WindowState)

1:创建完成TaskRecord之后便为ActivityRecord创建一个windowController,这块的逻辑在startActivityLocked中

    // If we are not placing the new activity frontmost, we do not want to deliver the
    // onUserLeaving callback to the actual frontmost activity
    final TaskRecord activityTask = r.getTask();
    if (task == activityTask && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
        mStackSupervisor.mUserLeaving = false;
        if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
                "startActivity() behind front, mUserLeaving=false");
    }
    task = activityTask;
    // Slot the activity into the history stack and proceed
    if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
            new RuntimeException("here").fillInStackTrace());
    // TODO: Need to investigate if it is okay for the controller to already be created by the
    // time we get to this point. I think it is, but need to double check.
    // Use test in b/34179495 to trace the call path.
    if (r.getWindowContainerController() == null) {
        r.createWindowContainer();------------------------>创建windowContainer
    }
    task.setFrontOfTask();--------------->将activityRecord所在task栈放在栈顶

2:创建AppWindowContainerController的过程
在AppWindowContainerController的构造方法中会创建一个AppWindowToken,AppWindowToken的数据类型是WindowToken,WindowToken的数据类型是WindowContainer,在WindowContainer中一个成员变量:
protected final WindowList mChildren = new WindowList();从上面我们可以看出AppWindowToken关联着一组WindowState,这样通过AppWindowContainerController将ActivityRecord和AppWindowToken关联在一起,在这个阶段appToken会传递给wms

void createWindowContainer() {
    inHistory = true;
    final TaskWindowContainerController taskController = task.getWindowContainerController();
    // TODO(b/36505427): Maybe this call should be moved inside updateOverrideConfiguration()
    task.updateOverrideConfigurationFromLaunchBounds();
    // Make sure override configuration is up-to-date before using to create window controller.
    updateOverrideConfiguration();
    mWindowContainerController = new AppWindowContainerController(taskController, appToken,
            this, Integer.MAX_VALUE /* add on top */, info.screenOrientation, fullscreen,
            (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, info.configChanges,
            task.voiceSession != null, mLaunchTaskBehind, isAlwaysFocusable(),
            appInfo.targetSdkVersion, mRotationAnimationHint,
            ActivityManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L);
    task.addActivityToTop(this);---------------->将activityRecord放在所在Task的栈顶
    // When an activity is started directly into a split-screen fullscreen stack, we need to
    // update the initial multi-window modes so that the callbacks are scheduled correctly when
    // the user leaves that mode.
    mLastReportedMultiWindowMode = inMultiWindowMode();
    mLastReportedPictureInPictureMode = inPinnedWindowingMode();
}

 public AppWindowContainerController(TaskWindowContainerController taskController,
        IApplicationToken token, AppWindowContainerListener listener, int index,
        int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int configChanges,
        boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
        int targetSdkVersion, int rotationAnimationHint, long inputDispatchingTimeoutNanos,
        WindowManagerService service) {
    super(listener, service);
    mHandler = new H(service.mH.getLooper());
    mToken = token;
    synchronized(mWindowMap) {
        AppWindowToken atoken = mRoot.getAppWindowToken(mToken.asBinder());
        if (atoken != null) {
            // TODO: Should this throw an exception instead?
            Slog.w(TAG_WM, "Attempted to add existing app token: " + mToken);
            return;
        }
        final Task task = taskController.mContainer;
        if (task == null) {
            throw new IllegalArgumentException("AppWindowContainerController: invalid "
                    + " controller=" + taskController);
        }
        atoken = createAppWindow(mService, token, voiceInteraction, task.getDisplayContent(),
                inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdkVersion,
                requestedOrientation, rotationAnimationHint, configChanges, launchTaskBehind,
                alwaysFocusable, this);
        if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addAppToken: " + atoken
                + " controller=" + taskController + " at " + index);
        task.addChild(atoken, index);
    }
}

1:ActivityRecord是ams端的一个真实的activity对象
2:在wms端WindowState是一个真正意义上的窗口,WindowState是在添加窗口的时候创建的,在Activity启动过程中appToken从ams传递到wms

AMS和WMS的各个对象的对应关系

test.jpg

你可能感兴趣的:(Android之AMS和WMS数据对应关系(基于Android9.0))