一.Wms的介绍
前面三讲主要多涉及的是有关window的概念。这讲我们主要介绍WindowManagerService。众所周知Wms是windowManager的管理者,其实他还有其他重要的职责。
WMS的主要的职责是:
1.保持窗口的层级关系,以便SurfaceFlinger能够据此绘制屏幕;
2.把窗口信息传递给InputManager对象,以便InputDispatcher能够把输入消息派发给和屏幕上显示一致的窗口;
二.Wms的接口结构
这里的接口结构是指Wms模块和其他模块之间的交互接口,具体如下图:
三.Wms的启动
和Ams一样,Wms也是在SystemServer启动的时候被创建。我们来看下创建的流程
SystemServer#startOtherService()
其中涉及到Wms的代码如下:
// 1
traceBeginAndSlog("StartWindowManagerService");
// WMS needs sensor service ready
ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
mSensorServiceStart = null;
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
traceEnd();
// 2
traceBeginAndSlog("SetWindowManagerService");
mActivityManagerService.setWindowManager(wm);
traceEnd();
// 3
traceBeginAndSlog("WindowManagerServiceOnInitReady");
wm.onInitReady();
traceEnd();
// 4
traceBeginAndSlog("MakeDisplayReady");
try {
wm.displayReady();
} catch (Throwable e) {
reportWtf("making display ready", e);
}
traceEnd();
// 5
traceBeginAndSlog("MakeWindowManagerServiceReady");
try {
wm.systemReady();
} catch (Throwable e) {
reportWtf("making Window Manager Service ready", e);
}
traceEnd();
我们分别来看(注释号对应着下面哥小节号)。
1.WindowManagerService#main
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm) {
return main(context, im, showBootMsgs, onlyCore, policy, atm,
SurfaceControl.Transaction::new);
}
/**
* Creates and returns an instance of the WindowManagerService. This call allows the caller
* to override the {@link TransactionFactory} to stub functionality under test.
*/
@VisibleForTesting
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
atm, transactionFactory), 0);
return sInstance;
}
DisplayThread.getHandler方法是用来获取DisplayThread的handler实例。然后就是调用Handler的runWithScissors()方法。
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");
}
// 1
if (Looper.myLooper() == mLooper) {
r.run();
return true;
}
BlockingRunnable br = new BlockingRunnable(r);
return br.postAndWait(this, timeout);
}
注释1:判断当前的线程是否是Handler所指向的线程(android.display线程)。很明显当前线程是system_server线程,而非android.display线程。0
如果是的话就直接执行run()方法,如果不是的话就会调用BlockingRunnable的postAndWait()方法。BlockingRunnable是Handler的内部类
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; // timeout
}
try {
wait(delay);
} catch (InterruptedException ex) {
}
}
} else {
while (!mDone) {
try {
wait();
} catch (InterruptedException ex) {
}
}
}
}
return true;
}
在Wms的main()方法中传入的timeout为0,所以if-else语句中会走到else中去,即当前的线程将处于wait状态。而这个线程需要等待的线程是什么?我们注意到一个变量mDone。它默认为false,赋值是在BlockingRunnable的run()方法中:
@Override
public void run() {
try {
mTask.run();
} finally {
synchronized (this) {
mDone = true;
notifyAll();
}
}
}
当执行完run()方法后,在finally语句中会将mDone置为true,这样上面的if-else语句就不会走进去,同时调用notifyAll()方法唤醒处于wait状态的线程。也就是说system_server线程需要等待android.display线程执行完毕才会被唤醒执行。
2.Ams#setWindowManager
// Ams
public void setWindowManager(WindowManagerService wm) {
synchronized (this) {
mWindowManager = wm;
mActivityTaskManager.setWindowManager(wm);
}
}
// ActivityTaskManagerService
public void setWindowManager(WindowManagerService wm) {
synchronized (mGlobalLock) {
mWindowManager = wm;
mLockTaskController.setWindowManager(wm);