做網(wǎng)站盡在美橙互聯(lián)世界羽聯(lián)最新排名
一 概述
本文Android14源代碼可參考:Search
在 Android 系統(tǒng)中,從設計的角度來看,窗口管理系統(tǒng)是基于 C/S 模式的。整個窗口系統(tǒng)分為服務端和客戶端兩大部分,客戶端負責請求創(chuàng)建窗口和使用窗口,服務端完成窗口的維護,窗口顯示等。
WMS 在 Android 系統(tǒng)的地位,它作為中間層,連接了上層的 View 框架和下層的 SurfaceFingler。
SurfaceFingler在systrace的表現(xiàn)可以參考:Perfetto詳細解析-CSDN博客
WMS 主要職責
窗口管理:負責啟動、添加、刪除窗口,管理窗口大小、層級,核心成員有:WindowContainer、RootWindowContainer、DisplayContent、TaskStack、Task、AppWindowToken、WindowState;
窗口動畫:由其子系統(tǒng) WindowAnimator 管理;
輸入系統(tǒng)中轉(zhuǎn)站:通過對窗口的觸摸從而產(chǎn)生觸摸事件,由 InputMethodService(IMS)對觸摸事件進行處理,它會尋找一個最合適的窗口處理觸摸反饋信息;
Surface 管理:為每個窗口分配一塊 Surface,用于繪制要顯示的內(nèi)容。
二、WMS重要成員
WMS
繼承于 IWindowManager.Stub,作為 Binder 服務端
mSessions
ArraySet 類型的變量,元素類型為 Session,保存著所有的 Session 對象,Session 繼承于 IWindowSession.Stub,作為 Binder 服務端,它主要用于進程間通信,其他的應用程序進程想要和 WMS 進程進行通信就需要經(jīng)過 Session,并且每個應用程序進程都會對應一個Session,WMS 保存這些 Session 用來記錄所有向 WMS 提出窗口管理服務的客戶端。
mPolicy
WindowManagerPolicy 類型的變量,是窗口管理策略的接口類,用來定義一個窗口策略所要遵循的通用規(guī)范,并提供了 WindowManager 所有的特定的 UI 行為。具體實現(xiàn)類為 PhoneWindowManager,這個實現(xiàn)類在 WMS 創(chuàng)建時被創(chuàng)建。WMP 允許定制窗口層級和特殊窗口類型以及關鍵的調(diào)度和布局。
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 是用來存儲正在調(diào)整大小的窗口的列表。
mAnimator
WindowAnimator 類型的變量,用于管理窗口的動畫以及特效動畫。
mH
H 類型的變量,系統(tǒng)的 Handler 類,用于將任務加入到主線程的消息隊列中,這樣代碼邏輯就會在主線程中執(zhí)行。
三、WMS 的啟動流程
3.1 SystemServer.java
3.1.1 main(String[] args)
/*** The main entry point from zygote.*/
public static void main(String[] args) {new SystemServer().run();
}
main方法中只調(diào)用了SystemServer的run方法,如下所示。
3.1.2 run()
從下面的注釋中可以看到,官方把系統(tǒng)服務分為了三種類型,分別是引導服務、核心服務和其他服務,其中其他服務是一些非緊要和一些不需要立即啟動的服務。系統(tǒng)服務總共大約有80多個,我們主要來查看引導服務WMS是如何啟動的。
private void run() {// Initialize native services.//1.加載了動態(tài)庫libandroid_servers.soSystem.loadLibrary("android_servers");......// Create the system service manager.//2.創(chuàng)建SystemServiceManager,它會對系統(tǒng)的服務進行創(chuàng)建、啟動和生命周期管理。mSystemServiceManager = new SystemServiceManager(mSystemContext);mSystemServiceManager.setStartInfo(mRuntimeRestart,mRuntimeStartElapsedTime, mRuntimeStartUptime);mDumper.addDumpable(mSystemServiceManager);...... // Start services.try {t.traceBegin("StartServices");//用SystemServiceManager啟動了ActivityManagerService、PowerManagerService、PackageManagerService等服務。startBootstrapServices(t);//啟動了BatteryService、UsageStatsService和WebViewUpdateService。startCoreServices(t);//啟動了CameraService、WindowManagerService、VrManagerService等服務。這些服務的父類均為SystemService。startOtherServices(t);startApexServices(t);// Only update the timeout after starting all the services so that we use// the default timeout to start system server.updateWatchdogTimeout(t);} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;} finally {t.traceEnd(); // StartServices}...}
3.1.3 startOtherServices(@NonNull TimingsTraceAndSlog t)
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {t.traceBegin("startOtherServices");mSystemServiceManager.updateOtherServicesStartIndex();
......t.traceBegin("StartInputManagerService");// wms與 InputManagerService 息息相關,創(chuàng)建 InputManagerService 對象inputManager = new InputManagerService(context);t.traceEnd();
......t.traceBegin("StartWindowManagerService");// WMS needs sensor service readymSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);3.2. 創(chuàng)建 WindowManagerService 對象wm = WindowManagerService.main(context, inputManager, !mFirstBoot,new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);// 將WindowManagerService添加到服務中ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);// 將InputManagerService 添加到服務中ServiceManager.addService(Context.INPUT_SERVICE, inputManager,/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);t.traceEnd();t.traceBegin("SetWindowManagerService");3.3. wms 與 ams 關聯(lián)mActivityManagerService.setWindowManager(wm);t.traceEnd();t.traceBegin("WindowManagerServiceOnInitReady");// 3.4 初始化完成wm.onInitReady();t.traceEnd();t.traceBegin("StartInputManager");// 3.5 InputManagerService 設置回調(diào),并啟動 InputManagerService inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());inputManager.start();t.traceEnd();
......t.traceBegin("MakeDisplayReady");try {// 3.6 調(diào)用 displayReady 方法wm.displayReady();} catch (Throwable e) {reportWtf("making display ready", e);}t.traceEnd();t.traceBegin("MakeDisplayReady");try {wm.displayReady();} catch (Throwable e) {reportWtf("making display ready", e);}t.traceEnd();......try {//3.7 系統(tǒng)準備完畢,調(diào)用 systemReadywm.systemReady();} catch (Throwable e) {reportWtf("making Window Manager Service ready", e);}t.traceEnd();
......
}
下面根據(jù)注釋的1-6跟進源碼查看
3.2 創(chuàng)建 WindowManagerService 對象
3.2.1 WindowManagerService.java & WindowManagerService main(...)
public static WindowManagerService main(final Context context, final InputManagerService im,final boolean showBootMsgs, WindowManagerPolicy policy,ActivityTaskManagerService atm) {return main(context, im, showBootMsgs, policy, atm, new DisplayWindowSettingsProvider(),SurfaceControl.Transaction::new, SurfaceControl.Builder::new);
}
//PhoneWindowManager,主要是負責窗口管理的各種策略。在 android.display 實例化 wms,所以wms 跑在android.display線程中// 一個Supplier可以通過lambda表達式、方法引用或默認構造函數(shù)來實例化。// Supplier在Java 8中被引入,屬于java.util.function包// transactionFactory 為 SurfaceControl.Transaction::new,創(chuàng)建 Transaction 對象// 通過get 可以獲取到對象 Transaction/*** Creates and returns an instance of the WindowManagerService. This call allows the caller* to override factories that can be used to stub native calls during test.*/
@VisibleForTesting
public static WindowManagerService main(final Context context, final InputManagerService im,final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm,DisplayWindowSettingsProvider displayWindowSettingsProvider,Supplier<SurfaceControl.Transaction> transactionFactory,Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {final WindowManagerService[] wms = new WindowManagerService[1];//3.2.2運行在"android.display"線程//3.2.4運行 runWithScissorsDisplayThread.getHandler().runWithScissors(() ->//執(zhí)行WindowManagerService構造函數(shù)wms[0] = new WindowManagerService(context, im, showBootMsgs, policy, atm,displayWindowSettingsProvider, transactionFactory,surfaceControlFactory), 0);return wms[0];
}
3.2.2 DisplayThread.java & getHandler()
DisplayThread 給系統(tǒng)使用的共享單例前臺線程類,線程名字為 android.display,專門提供給WindowManager, DisplayManager, InputManager來執(zhí)行快速響應的實時操作。public final class DisplayThread extends ServiceThread {private static DisplayThread sInstance;private static Handler sHandler;private DisplayThread() {// DisplayThread runs important stuff, but these are not as important as things running in// AnimationThread. Thus, set the priority to one lower.// 線程名字為 "android.display",優(yōu)先級為 -3super("android.display", Process.THREAD_PRIORITY_DISPLAY + 1, false /*allowIo*/);}private static void ensureThreadLocked() {if (sInstance == null) {sInstance = new DisplayThread();sInstance.start();sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);// 調(diào)用makeSharedHandler,跟進代碼sHandler = makeSharedHandler(sInstance.getLooper());}}public static DisplayThread get() {synchronized (DisplayThread.class) {ensureThreadLocked();return sInstance;}}
// 獲取到handlerpublic static Handler getHandler() {synchronized (DisplayThread.class) {ensureThreadLocked();return sHandler;}}/*** Disposes current display thread if it's initialized. Should only be used in tests to set up a* new environment.*/@VisibleForTestingpublic static void dispose() {synchronized (DisplayThread.class) {if (sInstance == null) {return;}//handler 執(zhí)行 runWithScissors 方法getHandler().runWithScissors(() -> sInstance.quit(), 0 /* timeout */);sInstance = null;}}
}
3.2.3 ServiceThread.java $ makeSharedHandler()
public class ServiceThread extends HandlerThread {private static final String TAG = "ServiceThread";private final boolean mAllowIo;public ServiceThread(String name, int priority, boolean allowIo) {super(name, priority);mAllowIo = allowIo;}@Overridepublic void run() {Process.setCanSelfBackground(false);if (!mAllowIo) {StrictMode.initThreadDefaults(null);}super.run();}//創(chuàng)建handler,looper 為 thread "android.display" 的looperprotected static Handler makeSharedHandler(Looper looper) {return new Handler(looper, /*callback=*/ null, /* async=*/ false, /* shared=*/ true);}
}
3.2.4 Handler.java & runWithScissors()
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");}if (Looper.myLooper() == mLooper) {r.run();return true;}BlockingRunnable br = new BlockingRunnable(r);
// 返回BlockingRunnable的postAndWaitreturn br.postAndWait(this, timeout);
}private static final class BlockingRunnable implements Runnable {private final Runnable mTask;private boolean mDone;public BlockingRunnable(Runnable task) {mTask = task;}@Overridepublic void run() {try {mTask.run();} finally {synchronized (this) {mDone = true;// 執(zhí)行完則喚醒系統(tǒng)主線程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 {// 阻塞systemserver 主線程wait();} catch (InterruptedException ex) {}}}}return true;}}
}
3.2.5 WindowManagerService構造函數(shù)
private WindowManagerService(Context context, InputManagerService inputManager,boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,ActivityTaskManagerService atm, DisplayWindowSettingsProviderdisplayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory,Supplier<Surface> surfaceFactory,Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {installLock(this, INDEX_WINDOW);// 鎖機制與 atm 一致mGlobalLock = atm.getGlobalLock();// 緩存 AtmSmAtmService = atm;mContext = context;mIsPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);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);inputManager.setInTouchMode(mInTouchMode, myPid(), myUid(), /* hasPermission = */ true);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);mAssistantOnTopOfDream = context.getResources().getBoolean(com.android.internal.R.bool.config_assistantOnTopOfDream);mLetterboxConfiguration = new LetterboxConfiguration(// Using SysUI context to have access to Material colors extracted from Wallpaper.ActivityThread.currentActivityThread().getSystemUiContext());// Must be before createDisplayContentLocked.mInputManager = inputManager; mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);mPossibleDisplayInfoMapper = new PossibleDisplayInfoMapper(mDisplayManagerInternal);mSurfaceControlFactory = surfaceControlFactory;mTransactionFactory = transactionFactory;mSurfaceFactory = surfaceFactory;// 獲取 Transaction 對象mTransaction = mTransactionFactory.get();mPolicy = policy;// 創(chuàng)建 WindowAnimator 對象mAnimator = new WindowAnimator(this);// 創(chuàng)建 RootWindowContainer 對象mRoot = new RootWindowContainer(this);final ContentResolver resolver = context.getContentResolver();mUseBLAST = Settings.Global.getInt(resolver,Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_VR, 1) == 1;mSyncEngine = new BLASTSyncEngine(this);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);// mH 為 final H mH = new H();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() {@Overridepublic int getServiceType() {return ServiceType.ANIMATION;}@Overridepublic 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);mDisplayNotificationController = new DisplayWindowListenerController(this);mTaskSystemBarsListenerController = new TaskSystemBarsListenerController();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);mTestUtilityService = LocalServices.getService(TestUtilityService.class);final IntentFilter suspendPackagesFilter = new IntentFilter();suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);context.registerReceiverAsUser(new BroadcastReceiver() {@Overridepublic 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 settingmWindowAnimationScaleSetting = 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;final String displaySettingsPath = Settings.Global.getString(resolver,DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH);mDisplayWindowSettingsProvider = displayWindowSettingsProvider;if (displaySettingsPath != null) {mDisplayWindowSettingsProvider.setBaseSettingsFilePath(displaySettingsPath);}mDisplayWindowSettings = new DisplayWindowSettings(this, mDisplayWindowSettingsProvider);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(mTransactionFactory,mPowerManagerInternal);mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);mTaskPositioningController = new TaskPositioningController(this);mDragDropController = new DragDropController(this, mH.getLooper());mHighRefreshRateDenylist = HighRefreshRateDenylist.create(context.getResources());mConstants = new WindowManagerConstants(this, DeviceConfigInterface.REAL);mConstants.start(new HandlerExecutor(mH));LocalServices.addService(WindowManagerInternal.class, new LocalService());mEmbeddedWindowController = new EmbeddedWindowController(mAtmService);mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources(mContext.getResources());mDisplayHashController = new DisplayHashController(mContext);setGlobalShadowSettings();mAnrController = new AnrController(this);mStartingSurfaceController = new StartingSurfaceController(this);// anr 控制類,無響應,無焦點等mBlurController = new BlurController(mContext, mPowerManager);mTaskFpsCallbackController = new TaskFpsCallbackController(mContext);mAccessibilityController = new AccessibilityController(this);
}
3.3 關聯(lián)wms 與 ams
3.3.1 ActivityTaskManagerService.java & setWindowManager()
public void setWindowManager(WindowManagerService wm) {synchronized (mGlobalLock) {mWindowManager = wm;// 緩存 RootWindowContainermRootWindowContainer = wm.mRoot;mWindowOrganizerController.setWindowManager(wm);mTempConfig.setToDefaults();mTempConfig.setLocales(LocaleList.getDefault());mConfigurationSeq = mTempConfig.seq = 1;mRootWindowContainer.onConfigurationChanged(mTempConfig);mLockTaskController.setWindowManager(wm);mTaskSupervisor.setWindowManager(wm);// RootWindowContainer 設置 WindowManagermRootWindowContainer.setWindowManager(wm);if (mBackNavigationController != null) {mBackNavigationController.setTaskSnapshotController(wm.mTaskSnapshotController);}}
}
3.4 初始化完成 onInitReady
3.4.1 WindowManagerService.java & onInitReady
//3.4.1 初始化完成 onInitReady
public void onInitReady() {initPolicy();// Add ourself to the Watchdog monitors.Watchdog.getInstance().addMonitor(this);createWatermark();showEmulatorDisplayOverlayIfNeeded();
}private void initPolicy() {// 在ui 線程執(zhí)行下列函數(shù),"android.ui"UiThread.getHandler().runWithScissors(new Runnable() {@Overridepublic void run() {WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());//3.4.2 初始化 PhoneWindowManagermPolicy.init(mContext, WindowManagerService.this);}}, 0);
}
3.4.2 PhoneWindowManager.java & init()
mHandler = new PolicyHandler();public void init(Context context, WindowManagerFuncs funcs) {init(new Injector(context, funcs));
}@VisibleForTesting
void init(Injector injector) {mContext = injector.getContext();mWindowManagerFuncs = injector.getWindowManagerFuncs();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);mSensorPrivacyManager = mContext.getSystemService(SensorPrivacyManager.class);mDisplayManager = mContext.getSystemService(DisplayManager.class);mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);mPackageManager = mContext.getPackageManager();mHasFeatureWatch = mPackageManager.hasSystemFeature(FEATURE_WATCH);mHasFeatureLeanback = mPackageManager.hasSystemFeature(FEATURE_LEANBACK);mHasFeatureAuto = mPackageManager.hasSystemFeature(FEATURE_AUTOMOTIVE);mHasFeatureHdmiCec = mPackageManager.hasSystemFeature(FEATURE_HDMI_CEC);mAccessibilityShortcutController = injector.getAccessibilityShortcutController(mContext, new Handler(), mCurrentUserId);mGlobalActionsFactory = injector.getGlobalActionsFactory();mLockPatternUtils = new LockPatternUtils(mContext);mLogger = new MetricsLogger();mScreenOffSleepTokenAcquirer = mActivityTaskManagerInternal.createSleepTokenAcquirer("ScreenOff");Resources res = mContext.getResources();mWakeOnDpadKeyPress =res.getBoolean(com.android.internal.R.bool.config_wakeOnDpadKeyPress);mWakeOnAssistKeyPress =res.getBoolean(com.android.internal.R.bool.config_wakeOnAssistKeyPress);mWakeOnBackKeyPress =res.getBoolean(com.android.internal.R.bool.config_wakeOnBackKeyPress);// Init display burn-in protectionboolean burnInProtectionEnabled = mContext.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 = mContext.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(mContext, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius);}
....
// handler是跑在ui 線程mSideFpsEventHandler = new SideFpsEventHandler(mContext, mHandler, mPowerManager);
3.5 InputManagerService 設置回調(diào),并啟InputManagerService
3.5.1 InputManagerService.java & setWindowManagerCallbacks
public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {// 保證只有一個 callbackif (mWindowManagerCallbacks != null) {unregisterLidSwitchCallbackInternal(mWindowManagerCallbacks);}mWindowManagerCallbacks = callbacks;registerLidSwitchCallbackInternal(mWindowManagerCallbacks);
}
3.5.2 InputManagerService.java & registerLidSwitchCallbackInternal()
void registerLidSwitchCallbackInternal(@NonNull LidSwitchCallback callback) {synchronized (mLidSwitchLock) {// 將 callback 保存到 mLidSwitchCallbacksmLidSwitchCallbacks.add(callback);// Skip triggering the initial callback if the system is not yet ready as the switch// state will be reported as KEY_STATE_UNKNOWN. The callback will be triggered in// systemRunning().if (mSystemReady) {boolean lidOpen = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, SW_LID)== KEY_STATE_UP;callback.notifyLidSwitchChanged(0 /* whenNanos */, lidOpen);}}
}
3.5.3 InputManagerService.java & start()
public void start() {Slog.i(TAG, "Starting input manager");mNative.start();// Add ourselves to the Watchdog monitors.Watchdog.getInstance().addMonitor(this);
}
3.6 調(diào)用 displayReady 方法
3.6.1 WindowManagerService.java & displayReady()
public void displayReady() {synchronized (mGlobalLock) {if (mMaxUiWidth > 0) {mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));}applyForcedPropertiesForDefaultDisplay();mAnimator.ready();mDisplayReady = true;// Reconfigure all displays to make sure that forced properties and// DisplayWindowSettings are applied.mRoot.forAllDisplays(DisplayContent::reconfigureDisplayLocked);mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN);mIsFakeTouchDevice = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);}mAtmService.updateConfiguration(null /* request to compute config */);
}
3.7 系統(tǒng)準備完畢,調(diào)用 systemReady
public void systemReady() {mSystemReady = true;// 調(diào)用 PhoneWindowManager的systemReadymPolicy.systemReady();mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);// 快照控制類mSnapshotController.systemReady();mHasWideColorGamutSupport = queryWideColorGamutSupport();mHasHdrSupport = queryHdrSupport();// ui線程執(zhí)行 loadSettingsUiThread.getHandler().post(mSettingsObserver::loadSettings);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}}
}
整個啟動過程有3個線程,systemserver主線程,”android.display”,”android.ui”,整個過程采用阻塞的方式(利用runWithScissors)執(zhí)行,WMS.mH的Looper運行在”android.display”進程。
參考:
WMS啟動流程分析 | Skytoby
WMS—啟動過程 - Gityuan博客 | 袁輝輝的技術博客
Android渲染(一)_系統(tǒng)服務WMS啟動過程(基于Android10) - 掘金
Android窗口管理2 WMS啟動過程_postandwait-CSDN博客
【安卓12源碼】WMS的作用及其啟動流程_android wms_蜘蛛俠不會飛的博客-CSDN博客