携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
一、概述
我们知道WMS
是在system server进程中启动的。 zygote进程fork()出system server进程后,会进入到SystemServer.java
的 main()方法。 然后会调用其run()方法,最终调用 startOtherServices()
来启动WMS服务,具体流程可以看看system server启动篇
。
一、SystemServer.startOtherServices() 方法
SystemServer.java
private void startOtherServices() {
WindowManagerService wm = null;
//...
traceBeginAndSlog("StartWindowManagerService");
// WMS needs sensor service ready
ConcurentUtils.waitForFutureNoInterrupt
(mSensorServiceStart,
START_SENSOR_SERVICE);
mSensorServiceStart = null;
// 1 创建 WMS,传入了system上下文、一个 inputManager对象、一个PhoneWindowManager 对象、atm对象
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
// 2 发布 WMS到 SM
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
// 发布inputManagerService 到SM
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
traceEnd();
traceBeginAndSlog("SetWindowManagerService");
// 3 让AMS持有 WMS的引用 ,方便后续调用
mActivityManagerService.setWindowManager(wm);
|
traceBeginAndSlog("WindowManagerServiceOnInitReady");
// 4 回调WMS的 onInitReady()方法
wm.onInitReady();
traceEnd();
// 5 回调WMS的
wm.displayReady();
// 6 回调WMS的
wm.systemReady();
//...
}
只看WMS相关的部分。
- 创建 WMS对象。传入了system的上下文、inputManager对象、PhoneWindowManager对象、atm对象
- 把WMS和IMS加入到 ServiceManager进行管理
- 让
AMS
持有WMS
的引用,方便后续调用 - 回调WMS的 onInitReady()方法
- 回调WMS的displayReady()
- 回调WMS的systemReady()
1.1 WindowManagerService.main()方法
WindowManagerService.java
传入了system上下文、inputManagerService 对象、PhoneWindowManager对象、atm对象。
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);
}
在后面追加了一个 SurfaceControl.Transaction
对象。继续调用另一个main()方法。
SurfaceControl 通过long型的handler值,指向了native层的surface对象(该对象被系统合成器来管理)。SurfaceControl包含了buffer源数据,以及如何展示这个buffer的一些元数据。当从SurfaceControl构造出来一个surface对象,可以通过它提交buffer给系统合成器。通过 SurfaceControl.Transaction,可以调整buffer如何在屏幕上显示的参数。此外,SurfaceControl 也是一个树形结构,可能会有parent,因此像转换、裁剪、z轴等属性都会继承自父亲的约束。
1.2 main()
@VisibleForTesting
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
// runnable 提交到 DisplayThread 线程
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
atm, transactionFactory), 0);
return sInstance;
}
- 调用Handler的
runWithScissors()
方法,第二个参数0
表示立即执行。 WindowManagerPolicy policy:
实现类是 PhoneWindowManager 对象。- 创建一个WMS对象,并且返回该实例。
DisplayThread 给系统使用的共享单例前台线程类,线程名字为 android.display,专门提供给WindowManager, DisplayManager, and InputManager来执行快速响应的实时操作。
1.3 Handler.runWithScissors()
Handler.java
public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
if (r == null) {
throw new IllegalArgumentException("runnable must not be null");
}
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be non-negative");
}
// 如果当前looper与当前handler一样
if (Looper.myLooper() == mLooper) {
r.run();
return true;
}
// 不一样,则新建 BlockingRunnable对象
BlockingRunnable br = new BlockingRunnable(r);
return br.postAndWait(this, timeout);
}
如果线程不一致,则新建 BlockingRunnable
,post到 Handler的线程,调用wait()
进入等待,直到被唤醒。 注意,此时调用方线程是system server的主线程。创建WMS的代码需要执行在 android.display
线程。因此,不一致,继续看下面的逻辑。
1.3.1 BlockingRunnable
private static final class BlockingRunnable implements Runnable {
private final Runnable mTask;
private boolean mDone;
public BlockingRunnable(Runnable task) {
mTask = task;
}
@Override
public void run() {
try {
mTask.run();
} finally {
synchronized (this) {
mDone = true;
// 唤醒 system server主线程
notifyAll();
}
}
}
public boolean postAndWait(Handler handler, long timeout) {
// 把task放入 Android.display线程
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 {
// system server主线程进入等待
wait();
} catch (InterruptedException ex) {
}
}
}
}
return true;
}
}
system server主线程
进入 wait()
状态,等待唤醒。当android.display
线程run()方法执行完后,在finally中 notifyAll()
唤醒。
为什么要这么设计呢? 因为WMS作为非常重要的服务,必须要等它初始化完成,system server主线程才能进行下一步操作。
接下来,就可以看看WMS的构造方法了。
1.3.2 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);
//... 属性
mInputManager = inputManager; // Must be before createDisplayContentLocked.
// 获取本进程 display 服务
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mDisplayWindowSettings = new DisplayWindowSettings(this);
mTransactionFactory = transactionFactory;
mTransaction = mTransactionFactory.make();
// 是 PhoneWindowManager对象
mPolicy = policy;
// window窗口动画
mAnimator = new WindowAnimator(this);
// root 窗口容器??
mRoot = new RootWindowContainer(this);
// 窗口的surface占位?
mWindowPlacerLocked = new WindowSurfacePlacer(this);
mTaskSnapshotController = new TaskSnapshotController(this);
mWindowTracing = WindowTracing.createDefaultAndStartLooper(this,
Choreographer.getInstance());
// 添加本进程的 windowPolicy 服务
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
// 获取本系统 displayManager 服务
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);
// AMS ATM 服务
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);
// PMS服务
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);
//...
//加入到本进程,作为本地服务
LocalServices.addService(WindowManagerInternal.class, new LocalService());
}
总结:
初始化 display、了AMS、ATM、MPolicy等成员。mH 为 final H mH = new H()
成员变量,因此WMS后面的消息也是运行在 android.display
线程中的。
1.4 wm.onInitReady()
在AMS与WMS绑定后,就会调用该方法。 此时是system server的 主线程。
public void onInitReady() {
initPolicy();
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
openSurfaceTransaction();
try {
createWatermarkInTransaction();
} finally {
closeSurfaceTransaction("createWatermarkInTransaction");
}
showEmulatorDisplayOverlayIfNeeded();
}
1.4.1 WMS.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);
}
UiThread
也是系统的单例共享后台线程,名字为 android.ui
。 同理,此时system server的主线程也会 wait(),等 android.ui
线程执行了run()方法后,才会唤醒 system server 主线程。
mPolicy
是 WindowManagerPolicy 类型,具体实现类是 PhoneWindowManager。
1.4.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);
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
...
mHandler = new PolicyHandler(); //运行在"android.ui"线程
mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
mOrientationListener = new MyOrientationListener(mContext, mHandler);
...
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");
...
mGlobalKeyManager = new GlobalKeyManager(mContext);
...
if (!mPowerManager.isInteractive()) {
startedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
finishedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
}
mWindowManagerInternal.registerAppTransitionListener(
mStatusBarController.getAppTransitionListener());
}
1.5 WMS.displayReady()
public void displayReady() {
synchronized (mGlobalLock) {
if (mMaxUiWidth > 0) {
mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
}
final boolean changed = applyForcedPropertiesForDefaultDisplay();
mAnimator.ready();
mDisplayReady = true;
if (changed) {
reconfigureDisplayLocked(getDefaultDisplayContentLocked());
}
mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TOUCHSCREEN);
}
try {
mActivityTaskManager.updateConfiguration(null);
} catch (RemoteException e) {
}
updateCircularDisplayMaskIfNeeded();
}
1.6 WMS.systemReady()
public void systemReady() {
mSystemReady = true;
mPolicy.systemReady();
//...
}
1.6.1 PhoneWindowManager.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();
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);
}
二、总结
- system server主线程开始执行,准备创建 WMS 对象
- system server主线程进入wait(),等待 android.display线程去创建WMS对象,因此,WMS中的 mH 发送的消息都在该线程处理。
- 唤醒system server主线程,继续执行onInitReady()方法
- system server主线程进入wait(),切换到 android.ui线程 ,PhoneWindowManager.init()执行完毕
- 唤醒system server主线程,继续执行后续代码。
关键点是 三个线程的切换逻辑。