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的模块也是同样的堆栈路径。

相关推荐
ObjectX前端实验室27 分钟前
【react18原理探究实践】异步可中断 & 时间分片
前端·react.js
SoaringHeart30 分钟前
Flutter进阶:自定义一个 json 转 model 工具
前端·flutter·dart
努力打怪升级32 分钟前
Rocky Linux 8 远程管理配置指南(宿主机 VNC + KVM 虚拟机 VNC)
前端·chrome
brzhang1 小时前
AI Agent 干不好活,不是它笨,告诉你一个残忍的现实,是你给他的工具太难用了
前端·后端·架构
brzhang1 小时前
一文说明白为什么现在 AI Agent 都把重点放在上下文工程(context engineering)上?
前端·后端·架构
reembarkation1 小时前
自定义分页控件,只显示当前页码的前后N页
开发语言·前端·javascript
gerrgwg2 小时前
React Hooks入门
前端·javascript·react.js
ObjectX前端实验室2 小时前
【react18原理探究实践】调度机制之注册任务
前端·react.js
汉字萌萌哒2 小时前
【 HTML基础知识】
前端·javascript·windows
ObjectX前端实验室3 小时前
【React 原理探究实践】root.render 干了啥?——深入 render 函数
前端·react.js