Skytoby

WMS启动流程分析

WMS启动流程分析

基于Android10.0,分析WMS的启动过程

一、概述

WindowManagerService作为Android系统中重要的服务,管理所有的窗口和输入事件的中转站,其相关类如下。

1.1 WMS类族

WMS

WMS继承于IWindowManager.Stub,作为Binder服务端

成员变量mSessions保存所有的Session对象,Session继承于IWindowSession.Stub,作为Binder服务端

成员变量mPolicy,实例是PhoneWindowManager,用于实现各种窗口相关的策略

成员变量mWindowMap,保存所有的WindowState对象;以IBinder为key, 是IWindow的Bp端;

每个窗口都对应一个WindowState对象, 该对象的成员变量mClient用于跟应用端交互,成员变量mToken用于跟AMS交互,WindowState的attach方法与SurfaceFlinger通信。

WindowManager与WindowManagerService通过Session进行通信,具体的实现由WMS处理。

WindowManager实现类是WindowManagerImpl ;

WindowManagerImpl 中成员变量 mParentWindow (Window),mGlobal (WindowManagerGlobal)

1.2 图形框架

Android系统图形系统复杂,包括WindowManager,SurfaceFlinger,Open GL,GPU等模块,其中SurfaceFlinger作为绘制应用UI的核心。Surface代表BufferQueue的生产者端,并由SurfaceFlinger消费。

Image Stream Producter(生产者):可产生graphic buffers的生产者,例如:OpenGL ES,Canvas 2D,mediaserver的视频编码器

Image Stream Consumers(消费者):使用Open GL和Hardware Composer来组合一组surfaces

Window Manager:用于管理window,这是一组view容器,WM将window元数据信息发送给SurfaceFlinger,因此SurfaceFlinger能将这些信息来合成surfaces,并输出到显示设备。

Hardware Composer(硬件合成器):显示子系统的硬件抽象层,SurfaceFlinger能将一些合成工作给Hardware Composer,从而降低OpenGL和GPU的负载。

Gralloc:全程graphics memory allocator,图像内存分配器,用于图形生产请求分配内存。

二、启动过程

WMS在SystemServer中的startOtherServices方法启动,和其启动相关的主要操作如下:

[->SystemServer.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void startOtherServices() {
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
...
//见2.1节
mActivityManagerService.setWindowManager(wm);
...
wm.onInitReady();
...
wm.displayReady();
...
wm.systemReady();

}

2.1 WMS.main

[->WindowManagerService.java]

1
2
3
4
5
6
7
8
9
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore,
WindowManagerPolicy policy) {
DisplayThread.getHandler().runWithScissors(() ->
//运行在android.display线程
sInstance = new WindowManagerService(context, im, haveInputMethods, showBootMsgs,
onlyCore, policy), 0);
return sInstance;
}

2.2 WindowManagerService

[->WindowManagerService.java]

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
private WindowManagerService(Context context, InputManagerService inputManager,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
WindowManagerPolicy policy) {
//初始化锁
installLock(this, INDEX_WINDOW);
mContext = context;
mHaveInputMethods = haveInputMethods;
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);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mDisplaySettings = new DisplaySettings();
mDisplaySettings.readSettingsLocked();

mPolicy = policy;
mAnimator = new WindowAnimator(this);
//创建根Window,用于支持多屏幕的功能
mRoot = new RootWindowContainer(this);

mWindowPlacerLocked = new WindowSurfacePlacer(this);
mTaskSnapshotController = new TaskSnapshotController(this);

mWindowTracing = WindowTracing.createDefaultAndStartLooper(context);

LocalServices.addService(WindowManagerPolicy.class, mPolicy);

if(mInputManager != null) {
final InputChannel inputChannel = mInputManager.monitorInput(TAG_WM);
mPointerEventDispatcher = inputChannel != null
? new PointerEventDispatcher(inputChannel) : null;
} else {
mPointerEventDispatcher = null;
}

mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);

mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);

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 (mWindowMap) {
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);

mAppTransition = new AppTransition(context, this);
mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);

final AnimationHandler animationHandler = new AnimationHandler();
mBoundsAnimationController = new BoundsAnimationController(context, mAppTransition,
AnimationThread.getHandler(), animationHandler);

mActivityManager = ActivityManager.getService();
mAmInternal = LocalServices.getService(ActivityManagerInternal.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);

// Get persisted window scale setting
mWindowAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
mTransitionAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
Settings.Global.TRANSITION_ANIMATION_SCALE,
context.getResources().getFloat(
R.dimen.config_appTransitionAnimationDurationScaleDefault));

setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));

IntentFilter filter = new IntentFilter();
// Track changes to DevicePolicyManager state so we can enable/disable keyguard.
filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter);

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, mInputMonitor, mActivityManager, mH.getLooper());
mDragDropController = new DragDropController(this, mH.getLooper());

LocalServices.addService(WindowManagerInternal.class, new LocalService());
}

WMS的初始化在“android.display”线程中执行,mH继承于Handler,采用的是当前线程的Looper, mH.sendMessage方法也运行在android.display”线程

2.3 WMS.onInitReady

[->WindowManagerService.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void onInitReady() {
initPolicy();

// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);

openSurfaceTransaction();
try {
createWatermarkInTransaction();
} finally {
closeSurfaceTransaction("createWatermarkInTransaction");
}

showEmulatorDisplayOverlayIfNeeded();
}

2.3.1 initPolicy

[->WindowManagerService.java]

1
2
3
4
5
6
7
8
9
10
11
private void initPolicy() {
//运行在Ui线程
UiThread.getHandler().runWithScissors(new Runnable() {
@Override
public void run() {
WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
//此处为PhoneWindowManager
mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
}
}, 0);
}

2.3.2 runWithScissors

[->Handler.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public final boolean runWithScissors(final 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");
}

if (Looper.myLooper() == mLooper) {
r.run();
return true;
}

BlockingRunnable br = new BlockingRunnable(r);
return br.postAndWait(this, timeout);
}

2.3.3 postAndWait

[->Handler.java::BlockingRunnable]

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 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;
}

postAndWait是阻塞操作,把消息放在Handler所指向的线程,此处是android.ui线程,由于该方法运行在android.display线程,从而会进入等待状态,直到执行完成,再唤醒android.display线程,PWM.init运行在android.ui线程,属于同步阻塞。

2.4 PWM.init

[->PhoneWindowManager.java]

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
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);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH);
mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK);
mAccessibilityShortcutController =
new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId);
mLogger = new MetricsLogger();
// Init display burn-in protection
boolean burnInProtectionEnabled = context.getResources().getBoolean(
com.android.internal.R.bool.config_enableBurnInProtection);
// Allow a system property to override this. Used by developer settings.
boolean burnInProtectionDevMode =
SystemProperties.getBoolean("persist.debug.force_burn_in", false);
if (burnInProtectionEnabled || burnInProtectionDevMode) {
final int minHorizontal;
final int maxHorizontal;
final int minVertical;
final int maxVertical;
final int maxRadius;
if (burnInProtectionDevMode) {
minHorizontal = -8;
maxHorizontal = 8;
minVertical = -8;
maxVertical = -4;
maxRadius = (isRoundWindow()) ? 6 : -1;
} else {
Resources resources = context.getResources();
minHorizontal = resources.getInteger(
com.android.internal.R.integer.config_burnInProtectionMinHorizontalOffset);
maxHorizontal = resources.getInteger(
com.android.internal.R.integer.config_burnInProtectionMaxHorizontalOffset);
minVertical = resources.getInteger(
com.android.internal.R.integer.config_burnInProtectionMinVerticalOffset);
maxVertical = resources.getInteger(
com.android.internal.R.integer.config_burnInProtectionMaxVerticalOffset);
maxRadius = resources.getInteger(
com.android.internal.R.integer.config_burnInProtectionMaxRadius);
}
mBurnInProtectionHelper = new BurnInProtectionHelper(
context, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius);
}
//运行在ui线程
mHandler = new PolicyHandler();
mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
mOrientationListener = new MyOrientationListener(mContext, mHandler);
try {
mOrientationListener.setCurrentRotation(windowManager.getDefaultDisplayRotation());
} catch (RemoteException ex) { }
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
mShortcutManager = new ShortcutManager(context);
mUiMode = context.getResources().getInteger(
com.android.internal.R.integer.config_defaultUiModeType);
mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
mHomeIntent.addCategory(Intent.CATEGORY_HOME);
mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
mEnableCarDockHomeCapture = context.getResources().getBoolean(
com.android.internal.R.bool.config_enableCarDockHomeLaunch);
mCarDockIntent = new Intent(Intent.ACTION_MAIN, null);
mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK);
mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
mDeskDockIntent = new Intent(Intent.ACTION_MAIN, null);
mDeskDockIntent.addCategory(Intent.CATEGORY_DESK_DOCK);
mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
mVrHeadsetHomeIntent = new Intent(Intent.ACTION_MAIN, null);
mVrHeadsetHomeIntent.addCategory(Intent.CATEGORY_VR_HOME);
mVrHeadsetHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

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"));
mSupportAutoRotation = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_supportAutoRotation);
mLidOpenRotation = readRotation(
com.android.internal.R.integer.config_lidOpenRotation);
mCarDockRotation = readRotation(
com.android.internal.R.integer.config_carDockRotation);
mDeskDockRotation = readRotation(
com.android.internal.R.integer.config_deskDockRotation);
mUndockedHdmiRotation = readRotation(
com.android.internal.R.integer.config_undockedHdmiRotation);
mCarDockEnablesAccelerometer = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_carDockEnablesAccelerometer);
mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_deskDockEnablesAccelerometer);
mLidKeyboardAccessibility = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lidKeyboardAccessibility);
mLidNavigationAccessibility = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lidNavigationAccessibility);
mLidControlsScreenLock = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_lidControlsScreenLock);
mLidControlsSleep = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_lidControlsSleep);
mTranslucentDecorEnabled = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_enableTranslucentDecor);

mAllowTheaterModeWakeFromKey = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromKey);
mAllowTheaterModeWakeFromPowerKey = mAllowTheaterModeWakeFromKey
|| mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromPowerKey);
mAllowTheaterModeWakeFromMotion = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromMotion);
mAllowTheaterModeWakeFromMotionWhenNotDreaming = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromMotionWhenNotDreaming);
mAllowTheaterModeWakeFromCameraLens = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromCameraLens);
mAllowTheaterModeWakeFromLidSwitch = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromLidSwitch);
mAllowTheaterModeWakeFromWakeGesture = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromGesture);

mGoToSleepOnButtonPressTheaterMode = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_goToSleepOnButtonPressTheaterMode);

mSupportLongPressPowerWhenNonInteractive = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_supportLongPressPowerWhenNonInteractive);

mLongPressOnBackBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_longPressOnBackBehavior);

mShortPressOnPowerBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_shortPressOnPowerBehavior);
mLongPressOnPowerBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_longPressOnPowerBehavior);
mVeryLongPressOnPowerBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_veryLongPressOnPowerBehavior);
mDoublePressOnPowerBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_doublePressOnPowerBehavior);
mTriplePressOnPowerBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_triplePressOnPowerBehavior);
mShortPressOnSleepBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_shortPressOnSleepBehavior);
mVeryLongPressTimeout = mContext.getResources().getInteger(
com.android.internal.R.integer.config_veryLongPressTimeout);
mAllowStartActivityForLongPressOnPowerDuringSetup = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_allowStartActivityForLongPressOnPowerInSetup);

mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION;

mHandleVolumeKeysInWM = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_handleVolumeKeysInWindowManager);

readConfigurationDependentBehaviors();

mAccessibilityManager = (AccessibilityManager) context.getSystemService(
Context.ACCESSIBILITY_SERVICE);

// register for dock events
IntentFilter filter = new IntentFilter();
filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE);
filter.addAction(UiModeManager.ACTION_ENTER_DESK_MODE);
filter.addAction(UiModeManager.ACTION_EXIT_DESK_MODE);
filter.addAction(Intent.ACTION_DOCK_EVENT);
Intent intent = context.registerReceiver(mDockReceiver, filter);
if (intent != null) {
// Retrieve current sticky dock event broadcast.
mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
Intent.EXTRA_DOCK_STATE_UNDOCKED);
}

// register for dream-related broadcasts
filter = new IntentFilter();
filter.addAction(Intent.ACTION_DREAMING_STARTED);
filter.addAction(Intent.ACTION_DREAMING_STOPPED);
context.registerReceiver(mDreamReceiver, filter);

// register for multiuser-relevant broadcasts
filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
context.registerReceiver(mMultiuserReceiver, filter);

// monitor for system gestures
// TODO(multi-display): Needs to be display specific.
mSystemGestures = new SystemGesturesPointerEventListener(context,
new SystemGesturesPointerEventListener.Callbacks() {
@Override
public void onSwipeFromTop() {
if (mStatusBar != null) {
requestTransientBars(mStatusBar);
}
}
@Override
public void onSwipeFromBottom() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
requestTransientBars(mNavigationBar);
}
}
@Override
public void onSwipeFromRight() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) {
requestTransientBars(mNavigationBar);
}
}
@Override
public void onSwipeFromLeft() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) {
requestTransientBars(mNavigationBar);
}
}
@Override
public void onFling(int duration) {
if (mPowerManagerInternal != null) {
mPowerManagerInternal.powerHint(
PowerHint.INTERACTION, duration);
}
}
@Override
public void onDebug() {
// no-op
}
@Override
public void onDown() {
mOrientationListener.onTouchStart();
}
@Override
public void onUpOrCancel() {
mOrientationListener.onTouchEnd();
}
@Override
public void onMouseHoverAtTop() {
mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS;
mHandler.sendMessageDelayed(msg, 500);
}
@Override
public void onMouseHoverAtBottom() {
mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION;
mHandler.sendMessageDelayed(msg, 500);
}
@Override
public void onMouseLeaveFromEdge() {
mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
}
});
mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext);
mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);

mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
mLongPressVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_longPressVibePattern);
mCalendarDateVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_calendarDateVibePattern);
mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_safeModeEnabledVibePattern);

mScreenshotChordEnabled = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_enableScreenshotChord);

mGlobalKeyManager = new GlobalKeyManager(mContext);

// Controls rotation and the like.
initializeHdmiState();

// Match current screen state.
if (!mPowerManager.isInteractive()) {
startedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
finishedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
}

mWindowManagerInternal.registerAppTransitionListener(
mStatusBarController.getAppTransitionListener());
mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
@Override
public int onAppTransitionStartingLocked(int transit, IBinder openToken,
IBinder closeToken, 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();
}
});
mScreenshotHelper = new ScreenshotHelper(mContext);
}

2.5 WMS.displayReady

1
2
3
4
5
6
7
8
9
10
11
private void displayReady(int displayId) {
synchronized(mWindowMap) {
//得到显示的displayid
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
mAnimator.addDisplayLocked(displayId);
displayContent.initializeDisplayBaseInfo();
reconfigureDisplayLocked(displayContent);
}
}
}

2.6 WMS.systemReady

[->WindowManagerService.java]

1
2
3
4
5
6
public void systemReady() {
mPolicy.systemReady();
//截屏systemReady
mTaskSnapshotController.systemReady();
mHasWideColorGamutSupport = queryWideColorGamutSupport();
}

2.6.1 PWM.systemReady

[->PhoneWindowManager]

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
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();
synchronized (mLock) {
updateOrientationListenerLp();
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();
}
}

mSystemGestures.systemReady();
mImmersiveModeConfirmation.systemReady();

mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
}

三、总结

整个启动过程有3个线程,systemserver主线程,”android.display”,”android.ui”,整个过程采用阻塞的方式(利用runWithScissors)执行,WMS.mH的Looper运行在”android.display”进程。流程如下:

附录

源码路径

1
2
3
4
5
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/UiThread.java
frameworks/base/core/java/android/os/Handler.java
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java