一 概述
在 Android 系统中,从设计的角度来看,窗口管理系统是基于 C/S 模式的。整个窗口系统分为服务端和客户端两大部分,客户端负责请求创建窗口和使用窗口,服务端完成窗口的维护,窗口显示等。
在 Client 端,并不是直接和 WindowManagerService 交互,而是直接和本地对象 WindowManager 交互,然后由 WindowManager 完成和 WindowManagerService 的交互。对于 Android 应用来说这个交互是透明的,应用感觉不到 WindowManagerService 的存在。本篇文章我们来介绍窗口管理服务 WindowManagerService 的启动过程。
1.1 WMS全貌
1.2 WMS功能
窗口管理
WMS 是窗口的管理者,它负责窗口的启动、添加和删除,另外窗口的大小和层级也是由 WMS 进行管理的。窗口管理的核心成员有 DisplayContent、WindowToken 和 WindowState。
窗口动画
窗口间进行切换时,使用窗口动画可以显得更炫一些,窗口动画由 WMS 的动画子系统来负责,动画子系统的管理者为 WindowAnimator。
输入系统的中转站
通过对窗口的触摸从而产生触摸事件,InputManagerService(IMS)会对触摸事件进行处理,它会寻找一个最合适的窗口来处理触摸反馈信息,WMS 是窗口的管理者,因此,WMS “理所应当” 的成为了输入系统的中转站。
Surface管理
窗口并不具备有绘制的功能,因此每个窗口都需要有一块 Surface 来供自己绘制。为每个窗口分配 Surface 是由 WMS 来完成的。
WMS 的职责可以简单总结为下图。
1.3 WMS重要成员
说明:
- WMS
继承于 IWindowManager.Stub,作为 Binder 服务端 - mSessions
ArraySet 类型的变量,元素类型为 Session,保存着所有的 Session 对象,Session 继承于 IWindowSession.Stub,作为 Binder 服务端,它主要用于进程间通信,其他的应用程序进程想要和 WMS 进程进行通信就需要经过 Session,并且每个应用程序进程都会对应一个Session,WMS 保存这些 Session 用来记录所有向 WMS 提出窗口管理服务的客户端。 - mPolicy
WindowManagerPolicy 类型的变量,是窗口管理策略的接口类,用来定义一个窗口策略所要遵循的通用规范,并提供了 WindowManager 所有的特定的 UI 行为。具体实现类为 PhoneWindowManager,这个实现类在 WMS 创建时被创建。WMP 允许定制窗口层级和特殊窗口类型以及关键的调度和布局。 - DisplayContent 的成员变量 mTokenMap,保存所有的 WindowToken 对象,以 IBinder 为 key,可以是 IAppWindowToken 或者其他 Binder 的 Bp 端;另一端情况:ActivityRecord.Token extends IApplicationToken.Stub
- mWindowMap
WindowHashMap 类型的变量,WindowHashMap 继承了 HashMap,它限制了 HashMap 的 key 值的类型为 IBinder,value 值的类型为 WindowState。保存 WMS 中所有的 WindowState 对象 - mResizingWindows
ArrayList 类型的变量,元素类型为 WindowState。mResizingWindows 是用来存储正在调整大小的窗口的列表。 - mAnimator
WindowAnimator 类型的变量,用于管理窗口的动画以及特效动画。 - mH
H 类型的变量,系统的 Handler 类,用于将任务加入到主线程的消息队列中,这样代码逻辑就会在主线程中执行。
涉及代码如下:
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
frameworks/base/services/core/java/com/android/server/DisplayThread.java
frameworks/base/services/core/java/com/android/server/wm/WindowState.java
frameworks/base/services/core/java/com/android/server/wm/AppWindowToken.java
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
frameworks/base/services/core/java/com/android/server/policy/WindowManagerPolicy.java
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
frameworks/base/services/core/java/com/android/server/wm/WindowAnimator.java
frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java
frameworks/base/services/core/java/com/android/server/wm/TaskPositioningController.java
frameworks/base/services/core/java/com/android/server/wm/DragDropController.java
二 SystemServer
frameworks/base/services/java/com/android/server/SystemServer.java
2.1 main
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
......
// 初始化系统上下文
createSystemContext();
// 初始化SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
......
// 启动相互依赖关系复杂的服务
startBootstrapServices();
// 启动相互独立的基本服务
startCoreServices();
// 启动其他服务
startOtherServices();
......
}
2.2 startOtherServices
private void startOtherServices() {
// 启动WMS前, 需要先启动SensorService
ConcurrentUtils.waitForFutureNoInterrupt(
mSensorServiceStart, START_SENSOR_SERVICE);
mSensorServiceStart = null;
WindowManagerService wm = WindowManagerService.main(context,
inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(),
mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
......
// 所有WMS相关的实体对象初始化完成
wm.onInitReady();
......
// Display ready
wm.displayReady();
......
// WMS ready
wm.systemReady();
......
final WindowManagerService windowManagerF = wm;
// 启动SystemUIService服务
startSystemUi(context, windowManagerF);
......
}
private static void startSystemUi(Context context,
WindowManagerService windowManager) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
// System UI已启动
windowManager.onSystemUiStarted();
}
三 WindowManagerService
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
3.1 组成元素
// ActivityTaskManager服务相关
// 管理Activity和其容器(如task/stacks/displays)的系统服务
final IActivityTaskManager mActivityTaskManager;
final ActivityTaskManagerService mAtmService;
// DisplayManager服务相关, 管理Display属性
final DisplayManagerInternal mDisplayManagerInternal;
final DisplayManager mDisplayManager;
final DisplayWindowSettings mDisplayWindowSettings;
// ActivityManager服务相关, 用于和四大组件交互
final IActivityManager mActivityManager;
final ActivityManagerInternal mAmInternal;
// PowerManager服务相关, 管理电源状态
PowerManager mPowerManager;
PowerManagerInternal mPowerManagerInternal;
// 输入管理服务
final InputManagerService mInputManager;
// 包管理本地系统服务
final PackageManagerInternal mPmInternal;
// 根窗口容器
RootWindowContainer mRoot;
// 提供UI相关行为的策略类, 其实现类为PhoneWindowManager
WindowManagerPolicy mPolicy;
// 在一个单独的task中执行动画和Surface操作的类
final WindowAnimator mAnimator;
// 用来确定Window和Surface位置的类
final WindowSurfacePlacer mWindowPlacerLocked;
// 任务快照管理器(当App不可见时, 会将Task的快照以Bitmap形式存在缓存中)
final TaskSnapshotController mTaskSnapshotController;
// Task定位控制器
final TaskPositioningController mTaskPositioningController;
// View的拖/拉操作控制器
final DragDropController mDragDropController;
// 当前活跃状态的Session连接队列(通常一个进程中包含一个Session, 用于和WindowManager交互)
final ArraySet<Session> mSessions = new ArraySet<>();
// <IBinder, WindowState>客户端Window token和服务端WindowState的映射
final WindowHashMap mWindowMap = new WindowHashMap();
// AppWindowToken是一个窗口容器类, 可以理解为正在显示Window的App
// 或Activity的窗口令牌(继承于WindowToken)
// replace超时的AppWindowToken令牌列表
final ArrayList<AppWindowToken> mWindowReplacementTimeouts = new ArrayList<>();
// WindowState表示服务端描述的Window
final ArrayList<WindowState> mResizingWindows = new ArrayList<>();
final ArrayList<WindowState> mPendingRemove = new ArrayList<>();
final ArrayList<WindowState> mDestroySurface = new ArrayList<>();
final ArrayList<WindowState> mDestroyPreservedSurface = new ArrayList<>();
final ArrayList<WindowState> mForceRemoves = new ArrayList<>();
ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>();
private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<>();
WindowState[] mPendingRemoveTmp = new WindowState[20];
// 主线程Handler
final H mH = new H();
3.2 启动过程
3.2.1 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);
}
public static WindowManagerService main(final Context context,
final InputManagerService im, final boolean showBootMsgs,
final boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
//运行在"android.display"线程
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, showBootMsgs,
onlyCore, policy, atm, transactionFactory), 0);
return sInstance;
}
在 “android.display” 线程中执行 WindowManagerService 对象的初始化过程,其中 final H mH = new H();此处 H 继承于 Handler,无参初始化的过程,便会采用当前所在线程的 Looper。那就是说WindowManagerService.H.handleMessage() 方法运行在 “android.display” 线程。
3.2.2 Handler.runWithScissors
Handler.java
public final boolean runWithScissors(final Runnable r, long timeout) {
//当前线程跟当前Handler都指向同一个Looper,则直接运行
if (Looper.myLooper() == mLooper) {
r.run();
return true;
}
BlockingRunnable br = new BlockingRunnable(r);
return br.postAndWait(this, timeout);
}
3.2.3 postAndWait
Handler.java ::BlockingRunnable
private static final class BlockingRunnable implements Runnable {
private final Runnable mTask;
private boolean mDone;
public BlockingRunnable(Runnable task) {
mTask = task;
}
public void run() {
try {
mTask.run();
} finally {
synchronized (this) {
mDone = true;
notifyAll();
}
}
}
public boolean postAndWait(Handler handler, long timeout) {
if (!handler.post(this)) {
return false;
}
synchronized (this) {
if (timeout > 0) {
final long expirationTime = SystemClock.uptimeMillis() + timeout;
while (!mDone) {
long delay = expirationTime - SystemClock.uptimeMillis();
if (delay <= 0) {
return false; // timeout
}
try {
wait(delay);
} catch (InterruptedException ex) {
}
}
} else {
while (!mDone) {
try {
wait();
} catch (InterruptedException ex) {
}
}
}
}
return true;
}
}
由此可见,BlockingRunnable.postAndWait() 方法是阻塞操作,就是先将消息放入 Handler 所指向的线程,此处是指 ”android.display” 线程,由于该方法本身运行在 system_server 主线程。也就意味着 system_server 主线程会进入等待状态,直到 handler 线程执行完成后再唤醒 system_server 主线程。所以在 WindowManagerService 启动完成之后,SystemServer 主线程才能继续往下走。
WMS 所在的线程就是 DisplayThread 这个显示线程,这个线程不仅被 WMS 使用,DisplayManagerService、InputManagerService 也会使用。当实例化 WindowManagerService 时,它的成员变量 mH 就与 DisplayThread 产生了关联,后期可以通过 mH 这个 handler 投递事件到 DisplayThread 的 looper 队列中。mH 是 WMS 的内部类 final class H extends Handler {}。
3.2.4 构造方法
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);
......
mInputManager = inputManager;
mDisplayManagerInternal =
LocalServices.getService(DisplayManagerInternal.class);
// Display设置
mDisplayWindowSettings = new DisplayWindowSettings(this);
mTransactionFactory = transactionFactory;
mTransaction = mTransactionFactory.make();
//PhoneWindowManager(继承于WindowManagerPolicy, 用来提供UI相关的一些行为)
mPolicy = policy;
// 在一个单独的task中执行动画和Surface操作的类
mAnimator = new WindowAnimator(this);
// 根Window容器
mRoot = new RootWindowContainer(this);
// 用来确定Window和Surface的位置
mWindowPlacerLocked = new WindowSurfacePlacer(this);
// 任务快照管理器(当App不可见时, 会将Task的快照以Bitmap形式存在缓存中)
mTaskSnapshotController = new TaskSnapshotController(this);
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
mDisplayManager =
(DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
// Keyguard处理器
mKeyguardDisableHandler =
KeyguardDisableHandler.create(mContext, mPolicy, mH);
// PowerManager是控制设备电池状态的管理器
mPowerManager =
(PowerManager)context.getSystemService(Context.POWER_SERVICE);
// PowerManagerInternal是PowerMananger的本地服务
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);
// 获取IActivity.Stub.Proxy(new BinderProxy())
mActivityManager = ActivityManager.getService();
// 获取IActivityTaskManager.Stub.Proxy
mActivityTaskManager = ActivityTaskManager.getService();
// ActivityManagerInternal是ActivityManager的本地服务
mAmInternal =
LocalServices.getService(ActivityManagerInternal.class);
// ActivityTaskManagerInternal是ActivityTaskManager的本地服务
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);
// PackageManagerInternal是PackageManager的本地服务
mPmInternal = LocalServices.getService(PackageManagerInternal.class);
// 注册Package suspend/unsuspend广播
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);
// 获取并设置window scale设置
final ContentResolver resolver = context.getContentResolver();
mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver,
Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
......
// 注册广播, 当DevicePolicyManager状态发生变化时设置keyguard属性是否可用
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiverAsUser(mBroadcastReceiver,
UserHandle.ALL, filter, null, null);
mLatencyTracker = LatencyTracker.getInstance(context);
mSettingsObserver = new SettingsObserver();
......
mSurfaceAnimationRunner = new SurfaceAnimationRunner(mPowerManagerInternal);
mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
// Task定位控制器
mTaskPositioningController = new TaskPositioningController(this,
mInputManager, mActivityTaskManager, mH.getLooper());
// View的拖/拉操作控制器
mDragDropController = new DragDropController(this, mH.getLooper());
......
// 注册WindowManager的本地服务WindowManagerInternal
LocalServices.addService(WindowManagerInternal.class, new LocalService());
}
3.2.5 onInitReady
public void onInitReady() {
// 初始化PhoneWindowManager
initPolicy();
// 添加Watchdog monitor
Watchdog.getInstance().addMonitor(this);
// 调用SurfaceControl.openTransaction(), 启动一个事务
openSurfaceTransaction();
// 创建水印
createWatermarkInTransaction();
// 结束事务
closeSurfaceTransaction("createWatermarkInTransaction");
// 显示模拟器显示层
showEmulatorDisplayOverlayIfNeeded();
}
3.2.6 initPolicy
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);
}
}, 0);
}
PhoneWindowManager 的初始化运行在 “android.ui” 线程。
3.2.7 displayReady
public void displayReady() {
synchronized (mGlobalLock) {
// 设置RootWindowContainer的Window列表的最大宽度
if (mMaxUiWidth > 0) {
mRoot.forAllDisplays(
displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
}
final boolean changed = applyForcedPropertiesForDefaultDisplay();
mAnimator.ready();
mDisplayReady = true;
if (changed) {
// 重新配置DiaplayContent属性
reconfigureDisplayLocked(getDefaultDisplayContentLocked());
}
mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TOUCHSCREEN);
}
// 1.修改当前configuration 2.确保当前Activity正在运行当前configuration
mActivityTaskManager.updateConfiguration(null);
// 更新CircularDisplayMask
updateCircularDisplayMaskIfNeeded();
}
3.2.8 systemReady
public void systemReady() {
mSystemReady = true;
mPolicy.systemReady();
mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
mTaskSnapshotController.systemReady();
// 是否支持色域
mHasWideColorGamutSupport = queryWideColorGamutSupport();
// 是否支持HDR渲染
mHasHdrSupport = queryHdrSupport();
UiThread.getHandler().post(mSettingsObserver::updateSystemUiSettings);
UiThread.getHandler().post(mSettingsObserver::updatePointerLocation);
// 获取IVrManager.Stub.Proxy, 并注册状态变化listener
IVrManager vrManager = IVrManager.Stub.asInterface(
ServiceManager.getService(Context.VR_SERVICE));
if (vrManager != null) {
final boolean vrModeEnabled = vrManager.getVrModeState();
synchronized (mGlobalLock) {
vrManager.registerListener(mVrStateCallbacks);
if (vrModeEnabled) {
mVrModeEnabled = vrModeEnabled;
mVrStateCallbacks.onVrStateChanged(vrModeEnabled);
}
}
}
}
3.3 主要功能
WMS 主要用于窗口的添加和移除操作,其对应的方法是 addWindow 和 removeWindow,关于窗口的添加和删除过程,放到后面文章去分析。
四 总结
整个启动过程涉及3个线程:system_server 主线程,“android.display”,“android.ui”,整个过程是采用阻塞方式(利用 Handler.runWithScissors) 执行的。其中 WindowManagerService.mH 的 Looper 运行在 “android.display” 进程,也就意味着 WMS.H.handleMessage() 在该线程执行。 流程如下: