WindowManagerService
前一节, 对Window
和WindowManager
进行了分析, blog, 其中的WMS
是不容忽视的角色
关于Android的framework层主要就是由它与另外一个系统服务
ActivityManagerService
和View
构成, 这三个模块穿插在整个framework
中.
和其他系统服务一样, WMS
也是由SystemServer
启动的. 调用了WMS#main()
静态方法来构建的对象. 之后其他进程就可以通过ServiceManger
查询window
来获取WMS
. main()
比较简单就是通过Handler#runWithScissors()
方法执行一个特殊的同步Task
并在其中构造WMS
的实例
WMS
的构造方法主要是对一些窗口管理将要使用到的成员变量进行初始化
private WindowManagerService(Context context, InputManagerService inputManager,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
// 成员变量的赋值
mContext = context;
// ....
// 获取显示服务
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
// 构造APP事务对象
mAppTransition = new AppTransition(context, mH);
// 获取IActivityManager对象
mActivityManager = ActivityManagerNative.getDefault();
// 构造Window对象
mAnimator = new WindowAnimator(this);
// 初始化窗口管理策略
initPolicy();
// 开启Surface事务
SurfaceControl.openTransaction();
}
WMS
主要功能可以分为两方面, 一是对窗口的管理, 二是对事件的管理和分发. 其接口方法以AIDL
的方式定义在IWindowManager.aidl
文件中, 编译后生成一个对应的IWindowManager.java
接口文件, 这个接口文件定义了WMS绝大部分的功能方法.
作为窗口管理承担者, WMS
中定义了许多不同的窗口, 他们都被定义在WMS
的成员变量中.
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
// 已经完成启动的应用
final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
// 渐变窗口
final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
// 尺寸正在改变的窗口
final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
// 动画结束的窗口
final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
// 即将释放Surface的窗口
final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
// 失去焦点的窗口
ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
// 为了释放内存需要关闭的窗口
ArrayList<WindowState> mForceRemoves;
// 正在打开的应用
final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<AppWindowToken>();
// 正在关闭的应用
final ArraySet<AppWindowToken> mClosingApps = new ArraySet<AppWindowToken>();
// 当前获得焦点的窗口
WindowState mCurrentFocus = null;
// 上一个获得焦点的窗口
WindowState mLastFocus = null;
// 输入法窗口下方的窗口
WindowState mInputMethodTarget = null;
// 输入法窗口
WindowState mInputMethodWindow = null;
// 墙纸窗口
WindowState mWallpaperTarget = null;
// 在切换过程中位于墙纸z-order下方的窗口
WindowState mLowerWallpaperTarget = null;
// 在切换过程中位于墙纸z-order上方的窗口
WindowState mUpperWallpaperTarget = null;
// 得到焦点的窗口
AppWindowToken mFocusedApp = null;
}
可以看到大量的线性表应用, 不同的窗口或同一个窗口在不同的状态下可能位于不同的表中. 虽然状态较多, 但是对于Android
来讲窗口可以用两种粗略的概括为应用窗口
,系统窗口
.
应用窗口
: 就是常见的Activity
,dialog
,popup
等都属于该类. 也可以继续分为子窗口
(比如子窗口AlertDialog的常规创建需要使用activity的context). 而与应用相关的Window
类主要是PhoneWindow
,主要应用于手机,PhoneWindow
继承与Window
,核心是DecorView
, 通过WindowManager
进行DecorView
的操作.系统窗口
: 常见的屏幕顶部的状态栏, 底部的导航栏, 桌面窗口等都是系统窗口. 系统窗口没有针对性的封装类, 只需要直接通过WindowManager
直接进行View
的操作即可.
WMS
是运行在系统进程中, 那么一个应用需要创建窗口时必然需要跨进程通信
通知WMS
生成一个窗口, 然后再由WMS
向应用返回和窗口交互的消息. 上一篇说过, WindowManger
的操作是桥接到了WindowMangerGlobal
实现的具体逻辑, 最后会调用ViewRootImpl#setView()
函数, 在该方法中通过addToDisplay()
函数向WMS
发起了一个Session
请求. 最终会调用到Session#addToDisplay()
函数.
@Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets,
InputChannel outInputChannel) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
outContentInsets, outInputChannel);
}
最后还是回到了WMS
中建立连接, addToDisplay()
最终返回的就是WMS#addWindow()
的返回结果.
WMS#addWindow()
逻辑主要是先检查权限, 区分系统权限
和应用权限
通过PhoneWindowManager#checkAddPermission()
判断窗口类型是否是系统级的. 如果不是系统级则返回一个ADD_OKAY
值表示允许, 否则就需要SYSTEM_ALERT_WINDOW
或者INTERNAL_SYSTEM_WINDOW
的权限. 权限之后则相关Display
显示信息以及窗口信息进行校队, 然后在WMS
中获取对应的WindowToken
, 之后根据不同的窗口类型检查窗口的有效性.
窗口的有效性检查完之后, 就会为该窗口创建一个WindowState
对象类, 维护窗口的状态以及根据适当的机制来调整窗口的状态.
在WindowState
对象构建完之后, 会通过mPolicy
本质上就是PhoneWindowManager
的adjustWindowParamsLw()
函数决定该窗口是否需要获取焦点. 判断逻辑就是只要是TYPE_SYSTEM_OVERLAY
或者TYPE_SECURE_SYSTEM_OVERLAY
就不获取.
最后将窗口与其他相关组件关联.
在addWindow
方法的最后一部分, 最重要的一步就是通过WindowState#attach()
函数创建了一个关联SurfaceSession
的对象以与SurfaceFlinger
通信, 而SurfaceSession
实际对应的就是native层
中的SurfaceComposerClient
对象. SurfaceComposerClient
主要作用就是在应用进程与SurfaceFlinger
服务之间建立连接.
以上就是一个系统窗口的添加的主要逻辑.