Loading...
avatar

Android系统_WMS启动流程

图文概括

启动流程

重要成员

  • Session
    • WMS的成员变量mSessions保存着所有的Session对象,Session继承于IWindowSession.Stub, 作为Binder服务端
    • 每一个应用进程都有一个唯一的 Session 对象与 WMS 通信
    • ViewRootImpl 和 WMS 之间的通信就是通过 Session 对象完成的
  • WindowState
    • WMS中,通过mWindowMap(WindowHashMap )保存所有的WindowState对象
    • WindowState 中保存了 WMS 对象、WMP 对象、Session 对象和 IWindow对象,一个 WindowState 对象就对应着一个应用进程中的 Window 对象; IWindow -> ViewRootImpl.W extends IWindow.Stub
  • WindowToken
    • WMS成员变量mTokenMap: 保存所有的WindowToken对象; 以IBinder为key,可以是IAppWindowToken或者其他Binder的Bp端;IBinder -> ActivityRecord.Token extends IApplicationToken.Stub
    • 一个 WindowToken 就代表着一个应用组件,应用组件包括:Activity、InputMethod 等。在 WMS 中,会将属于同一 WindowToken 的做统一处理,比如在对窗口进行 ZOrder 排序时,会将属于统一 WindowToken 的排在一起
    • WindowToken 也具有令牌的作用。应用组件在创建 Window 时都需要提供一个有效的 WindowToken 以表明自己的身份,并且窗口的类型必须与所持有的 WindowToken 类型保持一致。

源码分析—启动流程

基于API23

SystemServer启动WMS

  • 执行WMS的main方法,进行WMS创建及初始化
  • 执行WMS的displayReady方法,初始化显示信息
  • 执行WMS的systemReady方法,通知 WMS 系统的初始化工作完成

参考:Android系统_SystemServer启动流程分析

1
2
3
4
5
6
7
8
9
10
11
12
 // system server 执行启动其它系统服务
private void startOtherServices() {
...
// 执行 WMS的main方法
WindowManagerService wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);

wm.displayReady();
...
wm.systemReady();
}

main方法

  • WMS为单例模式
  • WMS的main方法,通过DisplayThread创建了一个WMS单例对象
  • 运行在”android.display”线程,DisplayThread 线程是一个系统前台线程,用于执行一些延时要非常小的关于显示的操作,一般只会在 WindowManager、DisplayManager 和 InputManager 中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {

private static WindowManagerService sInstance;
static WindowManagerService getInstance() {
return sInstance;
}

public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore,
WindowManagerPolicy policy) {
// "android.display"线程
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, haveInputMethods, showBootMsgs,
onlyCore, policy), 0);
return sInstance;
}

}

构造方法

  1. 赋值及初始化成员变量(context、inputManager、policy)等
  2. 创建一个 WindowAnimator 对象,用于管理所有窗口的动画
  3. 初始化 mPolicy ,具体的实现类是 PhoneWindowManager,WMS 的许多操作都是需要 WMP 规定的,比如:多个窗口的上下顺序,监听屏幕旋转的状态,预处理一些系统按键事件(例如HOME、BACK键等的默认行为就是在这里实现的)
  4. 将 WMS 实例对象本身添加到 Watchdog 中,WMS 类实现了 Watchdog.Monitor 接口。Watchdog 用于监控系统的一些关键服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
private WindowManagerService(Context context, InputManagerService inputManager, boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
mContext = context;
mHaveInputMethods = haveInputMethods;
mAllowBootMessages = showBootMsgs;
mOnlyCore = onlyCore;
...
mInputManager = inputManager;
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mDisplaySettings = new DisplaySettings();
mDisplaySettings.readSettingsLocked();

LocalServices.addService(WindowManagerPolicy.class, mPolicy);
mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));

mFxSession = new SurfaceSession();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
mDisplays = mDisplayManager.getDisplays();

for (Display display : mDisplays) {
createDisplayContentLocked(display);
}

mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
...

mAppTransition = new AppTransition(context, mH);
mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
mActivityManager = ActivityManagerNative.getDefault();
...
mAnimator = new WindowAnimator(this);


LocalServices.addService(WindowManagerInternal.class, new LocalService());
//初始化策略
initPolicy();

Watchdog.getInstance().addMonitor(this);

...
}

initPolicy

  • UiThread进行policy的初始化,此过程为同步阻塞过程,运行在android.ui线程
1
2
3
4
5
6
7
8
9
10
private void initPolicy() {
// 切换到 UiThread 执行,运行在"android.ui"线程,runWithScissors会判断当前执行线程,来决定是直接执行还是等待执行
UiThread.getHandler().runWithScissors(new Runnable() {
public void run() {
WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
// 初始化
mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
}
}, 0);
}

displayReady

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void displayReady() {
for (Display display : mDisplays) {
displayReady(display.getDisplayId());
}

synchronized(mWindowMap) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
readForcedDisplayPropertiesLocked(displayContent);
mDisplayReady = true;
}

mActivityManager.updateConfiguration(null);

synchronized(mWindowMap) {
mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TOUCHSCREEN);
configureDisplayPolicyLocked(getDefaultDisplayContentLocked());
}

mActivityManager.updateConfiguration(null);
}

systemReady

1
2
3
public void systemReady() {
mPolicy.systemReady();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public void systemReady() {
mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
mKeyguardDelegate.onSystemReady();

readCameraLensCoverState();
updateUiMode();
boolean bindKeyguardNow;
synchronized (mLock) {
updateOrientationListenerLp();
mSystemReady = true;

mHandler.post(new Runnable() {
public void run() {
updateSettings();
}
});

bindKeyguardNow = mDeferBindKeyguard;
if (bindKeyguardNow) {
mDeferBindKeyguard = false;
}
}

if (bindKeyguardNow) {
mKeyguardDelegate.bindService(mContext);
mKeyguardDelegate.onBootCompleted();
}
mSystemGestures.systemReady();
}

源码分析—重要成员

Session

  • WMS的成员变量mSessions保存着所有的Session对象,Session继承于IWindowSession.Stub, 作为Binder服务端;
  • 每一个应用进程都有一个唯一的 Session 对象与 WMS 通信
  • ViewRootImpl 和 WMS 之间的通信就是通过 Session 对象完成的。
WMS.mSessions
1
2
3
4
5
6
7
8
9
10
11
12
13
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
// All currently active sessions with clients.
final ArraySet<Session> mSessions = new ArraySet<>();

@Override
public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
IInputContext inputContext) {

Session session = new Session(this, callback, client, inputContext);
return session;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Session extends IWindowSession.Stub
implements IBinder.DeathRecipient {
final WindowManagerService mService; // 持有WMS
private int mNumWindow = 0;

public Session(WindowManagerService service, IWindowSessionCallback callback,
IInputMethodClient client, IInputContext inputContext) {
mService = service; // 赋值

}
// 添加
void windowAddedLocked(String packageName) {
if (mSurfaceSession == null) {
mService.mSessions.add(this);
}
mNumWindow++;
}

// 移除
void windowRemovedLocked() {
mNumWindow--;
killSessionLocked();
}

private void killSessionLocked() {
if (mNumWindow > 0 || !mClientDead) {
return;
}
mService.mSessions.remove(this);
}

}

WindowState

  • WMS中,通过mWindowMap(WindowHashMap )保存所有的WindowState对象
  • WindowState 中保存了 WMS 对象、WMP 对象、Session 对象和 IWindow对象,一个 WindowState 对象就对应着一个应用进程中的 Window 对象; IWindow -> ViewRootImpl.W extends IWindow.Stub
WindowManagerService.addWindowToken
1
2
3
4
5
6
7
8
9
10
11
12
final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<>();

public void addWindowToken(IBinder token, int type) {
synchronized(mWindowMap) {
WindowToken wtoken = mTokenMap.get(token);
wtoken = new WindowToken(this, token, type, true);
mTokenMap.put(token, wtoken);
if (type == TYPE_WALLPAPER) {
mWallpaperTokens.add(wtoken);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class WindowState extends WindowContainer<WindowState> implements WindowManagerPolicy.WindowState {
final WindowManagerService mService; // WMS
final WindowManagerPolicy mPolicy; // WMP
final Context mContext; //ctx
final Session mSession; // session
final IWindow mClient; // 应用进程中的 Window 对象

WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a,
int viewVisibility, int ownerId, boolean ownerCanAddInternalSystemWindow) {
mService = service;
mSession = s;
mClient = c;
mAppOp = appOp;
mToken = token;
mAppToken = mToken.asAppWindowToken();

......
}

void attach() {
mSession.windowAddedLocked(mAttrs.packageName);
}
}

// IWindow mClient 就是 ViewRootImpl 中的 final W mWindow 成员
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
final W mWindow;

static class W extends IWindow.Stub {
......
}
}

WindowToken

  • WMS成员变量mTokenMap: 保存所有的WindowToken对象; 以IBinder为key,可以是IAppWindowToken或者其他Binder的Bp端;IBinder -> ActivityRecord.Token extends IApplicationToken.Stub
  • 一个 WindowToken 就代表着一个应用组件,应用组件包括:Activity、InputMethod 等。在 WMS 中,会将属于同一 WindowToken 的做统一处理,比如在对窗口进行 ZOrder 排序时,会将属于统一 WindowToken 的排在一起
  • WindowToken 也具有令牌的作用。应用组件在创建 Window 时都需要提供一个有效的 WindowToken 以表明自己的身份,并且窗口的类型必须与所持有的 WindowToken 类型保持一致。
WMS.mTokenMap相关
1
2
3
4
5
6
7
8
9
10
11
12
final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<>();

public void addWindowToken(IBinder token, int type) {
synchronized(mWindowMap) {
WindowToken wtoken = mTokenMap.get(token);
wtoken = new WindowToken(this, token, type, true);
mTokenMap.put(token, wtoken);
if (type == TYPE_WALLPAPER) {
mWallpaperTokens.add(wtoken);
}
}
}

推荐阅读:图形系统总结
参考:
WMS—启动过程

Author: Afree
Link: https://afree8909.github.io/blog/2019/11/20/Android%E7%B3%BB%E7%BB%9F_WMS%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.

Comment