本文主要是基于android10.0.0来讲述下WMS的启动流程
1:概述
WMS作为系统的一个关键服务其是在SystemServer.java::startOtherServices中启动的
WMS主要有下面几个作用
1:应用程序通过WMS向SurfaceFinger申请surface,surface代表的是绘图表面,应用程序绘制都必须在绘图表面上
2:管理窗口的层级,一个窗口一般在WMS端都是一个WindowState,其是有层级区分的,其有baseLayer和subLayer两个值共同确定
3:窗口动画:WindowAnimator
2:WMS的启动
2.1:WindowManagerService.java的创建
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);//taskManager对象
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
mActivityManagerService.setWindowManager(wm);//ams持有wms对象
wm.onInitReady();//准备初始化
其中上面有一个比较重要的对象PhoneWindowManager,主要是负责窗口管理的各种策略
2.2:WindowManagerService.java::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);//调用的内部的main方法
}
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);//wms是运行在android.display线程
return sInstance;
}
2.3:WindowManagerService
private WindowManagerService(Context context, InputManagerService inputManager,
boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
installLock(this, INDEX_WINDOW);
mGlobalLock = atm.getGlobalLock();
mAtmService = atm;
mContext = context;
mAllowBootMessages = showBootMsgs;
mOnlyCore = onlyCore;
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
mHasPermanentDpad = context.getResources().getBoolean(
com.android.internal.R.bool.config_hasPermanentDpad);
mInTouchMode = context.getResources().getBoolean(
com.android.internal.R.bool.config_defaultInTouchMode);
mDrawLockTimeoutMillis = context.getResources().getInteger(
com.android.internal.R.integer.config_drawLockTimeoutMillis);
mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
mMaxUiWidth = context.getResources().getInteger(
com.android.internal.R.integer.config_maxUiWidth);
mDisableTransitionAnimation = context.getResources().getBoolean(
com.android.internal.R.bool.config_disableTransitionAnimation);
mPerDisplayFocusEnabled = context.getResources().getBoolean(
com.android.internal.R.bool.config_perDisplayFocusEnabled);
mLowRamTaskSnapshotsAndRecents = context.getResources().getBoolean(
com.android.internal.R.bool.config_lowRamTaskSnapshotsAndRecents);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mDisplayWindowSettings = new DisplayWindowSettings(this);
mTransactionFactory = transactionFactory;
mTransaction = mTransactionFactory.make();
mPolicy = policy;
mAnimator = new WindowAnimator(this);//窗口动画,管理系统里所有的动画
mRoot = new RootWindowContainer(this);//总管家,对应于ActivityDisplay,用来管理DisplayContent
mWindowPlacerLocked = new WindowSurfacePlacer(this);
mTaskSnapshotController = new TaskSnapshotController(this);
mWindowTracing = WindowTracing.createDefaultAndStartLooper(this,
Choreographer.getInstance());
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
mKeyguardDisableHandler = KeyguardDisableHandler.create(mContext, mPolicy, mH);
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
if (mPowerManagerInternal != null) {//电源管理相关的服务
mPowerManagerInternal.registerLowPowerModeObserver(
new PowerManagerInternal.LowPowerModeListener() {//注册监听
@Override
public int getServiceType() {
return ServiceType.ANIMATION;
}
@Override
public void onLowPowerModeChanged(PowerSaveState result) {
synchronized (mGlobalLock) {//低电量模式
final boolean enabled = result.batterySaverEnabled;
if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {
mAnimationsDisabled = enabled;
dispatchNewAnimatorScaleLocked(null);
}
}
}
});
mAnimationsDisabled = mPowerManagerInternal
.getLowPowerState(ServiceType.ANIMATION).batterySaverEnabled;
}
mScreenFrozenLock = mPowerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
mScreenFrozenLock.setReferenceCounted(false);
mActivityManager = ActivityManager.getService();
mActivityTaskManager = ActivityTaskManager.getService();
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
AppOpsManager.OnOpChangedInternalListener opListener =
new AppOpsManager.OnOpChangedInternalListener() {
@Override public void onOpChanged(int op, String packageName) {
updateAppOpsState();
}
};
mAppOps.startWatchingMode(OP_SYSTEM_ALERT_WINDOW, null, opListener);
mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener);
mPmInternal = LocalServices.getService(PackageManagerInternal.class);
final IntentFilter suspendPackagesFilter = new IntentFilter();
suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
context.registerReceiverAsUser(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String[] affectedPackages =
intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
final boolean suspended =
Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction());
updateHiddenWhileSuspendedState(new ArraySet<>(Arrays.asList(affectedPackages)),
suspended);
}
}, UserHandle.ALL, suspendPackagesFilter, null, null);
final ContentResolver resolver = context.getContentResolver();
// Get persisted window scale setting
mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver,
Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);//窗口动画缩放的比例
mTransitionAnimationScaleSetting = Settings.Global.getFloat(resolver,
Settings.Global.TRANSITION_ANIMATION_SCALE,
context.getResources().getFloat(
R.dimen.config_appTransitionAnimationDurationScaleDefault));
setAnimatorDurationScale(Settings.Global.getFloat(resolver,
Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));//动画时长缩放比例
mForceDesktopModeOnExternalDisplays = Settings.Global.getInt(resolver,
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
IntentFilter filter = new IntentFilter();
// Track changes to DevicePolicyManager state so we can enable/disable keyguard.
filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
mLatencyTracker = LatencyTracker.getInstance(context);
mSettingsObserver = new SettingsObserver();
mHoldingScreenWakeLock = mPowerManager.newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);
mHoldingScreenWakeLock.setReferenceCounted(false);
mSurfaceAnimationRunner = new SurfaceAnimationRunner(mPowerManagerInternal);
mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
mTaskPositioningController = new TaskPositioningController(
this, mInputManager, mActivityTaskManager, mH.getLooper());
mDragDropController = new DragDropController(this, mH.getLooper());
mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
mSystemGestureExcludedByPreQStickyImmersive =
DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
new HandlerExecutor(mH), properties -> {
synchronized (mGlobalLock) {
final int exclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
properties.getInt(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
final boolean excludedByPreQSticky = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
if (mSystemGestureExcludedByPreQStickyImmersive != excludedByPreQSticky
|| mSystemGestureExclusionLimitDp != exclusionLimitDp) {
mSystemGestureExclusionLimitDp = exclusionLimitDp;
mSystemGestureExcludedByPreQStickyImmersive = excludedByPreQSticky;
mRoot.forAllDisplays(DisplayContent::updateSystemGestureExclusionLimit);
}
}
});
LocalServices.addService(WindowManagerInternal.class, new LocalService());
}
2.3.1:PhoneWindowManager的初始化
traceBeginAndSlog("WindowManagerServiceOnInitReady");
wm.onInitReady();
traceEnd();
public void onInitReady() {
initPolicy();
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);//watchdog机制,添加一个监视锁
openSurfaceTransaction();
try {
createWatermarkInTransaction();
} finally {
closeSurfaceTransaction("createWatermarkInTransaction");
}
showEmulatorDisplayOverlayIfNeeded();
}
private void initPolicy() {
UiThread.getHandler().runWithScissors(new Runnable() {
@Override
public void run() {
WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);//运行在android.ui线程
}
}, 0);
}
2.3.2:PhoneWindowManager::init
public void init(Context context, IWindowManager windowManager,
WindowManagerFuncs windowManagerFuncs) {
mContext = context;
mWindowManager = windowManager;
mWindowManagerFuncs = windowManagerFuncs;
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
mHandler = new PolicyHandler();
mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
mShortcutManager = new ShortcutManager(context);
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"PhoneWindowManager.mBroadcastWakeLock");
mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"PhoneWindowManager.mPowerKeyWakeLock");
mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
mAllowStartActivityForLongPressOnPowerDuringSetup =
readConfigurationDependentBehaviors();
if (mLidControlsDisplayFold) {
mDisplayFoldController = DisplayFoldController.create(context, DEFAULT_DISPLAY);
} else if (SystemProperties.getBoolean("persist.debug.force_foldable", false)) {
mDisplayFoldController = DisplayFoldController.createWithProxSensor(context,
DEFAULT_DISPLAY);
}
mAccessibilityManager = (AccessibilityManager) context.getSystemService(
Context.ACCESSIBILITY_SERVICE);
// register for dock events
.............................................
mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
@Override
public int onAppTransitionStartingLocked(int transit, long duration,
long statusBarAnimationStartTime, long statusBarAnimationDuration) {
return handleStartTransitionForKeyguardLw(transit, duration);
}
@Override
public void onAppTransitionCancelledLocked(int transit) {
handleStartTransitionForKeyguardLw(transit, 0 /* duration */);
}
});
mKeyguardDelegate = new KeyguardServiceDelegate(mContext,
new StateCallback() {
@Override
public void onTrustedChanged() {
mWindowManagerFuncs.notifyKeyguardTrustedChanged();
}
@Override
public void onShowingChanged() {
mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged();
}
});
}
2.4:WindowManagerService::displayReady
traceBeginAndSlog("MakeDisplayReady");
try {
wm.displayReady();
} catch (Throwable e) {
reportWtf("making display ready", e);
}
traceEnd();
public void displayReady() {
synchronized (mGlobalLock) {
if (mMaxUiWidth > 0) {
mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
}
final boolean changed = applyForcedPropertiesForDefaultDisplay();
mAnimator.ready();//WindowAnimator
mDisplayReady = true;
if (changed) {
reconfigureDisplayLocked(getDefaultDisplayContentLocked());
}
mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TOUCHSCREEN);
}
try {
mActivityTaskManager.updateConfiguration(null);
} catch (RemoteException e) {
}
updateCircularDisplayMaskIfNeeded();
}
2.5:WindowManagerService::systemReady
traceBeginAndSlog("MakeWindowManagerServiceReady");
try {
wm.systemReady();
} catch (Throwable e) {
reportWtf("making Window Manager Service ready", e);
}
traceEnd();
public void systemReady() {
mSystemReady = true;
mPolicy.systemReady();//PhoneWindowManager对象
mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
mTaskSnapshotController.systemReady();
mHasWideColorGamutSupport = queryWideColorGamutSupport();
mHasHdrSupport = queryHdrSupport();
UiThread.getHandler().post(mSettingsObserver::updateSystemUiSettings);
UiThread.getHandler().post(mSettingsObserver::updatePointerLocation);
IVrManager vrManager = IVrManager.Stub.asInterface(
ServiceManager.getService(Context.VR_SERVICE));
if (vrManager != null) {
try {
final boolean vrModeEnabled = vrManager.getVrModeState();
synchronized (mGlobalLock) {
vrManager.registerListener(mVrStateCallbacks);
if (vrModeEnabled) {
mVrModeEnabled = vrModeEnabled;
mVrStateCallbacks.onVrStateChanged(vrModeEnabled);
}
}
} catch (RemoteException e) {
// Ignore, we cannot do anything if we failed to register VR mode listener
}
}
}
2.6:PhoneWindowManager.java::systemReady
public void systemReady() {
// In normal flow, systemReady is called before other system services are ready.
// So it is better not to bind keyguard here.
mKeyguardDelegate.onSystemReady();//keyguard
mVrManagerInternal = LocalServices.getService(VrManagerInternal.class);
if (mVrManagerInternal != null) {
mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
}
readCameraLensCoverState();
updateUiMode();
mDefaultDisplayRotation.updateOrientationListener();
synchronized (mLock) {
mSystemReady = true;
mHandler.post(new Runnable() {
@Override
public void run() {
updateSettings();
}
});
// If this happens, for whatever reason, systemReady came later than systemBooted.
// And keyguard should be already bound from systemBooted
if (mSystemBooted) {
mKeyguardDelegate.onBootCompleted();
}
}
mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
}
2.7:WindowManagerService.java中重要的变量
WindowManagerPolicy mPolicy;---------------->对应的实现类PhoneWindowManager,主要是窗口管理的策略和按键的处理
final ActivityManagerInternal mAmInternal;------>对应的是AMS,持有AMS对象
final ActivityTaskManagerInternal mAtmInternal;--->管理Task的,android10.0新增
final ArraySet<Session> mSessions = new ArraySet<>();---->会话,主要是建立和surfaceFinger的连接
final WindowHashMap mWindowMap = new WindowHashMap();---->缓存windowstate
AMS,WMS之间数据是对应的,通过token值可以在AMS,WMS,应用程序之后来唯一确定一组Window,token是关联着一组窗口的,可能有多个WindowState的token值是相同的
3:小结
整个启动过程涉及3个线程: system_server主线程, “android.display”, “android.ui”, 整个过程是采用阻塞方式(利用Handler.runWithScissors)执行的. 其中WindowManagerService.mH的Looper运行在 “android.display”进程,也就意味着WMS.H.handleMessage()在该线程执行。