Android WindowManager与Window

先看下app端的类图结构:

WindowManagerWindowActivityPhoneWindowWindowManagerImpl«Singleton»WindowManagerGlobalViewParentViewRootImplIWindowSessionIWindow.StubViewRootImpl.WIWindowIWindowManagerSurfaceSurfaceControl1n

IWindowManager

IWindowManager在IWindowManager.aidl文件中定义,是WindowManagerService的对外接口。

IWindowManagerIWindowManager.StubBinderWindowManagerServiceIWindowSessionIWindowSession.StubSession

IWindowSession

每个app都会有一个Window Session用于与window manager进行交互。IWindowSession是通过aidl定义的binder接口,app通过IWindowSession与WMS进行交互。


zenuml
new ViewRootImpl() {
    WindowManagerGlobal.getWindowSession {
        //sWindowSession是WindowManagerGlobal的静态类变量
        //如果sWindowSession为空就通过WMS.openSession来打开一个
        if (sWindowSession == null) {
            WindowManagerService.openSession {
                new Session()
            }
        }
        return sWindowSession
    }
}

addWindow把IWindow加入到WMS

IWindow是一个binder接口,这个binder的service端是app,实现类是ViewRootImpl.W,client端是WMS。WMS会通过IWindow这个binder接口来通知app window相关的事件。先看下addWindow的调用时序:


zenuml
group App {
    <<App>> WindowManagerGlobal
    <<App>> ViewRootImpl
}
group WMS {
    <<WMS>> WindowManagerService
    <<WMS>> Session
}
WindowManagerGlobal.addView {
    new ViewRootImpl() {
        "new Surface()"
        "new SurfaceControl()"
        WindowManagerGlobal.getWindowSession {
            WindowManagerService.openSession {
                new Session()
            }
        }
        "new W()"
    }
    ViewRootImpl.setView {
        requestLayout
        Session.addToDisplayAsUser {
            WindowManagerService.addWindow
        }
    }
}

addToDisplayAsUser函数的第一个参数是IWindow window,它的实现类就是ViewRootImpl.W类型,W接收到的WMS的事件大部分都交给了ViewRootImpl来处理。

WindowContainerDisplayAreaDisplayAreaDisplayAreaDisplayArea.DimmableRootDisplayAreaDisplayContentDisplayAreaWindowContainerWindowContainerWindowContainerTaskDisplayAreaWindowContainerWindowContainerTaskFragmentTaskWindowContainerWindowStateWindowTokenActivityRecord1n1n1n1n

relayoutWindow

Activity启动时在ViewRootImpl.performTraversals中执行relayoutWindow,就会调用mWindowSession.relayout,最后调用WindowManagerService.relayoutWindow

ViewRootImpl在执行relayoutWindow时,会把SurfaceControl传给WindowManagerService。


zenuml
group App {
    <<App>> ViewRootImpl
    <<App>> BLASTBufferQueue
}
ViewRootImpl.relayoutWindow {
    WindowManagerService.relayoutWindow {
        WindowState win = windowForClientLocked()
        DisplayContent displayContent = "win.getDisplayContent()"
        createSurfaceControl {
            "WindowStateAnimator.createSurfaceLocked()" {
                new WindowSurfaceController() {
                    new SurfaceControl()
                }
            }
            WindowSurfaceController.getSurfaceControl {
                SurfaceControl."outSurfaceControl.copyFrom"
            }
        }
    }
    updateBlastSurfaceIfNeeded {
        new BLASTBufferQueue()
        blastSurface = BLASTBufferQueue.createSurface
        "mSurface.transferFrom(blastSurface)"
    }
}
SurfaceControlSurfaceComposerClientSurface BnInterfaceISurfaceComposerBBinderISurfaceComposerBnSurfaceComposerSurfaceFlinger