Android 窗口管理服务WindowManagerService 简介

    Android Window Manager Service(WMS) 是android 最核心的服务之一, 本篇主要对WMS做一个简要的介绍, 包括一些跟WMS相关的基本概念。包括:

  • 什么是Window,window的分类: 系统窗口, app窗口等
  • WMS的主要功能,窗口边界, Z-order等。
  • WMS 与系统其它组件交互, 如与activity, Activity Manager Service 等的关系。
  • WMS 初始化。

    关于WMS, 计划会写一系列文章, 但是由于WMS逻辑复杂, 与其他系统组件, 例如AMS, SurfaceFlinger, InputManagerSevice交互很多,很难面面俱到的介绍相关功能。后续会以启动一个新的activity为例介绍WMS的主要功能,适合对android系统有一定了解并希望深入了解并阅读WMS代码的同学。 主要内容包括:

1.    添加新窗口

2.    Z-odered管理

3.    刷新Layout

4.    Token管理

5.    Focus window

6.    Focus App

7.    输入法窗口管理

8.    动画管理

9.    切换用户

    一个大坑,希望能写完。


一.    什么是窗口window。

下图是一个完整的屏幕截屏。

                                                                                     

在这个屏幕上有四个窗口:Status Bar, Navigation Bar,Sub Settings,Popup menu。 其中status bar 和navigation bar 是系统窗口,Sub Settings 是activity的主窗口,Popup Menu 是activity的子窗口。

             Android 定义了很多窗口类型,例如dialog,输入法( inpu method) 窗口,背景(wallpaper)窗口,锁屏(keyguard)窗口等。这些窗口可以分为两大类:

1.    app窗口

和application 相关的窗口。上图中Sub Settings,Popup menu就是app 窗口。App的窗口也分几个类型:主窗口, starting 窗口,子窗口。

  •  主窗口: 一个activity都 会有一个基本窗口,就是我们通常见到的activity 窗口,例如上例中的subSettings。
  • starting 窗口: 在activity启动过程中,在主窗口显示之前,还会有一个starting 窗口, starting 窗口是一个空白的窗口,只显示该activity的title。 通常,activity启动时主窗口从绘制到显示要花一些时间,系统会在这段时间内首先显示Starting窗口,在主窗口绘制完成后,starting 窗口即会消失。 Starting 窗口的作用是为了使用户感觉界面更友好, 响应更快。
  • 子窗口: 一个activity可能还会有一些子窗口,例如dialog, popupmenu。注意有些子窗口显示在主窗口之上,比如dialog, popup menu. 有些子窗口显示在主窗口之下,比如camera 里面的viewfinder 窗口,播放video 时的video 窗口。典型的SurfaceView中用到的就是这种类型的子窗口。

 所以,一个activity会有多个窗口。它们之间是通过什么关联的呢?这个以后会介绍。


2.    系统窗口

与application 无关的窗口,比如status bar, navigation bar, keyguard, alert, toast等。这类窗口使用时通常都会要求特别的权限。

关于窗口的定义,详细信息可以查看: frameworks/base/core/java/android/view/WindowManager.java


 

二.    WMS的主要功能。

顾名思义,WMS负责管理所有的窗口。主要包括以下功能:

1.    添加/删除窗口

当一个activity 启动时,添加新的窗口,activity退出时,删除相应的窗口

2.    窗口Z-odered管理

管理窗口之间叠加的顺序。

3.    计算窗口Layout

计算窗口的大小,边界等。

4.    Token管理

管理activity token, 建立子窗口与主窗口之间的联系。

5.    Focus window管理

设定哪一个窗口是focus window

6.    输入法窗口管理

管理输入法窗口

7.    动画管理

窗口切换时,显示动画效果。

8.    切换用户

当切换用户是,管理窗口的显示。


三.    WMS 与系统其它组件交互。

通过下图我们可以看到WMS在android系统中与其他服务和app之间的关系。


 

1.    WMS运行的 system service process 中。与AM, PM等运行在相同的process中, WMS与其它系统服务之间是进程内通信。

2.    WMS 通过 AppToken 与AM 进行交互。AM调用WMS的相应函数时,也会传递AppToken作为参数。AppToken是一个接口类,在WMS, Activity, AM通讯中扮演重演角色,可以认为一个AppToken代表一个Activity。

AM会调用WMS的相应函数添加窗口,设置focusApp, 切换用户等。

3.    WMS 与Surface Flinger 通过SurfaceSession通讯。 WMS添加窗口到Surface Flinger,设置SurfaceFlinger的窗口大小位置、动画参数,通知SurfaceFlinger显示窗口等。

Surface Flinger 是管理显示buffer 的服务。

4. WMS也直接同InputManagerService 相互。当启动一个activity时,activity 通过WMS与Input Manager建立联系,WMS通知Input manager 哪个app是 focus App,哪个窗口是 focus窗口。InputManager由两部分组成,InputRead 负责从Driver接收输入信息,例如touch 信息或者key 信息。 Inputdispatch 负责分发信息给相应的app。

5.WMS与activity交互。Activity 通过IWindowSession与WMS通信,调用IWindowSession的相应函数通知WMS添加窗口,设置layout, 以及绘制完窗口后通知WMS显示。

WMS通过IWindow与Activity通讯。比如通知窗口focus变化,size 变化等。

WMS与activity之间的通讯为进程间通讯,通过android 的AIDL技术完成。

6.WMS还与一个在android 系统中非常重要的类PhoneWindowManager

进行交互。PhoneWindowManager是一个类似于定义android 系统policy的类。

比如定义homekey 作用。定义各个窗口的Z-order. 监听rotation 变化并通知WMS等。

四.    WMS 初始化

WMS由SystemServer启动,运行在system process里。启动代码位于SystemServer.startOtherServices()@SystemServer.java。可以参见以下代码。

    private void startOtherServices() {
            ……
            inputManager = new InputManagerService(context);
            wm = WindowManagerService.main(context, inputManager,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,

                    !mFirstBoot, mOnlyCore);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm); 
            ……
            mActivityManagerService.setWindowManager(wm);

            inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
            inputManager.start();
            wm.displayReady();
            ActivityManagerNative.getDefault().showBootMessage(
                    context.getResources().getText(
                            com.android.internal.R.string.android_upgrading_starting_apps),
                    false);
            wm.systemReady();
            Configuration config = wm.computeNewConfiguration();
          ……
    }



可以看到在系统启动过程中,主要做了以下跟WMS相关的工作。
1)    调用WindowManagerService.main()。main 函数主要完成一下工作。
  • 新建一个WindowManagerService。
  • 在DisplayThread中运行WindowManagerService. DisplayThread是一个共享的单例线程。WindowManagerService, DisplayManagerService 和 InputManagerService 共同运行在该线程中。系统中优先级为-4。优先级数字越低,在系统中享有的优先级越高。
  • 新建一个 PhoneWindowManager 的实例,启动UiThread。 PhoneWindowManager 运行在UiThread中。UiThread也是一个共享线程,主要用于PhoneWindowManager的相关功能,并监听Settings变化等。优先级为-2。
2)     ServiceManager.addService(Context.WINDOW_SERVICE, wm), 将WMS加入系统中
3)     mActivityManagerService.setWindowManager(wm); 让AMS中持有WMS的实例
4)     wm.displayReady(). 设置显示尺寸.
5)    可能会显示bootMessage. 通常,系统第一次启动时会显示BootMessage, 由PackageManagerService发起,显示系统目前package 处理的情况。如果系统中package信息发生变化,例如oat升级后,手机关机重启后也可能显示BootMessage。可能会显示“Android™ is upgrading…”(系统正在升级)

6)    wm.systemReady().  会调用  mPolicy.systemReady() -->KeyguardMediator.onSystemReady()。 主要完成一下两个工作

  • Enable keyguard. 
  • Set a setting and orientation listener.  

7)    wm.computeNewConfiguration(). 计算一个新的configuration,并应用到系统。


到此, WMS的一些基本信息就差不多介绍完了,后续的文章会以启动一个activity为例介绍WMS的具体的相关功能。



阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页