基于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.javaprivate void startBootstrapServices (@NonNull TimingsTraceAndSlog t) { ... t.traceBegin("StartWatchdog" ); final Watchdog watchdog = Watchdog.getInstance(); watchdog.start(); mDumper.addDumpable(watchdog); t.traceEnd(); ... t.traceBegin("InitWatchdog" ); watchdog.init(mSystemContext, mActivityManagerService); t.traceEnd(); ... }private void startOtherServices (@NonNull TimingsTraceAndSlog t) { ... WindowManagerService wm = null ; ... InputManagerService inputManager = null ; ... try { ... t.traceBegin("StartInputManagerService" ); inputManager = new InputManagerService (context); t.traceEnd(); ... t.traceBegin("StartWindowManagerService" ); mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE); wm = WindowManagerService.main(context, inputManager, !mFirstBoot, new PhoneWindowManager (), mActivityManagerService.mActivityTaskManager); ServiceManager.addService(Context.WINDOW_SERVICE, wm, false , DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO); ServiceManager.addService(Context.INPUT_SERVICE, inputManager, false , DUMP_FLAG_PRIORITY_CRITICAL); t.traceEnd(); t.traceBegin("SetWindowManagerService" ); mActivityManagerService.setWindowManager(wm); t.traceEnd(); t.traceBegin("WindowManagerServiceOnInitReady" ); wm.onInitReady(); t.traceEnd(); ... } catch (Throwable e) { ... } ... t.traceBegin("MakeDisplayReady" ); try { wm.displayReady(); } catch (Throwable e) { ... } t.traceEnd(); ... t.traceBegin("MakeWindowManagerServiceReady" ); try { wm.systemReady(); } 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()方法。
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.javapublic 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 ); }@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(() -> wms[0 ] = new WindowManagerService (context, im, showBootMsgs, policy, atm, displayWindowSettingsProvider, transactionFactory, surfaceControlFactory), 0 ); 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.javapublic 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) { 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.javaprivate 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(); } finally { synchronized (this ) { mDone = true ; notifyAll(); } } } public boolean postAndWait (Handler handler, long timeout) { if (!handler.post(this )) { 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 ; } try { wait(delay); } catch (InterruptedException ex) { } } } else { while (!mDone) { try { wait(); } 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.javaprivate WindowManagerService (Context context, InputManagerService inputManager, boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm, DisplayWindowSettingsProvider displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory, Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) { ... mInputManager = inputManager; ... mAnimator = new WindowAnimator (this ); ... mActivityManager = ActivityManager.getService(); ... }
注释1处用来保存传进来的IMS,这样WMS就持有了IMS的引用。
注释2处创建了WindowAnimator,它用于管理所有的窗口动画。
注释3处得到AMS实例,并赋值给mActivityManager,这样WMS就持有了AMS的引用。
WindowManagerService.onInitReady()
1 2 3 4 5 6 frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.javapublic void onInitReady () { initPolicy(); Watchdog.getInstance().addMonitor(this ); ... }
注释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.javaprivate void initPolicy () { UiThread.getHandler().runWithScissors(new Runnable () { public void run () { WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper()); mPolicy.init(mContext, WindowManagerService.this ); } }, 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,为了便于理解,下面给出这三个线程之间的关系。
从上图可以看出,三个线程之间的关系可以分为三个步骤来实现:
首先在system_server线程中执行了SystemServer的startOtherServices()方法,在startOtherServices()方法中会调用WMS的main()方法,main()方法会创建WMS,创建的过程在android.display线程中实现,创建WMS的优先级更高,因此system_server线程要等WMS创建完成后,处于等待状态的system_server线程才会被唤醒从而继续执行下面的代码。
在WMS的构造方法中会调用WMS的initPolicy()方法,在initPolicy()方法中又会调用PWM.init()方法,PWM的init()方法在android.ui线程中运行,它的优先级要高于android.display线程,因此android.display线程要等PWM的init()方法执行完毕后,处于等待状态的android.display线程才会被唤醒从而继续执行下面的代码。
PWM的init()方法执行完毕后,android.display线程就完成了WMS的创建,等待的system_server线程被唤醒后继续执行WMS的main()方法后的代码逻辑,比如WMS的displayReady()方法用来初始化屏幕显示信息(SystemServer的startOtherServices()方法的注释8处)。