在Android系统中由WindowManagerService也就是WMS承担窗口位置的管理。
WMS
WMS是一个系统服务,运行在system server进程,系统启动便开始启动该服务
/frameworks/base/services/java/com/android/server/SystemServer.java
// Start services.
938 try {
939 t.traceBegin("StartServices");
940 startBootstrapServices(t);
941 startCoreServices(t);
942 startOtherServices(t);
943 startApexServices(t);
944 // Only update the timeout after starting all the services so that we use
945 // the default timeout to start system server.
946 updateWatchdogTimeout(t);
在这里面启动相关服务, 在startOtherServices(t)启动 WMS服务。
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
1425 t.traceBegin("startOtherServices");
1426 mSystemServiceManager.updateOtherServicesStartIndex();
t.traceBegin("StartWindowManagerService");
1604 // WMS needs sensor service ready
1605 mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
1606 wm = WindowManagerService.main(context, inputManager, !mFirstBoot,
1607 new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
1608 ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
1609 DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
1610 ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
1611 /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
1612 t.traceEnd();
上述代码可以看到,创建了wms对象并添加到服务管理进程中。
与wms交互
应用进程通过WindowManagerGlobal与WMS建立通信连接。
7 @UnsupportedAppUsage
168 public static IWindowManager getWindowManagerService() {
169 synchronized (WindowManagerGlobal.class) {
170 if (sWindowManagerService == null) {
171 sWindowManagerService = IWindowManager.Stub.asInterface(
172 ServiceManager.getService("window"));
173 try {
174 if (sWindowManagerService != null) {
175 ValueAnimator.setDurationScale(
176 sWindowManagerService.getCurrentAnimatorScale());
177 sUseBLASTAdapter = sWindowManagerService.useBLAST();
178 }
179 } catch (RemoteException e) {
180 throw e.rethrowFromSystemServer();
181 }
182 }
183 return sWindowManagerService;
184 }
185 }
@UnsupportedAppUsage
188 public static IWindowSession getWindowSession() {
189 synchronized (WindowManagerGlobal.class) {
190 if (sWindowSession == null) {
191 try {
192 // Emulate the legacy behavior. The global instance of InputMethodManager
193 // was instantiated here.
194 // TODO(b/116157766): Remove this hack after cleaning up @UnsupportedAppUsage
195 InputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary();
196 IWindowManager windowManager = getWindowManagerService();
197 sWindowSession = windowManager.openSession(
198 new IWindowSessionCallback.Stub() {
199 @Override
200 public void onAnimatorScaleChanged(float scale) {
201 ValueAnimator.setDurationScale(scale);
202 }
203 });
204 } catch (RemoteException e) {
205 throw e.rethrowFromSystemServer();
206 }
207 }
208 return sWindowSession;
209 }
210 }
通过getWindowManagerService,openSession方法获取到IWindowManager对象。应用进程通常用通过IWindowManager与WMS交互。
WMS与SurfaceFlinger交互
再上图可以看到,在system server中,通过WMS中的DisplayContent成员,创建DisplayContent对象时,也会闯将SurfaceSession对象。
然后SurfaceSeeion会通过JNI 调用nativeCreate创建SurfaceComposerClient对象,并把该对象的地址保存到mNativeClient中。
每创建一个SurfaceComposerClient对象,SurfaceFlinger进程都会创建一个Client对象与它对应。
总的来说,当WMS需要与Surfaceflinger进行交互的时候,会调用DisplayContent中的SurfaceSession取出SurfaceComposerClient对象的地址,然后在向Surfaceflinger发送请求。