WMShell初始化

wmshell是systemui进程里面的,随着systemui的application创建构造出来,包含了很多模块比如pip,freeform,split,shelltransition。大量使用了dagger2注解。

xml 复制代码
<application
        android:name=".SystemUIApplication"
        android:persistent="true"
        android:allowClearUserData="false"
        android:backupAgent=".backup.BackupHelper"
        android:killAfterRestore="false"
        android:hardwareAccelerated="true"
        android:label="@string/app_label"
        android:icon="@drawable/android15_patch_adaptive"
        android:process="com.android.systemui"
        android:supportsRtl="true"
        android:theme="@style/Theme.SystemUI"
        android:defaultToDeviceProtectedStorage="true"
        android:directBootAware="true"
        android:appComponentFactory=".PhoneSystemUIAppComponentFactory">

systemui自定义了application---> SystemUIApplication 并且提供了appComponentFactory工厂,这个是在构建四大组件的时候,方便用户定制自己的需求提供了钩子。

通过堆栈

java 复制代码
07-29 10:50:08.264   922   922 D xmsysui : java.lang.Exception
07-29 10:50:08.264   922   922 D xmsysui : 	at com.android.systemui.SystemUIAppComponentFactoryBase.instantiateApplicationCompat(SystemUIAppComponentFactoryBase.kt:83)
07-29 10:50:08.264   922   922 D xmsysui : 	at androidx.core.app.AppComponentFactory.instantiateApplication(AppComponentFactory.java:61)
07-29 10:50:08.264   922   922 D xmsysui : 	at android.app.Instrumentation.newApplication(Instrumentation.java:1357)
07-29 10:50:08.264   922   922 D xmsysui : 	at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1471)
07-29 10:50:08.264   922   922 D xmsysui : 	at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1403)
07-29 10:50:08.264   922   922 D xmsysui : 	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7658)
07-29 10:50:08.264   922   922 D xmsysui : 	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
07-29 10:50:08.264   922   922 D xmsysui : 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2500)
07-29 10:50:08.264   922   922 D xmsysui : 	at android.os.Handler.dispatchMessage(Handler.java:109)
07-29 10:50:08.264   922   922 D xmsysui : 	at android.os.Looper.loopOnce(Looper.java:232)
07-29 10:50:08.264   922   922 D xmsysui : 	at android.os.Looper.loop(Looper.java:317)
07-29 10:50:08.264   922   922 D xmsysui : 	at android.app.ActivityThread.main(ActivityThread.java:8934)
07-29 10:50:08.264   922   922 D xmsysui : 	at java.lang.reflect.Method.invoke(Native Method)
07-29 10:50:08.264   922   922 D xmsysui : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:591)
07-29 10:50:08.264   922   922 D xmsysui : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)

可以看到在创建application时,会回调android.app.AppComponentFactory中的instantiateApplication()方法,systemui里面提供了PhoneSystemUIAppComponentFactory。

class android.app.AppComponentFactory class androidx.core.app.AppComponentFactory class com.android.systemui.SystemUIAppComponentFactoryBase class com.android.systemui.PhoneSystemUIAppComponentFactory 下面的是上面的子类,systemiui的实现类SystemUIAppComponentFactoryBase。

回调instantiateApplicationCompat方法。

java 复制代码
packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt
override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application {
        val app = super.instantiateApplicationCompat(cl, className)
        if (app !is ContextInitializer) {
            throw RuntimeException("App must implement ContextInitializer")
        } else {
            // 使用application context
            app.setContextAvailableCallback { context ->
                createSystemUIInitializerInternal(context)
            }
        }

        return app
    }
    
初始化systemui各模块,用了dagger2
private fun createSystemUIInitializerInternal(context: Context): SystemUIInitializer {
        return systemUIInitializer ?: run {
            val initializer = createSystemUIInitializer(context.applicationContext)
            try {
                // systemui初始化
                initializer.init(false)
            }
            .....
            // 注入到当前对象this@SystemUIAppComponentFactoryBase
            initializer.sysUIComponent.inject(
                this@SystemUIAppComponentFactoryBase
            )

            systemUIInitializer = initializer
            return initializer
        }
    }

systemui初始化

java 复制代码
packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
public void init(boolean fromTest) throws ExecutionException, InterruptedException {
        mRootComponent = getGlobalRootComponentBuilder()
                .context(mContext)
                .instrumentationTest(fromTest)
                .build();

        mInitializationChecker = mRootComponent.getInitializationChecker();
        boolean initializeComponents = mInitializationChecker.initializeComponents();
        // Stand up WMComponent
        //设置wmshell相关的模块
        setupWmComponent(mContext);

        // And finally, retrieve whatever SysUI needs from WMShell and build SysUI.
        SysUIComponent.Builder builder = mRootComponent.getSysUIComponent();
        if (initializeComponents) {
            // Only initialize when not starting from tests since this currently initializes some
            // components that shouldn't be run in the test environment
            //调用mWMComponent.getXXX()方法
            builder = prepareSysUIComponentBuilder(builder, mWMComponent)
                    .setShell(mWMComponent.getShell())
                    .setPip(mWMComponent.getPip())
                    .setSplitScreen(mWMComponent.getSplitScreen())
                    .setOneHanded(mWMComponent.getOneHanded())
                    .setBubbles(mWMComponent.getBubbles())
                    .setTaskViewFactory(mWMComponent.getTaskViewFactory())
                    .setShellTransitions(mWMComponent.getShellTransitions())
                    .setKeyguardTransitions(mWMComponent.getKeyguardTransitions())
                    .setStartingSurface(mWMComponent.getStartingSurface())
                    .setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
                    .setRecentTasks(mWMComponent.getRecentTasks())
                    .setBackAnimation(mWMComponent.getBackAnimation())
                    .setDesktopMode(mWMComponent.getDesktopMode());

            // Only initialize when not starting from tests since this currently initializes some
            // components that shouldn't be run in the test environment
            // wmshell各模块初始化调用init方法
            mWMComponent.init();
        } else {
           
        }
        mSysUIComponent = builder.build();

        // Every other part of our codebase currently relies on Dependency, so we
        // really need to ensure the Dependency gets initialized early on.
        Dependency dependency = mSysUIComponent.createDependency();
        dependency.start();
    }

设置wmshell相关的模块

java 复制代码
packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
    private void setupWmComponent(Context context) {
        WMComponent.Builder wmBuilder = mRootComponent.getWMComponentBuilder();
       
        // If the shell main thread is enabled, initialize the component on that thread
        HandlerThread shellThread = WMShellConcurrencyModule.createShellMainThread();
        shellThread.start();

        // Use an async handler since we don't care about synchronization
        Handler shellHandler = Handler.createAsync(shellThread.getLooper());
        boolean built = shellHandler.runWithScissors(() -> {
            wmBuilder.setShellMainThread(shellThread);
            // 构造wmcomponent,使用了dagger2
            mWMComponent = wmBuilder.build();
        }, 5000);
        
    }

wmshell各模块初始化调用init方法

java 复制代码
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMComponent.java
    default void init() {
        getShell().onInit();
    }
    
libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
private class ShellInterfaceImpl implements ShellInterface {
    @Override
    public void onInit() {
        mMainExecutor.execute(ShellController.this::handleInit);
    }
}
private void handleInit() {
    SurfaceControlRegistry.createProcessInstance(mContext);
    mShellInit.init();
}


libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
public void init() {
    ProtoLog.v(WM_SHELL_INIT, "Initializing Shell Components: %d", mInitCallbacks.size());
    SurfaceControl.setDebugUsageAfterRelease(true);
    // Init in order of registration
    for (int i = 0; i < mInitCallbacks.size(); i++) {
        final Pair<String, Runnable> info = mInitCallbacks.get(i);
        final long t1 = SystemClock.uptimeMillis();
        info.second.run();
        final long t2 = SystemClock.uptimeMillis();
        ProtoLog.v(WM_SHELL_INIT, "\t%s init took %dms", info.first, (t2 - t1));
    }
    mInitCallbacks.clear();
    mHasInitialized = true;
}

最后就是遍历mInitCallbacks中的每个item调用runable的run方法。

这个mInitCallbacks里面的值从哪里来的,查找发现只有这个方法添加了item,这里面也有protolog

java 复制代码
public <T extends Object> void addInitCallback(Runnable r, T instance) {
    if (mHasInitialized) {
        if (Build.isDebuggable()) {
            // All callbacks must be added prior to the Shell being initialized
            throw new IllegalArgumentException("Can not add callback after init");
        }
        return;
    }
    final String className = instance.getClass().getSimpleName();
    mInitCallbacks.add(new Pair<>(className, r));
    ProtoLog.v(WM_SHELL_INIT, "Adding init callback for %s", className);
    android.util.Log.d("xmsysui", " addInitCallback ", new Exception());
}

抓了log如下:

java 复制代码
	Line  122: 07-29 10:50:08.658   922   922 V WindowManagerShell: Adding init callback for DisplayChangeController
	Line  157: 07-29 10:50:08.659   922   922 V WindowManagerShell: Adding init callback for DisplayController
	Line  191: 07-29 10:50:08.661   922   922 V WindowManagerShell: Adding init callback for DisplayInsetsController
	Line  228: 07-29 10:50:08.663   922   922 V WindowManagerShell: Adding init callback for DisplayImeController
	Line  262: 07-29 10:50:08.667   922   922 V WindowManagerShell: Adding init callback for ShellController
	Line  303: 07-29 10:50:08.722   922   922 V WindowManagerShell: Adding init callback for CompatUIController
	Line  379: 07-29 10:50:08.758   922   922 V WindowManagerShell: Adding init callback for TaskStackTransitionObserver
	Line  420: 07-29 10:50:08.771   922   922 V WindowManagerShell: Adding init callback for RecentTasksController
	Line  491: 07-29 10:50:08.784   922   922 V WindowManagerShell: Adding init callback for ShellTaskOrganizer
	Line  527: 07-29 10:50:08.882   922   922 V WindowManagerShell: Adding init callback for OneHandedController
	Line  565: 07-29 10:50:08.887   922   922 V WindowManagerShell: Adding init callback for RootTaskDisplayAreaOrganizer
	Line  645: 07-29 10:50:08.903   922   922 V WindowManagerShell: Adding init callback for DefaultTransitionHandler
	Line  688: 07-29 10:50:08.905   922   922 V WindowManagerShell: Adding init callback for Transitions
	Line  728: 07-29 10:50:08.913   922   922 V WindowManagerShell: Adding init callback for DragAndDropController
	Line  765: 07-29 10:50:08.953   922   922 V WindowManagerShell: Adding init callback for BubbleController
	Line  799: 07-29 10:50:09.059   922   922 V WindowManagerShell: Adding init callback for CaptionWindowDecorViewModel
	Line  839: 07-29 10:50:09.070   922   922 V WindowManagerShell: Adding init callback for SplitScreenController
	Line  876: 07-29 10:50:09.072   922   922 V WindowManagerShell: Adding init callback for FullscreenTaskListener
	Line  910: 07-29 10:50:09.088   922   922 V WindowManagerShell: Adding init callback for FreeformTaskListener
	Line  950: 07-29 10:50:09.090   922   922 V WindowManagerShell: Adding init callback for FreeformTaskTransitionObserver
	Line  990: 07-29 10:50:09.093   922   922 V WindowManagerShell: Adding init callback for FreeformTaskTransitionStarterInitializer
	Line 1030: 07-29 10:50:09.095   922   922 V WindowManagerShell: Adding init callback for RecentsTransitionHandler
	Line 1064: 07-29 10:50:09.099   922   922 V WindowManagerShell: Adding init callback for ActivityEmbeddingController
	Line 1099: 07-29 10:50:09.126   922   922 V WindowManagerShell: Adding init callback for PipTransition
	Line 1143: 07-29 10:50:09.133   922   922 V WindowManagerShell: Adding init callback for PerfHintController
	Line 1201: 07-29 10:50:09.154   922   922 V WindowManagerShell: Adding init callback for PipTransition
	Line 1245: 07-29 10:50:09.156   922   922 V WindowManagerShell: Adding init callback for KeyguardTransitionHandler
	Line 1285: 07-29 10:50:09.159   922   922 V WindowManagerShell: Adding init callback for DefaultMixedHandler
	Line 1322: 07-29 10:50:09.181   922   922 V WindowManagerShell: Adding init callback for StartingWindowController
	Line 1356: 07-29 10:50:09.189   922   922 V WindowManagerShell: Adding init callback for ProtoLogController
	Line 1390: 07-29 10:50:09.193   922   922 V WindowManagerShell: Adding init callback for TransitionStateHolder
	Line 1428: 07-29 10:50:09.210   922   922 V WindowManagerShell: Adding init callback for BackAnimationController
	Line 1474: 07-29 10:50:09.231   922   922 V WindowManagerShell: Adding init callback for PipTouchHandler
	Line 1511: 07-29 10:50:09.234   922   922 V WindowManagerShell: Adding init callback for DevicePostureController
	Line 1548: 07-29 10:50:09.235   922   922 V WindowManagerShell: Adding init callback for TabletopModeController
	Line 1582: 07-29 10:50:09.244   922   922 V WindowManagerShell: Adding init callback for PipController
	Line 1639: 07-29 10:50:09.247   922   922 V WindowManagerShell: Adding init callback for RootDisplayAreaOrganizer

也就是说wmshell有这些模块,这里面有熟悉的ShellTaskOrganizer,FreeformTaskListener,PipController,SplitScreenController,Transitions

分析一下SplitScreenController的初始化流程。在上面的addInitCallback添加堆栈,SplitScreenController是如何添加进来的。

java 复制代码
07-29 10:50:09.070   922   922 V WindowManagerShell: Adding init callback for SplitScreenController
07-29 10:50:09.071   922   922 D xmsysui :  addInitCallback 
07-29 10:50:09.071   922   922 D xmsysui : java.lang.Exception
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.wm.shell.sysui.ShellInit.addInitCallback(ShellInit.java:73)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.wm.shell.splitscreen.SplitScreenController.<init>(SplitScreenController.java:262)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.wm.shell.dagger.WMShellModule.provideSplitScreenController(WMShellModule.java:521)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.wm.shell.dagger.WMShellModule_ProvideSplitScreenControllerFactory.provideSplitScreenController(WMShellModule_ProvideSplitScreenControllerFactory.java:182)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$WMComponentImpl$SwitchingProvider.get0(DaggerReferenceGlobalRootComponent.java:5236)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$WMComponentImpl$SwitchingProvider.get(DaggerReferenceGlobalRootComponent.java:5669)
07-29 10:50:09.071   922   922 D xmsysui : 	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$WMComponentImpl$SwitchingProvider.get0(DaggerReferenceGlobalRootComponent.java:5233)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$WMComponentImpl$SwitchingProvider.get(DaggerReferenceGlobalRootComponent.java:5669)
07-29 10:50:09.071   922   922 D xmsysui : 	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$WMComponentImpl$SwitchingProvider.get0(DaggerReferenceGlobalRootComponent.java:5116)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$WMComponentImpl$SwitchingProvider.get(DaggerReferenceGlobalRootComponent.java:5669)
07-29 10:50:09.071   922   922 D xmsysui : 	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$WMComponentImpl$SwitchingProvider.get0(DaggerReferenceGlobalRootComponent.java:5113)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$WMComponentImpl$SwitchingProvider.get(DaggerReferenceGlobalRootComponent.java:5669)
07-29 10:50:09.071   922   922 D xmsysui : 	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.dagger.DaggerReferenceGlobalRootComponent$WMComponentImpl.getShell(DaggerReferenceGlobalRootComponent.java:5032)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.SystemUIInitializer.init(SystemUIInitializer.java:91)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.SystemUIAppComponentFactoryBase.createSystemUIInitializerInternal(SystemUIAppComponentFactoryBase.kt:67)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.SystemUIAppComponentFactoryBase.access$createSystemUIInitializerInternal(SystemUIAppComponentFactoryBase.kt:46)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.SystemUIAppComponentFactoryBase$instantiateProviderCompat$1.onContextAvailable(SystemUIAppComponentFactoryBase.kt:101)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.systemui.keyguard.CustomizationProvider.attachInfo(CustomizationProvider.kt:90)
07-29 10:50:09.071   922   922 D xmsysui : 	at android.app.ActivityThread.installProvider(ActivityThread.java:8509)
07-29 10:50:09.071   922   922 D xmsysui : 	at android.app.ActivityThread.installContentProviders(ActivityThread.java:8024)
07-29 10:50:09.071   922   922 D xmsysui : 	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7682)
07-29 10:50:09.071   922   922 D xmsysui : 	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
07-29 10:50:09.071   922   922 D xmsysui : 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2500)
07-29 10:50:09.071   922   922 D xmsysui : 	at android.os.Handler.dispatchMessage(Handler.java:109)
07-29 10:50:09.071   922   922 D xmsysui : 	at android.os.Looper.loopOnce(Looper.java:232)
07-29 10:50:09.071   922   922 D xmsysui : 	at android.os.Looper.loop(Looper.java:317)
07-29 10:50:09.071   922   922 D xmsysui : 	at android.app.ActivityThread.main(ActivityThread.java:8934)
07-29 10:50:09.071   922   922 D xmsysui : 	at java.lang.reflect.Method.invoke(Native Method)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:591)
07-29 10:50:09.071   922   922 D xmsysui : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)

可以看到是初始化application的时候,SystemUIInitializer.init -> WMShellModule.provideSplitScreenController -> SplitScreenController. -> ShellInit.addInitCallback 其他的wmshell的模块也是同样的堆栈路径。

相关推荐
若梦plus3 分钟前
Nuxt.js基础与进阶
前端·vue.js
樱花开了几轉9 分钟前
React中为甚么强调props的不可变性
前端·javascript·react.js
风清云淡_A9 分钟前
【REACT18.x】CRA+TS+ANTD5.X实现useImperativeHandle让父组件修改子组件的数据
前端·react.js
小飞大王66610 分钟前
React与Rudex的合奏
前端·react.js·前端框架
若梦plus39 分钟前
React之react-dom中的dom-server与dom-client
前端·react.js
若梦plus40 分钟前
react-router-dom中的几种路由详解
前端·react.js
若梦plus41 分钟前
Vue服务端渲染
前端·vue.js
Mr...Gan1 小时前
VUE3(四)、组件通信
前端·javascript·vue.js
OEC小胖胖1 小时前
渲染篇(二):解密Diff算法:如何用“最少的操作”更新UI
前端·算法·ui·状态模式·web
万少1 小时前
AI编程神器!Trae+Claude4.0 简单配置 让HarmonyOS开发效率飙升 - 坚果派
前端·aigc·harmonyos