• Android14 WMS-窗口添加流程(一)-Client端


          窗口布局在onCreate方法中通过setContentView(R.layout.xxx)加载,但窗口的显示并不是在wm_on_create_called中, 而是在wm_on_resume_called后,也就是说应用onResume时此窗口是不可见的,真正可见是当此window窗口的mDrawState变化状态从NO_SURFACE -> DRAW_PENDING -> COMMIT_DRAW_PENDING  -> HAS_DRAWN-> READY_TO_SHOW,然后才会将图层置为可见状态,这个在后面会讲解到。设置为可见的log如下:

    05-25 10:56:31.956  1915  1973 V WindowManager: performShow on Window{f4647f5 u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}: mDrawState=READY_TO_SHOW readyForDisplay=true starting=false during animation: policyVis=true parentHidden=false tok.visibleRequested=true tok.visible=true animating=false tok animating=false Callers=com.android.server.wm.WindowState.performShowLocked:4372 com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked:256 com.android.server.wm.DisplayContent.lambda$new$8:1082 com.android.server.wm.DisplayContent.$r8$lambda$NJwM1ysKPNyOazqyI2QXlp2I4yA:0 
    05-25 10:56:31.962  1915  1973 V WindowManager: Showing Window{f4647f5 u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}: mDrawState=READY_TO_SHOW readyForDisplay=true starting=false during animation: policyVis=true parentHidden=false tok.visibleRequested=true tok.visible=true animating=true tok animating=false Callers=com.android.server.wm.WindowState.performShowLocked:4387 com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked:256 com.android.server.wm.DisplayContent.lambda$new$8:1082 com.android.server.wm.DisplayContent.$r8$lambda$NJwM1ysKPNyOazqyI2QXlp2I4yA:0


    1. ActivityThread#handleResumeActivity

    Activity启动时一开始都是置为不可见INVISIBLE的,然后才置为可见VISIBLE。
    ActivityThread.java - OpenGrok cross reference for /frameworks/base/core/java/android/app/ActivityThread.java

    1. @Override
    2. public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
    3. boolean isForward, boolean shouldSendCompatFakeFocus, String reason) {
    4. // If we are getting ready to gc after going to the background, well
    5. // we are back active so skip it.
    6. unscheduleGcIdler();
    7. mSomeActivitiesChanged = true;
    8. // TODO Push resumeArgs into the activity for consideration
    9. // skip below steps for double-resume and r.mFinish = true case.
    10. //这个是activity resume很重要的一步,会调用到activity本身的onResume方法,后面会做详细解释
    11. if (!performResumeActivity(r, finalStateRequest, reason)) {
    12. return;
    13. }
    14. //如果mActivitiesToBeDestroyed集合包含此acitivity,则不往下执行resume操作。
    15. //mActivitiesToBeDestroyed是即将 要销毁的activity集合
    16. if (mActivitiesToBeDestroyed.containsKey(r.token)) {
    17. // Although the activity is resumed, it is going to be destroyed. So the following
    18. // UI operations are unnecessary and also prevents exception because its token may
    19. // be gone that window manager cannot recognize it. All necessary cleanup actions
    20. // performed below will be done while handling destruction.
    21. return;
    22. }
    23. final Activity a = r.activity;
    24. if (localLOGV) {
    25. Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity
    26. + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished);
    27. }
    28. ...
    29. //如果这个window没有被add进window manager,并且这个activity没有执行finish操作,或者启动其他activity,则首先要将此window添加进window manager中。
    30. boolean willBeVisible = !a.mStartedActivity;
    31. if (!willBeVisible) {
    32. willBeVisible = ActivityClient.getInstance().willActivityBeVisible(
    33. a.getActivityToken());
    34. }
    35. //这里代表这是首次启动这个activity
    36. //如果window为空,并且不要执行finish,并且申请可见,则进入如下逻辑
    37. if (r.window == null && !a.mFinished && willBeVisible) {
    38. r.window = r.activity.getWindow();
    39. View decor = r.window.getDecorView();
    40. //先将根布局设置为不可见
    41. decor.setVisibility(View.INVISIBLE);
    42. //获取当前window manager对象
    43. ViewManager wm = a.getWindowManager();
    44. //获取当前window属性
    45. WindowManager.LayoutParams l = r.window.getAttributes();
    46. a.mDecor = decor;
    47. //将window type类型设置为普通APP类型
    48. l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
    49. l.softInputMode |= forwardBit;
    50. if (r.mPreserveWindow) {
    51. a.mWindowAdded = true;
    52. r.mPreserveWindow = false;
    53. // Normally the ViewRoot sets up callbacks with the Activity
    54. // in addView->ViewRootImpl#setView. If we are instead reusing
    55. // the decor view we have to notify the view root that the
    56. // callbacks may have changed.
    57. //获取ViewRootImpl
    58. ViewRootImpl impl = decor.getViewRootImpl();
    59. if (impl != null) {
    60. impl.notifyChildRebuilt();
    61. }
    62. }
    63. if (a.mVisibleFromClient) {
    64. if (!a.mWindowAdded) {
    65. a.mWindowAdded = true;
    66. //如果此window没有被add进window manager过,则将此根view(decor)add进window manager中
    67. wm.addView(decor, l);
    68. } else {
    69. // The activity will get a callback for this {@link LayoutParams} change
    70. // earlier. However, at that time the decor will not be set (this is set
    71. // in this method), so no action will be taken. This call ensures the
    72. // callback occurs with the decor set.
    73. a.onWindowAttributesChanged(l);
    74. }
    75. }
    76. // If the window has already been added, but during resume
    77. // we started another activity, then don't yet make the
    78. // window visible.
    79. } else if (!willBeVisible) {//如果这个activity已经被add进window manager过了,并且在resume期间又起了其他activity,那么我们就不会将这个window设置为可见
    80. if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
    81. //设置立即hide的flag为true
    82. r.hideForNow = true;
    83. }
    84. // Get rid of anything left hanging around.
    85. cleanUpPendingRemoveWindows(r, false /* force */);
    86. // The window is now visible if it has been added, we are not
    87. // simply finishing, and we are not starting another activity.
    88. //这里代表这个activity已经被添加进window manager了,并非首次启动
    89. if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
    90. if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
    91. //获取ViewRootImpl
    92. ViewRootImpl impl = r.window.getDecorView().getViewRootImpl();
    93. //获取窗口属性
    94. WindowManager.LayoutParams l = impl != null
    95. ? impl.mWindowAttributes : r.window.getAttributes();
    96. if ((l.softInputMode
    97. & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
    98. != forwardBit) {
    99. l.softInputMode = (l.softInputMode
    100. & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
    101. | forwardBit;
    102. if (r.activity.mVisibleFromClient) {
    103. ViewManager wm = a.getWindowManager();
    104. View decor = r.window.getDecorView();
    105. wm.updateViewLayout(decor, l);
    106. }
    107. }
    108. r.activity.mVisibleFromServer = true;
    109. mNumVisibleActivities++;
    110. if (r.activity.mVisibleFromClient) {
    111. r.activity.makeVisible();
    112. }
    113. ...
    114. }

     这块大概的流程图如上所示,在执行handleResumeActivity的时候,会先去执行activity的onResume方法,然后再将当前的window add进window manager。

    这块有个地方拓展下,就是窗口类型,普通apk启动的窗口类型都是TYPE_BASE_APPLICATION

                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;

    Android系统三大窗口类型

    Android系统中共有三大窗口类型,分别是Application类型, 子窗口类型,以及系统窗口类型:

    窗口类型Vlaue含义
    以下窗口类型为普通APPLICAT窗口类型,范围1-99
    FIRST_APPLICATION_WINDOW 1App的初始值
    TYPE_BASE_APPLICATION1所有App的基础值
    TYPE_APPLICATION2普通应用程序窗口
    TYPE_APPLICATION_STARTING3starting窗口
    TYPE_DRAWN_APPLICATION4等待绘制完成的窗口
    LAST_APPLICATION_WINDOW 99App的最大值
    以下窗口类型为子窗口类型,范围1000-1999
    FIRST_SUB_WINDOW 1000子窗口的初始值
    TYPE_APPLICATION_PANELFIRST_SUB_WINDOW 应用程序窗口顶部的面板。这些窗口出现在它们的附属窗口的顶部。
    TYPE_APPLICATION_MEDIAFIRST_SUB_WINDOW +1media子窗口
    TYPE_APPLICATION_SUB_PANELFIRST_SUB_WINDOW +2子窗口之上的子窗口

    TYPE_APPLICATION_ATTACHED

    _DIALOG

    FIRST_SUB_WINDOW +3Dialog子窗口

    TYPE_APPLICATION_MEDIA

    _OVERLAY

    FIRST_SUB_WINDOW +4media子窗口之上的子窗口

    TYPE_APPLICATION_ABOVE_

    SUB_PANEL

    FIRST_SUB_WINDOW +5在SUB_PANEL之上的子窗口
    LAST_SUB_WINDOW 1999子窗口的最大值
    以下为系统窗口类型,范围2000-2999
    FIRST_SYSTEM_WINDOW2000系统窗口的初始值
    TYPE_STATUS_BARFIRST_SYSTEM_WINDOW系统状态栏窗口
    TYPE_SEARCH_BARFIRST_SYSTEM_WINDOW+1搜索条窗口
    TYPE_PHONEFIRST_SYSTEM_WINDOW+2通话窗口,位于状态栏之上
    TYPE_SYSTEM_ALERTFIRST_SYSTEM_WINDOW+3Alert窗口,如电量不足提示,显示在APP之上窗口
    TYPE_KEYGUARDFIRST_SYSTEM_WINDOW+4锁屏窗口
    TYPE_TOASTFIRST_SYSTEM_WINDOW+5短暂的提示框窗口
    TYPE_SYSTEM_OVERLAYFIRST_SYSTEM_WINDOW+6系统覆盖窗口,不能接受input焦点,否则会与屏保发生冲突
    TYPE_PRIORITY_PHONEFIRST_SYSTEM_WINDOW+7电话优先窗口,如屏保状态下显示来电窗口
    TYPE_SYSTEM_DIALOGFIRST_SYSTEM_WINDOW+8系统Dialog窗口
    TYPE_KEYGUARD_DIALOGFIRST_SYSTEM_WINDOW+9keyguard Dialog窗口
    TYPE_SYSTEM_ERRORFIRST_SYSTEM_WINDOW+10系统报错窗口
    TYPE_INPUT_METHODFIRST_SYSTEM_WINDOW+11输入法窗口
    TYPE_INPUT_METHOD_DIALOGFIRST_SYSTEM_WINDOW+12输入法Dialog窗口
    TYPE_WALLPAPERFIRST_SYSTEM_WINDOW+13壁纸窗口
    TYPE_STATUS_BAR_PANELFIRST_SYSTEM_WINDOW+14从状态栏滑出的面板在多用户系统中显示在所有用户的窗口上。

    TYPE_SECURE_SYSTEM_OVERLAY

    FIRST_SYSTEM_WINDOW+15@hide
    TYPE_DRAGFIRST_SYSTEM_WINDOW+16@hide拖拽窗口

    TYPE_STATUS_BAR_SUB_PANEL

    FIRST_SYSTEM_WINDOW+17@hide,status bar之上的子窗口
    TYPE_POINTERFIRST_SYSTEM_WINDOW+18@hide
    TYPE_NAVIGATION_BARFIRST_SYSTEM_WINDOW+19@hide导航栏窗口
    TYPE_VOLUME_OVERLAYFIRST_SYSTEM_WINDOW+20@hide系统音量条
    TYPE_BOOT_PROGRESSFIRST_SYSTEM_WINDOW+21@hide启动时的进度条窗口
    TYPE_INPUT_CONSUMERFIRST_SYSTEM_WINDOW+22@hide消耗input事件的窗口
    TYPE_NAVIGATION_BAR_PANELFIRST_SYSTEM_WINDOW+24@hide
    TYPE_DISPLAY_OVERLAYFIRST_SYSTEM_WINDOW+26@hide用于模拟第二个Display显示屏
    TYPE_MAGNIFICATION_OVERLAYFIRST_SYSTEM_WINDOW+27@hide
    TYPE_PRIVATE_PRESENTATIONFIRST_SYSTEM_WINDOW+30
    TYPE_VOICE_INTERACTIONFIRST_SYSTEM_WINDOW+31@hide
    TYPE_ACCESSIBILITY_OVERLAYFIRST_SYSTEM_WINDOW+32

    TYPE_VOICE_INTERACTION_STARTING

    FIRST_SYSTEM_WINDOW+33@hide
    TYPE_DOCK_DIVIDERFIRST_SYSTEM_WINDOW+34@hide
    TYPE_QS_DIALOGFIRST_SYSTEM_WINDOW+35@hide
    TYPE_SCREENSHOTFIRST_SYSTEM_WINDOW+36@hide在锁屏之上,该层保留截图动画,区域选择和UI。
    TYPE_PRESENTATIONFIRST_SYSTEM_WINDOW+37@hide用于在外部显示器上显示的窗口(多个屏幕情况下)
    TYPE_APPLICATION_OVERLAYFIRST_SYSTEM_WINDOW+38

    TYPE_ACCESSIBILITY_MAGNIFICATION

    _OVERLAY

    FIRST_SYSTEM_WINDOW+39@hide
    TYPE_NOTIFICATION_SHADEFIRST_SYSTEM_WINDOW+40@hide
    TYPE_STATUS_BAR_ADDITIONALFIRST_SYSTEM_WINDOW+41@hide
    LAST_SYSTEM_WINDOW2999系统窗口的最大值

     1.1. ActivityThread#performResumeActivity

    1. @VisibleForTesting
    2. public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
    3. String reason) {
    4. if (localLOGV) {
    5. Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished);
    6. }
    7. //如果activity将要finish,则直接return掉,不执行resume操作了
    8. if (r.activity.mFinished) {
    9. return false;
    10. }
    11. //如果activity已经on_resume了,则不继续往下执行,return
    12. if (r.getLifecycleState() == ON_RESUME) {
    13. if (!finalStateRequest) {
    14. final RuntimeException e = new IllegalStateException(
    15. "Trying to resume activity which is already resumed");
    16. ...
    17. }
    18. return false;
    19. }
    20. ...
    21. //执行activity的onResume操作
    22. r.activity.performResume(r.startsNotResumed, reason);
    23. r.state = null;
    24. r.persistentState = null;
    25. //设置activity状态为on_resume
    26. r.setState(ON_RESUME);
    27. //将会打印出event log---wm_on_top_resumed_gained_called相关信息
    28. reportTopResumedActivityChanged(r, r.isTopResumedActivity, "topWhenResuming");
    29. } catch (Exception e) {
    30. if (!mInstrumentation.onException(r.activity, e)) {
    31. throw new RuntimeException("Unable to resume activity "
    32. + r.intent.getComponent().toShortString() + ": " + e.toString(), e);
    33. }
    34. }
    35. return true;
    36. }

    本小节介绍了activity启动过程中其他的知识,下文再继续接着讲怎么添加窗口流程的,下面接着1.1中的addView方法。

    2. WindowManager#addView

    wm的获取方法如下,可以看到最后是获得到了一个WindowManager对象,

        private WindowManager mWindowManager;
        public WindowManager getWindowManager() {
            return mWindowManager;
        }

    那就来到了WindowManager中的addView方法

    查看WindowManager中没有addView方法,但是ViewManager中有,那我们再看下谁实现了WindowManager呢

    public interface WindowManager extends ViewManager {
    -------------------------------------------------------------
    public interface ViewManager
    {
        public void addView(View view, ViewGroup.LayoutParams params);
        public void updateViewLayout(View view, ViewGroup.LayoutParams params);
        public void removeView(View view);
    }

    可找到是WindowManagerImpl中实现此addView方法,因为WindowManagerImpl继承了WindowManager:

    1. /*
    2. * @see WindowManager
    3. * @see WindowManagerGlobal
    4. * @hide
    5. */
    6. public final class WindowManagerImpl implements WindowManager {
    7. ...
    8. @Override
    9. public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
    10. applyTokens(params);
    11. mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
    12. mContext.getUserId());
    13. }

    此方法又调用了 WindowManagerGlobal中的addView方法,并将view,窗口属性,要显示的屏幕,父window,以及user id传入

    WindowManagerGlobal.java - OpenGrok cross reference for /frameworks/base/core/java/android/view/WindowManagerGlobal.java

    1. public void addView(View view, ViewGroup.LayoutParams params,
    2. Display display, Window parentWindow, int userId) {
    3. if (view == null) {
    4. throw new IllegalArgumentException("view must not be null");
    5. }
    6. if (display == null) {
    7. throw new IllegalArgumentException("display must not be null");
    8. }
    9. if (!(params instanceof WindowManager.LayoutParams)) {
    10. throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
    11. }
    12. //获取窗口布局属性
    13. final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
    14. if (parentWindow != null) {
    15. //如果父窗口不为空,则调整当前父窗口下所有子窗口布局的属性
    16. parentWindow.adjustLayoutParamsForSubWindow(wparams);
    17. } else {
    18. // If there's no parent, then hardware acceleration for this view is
    19. // set from the application's hardware acceleration setting.
    20. final Context context = view.getContext();
    21. if (context != null
    22. && (context.getApplicationInfo().flags
    23. & ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
    24. wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
    25. }
    26. }
    27. ViewRootImpl root;
    28. View panelParentView = null;
    29. synchronized (mLock) {
    30. // Start watching for system property changes.
    31. if (mSystemPropertyUpdater == null) {
    32. mSystemPropertyUpdater = new Runnable() {
    33. @Override public void run() {
    34. synchronized (mLock) {
    35. for (int i = mRoots.size() - 1; i >= 0; --i) {
    36. mRoots.get(i).loadSystemProperties();
    37. }
    38. }
    39. }
    40. };
    41. SystemProperties.addChangeCallback(mSystemPropertyUpdater);
    42. }
    43. int index = findViewLocked(view, false);
    44. if (index >= 0) {
    45. if (mDyingViews.contains(view)) {
    46. // Don't wait for MSG_DIE to make it's way through root's queue.
    47. mRoots.get(index).doDie();
    48. } else {
    49. throw new IllegalStateException("View " + view
    50. + " has already been added to the window manager.");
    51. }
    52. // The previous removeView() had not completed executing. Now it has.
    53. }
    54. // If this is a panel window, then find the window it is being
    55. // attached to for future reference.
    56. //如果是子窗口
    57. if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
    58. wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
    59. final int count = mViews.size();
    60. for (int i = 0; i < count; i++) {
    61. if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
    62. panelParentView = mViews.get(i);
    63. }
    64. }
    65. }
    66. IWindowSession windowlessSession = null;
    67. // If there is a parent set, but we can't find it, it may be coming
    68. // from a SurfaceControlViewHost hierarchy.
    69. //如果token不为空并且不是子窗口
    70. if (wparams.token != null && panelParentView == null) {
    71. for (int i = 0; i < mWindowlessRoots.size(); i++) {
    72. ViewRootImpl maybeParent = mWindowlessRoots.get(i);
    73. if (maybeParent.getWindowToken() == wparams.token) {
    74. //获取WindowSession
    75. windowlessSession = maybeParent.getWindowSession();
    76. break;
    77. }
    78. }
    79. }
    80. if (windowlessSession == null) {
    81. //如果windowlessSession为空
    82. root = new ViewRootImpl(view.getContext(), display);
    83. } else {
    84. //如果windowlessSession不为空,则在此处传入windowlessSession
    85. root = new ViewRootImpl(view.getContext(), display,
    86. windowlessSession, new WindowlessWindowLayout());
    87. }
    88. //将窗口布局属性设置进view
    89. view.setLayoutParams(wparams);
    90. //将此view添加进mViews
    91. mViews.add(view);
    92. //将此root添加进MRoots
    93. mRoots.add(root);
    94. //将此窗口布局属性添加进mParams
    95. mParams.add(wparams);
    96. // do this last because it fires off messages to start doing things
    97. try {
    98. //将view,窗口属性和子窗口,user id 设置进ViewRootImpl
    99. root.setView(view, wparams, panelParentView, userId);
    100. } catch (RuntimeException e) {
    101. final int viewIndex = (index >= 0) ? index : (mViews.size() - 1);
    102. // BadTokenException or InvalidDisplayException, clean up.
    103. if (viewIndex >= 0) {
    104. removeViewLocked(viewIndex, true);
    105. }
    106. throw e;
    107. }
    108. }
    109. }

    3. ViewRootImpl#setView

    然后就从WindowManagerGlobal走到了ViewRootImpl中

    http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/view/ViewRootImpl.java#1214

    1. final IWindowSession mWindowSession;
    2. public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    3. setView(view, attrs, panelParentView, UserHandle.myUserId());
    4. }
    5. public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView, int userId) {
    6. synchronized (this) {
    7. //这个mView和上一个方法中的可不一样,当窗口detach后,这个mView会被置为空
    8. if (mView == null) {
    9. mView = view;
    10. ...
    11. mWindowAttributes.copyFrom(attrs)
    12. ...
    13. // Schedule the first layout -before- adding to the window
    14. // manager, to make sure we do the relayout before receiving
    15. // any other events from the system.
    16. //首先需要layout
    17. requestLayout();
    18. ...
    19. //这个是很重要的一步
    20. res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
    21. getHostVisibility(), mDisplay.getDisplayId(), userId,
    22. mInsetsController.getRequestedVisibleTypes(), inputChannel, mTempInsets, mTempControls, attachedFrame, compatScale);
    23. ...
    24. mPendingAlwaysConsumeSystemBars = mAttachInfo.mAlwaysConsumeSystemBars;
    25. mInsetsController.onStateChanged(mTempInsets);
    26. mInsetsController.onControlsChanged(mTempControls.get());
    27. final InsetsState state = mInsetsController.getState();
    28. final Rect displayCutoutSafe = mTempRect;
    29. state.getDisplayCutoutSafe(displayCutoutSafe);
    30. final WindowConfiguration winConfig = getCompatWindowConfiguration();
    31. mWindowLayout.computeFrames(mWindowAttributes, state,
    32. displayCutoutSafe, winConfig.getBounds(), winConfig.getWindowingMode(),
    33. UNSPECIFIED_LENGTH, UNSPECIFIED_LENGTH,
    34. mInsetsController.getRequestedVisibleTypes(), 1f /* compactScale */, mTmpFrames);
    35. setFrame(mTmpFrames.frame, true /* withinRelayout */);
    36. ...
    37. }

    接着往下走,就会讲到WindowSession.addToDisplayAsUser方法

    4. WindowSession.addToDisplayAsUser

    这里是涉及到AIDL通信,因为mWindowSession是final IWindowSession mWindowSession;

    用到的AIDL文件如下:

    frameworks/base/core/java/android/view/IWindowSession.aidl

    http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/view/IWindowSession.aidl

    Session.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/Session.java 

    1. @Override
    2. public int addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs,
    3. int viewVisibility, int displayId, int userId, @InsetsType int requestedVisibleTypes,
    4. InputChannel outInputChannel, InsetsState outInsetsState,
    5. InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame,
    6. float[] outSizeCompatScale) {
    7. //调用WMS的addWindow流程
    8. return mService.addWindow(this, window, attrs, viewVisibility, displayId, userId,
    9. requestedVisibleTypes, outInputChannel, outInsetsState, outActiveControls,
    10. outAttachedFrame, outSizeCompatScale);
    11. }

    下面是一个关于以上流程的setting主页面启动流程

    1. 05-25 12:58:21.791 1909 2175 I wm_task_created: 441
    2. 05-25 12:58:21.795 1909 2175 I wm_task_moved: [441,441,0,1,2]
    3. 05-25 12:58:21.795 1909 2175 I wm_task_to_front: [0,441,0]
    4. 05-25 12:58:21.795 1909 2175 I wm_create_task: [0,441,441,0]
    5. 05-25 12:58:21.795 1909 2175 I wm_create_activity: [0,232997572,441,com.android.settings/.homepage.SettingsHomepageActivity,android.settings.SETTINGS,NULL,NULL,335544320]
    6. 05-25 12:58:21.795 1909 2175 I wm_task_moved: [441,441,0,1,2]
    7. 05-25 12:58:22.265 1909 3494 I wm_restart_activity: [0,232997572,441,com.android.settings/.homepage.SettingsHomepageActivity]
    8. 05-25 12:58:22.267 1909 3494 I wm_set_resumed_activity: [0,com.android.settings/.homepage.SettingsHomepageActivity,minimalResumeActivityLocked - onActivityStateChanged]
    9. 05-25 12:58:22.363 2518 2518 I wm_on_create_called: [232997572,com.android.settings.homepage.SettingsHomepageActivity,performCreate,66]
    10. 05-25 12:58:22.457 2518 2518 I wm_on_start_called: [232997572,com.android.settings.homepage.SettingsHomepageActivity,handleStartActivity,92]
    11. 05-25 12:58:22.460 2518 2518 V ActivityThread: Performing resume of ActivityRecord{a4a98fc token=android.os.BinderProxy@c7155ef {com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}} finished=false
    12. 05-25 12:58:22.460 2518 2518 I wm_on_resume_called: [232997572,com.android.settings.homepage.SettingsHomepageActivity,RESUME_ACTIVITY,0]
    13. 05-25 12:58:22.525 2518 2518 V ActivityThread: Resume ActivityRecord{a4a98fc token=android.os.BinderProxy@c7155ef {com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}} started activity: false, hideForNow: false, finished: false
    14. 05-25 12:58:22.545 1909 2175 V WindowManager: Attaching Window{a90e6ab u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity} token=ActivityRecord{de342c4 u0 com.android.settings/.homepage.SettingsHomepageActivity t441}
    15. 05-25 12:58:22.552 2518 2518 V ActivityThread: Resuming ActivityRecord{a4a98fc token=android.os.BinderProxy@c7155ef {com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}} with isForward=true
    16. 05-25 12:58:22.552 2518 2518 V ActivityThread: Scheduling idle handler for ActivityRecord{a4a98fc token=android.os.BinderProxy@c7155ef {com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}}
    17. 05-25 12:58:22.553 2518 2518 I wm_on_top_resumed_gained_called: [232997572,com.android.settings.homepage.SettingsHomepageActivity,topStateChangedWhenResumed]
    18. 05-25 12:58:22.769 1909 1971 I wm_activity_launch_time: [0,232997572,com.android.settings/.homepage.SettingsHomepageActivity,970]

    6. WindowManagerService#addWindow

    这里就到了Server端,以上都是Client端。

    WMS的流程较复杂,后面再出关于Server端的文章。

  • 相关阅读:
    「运维有小邓」活动目录变更监控
    java毕业设计开题报告基于SSM学生成绩管理系统
    consul安装与配置
    Python调用摄像头
    自律成就自己
    单点登录常用协议原理和流程
    【Java精炼系列篇】【事务】【事务的使用】
    Lwip之ARP模块实现
    使用js实现响应式瀑布流布局(附带动画效果)
    Dubbo入门
  • 原文地址:https://blog.csdn.net/weixin_41028555/article/details/139174548