1.SystemServer:启动WindowManagerService
public static WindowManagerService main(final Context context,
final PowerManagerService pm, final DisplayManagerService dm,
final InputManagerService im, final Handler wmHandler,
final boolean haveInputMethods, final boolean showBootMsgs,
final boolean onlyCore) {
final WindowManagerService[] holder = new WindowManagerService[1];
wmHandler.runWithScissors(new Runnable() {
@Override
public void run() {
holder[0] = new WindowManagerService(context, pm, dm, im,
haveInputMethods, showBootMsgs, onlyCore);
}
}, 0);
return holder[0];
}
2.WindowManagerService的初始化
private WindowManagerService(Context context, PowerManagerService pm,
DisplayManagerService displayManager, InputManagerService inputManager,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
mContext = context;
mHaveInputMethods = haveInputMethods;
mAllowBootMessages = showBootMsgs;
mOnlyCore = onlyCore;
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
/* 得到InputManagerService。输入事件最终要分发给具有焦点的窗口,由WMS负责与IMS交互
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerService = displayManager;
mHeadless = displayManager.isHeadless();
mDisplaySettings = new DisplaySettings(context);
mDisplaySettings.readSettingsLocked();
mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
mFxSession = new SurfaceSession();
/* 初始化DisplayContent列表。DisplayContent是Android4.2为支持多屏幕输出所引入的一个
概念。一个DisplayContent指代一块屏幕,屏幕可以是手机自身的屏幕,也可以是基于Wi-FiDisplay
技术的虚拟屏幕[3]*/
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.registerDisplayListener(this, null);
Display[] displays = mDisplayManager.getDisplays();
for (Display display : displays) {
createDisplayContentLocked(display);
}
mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
/* 电源管理模块当有关屏亮屏动作的时候,需要WindowManagerPolicy去做相关的系统UI显示动作 */
mPowerManager = pm;
mPowerManager.setPolicy(mPolicy);
PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, “SCREEN_FROZEN”);
mScreenFrozenLock.setReferenceCounted(false);
mAppTransition = new AppTransition(context, mH);
mActivityManager = ActivityManagerNative.getDefault();
mBatteryStats = BatteryStatsService.getService();
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null,
new AppOpsManager.OnOpChangedInternalListener() {
@Override
public void onOpChanged(int op, String packageName) {
updateAppOpsState();
}
}
);
// 初始化全局系统设置的窗口切换动画的值
mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale));
// Track changes to DevicePolicyManager state so we can enable/disable keyguard.
IntentFilter filter = new IntentFilter();
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
filter.addAction(“jidou.app.action.AUTO_REBOOT”);
mContext.registerReceiver(mBroadcastReceiver, filter);
mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE, TAG);
mHoldingScreenWakeLock.setReferenceCounted(false);
//管理窗口动画对象
mAnimator = new WindowAnimator(this);
//实例化WindowManagerPolicy,实际就是初始化PhoneWindowManager
initPolicy(UiThread.getHandler());
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
SurfaceControl.openTransaction();
try {
createWatermarkInTransaction();
mFocusedStackFrame = new FocusedStackFrame(
getDefaultDisplayContentLocked().getDisplay(), mFxSession);
} finally {
SurfaceControl.closeTransaction();
}
}
3.初始化PhoneWindowManager
①.WindowManagerService对象创建的时候会通过PolicyManager的静态方法makeNewWindowManager()得到类型为IPolicy的mPolicy全局变量;
②.在PolicyManager类加载中,会通过反射的方式创建类型为IPolicy的 sPolicy对象,
③ IPolicy是一个接口文件,具体实现在为framework/base/policy/src/com/android/internal/policy/impl/Policy.java类,所以最终PolicyManager.makeNewWindowManager() 调用的就是Policy中的makeNewWindowManager(),返回的是一个PhoneWindowManager对象。
④ initPolicy方法所做的动作就是执行PhoneWindowManager中的init方法,做一些对象初始化动作,以及广播的监听,配置参数读取等。
4.PhoneWindowManager初始化完成之后,继续回来WindowManagerServivce中,相继执行displayReady(),systemReady()两个函数,然后等待客户端请求添加窗口。
5.接下来开始添加系统窗口,以添加NavigationBar为例,在SystemServer中,资源加载完成后,启动系统级应用SystemUI
SystemUI中有众多的组件,继承自SystemUI.java抽象类,这里不再赘述,我直接查找NavigationBar的创建流程。
①.SystemUIService在其生命周期的onCreate函数中,通过反射的方式,创建SystemBars组件的对象,然后调用其start()方法
②.在SystemBars的start方法中,实例化ServiceMonitor,并调用它的start()方法,最终会走到SystemBars中onNoService中,通过反射的方式,初始化父类为BaseStatusBar的PhoneStatusBar对象,然后执行该对象的start()方法。
③.在PhoneStatusBar中,添加NavigationBar的逻辑代码片段
//配置NavigationBar视图
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
mNavigationBarView.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//…..
}
//设置NavigationBar的窗口信息
private WindowManager.LayoutParams getNavigationBarLayoutParams() {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
0
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
// this will allow the navbar to run in an overlay on devices that support this
if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
lp.setTitle(“NavigationBar”);
lp.windowAnimations = 0;
return lp;
}
private void addNavigationBar() {
if (DEBUG) Log.v(TAG, “addNavigationBar: about to add ” + mNavigationBarView);
if (mNavigationBarView == null) return;
prepareNavigationBarView();
if (mNavigationBarView.isAttachedToWindow()) return;
mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
}
分析代码可知,NavigationBar是一个类型为WindowManager.LayoutParams.TYPE_NAVIGATION_BAR的视图窗口,通过WindowManager添加到视图系统中。
④继续走,mWindowManager是在BaseStatusBar中初始化的,通过源码跟踪,我们发现得到的其实为WindowManagerImpl.java,
//在源码core/java/android/app/ContextImpl.java中
registerService(WINDOW_SERVICE, new ServiceFetcher() {
Display mDefaultDisplay;
public Object getService(ContextImpl ctx) {
Display display = ctx.mDisplay;
if (display == null) {
if (mDefaultDisplay == null) {
DisplayManager dm = (DisplayManager)ctx.getOuterContext().
getSystemService(Context.DISPLAY_SERVICE);
mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
}
display = mDefaultDisplay;
}
return new WindowManagerImpl(display);
}});
所以mWindowManager.addView相当于执行了如下代码。
public void addView(View view, ViewGroup.LayoutParams params) {
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
这里的mDisplay为默认的,mParentWindow对象为NULL。
mGlobal为WindowManagerGlobal对象的实例,于是添加视图走到了该类的addView方法中,代码如下:
public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) {
if (view == null) { //不允许添加空对象的视图
throw new IllegalArgumentException(“view must not be null”);
}
if (display == null) {
throw new IllegalArgumentException(“display must not be null”);
}
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException(“Params must be WindowManager.LayoutParams”);
}
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
if (parentWindow != null) { //添加NavigationBar时,这里我们的parentWindow是为空
parentWindow.adjustLayoutParamsForSubWindow(wparams);
}
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
// Start watching for system property changes.
if (mSystemPropertyUpdater == null) {
mSystemPropertyUpdater = new Runnable() {
@Override public void run() {
synchronized (mLock) {
for (int i = mRoots.size() – 1; i >= 0; –i) {
mRoots.get(i).loadSystemProperties();
}
}
}
};
SystemProperties.addChangeCallback(mSystemPropertyUpdater);
}
int index = findViewLocked(view, false);
if (index >= 0) {
if (mDyingViews.contains(view)) {
// Don’t wait for MSG_DIE to make it’s way through root’s queue.
mRoots.get(index).doDie();
} else {
throw new IllegalStateException(“View ” + view
+ ” has already been added to the window manager.”);
}
// The previous removeView() had not completed executing. Now it has.
}
// If this is a panel window, then find the window it is being
// attached to for future reference.
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
final int count = mViews.size();
for (int i = 0; i < count; i++) {
if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
panelParentView = mViews.get(i);
}
}
}
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
}
// do this last because it fires off messages to start doing things
try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
synchronized (mLock) {
final int index = findViewLocked(view, false);
if (index >= 0) {
removeViewLocked(index, true);
}
}
throw e;
}
}
⑤ 这里创建一个ViewRootImlp对象,然后调用了它的setView方法,传递三个参数,一个正在添加的视图view,一个视图的相关参数,一个父类容器view,这里为空
⑥ 接着往下,可以看到setView中,有这样一句话
//…….
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mInputChannel);
} catch (RemoteException e) {
mAdded = false;
mView = null;
mAttachInfo.mRootView = null;
mInputChannel = null;
mFallbackEventHandler.setView(null);
unscheduleTraversals();
setAccessibilityFocus(null, null);
throw new RuntimeException(“Adding window failed”, e);
} finally {
if (restore) {
attrs.restore();
}
}
//…….
⑦ mWindowSession.addToDisplay实际就是调用了Session.java中的addToDisplay,
@Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets,
InputChannel outInputChannel) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
outContentInsets, outInputChannel);
}
最终addToDisplay被执行到了WindowManagerService的addWindow函数中