第一阶段:系统服务的启动(SystemServer 发起)
一切的起点在 SystemServer,这是 Android 框架中负责启动绝大多数核心系统服务的关键进程。
- 启动入口 :在
SystemServer的startOtherServices()方法中,会调用startSystemUi(context, windowManager)。 - 获取组件 :
startSystemUi方法会通过PackageManagerInternal来获取 SystemUI 的服务组件名(SystemUIService)。 - 发起启动 :最终,通过
context.startServiceAsUser(intent, UserHandle.SYSTEM),以系统用户身份启动了这个服务。至此,启动流程从系统进程跨入了 SystemUI 应用进程。
csharp
//frameworks/base/services/java/com/android/server/SystemServer.java
private static void startSystemUi(Context context, WindowManagerService windowManager) {
PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
Intent intent = new Intent();
//通过PMS配置获取
intent.setComponent(pm.getSystemUiServiceComponent());
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
/Users/apple/Downloads/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public ComponentName getSystemUiServiceComponent() {
return ComponentName.unflattenFromString(mContext.getResources().getString(
com.android.internal.R.string.config_systemUIServiceComponent));
}
//frameworks/base/core/res/res/values/config.xml
<string name="config_systemUIServiceComponent" translatable="false"
>com.android.systemui/com.android.systemui.SystemUIService</string>
第二阶段:应用与服务的初始化(SystemUI 应用内部)
当 SystemUIService 被拉起后,SystemUI 这个系统应用(APK)便开始启动。
- 应用入口 :作为应用的入口,
SystemUIApplication的onCreate()会被执行,进行一系列初始化工作。
scss
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@Override
public void onCreate() {
super.onCreate();
//这是一个回调,用于在 `Context` 可用时通知 Dagger2 的依赖注入框架
mContextAvailableCallback.onContextAvailable(this);
//`mRootComponent` 和 `mSysUIComponent` 是 Dagger2 生成的依赖注入图,
//所有 SystemUI 组件(StatusBar、Keyguard等)都从这里获取。
mRootComponent = SystemUIFactory.getInstance().getRootComponent();
mSysUIComponent = SystemUIFactory.getInstance().getSysUIComponent();
//`mComponentHelper`:用于通过反射动态创建 SystemUI 服务组件
mComponentHelper = mSysUIComponent.getContextComponentHelper();
//**`mBootCompleteCache`**:缓存系统启动完成状态,避免重复处理
mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
//应用层设置主题,确保所有 Service 继承该主题
//在 Manifest 中设置主题只对 Activity 有效,Service 需要显式设置
setTheme(R.style.Theme_SystemUI);
if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
//注册 BOOT_COMPLETED 广播
IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
//确保 SystemUI 能优先收到启动完成事件
bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
...
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
...
if (mServicesStarted) {
final int N = mServices.length;
for (int i = 0; i < N; i++) {
//遍历已启动的所有 SystemUI 组件(StatusBar、Keyguard等),
//调用它们的 `onBootCompleted()` 方法
mServices[i].onBootCompleted();
}
}
}
}, bootCompletedFilter);
//监听系统语言变更广播
IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
...
}
}, localeChangedFilter);
} else {
...
// 为当前非系统用户启动必要的服务
startSecondaryUserServicesIfNeeded();
}
}
-
启动所有服务组件 :在
SystemUIService的onCreate()中,会调用SystemUIApplication.startServicesIfNeeded()。startServicesIfNeeded()会通过反射机制,将配置文件中定义的所有 SystemUI 组件(如StatusBar,Keyguard,NotificationListener等)实例化并启动。- 这些组件都继承自
SystemUI基类,它们的start()方法会在此阶段被调用。
typescript
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@Override
public void onCreate() {
super.onCreate();
...
((SystemUIApplication) getApplication()).startServicesIfNeeded();
...
}
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java)
public void startServicesIfNeeded() {
String[] names = SystemUIFactory.getInstance().getSystemUIServiceComponents(getResources());
startServicesIfNeeded(/* metricsPrefix= */ "StartServices", names);
}
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java)
public String[] getSystemUIServiceComponents(Resources resources) {
return resources.getStringArray(R.array.config_systemUIServiceComponents);
}
//frameworks/base/packages/SystemUI/res/values/config.xml
//SystemUI组件配置
<string-array name="config_systemUIServiceComponents" translatable="false">
<item>com.android.systemui.util.NotificationChannels</item>
<item>com.android.systemui.keyguard.KeyguardViewMediator</item>
<item>com.android.systemui.recents.Recents</item>
<item>com.android.systemui.volume.VolumeUI</item>
<item>com.android.systemui.statusbar.phone.StatusBar</item>
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item>
<item>com.android.systemui.media.RingtonePlayer</item>
<item>com.android.systemui.keyboard.KeyboardUI</item>
<item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
<item>@string/config_systemUIVendorServiceComponent</item>
<item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
<item>com.android.systemui.LatencyTester</item>
<item>com.android.systemui.globalactions.GlobalActionsComponent</item>
<item>com.android.systemui.ScreenDecorations</item>
<item>com.android.systemui.biometrics.AuthController</item>
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
<item>com.android.systemui.theme.ThemeOverlayController</item>
<item>com.android.systemui.accessibility.WindowMagnification</item>
<item>com.android.systemui.accessibility.SystemActions</item>
<item>com.android.systemui.toast.ToastUI</item>
<item>com.android.systemui.wmshell.WMShell</item>
</string-array>
第三阶段:StatusBar 的创建与视图加载
在所有被启动的服务组件中,StatusBar 是构建状态栏和通知面板的核心。
- 执行
start()方法 :在StatusBar的start()方法中,会调用createAndAddWindows()。
scss
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java)
public void start() {
//监听屏幕开/关状态,控制状态栏的显示/隐藏
mScreenLifecycle.addObserver(mScreenObserver);
//监听系统唤醒状态(唤醒/睡眠),影响锁屏和通知行为
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
//监听UI模式变化
mUiModeManager = mContext.getSystemService(UiModeManager.class);
...
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
//屏保管理(Daydream)
mDreamManager = IDreamManager.Stub.asInterface(
ServiceManager.checkService(DreamService.DREAM_SERVICE));
...
// start old BaseStatusBar.start().
mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
//设备策略管理(如禁用状态栏)
mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
Context.DEVICE_POLICY_SERVICE);
...
//`StatusBarManagerService` 的Binder接口,用于与系统服务通信
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
//锁屏管理
mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
...
//CommandQueue实现了 `IStatusBar` 接口
mCommandQueue.addCallback(this);
...
RegisterStatusBarResult result = null;
try {
//向 `StatusBarManagerService` 注册回调,返回的 `result` 包含了初始状态信息
result = mBarService.registerStatusBar(mCommandQueue);
} catch (RemoteException ex) {
ex.rethrowFromSystemServer();
}
//创建窗口和视图
//- 加载 `super_status_bar.xml` 根布局
//- 创建折叠状态栏 (`CollapsedStatusBarFragment`)
//- 创建展开面板 (`NotificationPanelView`)
//- 通过 `StatusBarWindowController` 添加到 WindowManager
createAndAddWindows(result);
setUpPresenter();
...
mIconPolicy.init();
mKeyguardStateController.addCallback(this);
//初始化锁屏UI,但不一定显示(取决于锁屏状态)
startKeyguard();
//监听锁屏状态变化(如人脸解锁、指纹等)
mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
//初始化息屏显示(Always-On Display)相关功能
mDozeServiceHost.initialize(
this,
mStatusBarKeyguardViewManager,
mNotificationShadeWindowViewController,
mNotificationPanelViewController,
mAmbientIndicationContainer);
mDozeParameters.addCallback(this::updateLightRevealScrimVisibility);
...
}
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
//创建状态栏视图
makeStatusBarView(result);
//添加下拉通知面板窗口
mNotificationShadeWindowController.attach();
//添加状态栏窗口
mStatusBarWindowController.attach();
}
- 构建核心视图 :
createAndAddWindows()进一步调用makeStatusBarView(),这就是构建状态栏视图的关键入口。
scss
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
final Context context = mContext;
...
//加载 `super_status_bar.xml` 布局文件,创建 `StatusBarWindowView` 根视图
//创建下拉面板视图,创建状态栏窗口视图
inflateStatusBarWindow();
//将 `StatusBar` 实例和窗口控制器注入到下拉面板窗口控制器中,建立双向引用
mNotificationShadeWindowViewController.setService(this, mNotificationShadeWindowController);
//为下拉面板根视图设置触摸监听器,处理触摸事件分发
mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());
//初始化通知列表控制器
mStackScrollerController =
mNotificationPanelViewController.getNotificationStackScrollLayoutController();
//获取 `NotificationStackScrollLayout` 视图实例
mStackScroller = mStackScrollerController.getView();
//获取通知列表容器接口,用于操作通知列表
NotificationListContainer notifListContainer =
mStackScrollerController.getNotificationListContainer();
mNotificationLogger.setUpWithContainer(notifListContainer);
//创建底部工具条 (Shelf)
inflateShelf();
//将 Shelf 控制器设置到通知图标区域控制器中,建立关联
mNotificationIconAreaController.setupShelf(mNotificationShelfController);
//添加面板展开监听器,用于唤醒协调器(处理亮屏/暗屏过渡) mNotificationPanelViewController.addExpansionListener(mWakeUpCoordinator);
//添加面板展开监听器,用于在锁屏状态下面板展开时触发锁屏消失逻辑
mNotificationPanelViewController.addExpansionListener(
this::dispatchPanelExpansionForKeyguardDismiss);
...
//监听 `CollapsedStatusBarFragment` 的创建完成事件
FragmentHostManager.get(mPhoneStatusBarWindow)
//添加标签监听器,当带有 `TAG` 的 Fragment 被创建或重新创建时触发回调
.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
CollapsedStatusBarFragment statusBarFragment =
(CollapsedStatusBarFragment) fragment;
PhoneStatusBarView oldStatusBarView = mStatusBarView;
//从 Fragment 中获取新创建的 `PhoneStatusBarView` 视图
mStatusBarView = (PhoneStatusBarView) statusBarFragment.getView();
//将 `StatusBar` 实例注入到视图,用于回调状态栏事件
mStatusBarView.setBar(this);
//注入面板控制器,用于面板展开状态查询
mStatusBarView.setPanel(mNotificationPanelViewController);
//注入遮罩控制器,用于控制遮罩层
mStatusBarView.setScrimController(mScrimController);
//设置展开状态变化监听器列表
mStatusBarView.setExpansionChangedListeners(mExpansionChangedListeners);
for (ExpansionChangedListener listener : mExpansionChangedListeners) {
//向监听器发送当前展开状态(初始值)
sendInitialExpansionAmount(listener);
}
mNotificationPanel.notifyBarPanelExpansionChanged().
//检查是否有固定的 HeadsUp 通知(即正在显示的 HeadsUp)
if (mHeadsUpManager.hasPinnedHeadsUp()) {
//通知面板展开状态已变化,更新视图 mNotificationPanelViewController.notifyBarPanelExpansionChanged();
}
mStatusBarView.setBouncerShowing(mBouncerShowing);
...
//设置状态栏视图到面板窗口控制器
mNotificationShadeWindowViewController.setStatusBarView(mStatusBarView);
checkBarModes();
}).getFragmentManager()
.beginTransaction()
.replace(R.id.status_bar_container,
//创建折叠状态栏fragment
new CollapsedStatusBarFragment(
mOngoingCallController,//正在进行的通话控制器
mAnimationScheduler,//动画调度器
mStatusBarLocationPublisher,
mNotificationIconAreaController,//通知图标区域控制器
mFeatureFlags,
mStatusBarIconController,//状态栏图标控制器
mKeyguardStateController,//锁屏状态控制器
mNetworkController,//网络控制器(信号/WiFi)
mStatusBarStateController,//状态栏状态控制器
this,
mCommandQueue
),
CollapsedStatusBarFragment.TAG)
.commit();
...
//创建导航栏
createNavigationBar(result);
...
//初始化遮罩层
ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind);
ScrimView notificationsScrim = mNotificationShadeWindowView
.findViewById(R.id.scrim_notifications);
...
//初始化背景
BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
//初始化媒体管理器,设置背景、前景、遮罩控制器和锁屏壁纸
mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
backdrop.findViewById(R.id.backdrop_back), mScrimController, mLockscreenWallpaper);
...
//初始化快速设置面板QS
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();
});
...
}
...
//注册广播接收器(屏幕开/关、时间变化等)
registerBroadcastReceiver();
...
}
-
加载布局文件:在视图构建过程中,会加载核心布局文件。
- 根布局 :
super_status_bar.xml是整个状态栏窗口的根布局,super_notification_shade.xml是整个下栏栏窗口的根布局。 - 折叠状态栏 :通过
CollapsedStatusBarFragment(加载status_bar.xml)来构建我们看到的顶部状态栏。 - 展开面板 :
NotificationPanelView则是下拉通知面板和快捷设置面板的根布局,对应status_bar_expanded.xml文件。
- 根布局 :
scss
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
private void inflateStatusBarWindow() {
//使用工厂模式创建下拉面板视图,SuperStatusBarViewFactory
mNotificationShadeWindowView = mSuperStatusBarViewFactory.getNotificationShadeWindowView();
//获取构建器,将下拉面板视图作为依赖注入到组件中
StatusBarComponent statusBarComponent = mStatusBarComponentBuilder.get()
.statusBarWindowView(mNotificationShadeWindowView).build();
//从组件中获取下拉面板窗口控制器
mNotificationShadeWindowViewController = statusBarComponent
.getNotificationShadeWindowViewController();
//设置下拉面板视图到窗口控制器 mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
//设置展开状态栏
mNotificationShadeWindowViewController.setupExpandedStatusBar();
//获取状态栏窗口控制器
mStatusBarWindowController = statusBarComponent.getStatusBarWindowController();
//创建状态栏视图
mPhoneStatusBarWindow = mSuperStatusBarViewFactory.getStatusBarWindowView();
//获取通知面板控制器
mNotificationPanelViewController = statusBarComponent.getNotificationPanelViewController();
//初始化锁屏图标控制器
statusBarComponent.getLockIconViewController().init();
//管理生物识别认证时的波纹动画(如指纹解锁时的光效
mAuthRippleController = statusBarComponent.getAuthRippleController();
//认证波纹控制器初始化。
mAuthRippleController.init();
}
//创建下拉面板根视图,布局super_notification_shade
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
public NotificationShadeWindowView getNotificationShadeWindowView() {
if (mNotificationShadeWindowView != null) {
return mNotificationShadeWindowView;
}
mNotificationShadeWindowView = (NotificationShadeWindowView)
mInjectionInflationController.injectable(
LayoutInflater.from(mContext)).inflate(R.layout.super_notification_shade,
/* root= */ null);
...
return mNotificationShadeWindowView;
}
//创建状态栏根视图,布局super_status_bar
public StatusBarWindowView getStatusBarWindowView() {
if (mStatusBarWindowView != null) {
return mStatusBarWindowView;
}
mStatusBarWindowView =
(StatusBarWindowView) mInjectionInflationController.injectable(
LayoutInflater.from(mContext)).inflate(R.layout.super_status_bar,
/* root= */ null);
...
return mStatusBarWindowView;
}
//加载 `status_bar.xml` 布局,管理所有子视图
//利用 Fragment 的生命周期管理状态栏的创建、销毁和重建
//响应锁屏、网络、通知等状态变化
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.status_bar, container, false);
}
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mStatusBar = (PhoneStatusBarView) view;
//查找状态栏内容的根容器
View contents = mStatusBar.findViewById(R.id.status_bar_contents);
//添加布局变化监听器,当内容位置变化时触发
contents.addOnLayoutChangeListener(mStatusBarLayoutListener);
//发布状态栏的当前位置,供其他组件(如导航栏)调整
updateStatusBarLocation(contents.getLeft(), contents.getRight());
if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_PANEL_STATE)) {
mStatusBar.restoreHierarchyState(
savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE));
}
//初始化 DarkIconManager,管理状态栏右侧的图标
mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons), mFeatureFlags);
mDarkIconManager.setShouldLog(true);
//添加被阻止显示的图标类型(音量、闹钟、信号强度)
//**音量**:音量和铃声状态通常由系统控制,不常显示
//**闹钟**:闹钟图标在状态栏中容易与通知混淆
//**信号强度**:信号强度由 `SignalClusterView` 单独显示mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_volume));
mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_alarm_clock));
mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_call_strength));
mDarkIconManager.setBlockList(mBlockedIcons);
//状态栏图标控制器
mStatusBarIconController.addIconGroup(mDarkIconManager);
//系统图标区域(右侧,包含信号、WiFi、电量等)
mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
mClockView = mStatusBar.findViewById(R.id.clock);
//正在进行的通话芯片(显示通话时长等)
mOngoingCallChip = mStatusBar.findViewById(R.id.ongoing_call_chip);
//初始隐藏系统图标区域
//这些组件会在系统状态更新时(如锁屏状态变化、网络连接)才显示。
//这避免了在 Fragment 初始化时出现闪烁。
showSystemIconArea(false);
showClock(false);
//初始化紧急呼叫/加密守护者文本(锁屏时显示)
initEmergencyCryptkeeperText();
//初始化运营商名称(在锁屏或某些状态下显示)
initOperatorName();
//初始化通知图标区域(左侧,显示应用通知图标)
initNotificationIconArea();
mAnimationScheduler.addCallback(this);
}
- 添加下拉通知面板窗口 :通过
NotificationShadeWindowControllerImpl的attach()方法,将下拉通知面板添加到 WindowManager。
scss
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
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;
...
//将下拉面板视图添加到 WindowManager
mWindowManager.addView(mNotificationShadeView, mLp);
//同步锁屏状态
if (mKeyguardViewMediator.isShowingAndNotOccluded()) {
setKeyguardShowing(true);
}
}
- 添加状态栏窗口 :通过
StatusBarWindowController的attach()方法,将状态栏添加到 WindowManager。
csharp
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
public void attach() {
//创建窗口布局参数
mLp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
mBarHeight,
//状态栏专用窗口类型,**系统最高层级**
WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
PixelFormat.TRANSLUCENT);
mLp.privateFlags |= PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
mLp.token = new Binder();
...
//将状态栏视视图添加到 WindowManager
mWindowManager.addView(mStatusBarView, mLp);
}
- StatusBar等待数据驱动显示
StatusBarIconController → 显示系统图标 (信号/WiFi/电量/时钟)
NotificationIconAreaController → 显示通知图标
StatusBarWindowController :状态栏窗口的核心控制器 ,它负责状态栏窗口的创建、附加、布局参数配置、显示/隐藏 以及与 WindowManager 的交互。
StatusBarIconController :状态栏所有系统图标核心控制器 ,它负责将来自系统服务(如网络、电池、蓝牙等)的状态数据,转化为状态栏右侧区域显示的具体图标。
NotificationIconAreaController :状态栏左侧通知图标区域的核心控制器 。它负责将来自应用的通知,转化为状态栏上显示的小图标,并管理这些图标的添加、更新、移除和动画。
NotificationShadeWindowViewController :下拉通知面板窗口级别的控制器 ,它管理的是整个 NotificationShadeWindowView(即下拉面板的根视图),而不是面板内部的具体内容(如通知列表或 QS 面板)。
NotificationPanelViewController :下拉通知面板的核心控制器 ,它管理着整个面板的展开/收起动画、手势交互、状态管理 以及与锁屏、快捷设置(QS) 的协调。它是 SystemUI 中最复杂、最重要的控制器之一。
NotificationStackScrollLayoutController :不仅仅是"通知列表的控制器",它是 SystemUI 中通知视觉呈现与交互的神经中枢 。它直接管理着 NotificationStackScrollLayout(一个自定义的 ViewGroup),负责:
- 通知行(
ExpandableNotificationRow)的完整生命周期:创建、绑定数据、更新、移除、回收。 - 复杂交互逻辑:滑动删除、拖拽排序(如果启用)、通知分组展开/折叠、长按菜单。
- 动画编排:添加/移除动画、高度变化动画、分组展开/折叠动画。
- 滚动与布局:处理用户滚动、自动滚动到特定通知、响应面板展开/收起的布局调整。
- 状态同步 :将通知列表的状态(如当前可见通知、高度变化)实时同步给
StatusBar、NotificationPanelViewController和HeadsUpManager。
QSPanelController :快捷设置面板 (Quick Settings Panel) 的核心控制器,负责管理 QS 面板的 UI 逻辑、状态更新和交互响应。