图文概括 启动流程
重要成员
Session
WMS的成员变量mSessions保存着所有的Session对象,Session继承于IWindowSession.Stub, 作为Binder服务端
每一个应用进程都有一个唯一的 Session 对象与 WMS 通信
ViewRootImpl 和 WMS 之间的通信就是通过 Session 对象完成的
WindowState
WMS中,通过mWindowMap(WindowHashMap )保存所有的WindowState对象
WindowState 中保存了 WMS 对象、WMP 对象、Session 对象和 IWindow对象,一个 WindowState 对象就对应着一个应用进程中的 Window 对象; IWindow -> ViewRootImpl.W extends IWindow.Stub
WindowToken
WMS成员变量mTokenMap: 保存所有的WindowToken对象; 以IBinder为key,可以是IAppWindowToken或者其他Binder的Bp端;IBinder -> ActivityRecord.Token extends IApplicationToken.Stub
一个 WindowToken 就代表着一个应用组件,应用组件包括:Activity、InputMethod 等。在 WMS 中,会将属于同一 WindowToken 的做统一处理,比如在对窗口进行 ZOrder 排序时,会将属于统一 WindowToken 的排在一起
WindowToken 也具有令牌的作用。应用组件在创建 Window 时都需要提供一个有效的 WindowToken 以表明自己的身份,并且窗口的类型必须与所持有的 WindowToken 类型保持一致。
源码分析—启动流程
基于API23
SystemServer启动WMS
执行WMS的main方法,进行WMS创建及初始化
执行WMS的displayReady方法,初始化显示信息
执行WMS的systemReady方法,通知 WMS 系统的初始化工作完成
参考:Android系统_SystemServer启动流程分析
1 2 3 4 5 6 7 8 9 10 11 12 // system server 执行启动其它系统服务 private void startOtherServices() { ... // 执行 WMS的main方法 WindowManagerService wm = WindowManagerService.main(context, inputManager, mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore); wm.displayReady(); ... wm.systemReady(); }
main方法
WMS为单例模式
WMS的main方法,通过DisplayThread创建了一个WMS单例对象
运行在”android.display”线程,DisplayThread 线程是一个系统前台线程,用于执行一些延时要非常小的关于显示的操作,一般只会在 WindowManager、DisplayManager 和 InputManager 中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs { private static WindowManagerService sInstance; static WindowManagerService getInstance() { return sInstance; } public static WindowManagerService main(final Context context, final InputManagerService im, final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy) { // "android.display"线程 DisplayThread.getHandler().runWithScissors(() -> sInstance = new WindowManagerService(context, im, haveInputMethods, showBootMsgs, onlyCore, policy), 0); return sInstance; } }
构造方法
赋值及初始化成员变量(context、inputManager、policy)等
创建一个 WindowAnimator 对象,用于管理所有窗口的动画
初始化 mPolicy ,具体的实现类是 PhoneWindowManager,WMS 的许多操作都是需要 WMP 规定的,比如:多个窗口的上下顺序,监听屏幕旋转的状态,预处理一些系统按键事件(例如HOME、BACK键等的默认行为就是在这里实现的)
将 WMS 实例对象本身添加到 Watchdog 中,WMS 类实现了 Watchdog.Monitor 接口。Watchdog 用于监控系统的一些关键服务
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 private WindowManagerService(Context context, InputManagerService inputManager, boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) { mContext = context; mHaveInputMethods = haveInputMethods; mAllowBootMessages = showBootMsgs; mOnlyCore = onlyCore; ... mInputManager = inputManager; mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mDisplaySettings = new DisplaySettings(); mDisplaySettings.readSettingsLocked(); LocalServices.addService(WindowManagerPolicy.class, mPolicy); mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG)); mFxSession = new SurfaceSession(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mDisplays = mDisplayManager.getDisplays(); for (Display display : mDisplays) { createDisplayContentLocked(display); } mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy); ... mAppTransition = new AppTransition(context, mH); mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier); mActivityManager = ActivityManagerNative.getDefault(); ... mAnimator = new WindowAnimator(this); LocalServices.addService(WindowManagerInternal.class, new LocalService()); //初始化策略 initPolicy(); Watchdog.getInstance().addMonitor(this); ... }
initPolicy
UiThread进行policy的初始化,此过程为同步阻塞过程,运行在android.ui线程
1 2 3 4 5 6 7 8 9 10 private void initPolicy() { // 切换到 UiThread 执行,运行在"android.ui"线程,runWithScissors会判断当前执行线程,来决定是直接执行还是等待执行 UiThread.getHandler().runWithScissors(new Runnable() { public void run() { WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper()); // 初始化 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this); } }, 0); }
displayReady 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public void displayReady() { for (Display display : mDisplays) { displayReady(display.getDisplayId()); } synchronized(mWindowMap) { final DisplayContent displayContent = getDefaultDisplayContentLocked(); readForcedDisplayPropertiesLocked(displayContent); mDisplayReady = true; } mActivityManager.updateConfiguration(null); synchronized(mWindowMap) { mIsTouchDevice = mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TOUCHSCREEN); configureDisplayPolicyLocked(getDefaultDisplayContentLocked()); } mActivityManager.updateConfiguration(null); }
systemReady 1 2 3 public void systemReady() { mPolicy.systemReady(); }
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 public void systemReady() { mKeyguardDelegate = new KeyguardServiceDelegate(mContext); mKeyguardDelegate.onSystemReady(); readCameraLensCoverState(); updateUiMode(); boolean bindKeyguardNow; synchronized (mLock) { updateOrientationListenerLp(); mSystemReady = true; mHandler.post(new Runnable() { public void run() { updateSettings(); } }); bindKeyguardNow = mDeferBindKeyguard; if (bindKeyguardNow) { mDeferBindKeyguard = false; } } if (bindKeyguardNow) { mKeyguardDelegate.bindService(mContext); mKeyguardDelegate.onBootCompleted(); } mSystemGestures.systemReady(); }
源码分析—重要成员 Session
WMS的成员变量mSessions保存着所有的Session对象,Session继承于IWindowSession.Stub, 作为Binder服务端;
每一个应用进程都有一个唯一的 Session 对象与 WMS 通信
ViewRootImpl 和 WMS 之间的通信就是通过 Session 对象完成的。
WMS.mSessions 1 2 3 4 5 6 7 8 9 10 11 12 13 public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs { // All currently active sessions with clients. final ArraySet<Session> mSessions = new ArraySet<>(); @Override public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) { Session session = new Session(this, callback, client, inputContext); return session; } }
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 public class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { final WindowManagerService mService; // 持有WMS private int mNumWindow = 0; public Session(WindowManagerService service, IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) { mService = service; // 赋值 } // 添加 void windowAddedLocked(String packageName) { if (mSurfaceSession == null) { mService.mSessions.add(this); } mNumWindow++; } // 移除 void windowRemovedLocked() { mNumWindow--; killSessionLocked(); } private void killSessionLocked() { if (mNumWindow > 0 || !mClientDead) { return; } mService.mSessions.remove(this); } }
WindowState
WMS中,通过mWindowMap(WindowHashMap )保存所有的WindowState对象
WindowState 中保存了 WMS 对象、WMP 对象、Session 对象和 IWindow对象,一个 WindowState 对象就对应着一个应用进程中的 Window 对象; IWindow -> ViewRootImpl.W extends IWindow.Stub
WindowManagerService.addWindowToken 1 2 3 4 5 6 7 8 9 10 11 12 final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<>(); public void addWindowToken(IBinder token, int type) { synchronized(mWindowMap) { WindowToken wtoken = mTokenMap.get(token); wtoken = new WindowToken(this, token, type, true); mTokenMap.put(token, wtoken); if (type == TYPE_WALLPAPER) { mWallpaperTokens.add(wtoken); } } }
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 class WindowState extends WindowContainer<WindowState> implements WindowManagerPolicy.WindowState { final WindowManagerService mService; // WMS final WindowManagerPolicy mPolicy; // WMP final Context mContext; //ctx final Session mSession; // session final IWindow mClient; // 应用进程中的 Window 对象 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, int ownerId, boolean ownerCanAddInternalSystemWindow) { mService = service; mSession = s; mClient = c; mAppOp = appOp; mToken = token; mAppToken = mToken.asAppWindowToken(); ...... } void attach() { mSession.windowAddedLocked(mAttrs.packageName); } } // IWindow mClient 就是 ViewRootImpl 中的 final W mWindow 成员 public final class ViewRootImpl implements ViewParent, View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks { final W mWindow; static class W extends IWindow.Stub { ...... } }
WindowToken
WMS成员变量mTokenMap: 保存所有的WindowToken对象; 以IBinder为key,可以是IAppWindowToken或者其他Binder的Bp端;IBinder -> ActivityRecord.Token extends IApplicationToken.Stub
一个 WindowToken 就代表着一个应用组件,应用组件包括:Activity、InputMethod 等。在 WMS 中,会将属于同一 WindowToken 的做统一处理,比如在对窗口进行 ZOrder 排序时,会将属于统一 WindowToken 的排在一起
WindowToken 也具有令牌的作用。应用组件在创建 Window 时都需要提供一个有效的 WindowToken 以表明自己的身份,并且窗口的类型必须与所持有的 WindowToken 类型保持一致。
WMS.mTokenMap相关 1 2 3 4 5 6 7 8 9 10 11 12 final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<>(); public void addWindowToken(IBinder token, int type) { synchronized(mWindowMap) { WindowToken wtoken = mTokenMap.get(token); wtoken = new WindowToken(this, token, type, true); mTokenMap.put(token, wtoken); if (type == TYPE_WALLPAPER) { mWallpaperTokens.add(wtoken); } } }
推荐阅读:图形系统总结 参考:WMS—启动过程