android13#SystemUI#01入门学习

3,646 阅读13分钟
  • SystemUI是一个系统级的app,我们常用的状态栏,导航栏,通知栏,锁屏,recents等等都是包含在这个应用里的。
  • 我们这里先按照启动流程分析下相关的ui都是如何添加到屏幕的。
  • 注意一下,这个app是没有默认的启动页面的。

1.SystemUI咋启动的

这里就要提到SystemServer了,这个server的启动流程,网上很多,可以自己查下资料

1.1.SystemServer

frameworks/base/services/java/com/android/server/SystemServer.java

    public static void main(String[] args) {
        new SystemServer().run();
    }

>1.run

下边是run方法里的核心代码

            //初始化系统上下文,补充2
            createSystemContext();

            // Call per-process mainline module initialization.
            ActivityThread.initializeMainlineModules();

            // Sets the dumper service
            ServiceManager.addService("system_server_dumper", mDumper);
            mDumper.addDumpable(this);

            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setStartInfo(mRuntimeRestart,
                    mRuntimeStartElapsedTime, mRuntimeStartUptime);
            mDumper.addDumpable(mSystemServiceManager);

            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
            mDumper.addDumpable(tp);
            //...
        // Start services.
        try {
            startBootstrapServices(t);
            startCoreServices(t);
            startOtherServices(t);//补充3
            startApexServices(t);
        } catch (Throwable ex) {

>2.createSystemContext

    private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();//参考1.2
        mSystemContext = activityThread.getSystemContext();//参考1.2.3
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }

>3.startOtherServices

        try {
            startSystemUi(context, windowManagerF);//参考1.3
        }

1.2.ActivityThread

>1.systemMain

创建系统主线程

    public static ActivityThread systemMain() {
        ThreadedRenderer.initForSystemProcess();
        ActivityThread thread = new ActivityThread();
        thread.attach(true, 0);//补充2
        return thread;
    }

>2.attach(true,0)

        } else {
            // Don't set application object here -- if the system crashes,
            // we can't display an alert, we just want to die die die.
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this);
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplicationInner(true, null);
                mInitialApplication.onCreate();
            }
        }

>3.getSystemContext

    public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                mSystemContext = ContextImpl.createSystemContext(this);//补充4
            }
            return mSystemContext;
        }
    }

>4.getSystemContext

ContextImpl.java

    static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
                ContextParams.EMPTY, null, null, null, null, null, 0, null, null);
        context.setResources(packageInfo.getResources());
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetrics());
        context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
        return context;
    }

1.3.startSystemUi方法

这里是启动了SystemUI的service

    private static void startSystemUi(Context context, WindowManagerService windowManager) {
        PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
        Intent intent = new Intent();
        intent.setComponent(pm.getSystemUiServiceComponent());//补充2
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        context.startServiceAsUser(intent, UserHandle.SYSTEM);
        windowManager.onSystemUiStarted();
    }

>1.PackageManagerInternal来源

PackageManagerService的构造方法里有添加PackageManagerInternalImpl的实例

        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
       

>2.getSystemUiServiceComponent

  • packageManagerInternal的子类,也是PackageManagerInternalImpl的父类
  • frameworks/base/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
    public final ComponentName getSystemUiServiceComponent() {
        return ComponentName.unflattenFromString(getContext().getResources().getString(
                com.android.internal.R.string.config_systemUIServiceComponent));
    }

字符串内容

    <!-- SystemUi service component -->
    <string name="config_systemUIServiceComponent" translatable="false"
            >com.android.systemui/com.android.systemui.SystemUIService</string>

2.SystemUIAppComponentFactory

  • Activity,Service,Broadcast 交给mComponentHelper来实例化
  • Application,ContentProvider还是父类来实例化,完事进行了一些额外的初始化操作
public class SystemUIAppComponentFactory extends AppComponentFactory {

    @Inject
    public ContextComponentHelper mComponentHelper;//注解生成的

2.1.清单文件

  • appComponentFactory是自定义的,也就是说SystemUI的四大组件都是这个自定义的工厂类来实例化的
    <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/icon"
        android:process="com.android.systemui"
        android:supportsRtl="true"
        android:theme="@style/Theme.SystemUI"
        android:defaultToDeviceProtectedStorage="true"
        android:directBootAware="true"
        
        android:appComponentFactory=".SystemUIAppComponentFactory">

2.2.instantiateApplicationCompat

    public Application instantiateApplicationCompat(
            @NonNull ClassLoader cl, @NonNull String className)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        Application app = super.instantiateApplicationCompat(cl, className);
        //如果实现了这个接口,就设置对应的回调
        if (app instanceof ContextInitializer) {
            ((ContextInitializer) app).setContextAvailableCallback(
                    context -> {
                    //参考2.7.1
                        SystemUIFactory.createFromConfig(context);
                        //给SysUIComponent注入当前对象
                        SystemUIFactory.getInstance().getSysUIComponent().inject(
                                SystemUIAppComponentFactory.this);
                    }
            );
        }

        return app;
    }

2.3.instantiateProviderCompat

    public ContentProvider instantiateProviderCompat(
            @NonNull ClassLoader cl, @NonNull String className)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {

        ContentProvider contentProvider = super.instantiateProviderCompat(cl, className);
        //如果实现了这个接口,就设置对应的回调
        if (contentProvider instanceof ContextInitializer) {
            ((ContextInitializer) contentProvider).setContextAvailableCallback(
                    context -> {
                        SystemUIFactory.createFromConfig(context);
                        SysUIComponent rootComponent =
                                SystemUIFactory.getInstance().getSysUIComponent();
                        try {
                        //给SysUIComponent注入contentProvider
                            Method injectMethod = rootComponent.getClass()
                                    .getMethod("inject", contentProvider.getClass());
                            injectMethod.invoke(rootComponent, contentProvider);
                        }
                    }
            );
        }

        return contentProvider;
    }

2.4.instantiateActivityCompat

    public Activity instantiateActivityCompat(@NonNull ClassLoader cl, @NonNull String className,
            @Nullable Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        if (mComponentHelper == null) {
            //正常情况不应该走这里
            SystemUIFactory.getInstance().getSysUIComponent().inject(
                    SystemUIAppComponentFactory.this);
        }
        //通过helper类创建activity
        Activity activity = mComponentHelper.resolveActivity(className);
        if (activity != null) {
            return activity;
        }
        //失败再走默认的方法
        return super.instantiateActivityCompat(cl, className, intent);
    }

2.5.instantiateServiceCompat

    public Service instantiateServiceCompat(
            @NonNull ClassLoader cl, @NonNull String className, Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        if (mComponentHelper == null) {
            SystemUIFactory.getInstance().getSysUIComponent().inject(
                    SystemUIAppComponentFactory.this);
        }
        //同样交给helper类创建服务,失败再走默认的方法
        Service service = mComponentHelper.resolveService(className);
        if (service != null) {
            return service;
        }
        return super.instantiateServiceCompat(cl, className, intent);
    }

2.6.instantiateReceiverCompat

    public BroadcastReceiver instantiateReceiverCompat(@NonNull ClassLoader cl,
            @NonNull String className, @Nullable Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        if (mComponentHelper == null) {
            SystemUIFactory.getInstance().getSysUIComponent().inject(
                    SystemUIAppComponentFactory.this);
        }
         //同样交给helper类创建广播对象,失败再走默认的方法
        BroadcastReceiver receiver = mComponentHelper.resolveBroadcastReceiver(className);
        if (receiver != null) {
            return receiver;
        }

        return super.instantiateReceiverCompat(cl, className, intent);
    }

2.7.SystemUIFactory

>1.getInstance

单例默认

    static SystemUIFactory mFactory;

    public static <T extends SystemUIFactory> T getInstance() {
        return (T) mFactory;
    }

>2.createFromConfig

2.2或者2.3会调用

    public static void createFromConfig(Context context) {
        createFromConfig(context, false);
    }

    public static void createFromConfig(Context context, boolean fromTest) {
        if (mFactory != null) {
            return;
        }

        final String clsName = context.getString(R.string.config_systemUIFactoryComponent);
        if (clsName == null || clsName.length() == 0) {
            throw new RuntimeException("No SystemUIFactory component configured");
        }

        try {
            Class<?> cls = null;
            cls = context.getClassLoader().loadClass(clsName);
            mFactory = (SystemUIFactory) cls.newInstance();
            mFactory.init(context, fromTest);
        }
    }
    <!-- SystemUIFactory component -->
    <string name="config_systemUIFactoryComponent" >com.android.systemui.SystemUIInitializerImpl</string>

>3.init

    public void init(Context context, boolean fromTest)
            throws ExecutionException, InterruptedException {
        //只有在主系统进程,系统用户的情况下初始化组件
        mInitializeComponents = !fromTest
                && android.os.Process.myUserHandle().isSystem()
                && ActivityThread.currentProcessName().equals(ActivityThread.currentPackageName());
                //补充4
        mRootComponent = buildGlobalRootComponent(context);

        // 启动 WMComponent,补充5
        setupWmComponent(context);
        if (mInitializeComponents) {
            //
            mWMComponent.init();
        }

        //
        SysUIComponent.Builder builder = mRootComponent.getSysUIComponent();
        if (mInitializeComponents) {
            builder = prepareSysUIComponentBuilder(builder, mWMComponent)
                    .setPip(mWMComponent.getPip())
                    .setLegacySplitScreen(mWMComponent.getLegacySplitScreen())
                    .setSplitScreen(mWMComponent.getSplitScreen())
                    .setOneHanded(mWMComponent.getOneHanded())
                    .setBubbles(mWMComponent.getBubbles())
                    .setHideDisplayCutout(mWMComponent.getHideDisplayCutout())
                    .setShellCommandHandler(mWMComponent.getShellCommandHandler())
                    .setAppPairs(mWMComponent.getAppPairs())
                    .setTaskViewFactory(mWMComponent.getTaskViewFactory())
                    .setTransitions(mWMComponent.getTransitions())
                    .setStartingSurface(mWMComponent.getStartingSurface())
                    .setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
                    .setTaskSurfaceHelper(mWMComponent.getTaskSurfaceHelper())
                    .setRecentTasks(mWMComponent.getRecentTasks())
                    .setCompatUI(mWMComponent.getCompatUI())
                    .setDragAndDrop(mWMComponent.getDragAndDrop())
                    .setBackAnimation(mWMComponent.getBackAnimation());
        } else {//不需要初始化,设置数据都是空
            builder = prepareSysUIComponentBuilder(builder, mWMComponent)
                    .setPip(Optional.ofNullable(null))
                    .setLegacySplitScreen(Optional.ofNullable(null))
                    .setSplitScreen(Optional.ofNullable(null))
                    .setOneHanded(Optional.ofNullable(null))
                    .setBubbles(Optional.ofNullable(null))
                    .setHideDisplayCutout(Optional.ofNullable(null))
                    .setShellCommandHandler(Optional.ofNullable(null))
                    .setAppPairs(Optional.ofNullable(null))
                    .setTaskViewFactory(Optional.ofNullable(null))
                    .setTransitions(new ShellTransitions() {})
                    .setDisplayAreaHelper(Optional.ofNullable(null))
                    .setStartingSurface(Optional.ofNullable(null))
                    .setTaskSurfaceHelper(Optional.ofNullable(null))
                    .setRecentTasks(Optional.ofNullable(null))
                    .setCompatUI(Optional.ofNullable(null))
                    .setDragAndDrop(Optional.ofNullable(null))
                    .setBackAnimation(Optional.ofNullable(null));
        }
        mSysUIComponent = builder.build();
        if (mInitializeComponents) {
            mSysUIComponent.init();
        }
        //
        Dependency dependency = mSysUIComponent.createDependency();
        dependency.start();
    }

>4.buildGlobalRootComponent

  • DaggerGlobalRootComponent源码里没有这个类的,这是dagger库自动生成的,原本接口是GlobalRootComponent
    protected GlobalRootComponent buildGlobalRootComponent(Context context) {
        return DaggerGlobalRootComponent.builder()
                .context(context)
                .build();
    }

>5.setupWmComponent

    private void setupWmComponent(Context context) {
        WMComponent.Builder wmBuilder = mRootComponent.getWMComponentBuilder();
        if (!mInitializeComponents || !WMShellConcurrencyModule.enableShellMainThread(context)) {
            mWMComponent = wmBuilder.build();
            return;
        }

        // 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);
            mWMComponent = wmBuilder.build();
        }, 5000);

3.SystemUIApplication

3.1.onCreate

    public void onCreate() {
        super.onCreate();
//callback是2.2赋值的
        mContextAvailableCallback.onContextAvailable(this);
        mRootComponent = SystemUIFactory.getInstance().getRootComponent();
        mSysUIComponent = SystemUIFactory.getInstance().getSysUIComponent();
        mComponentHelper = mSysUIComponent.getContextComponentHelper();
        mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();

        setTheme(R.style.Theme_SystemUI);

        if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
            IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
            bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);

            int sfPriority = SurfaceControl.getGPUContextPriority();

            if (sfPriority == ThreadedRenderer.EGL_CONTEXT_PRIORITY_REALTIME_NV) {
                ThreadedRenderer.setContextPriority(
                        ThreadedRenderer.EGL_CONTEXT_PRIORITY_HIGH_IMG);
            }
            registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (mBootCompleteCache.isBootComplete()) return;

                    unregisterReceiver(this);
                    mBootCompleteCache.setBootComplete();
                    //服务是否已经启动,3.2方法执行完会设置为true
                    if (mServicesStarted) {
                        final int N = mServices.length;
                        for (int i = 0; i < N; i++) {
                            mServices[i].onBootCompleted();
                        }
                    }
                }
            }, bootCompletedFilter);

            IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
            registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
                        if (!mBootCompleteCache.isBootComplete()) return;
                        //语言改变,更新通知渠道名
                        NotificationChannels.createAll(context);
                    }
                }
            }, localeChangedFilter);
        } else {
            /
            String processName = ActivityThread.currentProcessName();
            ApplicationInfo info = getApplicationInfo();
            if (processName != null && processName.startsWith(info.processName + ":")) {
                return;
            }
            startSecondaryUserServicesIfNeeded();
        }
    }

3.2.startServicesIfNeeded

  • SystemUIService.java的onCreate方法里调用
    public void startServicesIfNeeded() {
    //厂商自定义的组件在这里启动,参考3.3
        final String vendorComponent = mInitializer.getVendorComponent(getResources());

        //按类名排序的map
        Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
                Comparator.comparing(Class::getName));
                //添加一些实现了startable接口的类,方便循环执行他们的start方法
        sortedStartables.putAll(mSysUIComponent.getStartables());
        sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
        //补充1
        startServicesIfNeeded(
                sortedStartables, "StartServices", vendorComponent);
    }

>1.startServicesIfNeeded

暂时先不管Startables数据咋获取的,继续往下看

    private void startServicesIfNeeded(
            Map<Class<?>, Provider<CoreStartable>> startables,
            String metricsPrefix,
            String vendorComponent) {
        if (mServicesStarted) {
            return;
        }
    //...
    //通用的组件
        int i = 0;
        for (Map.Entry<Class<?>, Provider<CoreStartable>> entry : startables.entrySet()) {
            String clsName = entry.getKey().getName();
            int j = i;  // Copied to make lambda happy.
            //这个方法就是打印下runnable的用时
            timeInitialization(
                    clsName,
                    //实际就是执行这个,参考补充2
                    () -> mServices[j] = startStartable(clsName, entry.getValue()),
                    log,
                    metricsPrefix);
            i++;
        }
//厂商自定义的组件
        if (vendorComponent != null) {
            timeInitialization(
                    vendorComponent,
                    () -> mServices[mServices.length - 1] =
                            startAdditionalStartable(vendorComponent),//补充3
                    log,
                    metricsPrefix);
        }

        for (i = 0; i < mServices.length; i++) {
            if (mBootCompleteCache.isBootComplete()) {
                notifyBootCompleted(mServices[i]);
            }

            mDumpManager.registerDumpable(mServices[i].getClass().getName(), mServices[i]);
        }
//...
        mServicesStarted = true;
    }

>2.startStartable()

  • 可以看到拿到CoreStartable对象,调用其start方法
    private static CoreStartable startStartable(String clsName, Provider<CoreStartable> provider) {
    
        CoreStartable startable = provider.get();
     
        return startStartable(startable);
    }

    private static CoreStartable startStartable(CoreStartable startable) {

        startable.start();

        return startable;
    }

>3.startAdditionalStartable()

厂商那个是返回的class的名字,所以是反射创建对象,同样调用其start方法

    private static CoreStartable startAdditionalStartable(String clsName) {

        try {
            startable = (CoreStartable) Class.forName(clsName).newInstance();
        } 
        return startStartable(startable);
    }

3.3.getVendorComponent

SystemUIInitializer.java

    public String getVendorComponent(Resources resources) {
        return resources.getString(R.string.config_systemUIVendorServiceComponent);
    }
    <!-- SystemUI vender service, used in config_systemUIServiceComponents. -->
    <string name="config_systemUIVendorServiceComponent" translatable="false">com.android.systemui.VendorServices</string>

>1.VendorServices

源码里这个service是空的实现

/**
 * Placeholder for any vendor-specific services.
 */
public class VendorServices implements CoreStartable {

    public VendorServices() {
    }

    @Override
    public void start() {
        // no-op
    }
}

3.4.SysUIComponent

看下下边这两个值是啥,好确定都启动了哪些服务

sortedStartables.putAll(mSysUIComponent.getStartables());
sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
  • 注解生成的
  • 这个类是通过@Subcomponent.Builder来实例化的

>1.接口类

@SysUISingleton
@Subcomponent(modules = {
        DefaultComponentBinder.class,
        DependencyProvider.class,
        NotificationInsetsModule.class,
        QsFrameTranslateModule.class,
        SystemUIBinder.class,
        SystemUIModule.class,
        SystemUICoreStartableModule.class,
        ReferenceSystemUIModule.class})
public interface SysUIComponent {

    /**
     * Builder for a SysUIComponent.
     */
    @SysUISingleton
    @Subcomponent.Builder
    interface Builder {
        @BindsInstance
        Builder setShell(ShellInterface s);
        //...

//这个是相关的startbles
Map<Class<?>, Provider<CoreStartable>> getStartables();


//这个目前就发现一个 NotificationChannels,也在下边那个module类里
@PerUser Map<Class<?>, Provider<CoreStartable>> getPerUserStartables();

>2.SystemUICoreStartableModule

  • 上述getStartables()返回的map数据主要是在这个类里,可能还有其他的,需要自己搜下"): CoreStartable"
  • 另外这个类是对普通手机来讲的,如果是car,tv就会是其他类了,比如CarSystemUICoreStartableModule,TVSystemUICoreStartableModule
  • 通过注解@IntoMap把数据传给map的,下边贴了部分

@Module(includes = [MultiUserUtilsModule::class])
abstract class SystemUICoreStartableModule {
    /** Inject into AuthController.  */
    @Binds
    @IntoMap
    @ClassKey(AuthController::class)
    abstract fun bindAuthController(service: AuthController): CoreStartable

    /** Inject into FsiChromeWindowBinder.  */
    @Binds
    @IntoMap
    @ClassKey(FsiChromeViewBinder::class)
    abstract fun bindFsiChromeWindowBinder(sysui: FsiChromeViewBinder): CoreStartable

    /** Inject into GarbageMonitor.Service.  */
    @Binds
    @IntoMap
    @ClassKey(GarbageMonitor::class)
    abstract fun bindGarbageMonitorService(sysui: GarbageMonitor.Service): CoreStartable

    /** Inject into LatencyTests.  */
    @Binds
    @IntoMap
    @ClassKey(LatencyTester::class)
    abstract fun bindLatencyTester(sysui: LatencyTester): CoreStartable

    /** Inject into NotificationChannels.  */
    @Binds
    @IntoMap
    @ClassKey(NotificationChannels::class)
    @PerUser //这个就是给同样注解的map用的
    abstract fun bindNotificationChannels(sysui: NotificationChannels): CoreStartable

>3.StartCentralSurfacesModule

补充1里声明的子模块ReferenceSystemUIModule.class里边声明的子模块CentralSurfacesModule.class,

@Module
interface StartCentralSurfacesModule {
    /** Start the CentralSurfaces   */
    @Binds
    @IntoMap
    @ClassKey(CentralSurfaces::class)
    abstract fun bindsCentralSurfaces(centralSurfaces: CentralSurfacesImpl): CoreStartable
}

4.CentralSurfacesImpl

  • SystemUI的启动核心就在这个类里了,这个类的构造方法参数就有90个左右,吓死个人,还好用的dagger2注解生成的对象,要不想想都怕
  • 这个类也在mSysUIComponent.getStartables()返回的map里,所以会调用start方法

4.1.start方法

核心方法了,一切从这里开始

    public void start() {
        mScreenLifecycle.addObserver(mScreenObserver);
        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
        mUiModeManager = mContext.getSystemService(UiModeManager.class);
        if (mBubblesOptional.isPresent()) {
            mBubblesOptional.get().setExpandListener(mBubbleExpandListener);
        }

//statusBar相关,主要处理和信号有关的icon,比如mobile,wifi,vpn等
        mStatusBarSignalPolicy.init();
     //TODO
        mKeyguardIndicationController.init();
//回调里会update theme
        mColorExtractor.addOnColorsChangedListener(mOnColorsChangedListener);

        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);

        mDisplay = mContext.getDisplay();
        mDisplayId = mDisplay.getDisplayId();
        updateDisplaySize();
        //TODO
        mStatusBarHideIconsForBouncerManager.setDisplayId(mDisplayId);

        initShadeVisibilityListener();

        // start old BaseStatusBar.start().
        mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
        mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
                Context.DEVICE_POLICY_SERVICE);

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

        mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
        mBarService = IStatusBarService.Stub.asInterface(
                ServiceManager.getService(Context.STATUS_BAR_SERVICE));

        mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
        mWallpaperSupported = mWallpaperManager.isWallpaperSupported();

        RegisterStatusBarResult result = null;
        try {
            result = mBarService.registerStatusBar(mCommandQueue);
        } catch (RemoteException ex) {
            ex.rethrowFromSystemServer();
        }
//这里就是添加view的核心代码了,参考4.2
        createAndAddWindows(result);
//有壁纸的话,壁纸修改的监听
        if (mWallpaperSupported) {
            // Make sure we always have the most current wallpaper info.
            IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
            mBroadcastDispatcher.registerReceiver(mWallpaperChangedReceiver, wallpaperChangedFilter,
                    null /* handler */, UserHandle.ALL);
            mWallpaperChangedReceiver.onReceive(mContext, null);
        } else if (DEBUG) {
            Log.v(TAG, "start(): no wallpaper service ");
        }

        // Set up the initial notification state. This needs to happen before CommandQueue.disable()
        //初始化通知栏状态,具体见章节6
        setUpPresenter();

        if (containsType(result.mTransientBarTypes, ITYPE_STATUS_BAR)) {
            showTransientUnchecked();
        }
        mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance,
                result.mAppearanceRegions, result.mNavbarColorManagedByIme, result.mBehavior,
                result.mRequestedVisibilities, result.mPackageName, result.mLetterboxDetails);

        // StatusBarManagerService has a back up of IME token and it's restored here.
        mCommandQueueCallbacks.setImeWindowStatus(mDisplayId, result.mImeToken,
                result.mImeWindowVis, result.mImeBackDisposition, result.mShowImeSwitcher);

        // Set up the initial icon state
        int numIcons = result.mIcons.size();
        for (int i = 0; i < numIcons; i++) {
            mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));
        }

//TODO banner到底是啥?
        IntentFilter internalFilter = new IntentFilter();
        internalFilter.addAction(BANNER_ACTION_CANCEL);
        internalFilter.addAction(BANNER_ACTION_SETUP);
        mContext.registerReceiver(mBannerActionBroadcastReceiver, internalFilter, PERMISSION_SELF,
                null, Context.RECEIVER_EXPORTED_UNAUDITED);

        if (mWallpaperSupported) {
            IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface(
                    ServiceManager.getService(Context.WALLPAPER_SERVICE));
            try {
                wallpaperManager.setInAmbientMode(false /* ambientMode */, 0L /* duration */);
            } catch (RemoteException e) {
                // Just pass, nothing critical.
            }
        }

        // end old BaseStatusBar.start().

        // Lastly, call to the icon policy to install/update all the icons.
        //这个是常见的icon的处理类,比如蓝牙,定位,录屏等状态图标的显示
        mIconPolicy.init();

        // Based on teamfood flag, turn predictive back dispatch on at runtime.
        if (mFeatureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_SYSUI)) {
            mContext.getApplicationInfo().setEnableOnBackInvokedCallback(true);
        }

        mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
//...
//锁屏相关,4.6
        startKeyguard();

        mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
        //TODO 
        mDozeServiceHost.initialize(
                this,
                mStatusBarKeyguardViewManager,
                mNotificationShadeWindowViewController,
                mNotificationPanelViewController,
                mAmbientIndicationContainer);
        updateLightRevealScrimVisibility();

        mConfigurationController.addCallback(mConfigurationListener);

        mBatteryController.observe(mLifecycle, mBatteryStateChangeCallback);
        mLifecycle.setCurrentState(RESUMED);

//无障碍功能
        mAccessibilityFloatingMenuController.init();

        // set the initial view visibility
        int disabledFlags1 = result.mDisabledFlags1;
        int disabledFlags2 = result.mDisabledFlags2;
        mInitController.addPostInitTask(() -> {
            setUpDisableFlags(disabledFlags1, disabledFlags2);
//...
        });

        mFalsingManager.addFalsingBeliefListener(mFalsingBeliefListener);

        mPluginManager.addPluginListener(
//...

        mStartingSurfaceOptional.ifPresent(startingSurface -> startingSurface.setSysuiProxy(
                (requestTopUi, componentTag) -> mMainExecutor.execute(() ->
                        mNotificationShadeWindowController.setRequestTopUi(
                                requestTopUi, componentTag))));
    }

4.2.ceateAndAddWindows(result)

    public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
        makeStatusBarView(result);//参考4.3
        mNotificationShadeWindowController.attach();//添加通知栏面板到屏幕,具体的见6.3
        mStatusBarWindowController.attach();//添加statusBar到屏幕,具体的见6.4
    }

4.3.makeStatusBarView

    protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
        updateDisplaySize(); // populates mDisplayMetrics
        updateResources();
        updateTheme();

//状态栏,补充1
        inflateStatusBarWindow();
        mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());
        mWallpaperController.setRootView(mNotificationShadeWindowView);


        mNotificationIconAreaController.setupShelf(mNotificationShelfController);
        mShadeExpansionStateManager.addExpansionListener(mWakeUpCoordinator);

        // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
        mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
        mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);

        // Set up CollapsedStatusBarFragment and PhoneStatusBarView
        StatusBarInitializer initializer = mCentralSurfacesComponent.getStatusBarInitializer();
        initializer.setStatusBarViewUpdatedListener(
                (statusBarView, statusBarViewController, statusBarTransitions) -> {
                    mStatusBarView = statusBarView;
                    mPhoneStatusBarViewController = statusBarViewController;
                    mStatusBarTransitions = statusBarTransitions;
                    mNotificationShadeWindowViewController
                            .setStatusBarViewController(mPhoneStatusBarViewController);
                    // Ensure we re-propagate panel expansion values to the panel controller and
                    // any listeners it may have, such as PanelBar. This will also ensure we
                    // re-display the notification panel if necessary (for example, if
                    // a heads-up notification was being displayed and should continue being
                    // displayed).
                    mNotificationPanelViewController.updatePanelExpansionAndVisibility();
                    setBouncerShowingForStatusBarComponents(mBouncerShowing);
                    checkBarModes();
                });
                //replace容器为CollapsedStatusBarFragment
        initializer.initializeStatusBar(mCentralSurfacesComponent);

        mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView);
        mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
//导航栏,补充3
        createNavigationBar(result);

        if (ENABLE_LOCKSCREEN_WALLPAPER && mWallpaperSupported) {
            mLockscreenWallpaper = mLockscreenWallpaperLazy.get();
        }

        mAmbientIndicationContainer = mNotificationShadeWindowView.findViewById(
                R.id.ambient_indication_container);

        mAutoHideController.setStatusBar(new AutoHideUiElement() {
            @Override
            public void synchronizeState() {
                checkBarModes();
            }

            @Override
            public boolean shouldHideOnTouch() {
                return !mRemoteInputManager.isRemoteInputActive();
            }

            @Override
            public boolean isVisible() {
                return isTransientShown();
            }

            @Override
            public void hide() {
                clearTransient();
            }
        });

        ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind);
        ScrimView notificationsScrim = mNotificationShadeWindowView
                .findViewById(R.id.scrim_notifications);
        ScrimView scrimInFront = mNotificationShadeWindowView.findViewById(R.id.scrim_in_front);

        mScrimController.setScrimVisibleListener(scrimsVisible -> {
            mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
        });
        mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront);

        mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim);

        if (mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)) {
            LightRevealScrimViewBinder.bind(
                    mLightRevealScrim, mLightRevealScrimViewModelLazy.get());
        }

        mLightRevealScrim.setScrimOpaqueChangedListener((opaque) -> {
            Runnable updateOpaqueness = () -> {
                mNotificationShadeWindowController.setLightRevealScrimOpaque(
                        mLightRevealScrim.isScrimOpaque());
                mScreenOffAnimationController
                        .onScrimOpaqueChanged(mLightRevealScrim.isScrimOpaque());
            };
            if (opaque) {
                // Delay making the view opaque for a frame, because it needs some time to render
                // otherwise this can lead to a flicker where the scrim doesn't cover the screen
                mLightRevealScrim.post(updateOpaqueness);
            } else {
                updateOpaqueness.run();
            }
        });

        mScreenOffAnimationController.initialize(this, mLightRevealScrim);
        updateLightRevealScrimVisibility();

        mNotificationPanelViewController.initDependencies(
                this,
                mGestureRec,
                mShadeController::makeExpandedInvisible,
                mNotificationShelfController);

        BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
        mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
                backdrop.findViewById(R.id.backdrop_back), mScrimController, mLockscreenWallpaper);
        float maxWallpaperZoom = mContext.getResources().getFloat(
                com.android.internal.R.dimen.config_wallpaperMaxScale);
        mNotificationShadeDepthControllerLazy.get().addListener(depth -> {
            float scale = MathUtils.lerp(maxWallpaperZoom, 1f, depth);
            backdrop.setPivotX(backdrop.getWidth() / 2f);
            backdrop.setPivotY(backdrop.getHeight() / 2f);
            backdrop.setScaleX(scale);
            backdrop.setScaleY(scale);
        });

        // Set up the quick settings tile panel
        final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
        if (container != null) {
            FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
            ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
                    mExtensionController
                            .newExtension(QS.class)
                            .withPlugin(QS.class)
                            .withDefault(this::createDefaultQSFragment)
                            .build());
            mBrightnessMirrorController = new BrightnessMirrorController(
                    mNotificationShadeWindowView,
                    mNotificationPanelViewController,
                    mNotificationShadeDepthControllerLazy.get(),
                    mBrightnessSliderFactory,
                    (visible) -> {
                        mBrightnessMirrorVisible = visible;
                        updateScrimController();
                    });
            fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
                QS qs = (QS) f;
                if (qs instanceof QSFragment) {
                    mQSPanelController = ((QSFragment) qs).getQSPanelController();
                    ((QSFragment) qs).setBrightnessMirrorController(mBrightnessMirrorController);
                }
            });
        }

        mReportRejectedTouch = mNotificationShadeWindowView
                .findViewById(R.id.report_rejected_touch);
        if (mReportRejectedTouch != null) {
            updateReportRejectedTouchVisibility();
            mReportRejectedTouch.setOnClickListener(v -> {
                Uri session = mFalsingManager.reportRejectedTouch();
                if (session == null) { return; }

                StringWriter message = new StringWriter();
                message.write("Build info: ");
                message.write(SystemProperties.get("ro.build.description"));
                message.write("\nSerial number: ");
                message.write(SystemProperties.get("ro.serialno"));
                message.write("\n");

                startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND)
                                .setType("*/*")
                                .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report")
                                .putExtra(Intent.EXTRA_STREAM, session)
                                .putExtra(Intent.EXTRA_TEXT, message.toString()),
                        "Share rejected touch report")
                                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
                        true /* onlyProvisioned */, true /* dismissShade */);
            });
        }

        if (!mPowerManager.isInteractive()) {
            mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
        }
        mGestureWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
                "sysui:GestureWakeLock");

        // receive broadcasts
        registerBroadcastReceiver();

        IntentFilter demoFilter = new IntentFilter();
        if (DEBUG_MEDIA_FAKE_ARTWORK) {
            demoFilter.addAction(ACTION_FAKE_ARTWORK);
        }
        mContext.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
                android.Manifest.permission.DUMP, null,
                Context.RECEIVER_EXPORTED_UNAUDITED);

        // listen for USER_SETUP_COMPLETE setting (per-user)
        mDeviceProvisionedController.addCallback(mUserSetupObserver);
        mUserSetupObserver.onUserSetupChanged();

        // disable profiling bars, since they overlap and clutter the output on app windows
        ThreadedRenderer.overrideProperty("disableProfileBars", "true");

        // Private API call to make the shadows look better for Recents
        ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
    }

>1.inflateStatusBarWindow

    private void inflateStatusBarWindow() {
//...
        ## 拿到dagger2生成的component
        mCentralSurfacesComponent = mCentralSurfacesComponentFactory.create();
        ## 把component里方法返回类型是fragment的储存起来,方便之后实例化fragment对象,补充2
        mFragmentService.addFragmentInstantiationProvider(mCentralSurfacesComponent);
## 帧布局,注解生成的,加载的是一个布局,具体在StatusBarViewModule.java,详见另一篇blog
        mNotificationShadeWindowView = mCentralSurfacesComponent.getNotificationShadeWindowView();
        ## 注解获取,参考6.1
        mNotificationShadeWindowViewController = mCentralSurfacesComponent
                .getNotificationShadeWindowViewController();
        ## 把view传给controller,6.2小节用到
        mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
        mNotificationShadeWindowViewController.setupExpandedStatusBar();
        mNotificationPanelViewController =
                mCentralSurfacesComponent.getNotificationPanelViewController();
        mShadeController.setNotificationPanelViewController(mNotificationPanelViewController);
        mShadeController.setNotificationShadeWindowViewController(
                mNotificationShadeWindowViewController);
                ## 锁屏icon的controller
        mCentralSurfacesComponent.getLockIconViewController().init();
        mStackScrollerController =
                mCentralSurfacesComponent.getNotificationStackScrollLayoutController();
                ## mNotificationPanelViewController构造方法里给view赋值的
        mStackScroller = mStackScrollerController.getView();
        mNotifListContainer = mCentralSurfacesComponent.getNotificationListContainer();
        mPresenter = mCentralSurfacesComponent.getNotificationPresenter();
        mNotificationActivityStarter = mCentralSurfacesComponent.getNotificationActivityStarter();
        mNotificationShelfController = mCentralSurfacesComponent.getNotificationShelfController();
        ## 解锁成功后的波纹效果
        mAuthRippleController = mCentralSurfacesComponent.getAuthRippleController();
        mAuthRippleController.init();
##警告管理监听
        mHeadsUpManager.addListener(mCentralSurfacesComponent.getStatusBarHeadsUpChangeListener());

        // Listen for demo mode changes
        mDemoModeController.addCallback(mDemoModeCallback);

        if (mCommandQueueCallbacks != null) {
            mCommandQueue.removeCallback(mCommandQueueCallbacks);
        }
        mCommandQueueCallbacks =
                mCentralSurfacesComponent.getCentralSurfacesCommandQueueCallbacks();
        // Connect in to the status bar manager service
        mCommandQueue.addCallback(mCommandQueueCallbacks);

        // Perform all other initialization for CentralSurfacesScope
        for (CentralSurfacesComponent.Startable s : mCentralSurfacesComponent.getStartables()) {
            s.start();
        }
    }

>2.addFragmentInstantiationProvider

    public void addFragmentInstantiationProvider(Object daggerComponent) {
        for (Method method : daggerComponent.getClass().getDeclaredMethods()) {
            if (Fragment.class.isAssignableFrom(method.getReturnType())
                    && (method.getModifiers() & Modifier.PUBLIC) != 0) {
                String fragmentName = method.getReturnType().getName();
                if (mInjectionMap.containsKey(fragmentName)) {
                    Log.w(TAG, "Fragment " + fragmentName + " is already provided by different"
                            + " Dagger component; Not adding method");
                    continue;
                }
                mInjectionMap.put(
                        fragmentName, new FragmentInstantiationInfo(method, daggerComponent));
            }
        }
    }

>3.createNavigationBar(result);

导航栏的创建

    protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
    //参考5.1
        mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);
    }

4.4.setUpPresenter();

通知的初始化

    private void setUpPresenter() {
        // Set up the initial notification state.
        mActivityLaunchAnimator.setCallback(mActivityLaunchAnimatorCallback);
        mActivityLaunchAnimator.addListener(mActivityLaunchAnimatorListener);
        mNotificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider(
                mNotificationShadeWindowViewController,
                mNotifListContainer,
                mHeadsUpManager,
                mJankMonitor);
        mNotificationShelfController.setOnActivatedListener(mPresenter);
        mRemoteInputManager.addControllerCallback(mNotificationShadeWindowController);
        mStackScrollerController.setNotificationActivityStarter(mNotificationActivityStarter);
        mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
        mShadeController.setNotificationPresenter(mPresenter);
        mNotificationsController.initialize(
                this,
                mPresenter,
                mNotifListContainer,
                mStackScrollerController.getNotifStackController(),
                mNotificationActivityStarter,
                mCentralSurfacesComponent.getBindRowCallback());
    }

我们看下最后那个initialize方法

>1.NotificationsController

这个类有两个实现类,根据配置参数决定加载哪个,

    @Provides
    static NotificationsController provideNotificationsController(
            Context context,
            Provider<NotificationsControllerImpl> realController,//正常是这个,参考4.5
            Provider<NotificationsControllerStub> stubController) {//这个是空的实现
        if (context.getResources().getBoolean(R.bool.config_renderNotifications)) {
            return realController.get();
        } else {
            return stubController.get();
        }
    }

4.5.NotificationsControllerImpl

>1.initialize

    override fun initialize(
        centralSurfaces: CentralSurfaces,
        presenter: NotificationPresenter,
        listContainer: NotificationListContainer,
        stackController: NotifStackController,
        notificationActivityStarter: NotificationActivityStarter,
        bindRowCallback: NotificationRowBinderImpl.BindRowCallback
    ) {
        notificationListener.registerAsSystemService()

        notifPipeline.get().addCollectionListener(object : NotifCollectionListener {
            override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
                listContainer.cleanUpViewStateForEntry(entry)
            }
        })
//通知item的点击事件,交给clickBuilder处理
        notificationRowBinder.setNotificationClicker(
                clickerBuilder.build(
                    Optional.ofNullable(centralSurfaces), bubblesOptional,
                        notificationActivityStarter))
        notificationRowBinder.setUpWithPresenter(
                presenter,
                listContainer,
                bindRowCallback)
        headsUpViewBinder.setPresenter(presenter)
        notifBindPipelineInitializer.initialize()
        animatedImageNotificationManager.bind()

        notifPipelineInitializer.get().initialize(
                notificationListener,
                notificationRowBinder,
                listContainer,
                stackController)

        targetSdkResolver.initialize(notifPipeline.get())
        notificationsMediaManager.setUpWithPresenter(presenter)
        notificationLogger.setUpWithContainer(listContainer)
        peopleSpaceWidgetManager.attach(notificationListener)
        fgsNotifListener.init()
        if (featureFlags.isEnabled(Flags.NOTIFICATION_MEMORY_MONITOR_ENABLED)) {
            memoryMonitor.get().init()
        }
    }

4.6.startKeyguard

    protected void startKeyguard() {
        Trace.beginSection("CentralSurfaces#startKeyguard");
        mStatusBarStateController.addCallback(mStateListener,
                SysuiStatusBarStateController.RANK_STATUS_BAR);
        mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
        mBiometricUnlockController.addBiometricModeListener(
                new BiometricUnlockController.BiometricModeListener() {
                    @Override
                    public void onResetMode() {
                        setWakeAndUnlocking(false);
                        notifyBiometricAuthModeChanged();
                    }

                    @Override
                    public void onModeChanged(int mode) {
                        switch (mode) {
                            case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_FROM_DREAM:
                            case BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING:
                            case BiometricUnlockController.MODE_WAKE_AND_UNLOCK:
                                setWakeAndUnlocking(true);
                        }
                        notifyBiometricAuthModeChanged();
                    }

                    private void setWakeAndUnlocking(boolean wakeAndUnlocking) {
                        if (getNavigationBarView() != null) {
                            getNavigationBarView().setWakeAndUnlocking(wakeAndUnlocking);
                        }
                    }
                });
        mKeyguardViewMediator.registerCentralSurfaces(
                /* statusBar= */ this,
                mNotificationPanelViewController,
                mShadeExpansionStateManager,
                mBiometricUnlockController,
                mStackScroller,
                mKeyguardBypassController);
        mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
        mKeyguardIndicationController
                .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
        mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
        mRemoteInputManager.addControllerCallback(mStatusBarKeyguardViewManager);

        mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
        mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
        mKeyguardDismissUtil.setDismissHandler(this::executeWhenUnlocked);
    }

5.NavigationBarController

  • 这个类,在systemUI目录下,inputmethod那边也有个同名类,别找错了。

5.1. createNavigationBars

    public void createNavigationBars(final boolean includeDefaultDisplay,
            RegisterStatusBarResult result) {
        updateAccessibilityButtonModeIfNeeded();

        //看下是否创建了taskbar(平板用),两者是二选一
        final boolean shouldCreateDefaultNavbar = includeDefaultDisplay
                && !initializeTaskbarIfNecessary();
        Display[] displays = mDisplayManager.getDisplays();
        for (Display display : displays) {
            if (shouldCreateDefaultNavbar || display.getDisplayId() != DEFAULT_DISPLAY) {
            //补充1
                createNavigationBar(display, null /* savedState */, result);
            }
        }
    }

>1.createNavigationBar

    void createNavigationBar(Display display, Bundle savedState, RegisterStatusBarResult result) {
    //...
        final Context context = isOnDefaultDisplay
                ? mContext
                : mContext.createDisplayContext(display);
        NavigationBarComponent component = mNavigationBarComponentFactory.create(
                context, savedState);
                //这个是注解生成的对象
        NavigationBar navBar = component.getNavigationBar();
        navBar.init();
        mNavigationBars.put(displayId, navBar);

5.2.NavigationBar

>1.构造方法

  • 变量mView就是NavigationBarView,mFrame就是NavigationBarFrame
  • 构造方法里用到的对象也都注解生成的,参考补充3
    @Inject
    NavigationBar(
            NavigationBarView navigationBarView,
            NavigationBarFrame navigationBarFrame,
            //...
            super(navigationBarView);
           mFrame = navigationBarFrame;

super方法

    protected ViewController(T view) {
        mView = view;
    }

>2.onInit

  • init是父类的方法,子类实现的是onInit,在这里会把view添加到窗口上
    @Override
    public void onInit() {
        mView.setBarTransitions(mNavigationBarTransitions);
        mView.setTouchHandler(mTouchHandler);
        setNavBarMode(mNavBarMode);
        mEdgeBackGestureHandler.setStateChangeCallback(mView::updateStates);
        mNavigationBarTransitions.addListener(this::onBarTransition);
        mView.updateRotationButton();

        mView.setVisibility(
                mStatusBarKeyguardViewManager.isNavBarVisible() ? View.VISIBLE : View.INVISIBLE);

//..mFrame,构造方法里传递进来的。
        mWindowManager.addView(mFrame,
                getBarLayoutParams(mContext.getResources().getConfiguration().windowConfiguration
                        .getRotation()));

>3.NavigationBarModule.java

  • 补充1的构造方法里用到的对象都是下边注解生成的
  • 导航栏里边的具体逻辑这里暂时不看了,后续其他帖子再深入
    @Provides
    @NavigationBarScope
    @DisplayId
    static LayoutInflater provideLayoutInflater(@DisplayId Context context) {
        return LayoutInflater.from(context);
    }

    /**加载根容器布局 */
    @Provides
    @NavigationBarScope
    static NavigationBarFrame provideNavigationBarFrame(@DisplayId LayoutInflater layoutInflater) {
        return (NavigationBarFrame) layoutInflater.inflate(R.layout.navigation_bar_window, null);
    }

    /**又加载一个容器布局到上边的frame里*/
    @Provides
    @NavigationBarScope
    static NavigationBarView provideNavigationBarview(
            @DisplayId LayoutInflater layoutInflater, NavigationBarFrame frame) {
        View barView = layoutInflater.inflate(R.layout.navigation_bar, frame);
        return barView.findViewById(R.id.navigation_bar_view);
    }

6.NotificationShadeWindowController

  • 这个类是个接口,它的实例化应该是通过注解生成的,参考6.1
  • 搜下这个类,一般应该在XXXXModule.java类里边

6.1.ReferenceSystemUIModule.java

  • 实现类是NotificationShadeWindowControllerImpl.java
    @Binds
    abstract NotificationShadeWindowController bindNotificationShadeController(
            NotificationShadeWindowControllerImpl notificationShadeWindowController);

6.2.setNotificationShadeView

小节4.3.1调用

    public void setNotificationShadeView(ViewGroup view) {
        mNotificationShadeView = view;
    }

6.3.attach

    public void attach() {
        mLp = new LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT,
                LayoutParams.TYPE_NOTIFICATION_SHADE,
                LayoutParams.FLAG_NOT_FOCUSABLE
                        | LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                        | LayoutParams.FLAG_SPLIT_TOUCH
                        | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                        | LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
                PixelFormat.TRANSLUCENT);
        mLp.token = new Binder();
        mLp.gravity = Gravity.TOP;
        mLp.setFitInsetsTypes(0 /* types */);
        mLp.setTitle("NotificationShade");
        mLp.packageName = mContext.getPackageName();
        mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;

        mLp.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
        mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
//通过windowManager添加view,数据6.2设置的
        mWindowManager.addView(mNotificationShadeView, mLp);

        mLpChanged.copyFrom(mLp);
        onThemeChanged();

        if (mKeyguardViewMediator.isShowingAndNotOccluded()) {
            setKeyguardShowing(true);
        }
    }

>1.StatusBarViewModule

mNotificationShadeWindowView也是注解生成的,具体如下,加载的布局

    @Provides
    @CentralSurfacesComponent.CentralSurfacesScope
    public static NotificationShadeWindowView providesNotificationShadeWindowView(
            LayoutInflater layoutInflater) {
        NotificationShadeWindowView notificationShadeWindowView = (NotificationShadeWindowView)
                layoutInflater.inflate(R.layout.super_notification_shade, /* root= */ null);
        if (notificationShadeWindowView == null) {
            throw new IllegalStateException(
                    "R.layout.super_notification_shade could not be properly inflated");
        }

        return notificationShadeWindowView;
    }

6.4.StatusBarWindowController

>1.构造方法

  • mStatusBarWindowView是构造方法里传递进来的,注解生成的
    public StatusBarWindowController(
            Context context,
            //注解生成的,参考补充2
            @StatusBarWindowModule.InternalWindowView StatusBarWindowView statusBarWindowView,
            WindowManager windowManager,
            IWindowManager iWindowManager,
            StatusBarContentInsetsProvider contentInsetsProvider,
            @Main Resources resources,
            Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider) {
        mContext = context;
        mWindowManager = windowManager;
        mIWindowManager = iWindowManager;
        mContentInsetsProvider = contentInsetsProvider;
        mStatusBarWindowView = statusBarWindowView;//这个
        mLaunchAnimationContainer = mStatusBarWindowView.findViewById(
                R.id.status_bar_launch_animation_container);
        mLpChanged = new WindowManager.LayoutParams();

        if (mBarHeight < 0) {
            mBarHeight = SystemBarUtils.getStatusBarHeight(mContext);
        }

2.StatusBarWindowModule

可以看到,StatusBarWindowView也是加载布局生成的

@Module
abstract class StatusBarWindowModule {
    /**
     * Only [StatusBarWindowController] should inject the view.
     */
    @Module
    companion object {
        @JvmStatic
        @Provides
        @SysUISingleton
        @InternalWindowView
        fun providesStatusBarWindowView(layoutInflater: LayoutInflater): StatusBarWindowView {
            return layoutInflater.inflate(
                R.layout.super_status_bar,
                /* root= */null
            ) as StatusBarWindowView?
                ?: throw IllegalStateException(
                    "R.layout.super_status_bar could not be properly inflated"
                )
        }
    }

>3.attach

通过windowmanager把statusbar的view添加到屏幕上

    public void attach() {

        mLp = getBarLayoutParams(mContext.getDisplay().getRotation());
//...

        mWindowManager.addView(mStatusBarWindowView, mLp);

7.总结

  • SystemUi是个系统app,是通过SystemServer启动的
  • 在SystemUiService里会调用Appilcation里的方法,启动一系列实现了startable的对象,其中最重要的一个就是CentralSurfacesImpl这个类了。
  • 在CentralSurfacesImpl这个类,会通过windowManager添加各种view,比如状态栏,导航栏,通知栏等等
  • 每一部分都很复杂,所以后边再细看,这边就简单整理下整体流程。