android16 SystemUI之CentralSurfacesImpl原StatusBar

99 阅读8分钟

SystemUI启动的时候,读取要启动的核心组件(不再通过config.xml):

  • SystemUIService调用SystemUIApplication的startSystemUserServicesIfNeeded()
  • 通过 Dagger 组件 (mSysUIComponent) 获取所有标注好的 CoreStartable 实现类。
  • 通过 Dagger 的 @Binds 注解自动注入到 getStartables() 集合中。
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@Override
public void onCreate() {
    super.onCreate();
   //android12调用的是startServicesIfNeeded
   // Start all of SystemUI
   ((SystemUIApplication) getApplication()).startSystemUserServicesIfNeeded();
    ...
    
}


//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java)

 public void startSystemUserServicesIfNeeded() {
          if (!shouldStartSystemUserServices()) {
             
              return;  
          }
          //SystemUIInitializer mInitializer;
          final String vendorComponent = mInitializer.getVendorComponent(getResources());
  
          // Sort the startables so that we get a deterministic ordering.
          // TODO: make #start idempotent and require users of CoreStartable to call it.
          Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
                  Comparator.comparing(Class::getName));
          //全局核心服务
          sortedStartables.putAll(mSysUIComponent.getStartables());
          //用户核心服务
          sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
          startServicesIfNeeded(
                  sortedStartables, "StartServices", vendorComponent);
      }

真正启动组件:

  • 遍历 sortedStartables 列表,依次调用每个 CoreStartable 的 start() 方法。
  • 处理传入的 vendorComponent 字符串,通过反射机制实例化并启动这个厂商自定义组件。
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java)
 private void startServicesIfNeeded(
              Map<Class<?>, Provider<CoreStartable>> startables,
              String metricsPrefix,
              String vendorComponent) {
          if (mServicesStarted) {
              return;
          }
          mServices = new CoreStartable[startables.size() + (vendorComponent == null ? 0 : 1)];
  
          if (!mBootCompleteCache.isBootComplete()) {
              // check to see if maybe it was already completed long before we began
              // see ActivityManagerService.finishBooting()
              if ("1".equals(getRootComponent().getSystemPropertiesHelper()
                      .get("sys.boot_completed"))) {
                  mBootCompleteCache.setBootComplete();
                  if (DEBUG) {
                      Log.v(TAG, "BOOT_COMPLETED was already sent");
                  }
              }
          }
  
          DumpManager dumpManager = mSysUIComponent.createDumpManager();
  
          Log.v(TAG, "Starting SystemUI services for user " +
                  Process.myUserHandle().getIdentifier() + ".");
          TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
                  Trace.TRACE_TAG_APP);
          log.traceBegin(metricsPrefix);
  
          HashSet<Class<?>> startedStartables = new HashSet<>();
  
          // Perform a form of topological sort:
          // 1) Iterate through a queue of all non-started startables
          //   If the startable has all of its dependencies met
          //     - start it
          //   Else
          //     - enqueue it for the next iteration
          // 2) If anything was started and the "next" queue is not empty, loop back to 1
          // 3) If we're done looping and there are any non-started startables left, throw an error.
          //
          // This "sort" is not very optimized. We assume that most CoreStartables don't have many
          // dependencies - zero in fact. We assume two or three iterations of this loop will be
          // enough. If that ever changes, it may be worth revisiting.
  
          log.traceBegin("Topologically start Core Startables");
          boolean startedAny = false;
          ArrayDeque<Map.Entry<Class<?>, Provider<CoreStartable>>> queue;
          ArrayDeque<Map.Entry<Class<?>, Provider<CoreStartable>>> nextQueue =
                  new ArrayDeque<>(startables.entrySet());
          int numIterations = 0;
  
          int serviceIndex = 0;
  
          do {
              startedAny = false;
              queue = nextQueue;
              nextQueue = new ArrayDeque<>(startables.size());
  
              while (!queue.isEmpty()) {
                  Map.Entry<Class<?>, Provider<CoreStartable>> entry = queue.removeFirst();
  
                  Class<?> cls = entry.getKey();
                  Set<Class<? extends CoreStartable>> deps =
                          mSysUIComponent.getStartableDependencies().get(cls);
                  if (deps == null || startedStartables.containsAll(deps)) {
                      String clsName = cls.getName();
                      int i = serviceIndex;  // Copied to make lambda happy.
                      timeInitialization(
                              clsName,
                              () -> mServices[i] = startStartable(clsName, entry.getValue()),
                              log,
                              metricsPrefix);
                      startedStartables.add(cls);
                      startedAny = true;
                      serviceIndex++;
                  } else {
                      nextQueue.add(entry);
                  }
              }
              numIterations++;
          } while (startedAny && !nextQueue.isEmpty()); // if none were started, stop.
  
          if (!nextQueue.isEmpty()) { // If some startables were left over, throw an error.
              while (!nextQueue.isEmpty()) {
                  Map.Entry<Class<?>, Provider<CoreStartable>> entry = nextQueue.removeFirst();
                  Class<?> cls = entry.getKey();
                  Set<Class<? extends CoreStartable>> deps =
                          mSysUIComponent.getStartableDependencies().get(cls);
                  StringJoiner stringJoiner = new StringJoiner(", ");
                  for (Class<? extends CoreStartable> c : deps) {
                      if (!startedStartables.contains(c)) {
                          stringJoiner.add(c.getName());
                      }
                  }
                  Log.e(TAG, "Failed to start " + cls.getName()
                          + ". Missing dependencies: [" + stringJoiner + "]");
              }
  
              throw new RuntimeException("Failed to start all CoreStartables. Check logcat!");
          }
          Log.i(TAG, "Topological CoreStartables completed in " + numIterations + " iterations");
          log.traceEnd();
  
          if (vendorComponent != null) {
              timeInitialization(
                      vendorComponent,
                      () -> mServices[mServices.length - 1] =
                              startAdditionalStartable(vendorComponent),
                      log,
                      metricsPrefix);
          }
  
          for (serviceIndex = 0; serviceIndex < mServices.length; serviceIndex++) {
              final CoreStartable service = mServices[serviceIndex];
              if (mBootCompleteCache.isBootComplete()) {
                  notifyBootCompleted(service);
              }
  
              if (service.isDumpCritical()) {
                  dumpManager.registerCriticalDumpable(service);
              } else {
                  dumpManager.registerNormalDumpable(service);
              }
          }
          mSysUIComponent.getInitController().executePostInitTasks();
          log.traceEnd();
  
          mServicesStarted = true;
  }

android16中StatusBar没有了,变成了CentralSurfacesImpl,不再继承SystemUI,改成了实现CoreStartable

启动状态栏,通知栏,导航栏

//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java)

 
public void start() {

  
          
  
     
          mBarService = IStatusBarService.Stub.asInterface(
                  ServiceManager.getService(Context.STATUS_BAR_SERVICE));
  
          mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
          mWallpaperSupported = mWallpaperManager.isWallpaperSupported();
  
          RegisterStatusBarResult result = null;
          if (!StatusBarConnectedDisplays.isEnabled()) {
              try {
              //注册CommandQueue到StatusBarManagerService
                  result = mBarService.registerStatusBar(mCommandQueue);
              } catch (RemoteException ex) {
                  ex.rethrowFromSystemServer();
              }
          }
         
         //创建状态栏,导航栏,通知栏
          createAndAddWindows(result);
          //初始化通知栏状态
          setUpPresenter();
  
         
  
         ...
  
          // end old BaseStatusBar.start().
  
          // Lastly, call to the icon policy to install/update all the icons.
          //初始化状态栏图标 PhoneStatusBarPolicy mIconPolicy
          mIconPolicy.init();
  
        
  

          startKeyguard();
  
          mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
          mDozeServiceHost.initialize(
                  this,
                  mStatusBarKeyguardViewManager,
                  getNotificationShadeWindowViewController(),
                  mAmbientIndicationContainer);


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

注册CommandQueue到StatusBarManagerService,同时返回服务端保存的图标列表

//frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java)
 
  public RegisterStatusBarResult registerStatusBar(IStatusBar bar) {
          enforceStatusBarService();
          enforceValidCallingUser();
  
          Slog.i(TAG, "registerStatusBar bar=" + bar);
          mBar = bar;
          mDeathRecipient.linkToDeath();
          notifyBarAttachChanged();
          final ArrayMap<String, StatusBarIcon> icons;
          synchronized (mIcons) {
              icons = new ArrayMap<>(mIcons);
          }
          synchronized (mLock) {
              final UiState state = mDisplayUiState.get(DEFAULT_DISPLAY);
              return new RegisterStatusBarResult(icons, gatherDisableActionsLocked(mCurrentUserId, 1),
                      state.mAppearance, state.mAppearanceRegions, state.mImeWindowVis,
                      state.mImeBackDisposition, state.mShowImeSwitcher,
                      gatherDisableActionsLocked(mCurrentUserId, 2),
                      state.mNavbarColorManagedByIme, state.mBehavior, state.mRequestedVisibleTypes,
                      state.mPackageName, state.mTransientBarTypes, state.mLetterboxDetails);
          }
}

PhoneStatusBarPolicy初始化状态栏图标入口

  • PhoneStatusBarPolicy:决定了哪些图标应在开机时加载到状态栏。它会根据系统状态(如蓝牙是否开启、是否有闹钟等)来显示和隐藏系统图标。
  • CentralSurfacesImpl:SystemUI的主入口,负责初始化整体布局并实例。化 PhoneStatusBarPolicy。
  • StatusBarManagerService:系统服务,负责接收并管理来自各个应用的图标更新请求。
  • IconManager:实际负责将 StatusBarIconView 添加到状态栏布局中。
  • StatusBarIconView:负责单个图标的具体显示和更。
  • StatusBarIconControllerImpl:作为中间层,将 PhoneStatusBarPolicy 的控制指令分发到具体的 IconManager 去执行。
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java)
    public void init() {
          ...
          // TTY status
          updateTTY();
  
          // bluetooth status
          updateBluetooth();
  
          // Alarm clock
          //private final StatusBarIconController mIconController;
          //设置图标
          mIconController.setIcon(mSlotAlarmClock, R.drawable.stat_sys_alarm, null);
          mIconController.setIconVisibility(mSlotAlarmClock, false);
          ...
         
          mCommandQueue.addCallback(this);
      }

状态栏图标列表配置在config.xml 中的 config_statusBarIcons 数组,StatusBarIconControllerImpl的构造函数中初始化StatusBarIconList的时候通过Dagger注入


//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java)
  
@Inject
public StatusBarIconControllerImpl(
              Context context,
              CommandQueue commandQueue,
              DemoModeController demoModeController,
              ConfigurationController configurationController,
              TunerService tunerService,
              DumpManager dumpManager,
              StatusBarIconList statusBarIconList,
              StatusBarPipelineFlags statusBarPipelineFlags,
              BindableIconsRegistry modernIconsRegistry
      ) {
          mStatusBarIconList = statusBarIconList;
          mContext = context;
          mStatusBarPipelineFlags = statusBarPipelineFlags;
  
          configurationController.addCallback(this);
          commandQueue.addCallback(mCommandQueueCallbacks);
          tunerService.addTunable(this, ICON_HIDE_LIST);
          demoModeController.addCallback(this);
          dumpManager.registerDumpable(getClass().getSimpleName(), this);
  
          addModernBindableIcons(modernIconsRegistry);
      }

 }
 
//状态栏图标列表
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java

@Provides
      @SysUISingleton
      static StatusBarIconList provideStatusBarIconList(Context context) {
          return new StatusBarIconList(
                  context.getResources().getStringArray(
                          com.android.internal.R.array.config_statusBarIcons));
 }

创建状态栏,通知栏,导航栏

//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java)
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {       //1.创建状态栏,导航栏,通知栏View
    makeStatusBarView(result);    
    //2.通过WindowManager.addView 添加通知栏窗口
    mNotificationShadeWindowController.attach();  
    //当未启用新多屏功能时,通过 Store 获取默认显示屏的控制器
    //3.通过WindowManager.addView 添加状态栏窗口
   if (!StatusBarConnectedDisplays.isEnabled()) {
              mStatusBarWindowControllerStore.getDefaultDisplay().attach();
          } 
    }


创建导航栏,通知栏View

 //frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java)
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
          ...
          //创建通知栏
          setUpShade();
          getNotificationShadeWindowView().setOnTouchListener(getStatusBarWindowTouchListener());
          mWallpaperController.setRootView(getNotificationShadeWindowView());
  
          mDemoModeController.addCallback(mDemoModeCallback);
          // When the StatusBarConnectedDisplays flag is enabled, this logic will be done in
          // StatusBarOrchestrator.
          if (!StatusBarConnectedDisplays.isEnabled()) {
              mJavaAdapter.alwaysCollectFlow(
                      mStatusBarModeRepository.getDefaultDisplay().isTransientShown(),
                      this::onTransientShownChanged);
              mJavaAdapter.alwaysCollectFlow(
                      mStatusBarModeRepository.getDefaultDisplay().getStatusBarMode(),
                      this::updateBarMode);
          }
          mCommandQueueCallbacks = mCommandQueueCallbacksLazy.get();
          mCommandQueue.addCallback(mCommandQueueCallbacks);
  
          // TODO: Deal with the ugliness that comes from having some of the status bar broken out
          // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
          ShadeExpansionChangeEvent currentState =
                  mShadeExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
          mWakeUpCoordinator.onPanelExpansionChanged(currentState);
  
          // When the StatusBarConnectedDisplays flag is enabled, all this logic will be done in
          // StatusBarOrchestrator.
          if (!StatusBarConnectedDisplays.isEnabled()) {
              // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
              mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
              mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
  
              // Set up CollapsedStatusBarFragment and PhoneStatusBarView
              mStatusBarInitializer.setStatusBarViewUpdatedListener(
                      (statusBarViewController, statusBarTransitions) -> {
  
                          mPhoneStatusBarViewController = statusBarViewController;
                          mStatusBarTransitions = statusBarTransitions;
                          getNotificationShadeWindowViewController()
                                  .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).
                          mShadeSurface.updateExpansionAndVisibility();
                          setBouncerShowingForStatusBarComponents(mBouncerShowing);
                          checkBarModes();
                      });
          }
          
         // 只有当“状态栏根视图现代化”和“状态栏连接显示屏”这两个特性都**没有启用**时
          if (!StatusBarRootModernization.isEnabled() && !StatusBarConnectedDisplays.isEnabled()) {
              // When the flag is on, we register the fragment as a core startable and this is not
              // needed
              // 才走“老路”,手动调用 StatusBarInitializer 来初始化状态栏
              mStatusBarInitializer.initializeStatusBar();
          }
  
          mShadeTouchableRegionManager.setup(getNotificationShadeWindowView());
  
          if (!StatusBarConnectedDisplays.isEnabled()) {
          //创建导航栏
              createNavigationBar(result);
          }
  
          mAmbientIndicationContainer = getNotificationShadeWindowView().findViewById(
                  R.id.ambient_indication_container);
  
          // When the StatusBarConnectedDisplays flag is enabled, all this logic will be done in
          // StatusBarOrchestrator.
          if (!StatusBarConnectedDisplays.isEnabled()) {
              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() {
                              mStatusBarModeRepository.getDefaultDisplay().clearTransient();
                          }
                      });
          }
  
          ScrimView scrimBehind = getNotificationShadeWindowView().findViewById(R.id.scrim_behind);
          ScrimView notificationsScrim = getNotificationShadeWindowView()
                  .findViewById(R.id.scrim_notifications);
          ScrimView scrimInFront = getNotificationShadeWindowView().findViewById(R.id.scrim_in_front);
  
          mScrimController.setScrimVisibleListener(scrimsVisible -> {
              mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
          });
          mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront);
  
          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, mShadeSurface, mLightRevealScrim);
  
          if (!SceneContainerFlag.isEnabled()) {
              mShadeSurface.initDependencies(
                      this,
                      mGestureRec,
                      mShadeController::makeExpandedInvisible,
                      mHeadsUpManager);
          }
  
          // Set up the quick settings tile panel
          final View container = getNotificationShadeWindowView().findViewById(R.id.qs_frame);
          if (container != null && !SceneContainerFlag.isEnabled()) {
              FragmentHostManager fragmentHostManager =
                      mFragmentService.getFragmentHostManager(container);
              ExtensionFragmentListener.attachExtensonToFragment(
                      mFragmentService,
                      container,
                      QS.TAG,
                      R.id.qs_frame,
                      mExtensionController
                              .newExtension(QS.class)
                              .withPlugin(QS.class)
                              .withDefault(this::createDefaultQSFragment)
                              .build());
              mBrightnessMirrorController = new BrightnessMirrorController(
                      getNotificationShadeWindowView(),
                      mShadeSurface,
                      mNotificationShadeDepthControllerLazy.get(),
                      mBrightnessSliderFactory,
                      this::setBrightnessMirrorShowing);
              fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
                  QS qs = (QS) f;
                  if (qs instanceof QSFragmentLegacy) {
                      QSFragmentLegacy qsFragment = (QSFragmentLegacy) qs;
                      mQSPanelController = qsFragment.getQSPanelController();
                      qsFragment.setBrightnessMirrorController(mBrightnessMirrorController);
                  }
              });
          }
  
          mReportRejectedTouch = getNotificationShadeWindowView()
                  .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");
  
                  
  
          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();
  
          // 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));
      }

       
       
   
      
        

加载状态栏:

  • super_status_bar为状态栏根布局,在StatusBarWindowControllerImpl的构造函数中通过StatusBarWindowViewInflater来加载。StatusBarWindowViewInflater的实现类是StatusBarWindowViewInflaterImpl。mStatusBarWindowControllerStore( StatusBarWindowControllerStore)在CentralSurfacesImpl的构造函数中初始化,实际就是构造一个StatusBarWindowControllerImpl。
  • CollapsedStatusBarFragment负责展示,管理状态栏的布局和具体UI元素, 在CentralSurfacesImpl的构造函数中初始化StatusBarInitializer,通过StatusBarInitializer被动态地替换到 super_status_bar.xml的ID为status_bar_container 容器中。super_status_bar.xml是状态栏的根布局。
//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
  public StatusBarWindowControllerImpl(
100              @Assisted Context context,
101              @InternalWindowViewInflater StatusBarWindowViewInflater statusBarWindowViewInflater,
102              @Assisted WindowManager windowManager,
103              @Assisted StatusBarConfigurationController statusBarConfigurationController,
104              IWindowManager iWindowManager,
105              @Assisted StatusBarContentInsetsProvider contentInsetsProvider,
106              FragmentService fragmentService,
107              Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider,
108              @Main Executor mainExecutor) {
109          mContext = context;
110          mWindowManager = windowManager;
111          mStatusBarConfigurationController = statusBarConfigurationController;
112          mIWindowManager = iWindowManager;
113          mContentInsetsProvider = contentInsetsProvider;
114          mMainExecutor = mainExecutor;
115          mStatusBarWindowView = statusBarWindowViewInflater.inflate(context);
116          mFragmentService = fragmentService;
117          mLaunchAnimationContainer = mStatusBarWindowView.findViewById(
118                  R.id.status_bar_launch_animation_container);
119          mLpChanged = new WindowManager.LayoutParams();
120  
121          if (mBarHeight < 0) {
122              mBarHeight = SystemBarUtils.getStatusBarHeight(mContext);
123          }
124          unfoldTransitionProgressProvider.ifPresent(
125                  unfoldProgressProvider -> unfoldProgressProvider.addCallback(
126                          new JankMonitorTransitionProgressListener(
127                                  /* attachedViewProvider=*/ () -> mStatusBarWindowView)));
128      }



//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowViewInflater.kt
interface StatusBarWindowViewInflater {
      fun inflate(context: Context): StatusBarWindowView
  }
  
  class StatusBarWindowViewInflaterImpl @Inject constructor() : StatusBarWindowViewInflater {
  
      override fun inflate(context: Context): StatusBarWindowView {
          val layoutInflater = LayoutInflater.from(context)
          return layoutInflater.inflate(R.layout.super_status_bar, /* root= */ null)
              as StatusBarWindowView?
              ?: throw IllegalStateException(
                  "R.layout.super_status_bar could not be properly inflated"
              )
      }
  }
  
  
  
  
//初始化CollapsedStatusBarFragment
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt

override fun start() {
          doStart()
 }
  
 override fun initializeStatusBar() {
          StatusBarRootModernization.assertInLegacyMode()
          doStart()
 }
  
 private fun doStart() {
          if (StatusBarRootModernization.isEnabled) doComposeStart() else doLegacyStart()
  }
  
      /**
       * Stand up the [PhoneStatusBarView] in a compose root. There will be no
       * [CollapsedStatusBarFragment] in this mode
       */
private fun doComposeStart() {
          initialized = true
          val statusBarRoot =
              statusBarRootFactory.create(statusBarWindowController.backgroundView as ViewGroup) { cv
                  ->
                  val phoneStatusBarView = cv.findViewById<PhoneStatusBarView>(R.id.status_bar)
                  component =
                      componentFactory
                          .create(
                              phoneStatusBarView,
                              statusBarConfigurationController,
                              statusBarWindowController,
                              darkIconDispatcher,
                          )
                          .also { component ->
                              // CollapsedStatusBarFragment used to be responsible initializing
                              component.init()
  
                              statusBarViewUpdatedListener?.onStatusBarViewUpdated(
                                  component.phoneStatusBarViewController,
                                  component.phoneStatusBarTransitions,
                              )
  
                              if (StatusBarConnectedDisplays.isEnabled) {
                                  statusBarModePerDisplayRepository.onStatusBarViewInitialized(
                                      component
                                  )
                              } else {
                                  creationListeners.forEach { listener ->
                                      listener.onStatusBarViewInitialized(component)
                                  }
                              }
                          }
              }
  
          // Add the new compose view to the hierarchy because we don't use fragment transactions
          // anymore
          val windowBackgroundView = statusBarWindowController.backgroundView as ViewGroup
          windowBackgroundView.addView(statusBarRoot)
      }
  
      private fun doLegacyStart() {
          initialized = true
          statusBarWindowController.fragmentHostManager
              .addTagListener(
                  CollapsedStatusBarFragment.TAG,
                  object : FragmentHostManager.FragmentListener {
                      override fun onFragmentViewCreated(tag: String, fragment: Fragment) {
                          val statusBarFragment = fragment as CollapsedStatusBarFragment
                          if (statusBarFragment.homeStatusBarComponent == null) {
                              return
                          }
                          component = fragment.homeStatusBarComponent
                          statusBarViewUpdatedListener?.onStatusBarViewUpdated(
                              component!!.phoneStatusBarViewController,
                              component!!.phoneStatusBarTransitions,
                          )
                          creationListeners.forEach { listener ->
                              listener.onStatusBarViewInitialized(component!!)
                          }
                      }
  
                      override fun onFragmentViewDestroyed(tag: String?, fragment: Fragment?) {
                          // nop
                      }
                  },
              )
              .fragmentManager
              .beginTransaction()
              .replace(
                  R.id.status_bar_container,
                  collapsedStatusBarFragmentProvider.get(),
                  CollapsedStatusBarFragment.TAG,
              )
              .commit()     
}

加载通知栏,初始化入口变得更隐蔽。super_notification_shade为通知栏根布局。NotificationShadeWindowControllerImpl构造函数创建windowRootViewComponent,CentralSurfacesImpl的构造函数又会创建NotificationShadeWindowControllerImpl。

https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java

   public NotificationShadeWindowControllerImpl(
              @ShadeDisplayAware Context context,
              WindowRootViewComponent.Factory windowRootViewComponentFactory,
              @ShadeDisplayAware WindowManager windowManager,
              IActivityManager activityManager,
              DozeParameters dozeParameters,
              StatusBarStateController statusBarStateController,
              @ShadeDisplayAware ConfigurationController configurationController,
              KeyguardViewMediator keyguardViewMediator,
              KeyguardBypassController keyguardBypassController,
              @Main Executor mainExecutor,
              @Background Executor backgroundExecutor,
              SysuiColorExtractor colorExtractor,
              DumpManager dumpManager,
              KeyguardStateController keyguardStateController,
              AuthController authController,
              Lazy<ShadeInteractor> shadeInteractorLazy,
              ShadeWindowLogger logger,
              Lazy<SelectedUserInteractor> userInteractor,
              UserTracker userTracker,
              NotificationShadeWindowModel notificationShadeWindowModel,
              Lazy<CommunalInteractor> communalInteractor,
              @ShadeDisplayAware LayoutParams shadeWindowLayoutParams) 
              

//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
  fun providesWindowRootView(
              @ShadeDisplayAware layoutInflater: LayoutInflater,
              viewModelFactory: SceneContainerViewModel.Factory,
              containerConfigProvider: Provider<SceneContainerConfig>,
              scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>,
              overlaysProvider: Provider<Set<@JvmSuppressWildcards Overlay>>,
              layoutInsetController: NotificationInsetsController,
              sceneDataSourceDelegator: Provider<SceneDataSourceDelegator>,
              qsSceneAdapter: Provider<QSSceneAdapter>,
              sceneJankMonitorFactory: SceneJankMonitor.Factory,
              windowRootViewKeyEventHandler: WindowRootViewKeyEventHandler,
          ): WindowRootView {
              return if (SceneContainerFlag.isEnabled) {
                  checkNoSceneDuplicates(scenesProvider.get())
                  val sceneWindowRootView =
                      layoutInflater.inflate(R.layout.scene_window_root, null) as SceneWindowRootView
                  sceneWindowRootView.init(
                      viewModelFactory = viewModelFactory,
                      containerConfig = containerConfigProvider.get(),
                      sharedNotificationContainer =
                          sceneWindowRootView.requireViewById(R.id.shared_notification_container),
                      scenes = scenesProvider.get(),
                      overlays = overlaysProvider.get(),
                      layoutInsetController = layoutInsetController,
                      sceneDataSourceDelegator = sceneDataSourceDelegator.get(),
                      qsSceneAdapter = qsSceneAdapter,
                      sceneJankMonitorFactory = sceneJankMonitorFactory,
                      windowRootViewKeyEventHandler = windowRootViewKeyEventHandler,
                  )
                  sceneWindowRootView
              } else {
                  layoutInflater.inflate(R.layout.super_notification_shade, null)
              }
                  as WindowRootView?
                  ?: throw IllegalStateException("Window root view could not be properly inflated")
          }
  




//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
 private void setUpShade() {
          
          mNotificationShadeWindowController.fetchWindowRootView();
          getNotificationShadeWindowViewController().setupExpandedStatusBar();
          getNotificationShadeWindowViewController().setupCommunalHubLayout();
      }
      
      
      

//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
 public void fetchWindowRootView() {
309          WindowRootViewComponent component = mWindowRootViewComponentFactory.create();
310          mWindowRootView = component.getWindowRootView();
311          collectFlow(
312                  mWindowRootView,
313                  mShadeInteractorLazy.get().isAnyExpanded(),
314                  this::onShadeOrQsExpanded
315          );
316          collectFlow(
317                  mWindowRootView,
318                  mShadeInteractorLazy.get().isQsExpanded(),
319                  this::onQsExpansionChanged
320          );
321          collectFlow(
322                  mWindowRootView,
323                  mCommunalInteractor.get().isCommunalVisible(),
324                  this::onCommunalVisibleChanged
325          );
326  
327          if (!SceneContainerFlag.isEnabled() && Flags.useTransitionsForKeyguardOccluded()) {
328              collectFlow(
329                      mWindowRootView,
330                      mNotificationShadeWindowModel.isKeyguardOccluded(),
331                      this::setKeyguardOccluded
332              );
333          }
334          if (ComposeBouncerFlags.INSTANCE.isComposeBouncerOrSceneContainerEnabled()) {
335              collectFlow(mWindowRootView, mNotificationShadeWindowModel.isBouncerShowing(),
336                      this::setBouncerShowing);
337              collectFlow(mWindowRootView, mNotificationShadeWindowModel.getDoesBouncerRequireIme(),
338                      this::setKeyguardNeedsInput);
339          }
340      }

创建导航栏

//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
          StatusBarConnectedDisplays.assertInLegacyMode();
          //NavigationBarControllerImpl mNavigationBarController
          mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);
      }
      
      
//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
public void createNavigationBars(final boolean includeDefaultDisplay,
              RegisterStatusBarResult result) {
          // Don't need to create nav bar on the default display if we initialize TaskBar.
          final boolean shouldCreateDefaultNavbar = includeDefaultDisplay
                  && !initializeTaskbarIfNecessary();
          Display[] displays = mDisplayTracker.getAllDisplays();
          for (Display display : displays) {
              if (shouldCreateDefaultNavbar
                      || display.getDisplayId() != mDisplayTracker.getDefaultDisplayId()) {
                  createNavigationBar(display, null /* savedState */, result);
              }
          }
      }


添加通知栏窗口

```NotificationShadeWindowControllerImpl
//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
 public void attach() {
          // Now that the notification shade encompasses the sliding panel and its
          // translucent backdrop, the entire thing is made TRANSLUCENT and is
          // hardware-accelerated.
          // mLP is assigned here (instead of the constructor) as its null value is also used to check
          // if the shade window has been attached.
          mLp = mShadeWindowLayoutParams;
          mWindowManager.addView(mWindowRootView, mLp);
  
          // We use BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE here, however, there is special logic in
          // window manager which disables the transient show behavior.
          // TODO: Clean this up once that behavior moves into the Shell.
          if (mWindowRootView.getWindowInsetsController() != null) {
              mWindowRootView.getWindowInsetsController().setSystemBarsBehavior(
                      BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
          }
  
          mLpChanged.copyFrom(mLp);
          onThemeChanged();
  
          // Make the state consistent with KeyguardViewMediator#setupLocked during initialization.
          if (mKeyguardViewMediator.isShowingAndNotOccluded()) {
              setKeyguardShowing(true);
          }
      }

添加状态栏窗口

//https://xrefandroid.com/android-16.0.0_r2/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
  public void attach() {
          if (StatusBarConnectedDisplays.isEnabled()) {
              mStatusBarWindowView.setStatusBarConfigurationController(
                      mStatusBarConfigurationController);
          }
          // Now that the status bar window encompasses the sliding panel and its
          // translucent backdrop, the entire thing is made TRANSLUCENT and is
          // hardware-accelerated.
          Trace.beginSection("StatusBarWindowController.getBarLayoutParams");
          mLp = getBarLayoutParams(mContext.getDisplay().getRotation());
          Trace.endSection();
  
          try {
              mWindowManager.addView(mStatusBarWindowView, mLp);
          } catch (WindowManager.InvalidDisplayException e) {
              // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
              // after being added, and initialization hasn't finished yet.
              Log.e(
                      TAG,
                      "Unable to add view to WindowManager. Display with id "
                              + mContext.getDisplayId()
                              + " doesn't exist anymore.",
                      e);
          }
          mLpChanged.copyFrom(mLp);
  
          mContentInsetsProvider.addCallback(this::calculateStatusBarLocationsForAllRotations);
          calculateStatusBarLocationsForAllRotations();
          mIsAttached = true;
          apply(mCurrentState);
   }