WMS的创建

基于Android U

WMS的创建过程

WMS是在SystemServer中创建的。

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
...
t.traceBegin("StartWatchdog");
final Watchdog watchdog = Watchdog.getInstance(); // 1
watchdog.start();
mDumper.addDumpable(watchdog);
t.traceEnd();
...
t.traceBegin("InitWatchdog");
watchdog.init(mSystemContext, mActivityManagerService); // 2
t.traceEnd();
...
}

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
WindowManagerService wm = null;
...
InputManagerService inputManager = null;
...

try {
...
t.traceBegin("StartInputManagerService");
inputManager = new InputManagerService(context); // 3
t.traceEnd();
...
t.traceBegin("StartWindowManagerService");
// WMS needs sensor service ready
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
wm = WindowManagerService.main(context, inputManager, !mFirstBoot,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager); // 4
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO); // 5
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL); // 6
t.traceEnd();

t.traceBegin("SetWindowManagerService");
mActivityManagerService.setWindowManager(wm);
t.traceEnd();

t.traceBegin("WindowManagerServiceOnInitReady");
wm.onInitReady(); // 7
t.traceEnd();
...
} catch (Throwable e) {
...
}
...
t.traceBegin("MakeDisplayReady");
try {
wm.displayReady(); // 8
} catch (Throwable e) {
...
}
t.traceEnd();
...
t.traceBegin("MakeWindowManagerServiceReady");
try {
wm.systemReady(); // 9
} catch (Throwable e) {
...
}
t.traceEnd();
...
}

注释1、2处分别得到Watchdog实例并对它进行初始化,Watchdog用来监控系统的一些关键服务的运行状况。

注释3处创建了IMS,并赋值给IMS类型的inputManager对象。

注释4处执行了WMS的main()方法,其内部会创建WMS,需要注意的是main()方法其中一个传入的参数就是在注释3处创建的IMS,WMS是输入事件的中转站,其内部包含了IMS引用并不意外。WMS的main()方法是运行在SystemServer的run()方法中的,换句话说就是运行在“system_server”线程中。

在注释5、6处分别将WMS和IMS注册到ServiceManager中,这样如果某个客户端想要使用WMS,就需要先去ServiceManager中查询信息,然后根据信息与WMS所在的进程建立通信通路,客户端就可以使用WMS了。

注释7处用来初始化窗口管理策略的接口类,以及将WMS添加到Watchdog中。

注释8处用来初始化屏幕显示信息。

注释9处用来通知WMS,系统的初始化工作已经完成,其内部调用了WindowManagerPolicy的systemReady()方法。

  1. WindowManagerService.main()
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
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, WindowManagerPolicy policy,
ActivityTaskManagerService atm) {
return main(context, im, showBootMsgs, policy, atm, new DisplayWindowSettingsProvider(),
SurfaceControl.Transaction::new, SurfaceControl.Builder::new);
}

/**
* Creates and returns an instance of the WindowManagerService. This call allows the caller
* to override factories that can be used to stub native calls during test.
*/
@VisibleForTesting
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm,
DisplayWindowSettingsProvider displayWindowSettingsProvider,
Supplier<SurfaceControl.Transaction> transactionFactory,
Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
final WindowManagerService[] wms = new WindowManagerService[1];
DisplayThread.getHandler().runWithScissors(() -> // 1
wms[0] = new WindowManagerService(context, im, showBootMsgs, policy, atm,
displayWindowSettingsProvider, transactionFactory,
surfaceControlFactory), 0); // 2
return wms[0];
}

注释1处调用了DisplayThread的getHandler()方法,用来得到DisplayThread的Handler实例。DisplayThread是一个单例的前台线程,这个线程用来处理需要低延时显示的相关操作,并只能由WindowManager、DisplayManager和InputManager实时执行快速操作。

注释2处创建了WMS的实例,这个过程运行在Runnable的run()方法中,而Runnable则传到了DisplayThread对应的Handler的runWithScissors()方法中,说明WMS的创建是运行在android.displ ay线程中的。需要注意的是,runWithScissors()方法的第二个参数传入的是0。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
frameworks/base/core/java/android/os/Handler.java
public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
if (r == null) {
throw new IllegalArgumentException("runnable must not be null");
}
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be non-negative");
}

if (Looper.myLooper() == mLooper) { // 1
r.run();
return true;
}

BlockingRunnable br = new BlockingRunnable(r);
return br.postAndWait(this, timeout);
}

开头对传入的Runnable和timeout进行了判断,如果Runnable为null或者timeout小于0则抛出异常。在注释1处根据每个线程只有一个Looper的原理来判断当前的线程(system_server线程)是否是Handler所指向的线程(android.display线程),如果是则直接执行Runnable的run()方法,如果不是则调用BlockingRunnable的postAndWait()方法,并将当前线程的Runnable作为参数传进去,BlockingRunnable是Handler的内部类。

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
41
42
43
44
45
46
47
48
49
50
51
frameworks/base/core/java/android/os/Handler.java
private static final class BlockingRunnable implements Runnable {
private final Runnable mTask;
private boolean mDone;

public BlockingRunnable(Runnable task) {
mTask = task;
}

@Override
public void run() {
try {
mTask.run(); // 1
} finally {
synchronized (this) {
mDone = true;
notifyAll();
}
}
}

public boolean postAndWait(Handler handler, long timeout) {
if (!handler.post(this)) { // 2
return false;
}

synchronized (this) {
if (timeout > 0) {
final long expirationTime = SystemClock.uptimeMillis() + timeout;
while (!mDone) {
long delay = expirationTime - SystemClock.uptimeMillis();
if (delay <= 0) {
return false; // timeout
}
try {
wait(delay);
} catch (InterruptedException ex) {
}
}
} else {
while (!mDone) {
try {
wait(); // 3
} catch (InterruptedException ex) {
}
}
}
}
return true;
}
}

在注释2处将当前的BlockingRunnable添加到Handler的任务队列中。前面的runWithScissors()方法的第二个参数为0,因此timeout等于0,这样如果mDone为false的话会一直调用注释3处的wait()方法使得当前线程(system_server线程)进入等待状态,那么等待的是哪个线程呢?我们往上看,在注释1处执行了传入的Runnable的run()方法(运行在android.display线程),执行完毕后在finally代码块中将mDone设置为true,并调用notifyAll()方法唤醒处于等待状态的线程,这样就不会继续调用注释3处的wait()方法。因此得出结论,system_server线程等待的就是android.display线程,这是因为android.display线程内部执行了WMS的创建,而WMS的创建优先级要更高。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
private WindowManagerService(Context context, InputManagerService inputManager,
boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm,
DisplayWindowSettingsProvider displayWindowSettingsProvider,
Supplier<SurfaceControl.Transaction> transactionFactory,
Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
...
mInputManager = inputManager; // 1
...
mAnimator = new WindowAnimator(this); // 2
...
mActivityManager = ActivityManager.getService(); // 3
...
}

注释1处用来保存传进来的IMS,这样WMS就持有了IMS的引用。

注释2处创建了WindowAnimator,它用于管理所有的窗口动画。

注释3处得到AMS实例,并赋值给mActivityManager,这样WMS就持有了AMS的引用。

  1. WindowManagerService.onInitReady()
1
2
3
4
5
6
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public void onInitReady() {
initPolicy(); // 1
Watchdog.getInstance().addMonitor(this); // 2
...
}

注释1处初始化了窗口管理策略的接口类WindowManagerPolicy(WMP),它用来定义一个窗口策略所要遵循的通用规范。

注释2处将自身也就是WMS通过addMonitor()方法添加到Watchdog中,Watchdog用来监控系统的一些关键服务的运行状况(比如传入的WMS的运行状况),这些被监控的服务都会实现Watchdog.Monitor接口。Watchdog每分钟都会对被监控的系统服务进行检查,如果被监控的系统出现了死锁,则会杀死Watchdog所在的进程,也就是SystemServer进程。

1
2
3
4
5
6
7
8
9
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
private void initPolicy() {
UiThread.getHandler().runWithScissors(new Runnable() {
public void run() {
WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
mPolicy.init(mContext, WindowManagerService.this); // 1
}
}, 0);
}

initPolicy()方法和此前讲的WMS的main()方法的实现类似,在注释1处执行了WMP的init()方法,WMP是一个接口,init()方法具体在PhoneWindowManager(PWM)中实现。PWM的init()方法运行在android.ui线程中,它的优先级要高于initPolicy()方法所在的android.display线程,因此android.display线程要等PWM的init()方法执行完毕后,处于等待状态的android.display线程才会被唤醒从而继续执行下面的代码。

线程间关系

本文共提到了三个线程,分别是system_server、android.display和android.ui,为了便于理解,下面给出这三个线程之间的关系。

从上图可以看出,三个线程之间的关系可以分为三个步骤来实现:

  1. 首先在system_server线程中执行了SystemServer的startOtherServices()方法,在startOtherServices()方法中会调用WMS的main()方法,main()方法会创建WMS,创建的过程在android.display线程中实现,创建WMS的优先级更高,因此system_server线程要等WMS创建完成后,处于等待状态的system_server线程才会被唤醒从而继续执行下面的代码。
  2. 在WMS的构造方法中会调用WMS的initPolicy()方法,在initPolicy()方法中又会调用PWM.init()方法,PWM的init()方法在android.ui线程中运行,它的优先级要高于android.display线程,因此android.display线程要等PWM的init()方法执行完毕后,处于等待状态的android.display线程才会被唤醒从而继续执行下面的代码。
  3. PWM的init()方法执行完毕后,android.display线程就完成了WMS的创建,等待的system_server线程被唤醒后继续执行WMS的main()方法后的代码逻辑,比如WMS的displayReady()方法用来初始化屏幕显示信息(SystemServer的startOtherServices()方法的注释8处)。

WMS的创建
https://citrus-maxima.github.io/2024/03/10/WMS的创建/
作者
柚子树
发布于
2024年3月10日
许可协议