Android WindowManagerService相关的Session

本文基于Android7.0

Session类路径

framework/base/services/core/java/com/android/server/wm/Session.java

内容

/**
 * This class represents an active client session.  There is generally one
 * Session object per process that is interacting with the window manager.
 */
final class Session extends IWindowSession.Stub
        implements IBinder.DeathRecipient {
    final WindowManagerService mService;
    final IWindowSessionCallback mCallback;
    final IInputMethodClient mClient;
    final IInputContext mInputContext;
    final int mUid;
    final int mPid;
    final String mStringName;
    SurfaceSession mSurfaceSession;
    int mNumWindow = 0;
    boolean mClientDead = false;
    float mLastReportedAnimatorScale;

那么这个类继承自IWindowSession.Stub,所以他是个AIDL服务器端的实现,客户端要使用它时,会通过IWindowSession.Stub.asInterface这种调用获取aidl的对应代理,不过搜索了一下源码,没找到对应的代码,这就非常奇怪了,有待后续调查

一个函数

    public void remove(IWindow window) {
        mService.removeWindow(this, window);
    }

其实该类中大部分函数都是调用mService的方法
而mService就是WindowManagerService
所以本质上Session其实用来调用WindowManagerService中方法的一个类

从网上的一些文章看,这个Session是每个app一个Session
一个Session可以对应多个WindowState,或者叫多个Window
当然,一个app可以有多个Window,比如:主画面是一个Window,弹出菜单是另外一个Window

以Android7.0刚启动的情况,进入adb shell
执行dumpsys window
找到WINDOW MANAGER WINDOWS (dumpsys window windows)部分内容如下:

WINDOW MANAGER WINDOWS (dumpsys window windows)
  Window #5 Window{125c9d7 u0 NavigationBar}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} mClient=android.os.BinderProxy@f07a556
    mOwnerUid=10026 mShowToOwnerOnly=false package=com.android.systemui appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=2019 fl=#1840068 fmt=-3}
    Requested w=1280 h=544 mLayoutSeq=87
    mHasSurface=true mShownPosition=[0,624] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{5066eb7 NavigationBar}:
      Surface: shown=true layer=211000 alpha=1.0 rect=(0.0,624.0) 1280.0 x 96.0
    mLastFreezeDuration=+165ms
  Window #4 Window{1669639 u0 StatusBar}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} mClient=android.os.BinderProxy@3083e00
    mOwnerUid=10026 mShowToOwnerOnly=false package=com.android.systemui appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(fillx96) gr=#30 sim=#10 ty=2000 fl=#81840048 fmt=-3 vsysui=0x600}
    Requested w=1280 h=96 mLayoutSeq=87
    mHasSurface=true mShownPosition=[0,0] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{3e251b6 StatusBar}:
      Surface: shown=true layer=161000 alpha=1.0 rect=(0.0,0.0) 1280.0 x 96.0
    mLastFreezeDuration=+257ms
  Window #3 Window{4581587 u0 KeyguardScrim}:
    mDisplayId=0 stackId=0 mSession=Session{ef9f4e4 1505:1000} mClient=android.view.ViewRootImpl$W@f8a11c6
    mOwnerUid=1000 mShowToOwnerOnly=false package=android appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#10 ty=2029 fl=#1110900 pfl=0x1 fmt=-3 or=5 vsysui=0x3610000}
    Requested w=1280 h=624 mLayoutSeq=44
    mHasSurface=false mShownPosition=[0,0] isReadyForDisplay()=false hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{649f551 KeyguardScrim}:
  Window #2 Window{45af05b u0 DockedStackDivider}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} mClient=android.os.BinderProxy@abf036a
    mOwnerUid=10026 mShowToOwnerOnly=false package=com.android.systemui appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(48xfill) sim=#20 ty=2034 fl=#21840028 pfl=0x40 fmt=-3 vsysui=0x700}
    Requested w=48 h=528 mLayoutSeq=87
    mPolicyVisibility=false mPolicyVisibilityAfterAnim=false mAppOpVisibility=true mAttachedHidden=false
    mHasSurface=false mShownPosition=[0,0] isReadyForDisplay()=false hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{15fca78 DockedStackDivider}:
      mShownAlpha=0.0 mAlpha=1.0 mLastAlpha=0.0
  Window #1 Window{a1fb83b u0 com.android.launcher/com.android.launcher2.Launcher}:
    mDisplayId=0 stackId=0 mSession=Session{3fca46c 1958:u0a10016} mClient=android.os.BinderProxy@5bc7eca
    mOwnerUid=10016 mShowToOwnerOnly=true package=com.android.launcher appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=1 fl=#d910100 pfl=0x20000 fmt=-2 wanim=0x10303ea vsysui=0x700 needsMenuKey=2}
    Requested w=1280 h=528 mLayoutSeq=87
    mHasSurface=true mShownPosition=[0,0] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{6d6afdb com.android.launcher/com.android.launcher2.Launcher}:
      Surface: shown=true layer=21005 alpha=1.0 rect=(0.0,0.0) 1280.0 x 720.0
    mLastFreezeDuration=+1s119ms
    mWallpaperX=0.0 mWallpaperY=0.5
    mWallpaperXStep=0.0 mWallpaperYStep=0.0
  Window #0 Window{cf21006 u0 com.android.systemui.ImageWallpaper}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} mClient=android.os.BinderProxy@5037ae1
    mOwnerUid=10026 mShowToOwnerOnly=true package=com.android.systemui appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(1280x720) gr=#800033 ty=2013 fl=#10318 fmt=2 wanim=0x10302f2}
    Requested w=1280 h=720 mLayoutSeq=87
    mIsImWindow=false mIsWallpaper=true mIsFloatingLayer=true mWallpaperVisible=true
    mHasSurface=true mShownPosition=[0,0] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{1dc10ea com.android.systemui.ImageWallpaper}:
      Surface: shown=true layer=21000 alpha=1.0 rect=(0.0,0.0) 1280.0 x 720.0
    mLastFreezeDuration=+1s120ms
    mWallpaperX=0.0 mWallpaperY=0.5
    mWallpaperXStep=0.0 mWallpaperYStep=0.0

可以看到开机刚启动结束,桌面显示出来的情况下,系统就已经有6个Window,我们把这部分内容浓缩一下

  Window #5 Window{125c9d7 u0 NavigationBar}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} 
  Window #4 Window{1669639 u0 StatusBar}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} 
  Window #3 Window{4581587 u0 KeyguardScrim}:
    mDisplayId=0 stackId=0 mSession=Session{ef9f4e4 1505:1000} 
  Window #2 Window{45af05b u0 DockedStackDivider}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} 
  Window #1 Window{a1fb83b u0 com.android.launcher/com.android.launcher2.Launcher}:
    mDisplayId=0 stackId=0 mSession=Session{3fca46c 1958:u0a10016} 
  Window #0 Window{cf21006 u0 com.android.systemui.ImageWallpaper}:
    mDisplayId=0 stackId=0 mSession=Session{1b0f084 1627:u0a10026} 

他们分别是
NavigationBar,
StatusBar,
KeyguardScrim,
DockedStackDivider,com.android.launcher/com.android.launcher2.Launcher
com.android.systemui.ImageWallpaper

从上面的dump log可以看出
NavigationBar,
StatusBar,
DockedStackDivider,
com.android.systemui.ImageWallpaper
的Session是同一个

mSession=Session{1b0f084 1627:u0a10026} 

这个Session对应的app就是SystemUI
路径为

frameworks/base/packages/SystemUI

Launcher的Session是

mSession=Session{3fca46c 1958:u0a10016} 

对应的app是Launcher就是桌面或者Home,路径为

packages/apps/Launcher2

KeyguardScrim的Session是

mSession=Session{ef9f4e4 1505:1000}  

这个Session对应的app没做过相关调查,不清楚属于哪个app进程,有待调查

从上面的内容可以得出结论,一个Session确实对应一个app进程,一个Session确实可以对应多个Window,SystemUI就是4个Window

下面我们再来试试启动一个普通的app Calculator
你会发现dump log中多了一个Window,

  Window #2 Window{982977b u0 com.android.calculator2/com.android.calculator2.Calculator}:
    mDisplayId=0 stackId=1 mSession=Session{3c2ceac 2224:u0a10043} mClient=android.os.BinderProxy@fee530a
    mOwnerUid=10043 mShowToOwnerOnly=true package=com.android.calculator2 appop=NONE
    mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#123 ty=1 fl=#81810100 pfl=0x20000 wanim=0x1030468 vsysui=0x600 needsMenuKey=2}
    Requested w=1280 h=528 mLayoutSeq=112
    mHasSurface=true mShownPosition=[0,0] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{9be4744 com.android.calculator2/com.android.calculator2.Calculator}:
      Surface: shown=true layer=21010 alpha=1.0 rect=(0.0,0.0) 1280.0 x 720.0

Session是

mSession=Session{3c2ceac 2224:u0a10043}

之后我们弹出Calculator的菜单,再dumpsys window看一下
多了一个PopupWindow

  Window #3 Window{d4992ba u0 PopupWindow:822a2fb}:
    mDisplayId=0 stackId=1 mSession=Session{3c2ceac 2224:u0a10043} mClient=android.os.BinderProxy@89947e5
    mOwnerUid=10043 mShowToOwnerOnly=true package=com.android.calculator2 appop=NONE
    mAttrs=WM.LayoutParams{(1072,104)(196x48) gr=#33 sim=#11 ty=1002 fl=#41860200 pfl=0x18000 fmt=-3 surfaceInsets=Rect(32, 32 - 32, 32) (manual)}
    Requested w=196 h=48 mLayoutSeq=116
    mAttachedWindow=Window{982977b u0 com.android.calculator2/com.android.calculator2.Calculator} mLayoutAttached=true
    mHasSurface=true mShownPosition=[1072,104] isReadyForDisplay()=true hasSavedSurface()=false mWindowRemovalAllowed=false
    WindowStateAnimator{8e4556b PopupWindow:822a2fb}:
      Surface: shown=true layer=21015 alpha=1.0 rect=(1040.0,72.0) 260.0 x 112.0

Session是

mSession=Session{3c2ceac 2224:u0a10043}

与Calculator相同的Session,这也充分证明了前面的结论是正确的

其实这个Session类还有个很重要的成员

    SurfaceSession mSurfaceSession;

对应有3个关键方法


    void windowAddedLocked() {
        if (mSurfaceSession == null) {
            if (WindowManagerService.localLOGV) Slog.v(
                TAG_WM, "First window added to " + this + ", creating SurfaceSession");
            mSurfaceSession = new SurfaceSession();
            if (SHOW_TRANSACTIONS) Slog.i(
                    TAG_WM, "  NEW SURFACE SESSION " + mSurfaceSession);
            mService.mSessions.add(this);
            if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
                mService.dispatchNewAnimatorScaleLocked(this);
            }
        }
        mNumWindow++;
    }

    void windowRemovedLocked() {
        mNumWindow--;
        killSessionLocked();
    }

    void killSessionLocked() {
        if (mNumWindow <= 0 && mClientDead) {
            mService.mSessions.remove(this);
            if (mSurfaceSession != null) {
                if (WindowManagerService.localLOGV) Slog.v(
                    TAG_WM, "Last window removed from " + this
                    + ", destroying " + mSurfaceSession);
                if (SHOW_TRANSACTIONS) Slog.i(
                        TAG_WM, "  KILL SURFACE SESSION " + mSurfaceSession);
                try {
                    mSurfaceSession.kill();
                } catch (Exception e) {
                    Slog.w(TAG_WM, "Exception thrown when killing surface session "
                        + mSurfaceSession + " in session " + this
                        + ": " + e.toString());
                }
                mSurfaceSession = null;
            }
        }
    }

这样看起来
windowAddedLocked()
windowRemovedLocked()
是成对的方法,对应Window追加和删除
第一次追加Window时,如果mSurfaceSession为null就创建一个并且将自己放到WindowManagerService的mSessions列表中
删除时如果mNumWindow小于等于0就从mSessions列表中删除,并kill掉SurfaceSession

至于SurfaceSession具体是什么,不得而知
猜测跟SurfaceFlinger有关系,具体可以参考下面的文章
http://blog.youkuaiyun.com/jamikabin/article/details/54411769

<think>我们正在处理一个关于AndroidWindowManagerService(WMS)框架深度解析的请求,要求包括时序图或代码的详细分析。根据用户需求,我们需要提供WMS框架的深度解析,包括其核心功能、关键流程的时序图以及相关代码分析。由于WMS是一个非常复杂的系统服务,我们将聚焦于几个关键方面:WMS的启动过程、窗口添加流程、窗口管理策略以及输入事件的分发。由于文本限制,我们无法展示完整的时序图,但会描述关键步骤,并尽可能提供代码片段和流程说明。参考引用[1]中提到了DecorView和PhoneWindow的生成过程,这与WMS管理窗口的起点有关。在Activity启动过程中,ActivityThread会创建Activity,并调用其attach方法,进而创建PhoneWindow。然后,通过setContentView将视图添加到DecorView的contentParent中。但是,窗口的真正创建和显示需要与WMS交互。参考引用[2]中提到了学习Framework的方法,我们可以借鉴:构建框架、深究细节、善用工具。因此,在解析WMS时,我们首先从整体框架入手,然后深入关键流程的细节。参考引用[3]提到了一个时间监控的标签,这可能是性能分析的一部分,但与我们当前主题关联不大。参考引用[4]列出了HAL模块,与WMS无直接关系。因此,我们将主要结合Android源码(以Android10为参考)进行解析。步骤:1.WMS的启动与初始化2.窗口添加流程(以Activity窗口为例)3.窗口管理策略(如布局和绘制)4.输入事件分发(简要提及)注意:由于篇幅限制,我们无法覆盖所有细节,但会提供关键点。由于用户要求深度解析,我们将尽可能详细地描述流程,并给出关键代码的位置和功能。另外,我们需要在回答末尾生成相关问题。</think>### Android WindowManagerService (WMS) 深度解析 #### 一、WMS核心功能与架构 1. **核心职责** - 窗口生命周期管理(创建/销毁) - 窗口层级(Z-order)控制 - 输入事件分发 - 动画与合成管理 - 多显示器支持 2. **架构层次** ```mermaid graph LR A[应用进程] -->|Binder IPC| B[WMS] B --> C[SurfaceFlinger] C --> D[显示驱动] ``` #### 二、窗口添加流程时序分析(关键代码路径) 1. **Activity启动流程** ```java // 关键调用链: ActivityThread.handleResumeActivity() → WindowManagerImpl.addView() → WindowManagerGlobal.addView() → ViewRootImpl.setView() → Session.addToDisplay() // 跨进程调用WMS ``` 2. **WMS处理窗口添加** ```java // frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java public int addWindow(Session session, IWindow client, ...) { // 1. 创建WindowToken WindowToken token = getWindowToken(attrs.token); // 2. 创建WindowState(核心数据结构) final WindowState win = new WindowState(this, session, client, token, ...); // 3. 计算层级(Z-order) win.mBaseLayer = mPolicy.getWindowLayerLw(attrs.type); // 4. 添加至窗口树 mWindowMap.put(client.asBinder(), win); // 5. 触发重新布局 mWindowPlacerLocked.performSurfacePlacement(); } ``` 3. **布局与合成流程** ```java // frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java void performSurfacePlacement() { // 1. 收集所有窗口状态 mService.mRoot.forAllWindows(collector, true); // 2. 计算可见区域(应用裁剪区域) mService.mRoot.computeScreenConfiguration(false); // 3. 分配Surface缓冲区 mService.mRoot.performSurfacePlacement(); // 4. 提交至SurfaceFlinger mService.scheduleAnimationLocked(); } ``` #### 三、关键数据结构 1. **WindowState** - 封装窗口所有属性(位置/尺寸/Z-order/焦点状态) - 持有`SurfaceControl`对象(与SurfaceFlinger交互) - 维护与`ViewRootImpl`的Binder连接 2. **DisplayContent** - 管理单显示器上的窗口树 - 包含`TaskStack`(Activity栈)和`WindowToken`集合 #### 四、输入事件分发机制 ```mermaid sequenceDiagram InputReader->>InputDispatcher: 读取原始事件 InputDispatcher->>WMS: 查询事件目标窗口 WMS->>InputDispatcher: 返回焦点窗口信息 InputDispatcher->>应用进程: 通过Socket发送事件 应用进程->>ViewRootImpl: 处理事件 ``` #### 五、性能优化关键点 1. **布局算法优化** - 增量更新(仅修改脏区域) - 层级缓存(`DisplayContent.mTmpRect`) 2. **Surface管理** ```java // 窗口销毁时释放资源 void removeSurface() { mSurfaceControl.destroy(); mSurface.release(); } ``` #### 六、调试工具 1. `adb shell dumpsys window`:查看窗口状态 2. `adb shell dumpsys SurfaceFlinger`:检查合成队列 3. Systrace标签:`WindowManager`/`SurfaceFlinger` > **深度分析建议**:结合AOSP源码重点研究: > 1. `WindowManagerService.java` (核心逻辑) > 2. `WindowState.java` (窗口状态机) > 3. `DisplayPolicy.java` (策略模式实现) > 4. `SurfaceControl.java` (跨进程通信封装)[^1][^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值