Android 8.0 SystemUI(三)——StatusBar

房学
2023-12-01

状态栏与导航栏的启动由StatusBar.start()完成

/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
    @Override
    public void start() {
        mNetworkController = Dependency.get(NetworkController.class);
        mUserSwitcherController = Dependency.get(UserSwitcherController.class);
        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
        mScreenLifecycle.addObserver(mScreenObserver);
        mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
        mBatteryController = Dependency.get(BatteryController.class);
        mAssistManager = Dependency.get(AssistManager.class);
        mSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
        mOverlayManager = IOverlayManager.Stub.asInterface(
                ServiceManager.getService(Context.OVERLAY_SERVICE));
        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
        mColorExtractor.addOnColorsChangedListener(this);
        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        mForegroundServiceController = Dependency.get(ForegroundServiceController.class);
        mDisplay = mWindowManager.getDefaultDisplay();
        updateDisplaySize();
	......
	//创建状态栏与导航栏的窗口
        createAndAddWindows();
	......
    }

跟踪createAndAddWindows():

/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
    public void createAndAddWindows() {
        addStatusBarWindow();
    }
    private void addStatusBarWindow() {
        makeStatusBarView();
	//创建StatusBarWindowManager对象
        mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
        mRemoteInputController = new RemoteInputController(mHeadsUpManager);
	//调用它的add()函数为StatusBar创建窗口,包括窗口的大小、位置、是否透明等属性。getStatusBarHeight()为StatusBar的高度,由com.android.internal.R.dimen.status_bar_height确定
        mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
    }

先来分析makeStatusBarView()函数:

protected void makeStatusBarView() {
    final Context context = mContext;
	//获取屏幕参数
    updateDisplaySize(); // populates mDisplayMetrics
	//更新Panels资源数据,statusbar包含很多panel,在创建PhoneStatusBarView时需要更新panel数据
    updateResources();
    updateTheme();
    //引入StatusBarWindowView布局
    inflateStatusBarWindow(context);
 	//statusbarwindow
    mStatusBarWindow.setService(this);
	//设置触摸事件监听器
    mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
    // TODO: Deal with the ugliness that comes from having some of the statusbar broken out
    // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
    mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
            R.id.notification_panel);
    mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
            R.id.notification_stack_scroller);
    mNotificationPanel.setStatusBar(this);
    mNotificationPanel.setGroupManager(mGroupManager);
    mAboveShelfObserver = new AboveShelfObserver(mStackScroller);
    mAboveShelfObserver.setListener(mStatusBarWindow.findViewById(
            R.id.notification_container_parent));
    mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
    mNotificationIconAreaController = SystemUIFactory.getInstance()
            .createNotificationIconAreaController(context, this);
    inflateShelf();
    mNotificationIconAreaController.setupShelf(mNotificationShelf);
    Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController);
    FragmentHostManager.get(mStatusBarWindow)
            .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
                CollapsedStatusBarFragment statusBarFragment =
                        (CollapsedStatusBarFragment) fragment;
                statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
                mStatusBarView = (PhoneStatusBarView) fragment.getView();
                mStatusBarView.setBar(this);
                mStatusBarView.setPanel(mNotificationPanel);
                mStatusBarView.setScrimController(mScrimController);
                mStatusBarView.setBouncerShowing(mBouncerShowing);
                setAreThereNotifications();
                checkBarModes();
            }).getFragmentManager()
            .beginTransaction()
            .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
                    CollapsedStatusBarFragment.TAG)
            .commit();
    mIconController = Dependency.get(StatusBarIconController.class);
	//通知样式
    mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
    mHeadsUpManager.setBar(this);
    mHeadsUpManager.addListener(this);
    mHeadsUpManager.addListener(mNotificationPanel);
    mHeadsUpManager.addListener(mGroupManager);
    mHeadsUpManager.addListener(mVisualStabilityManager);
    mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
    mNotificationData.setHeadsUpManager(mHeadsUpManager);
    mGroupManager.setHeadsUpManager(mHeadsUpManager);
    mHeadsUpManager.setVisualStabilityManager(mVisualStabilityManager);
    if (MULTIUSER_DEBUG) {
        mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
                R.id.header_debug_info);
        mNotificationPanelDebugText.setVisibility(View.VISIBLE);
    }
    try {
        boolean showNav = mWindowManagerService.hasNavigationBar();
        if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
    //检查是否显示导航栏
        if (showNav) {
        	//引入导航栏navigationbarview的布局
            createNavigationBar();
        }
    } catch (RemoteException ex) {
        // no window manager? good luck with that
    }
	......
}

其中的inflateStatusBarWindow( )和createNavigationBar( )

protected void inflateStatusBarWindow(Context context) {
//引入StatusBarWindowView布局
    mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
            R.layout.super_status_bar, null);
}
protected void createNavigationBar() {
//引入导航栏navigationbarview的布局
    mNavigationBarView = NavigationBarFragment.create(mContext, (tag, fragment) -> {
        mNavigationBar = (NavigationBarFragment) fragment;
        if (mLightBarController != null) {
            mNavigationBar.setLightBarController(mLightBarController);
        }
        mNavigationBar.setCurrentSysuiVisibility(mSystemUiVisibility);
    });
}

关于状态栏布局

/frameworks/base/packages/SystemUI/res/layout/super_status_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- This is the combined status bar / notification panel window. -->
<com.android.systemui.statusbar.phone.StatusBarWindowView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:sysui="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    
    <com.android.systemui.statusbar.BackDropView
            android:id="@+id/backdrop"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"
            sysui:ignoreRightInset="true">
            
        <ImageView android:id="@+id/backdrop_back"
                   android:layout_width="match_parent"
                   android:scaleType="centerCrop"
                   android:layout_height="match_parent" />
                   
        <ImageView android:id="@+id/backdrop_front"
                   android:layout_width="match_parent"
                   android:layout_height="match_parent"
                   android:scaleType="centerCrop"
                   android:visibility="invisible" />
    </com.android.systemui.statusbar.BackDropView>
    
    <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_behind"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:importantForAccessibility="no"
        sysui:ignoreRightInset="true"/>
        
    <com.android.systemui.statusbar.AlphaOptimizedView
        android:id="@+id/heads_up_scrim"
        android:layout_width="match_parent"
        android:layout_height="@dimen/heads_up_scrim_height"
        android:background="@drawable/heads_up_scrim"
        sysui:ignoreRightInset="true"
        android:importantForAccessibility="no"/>
     
    <!-- 加载的status_bar.xml布局-->
    <FrameLayout
        android:id="@+id/status_bar_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
        
    <include layout="@layout/brightness_mirror" />
    
    <ViewStub android:id="@+id/fullscreen_user_switcher_stub"
              android:layout="@layout/car_fullscreen_user_switcher"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>
              
    <include layout="@layout/status_bar_expanded"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible" />
        
    <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_in_front"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:importantForAccessibility="no"
        sysui:ignoreRightInset="true"/>
</com.android.systemui.statusbar.phone.StatusBarWindowView>

关于status_bar布局:

/frameworks/base/packages/SystemUI/res/layout/status_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.statusbar.phone.PhoneStatusBarView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
    android:layout_width="match_parent"
    android:layout_height="@dimen/status_bar_height"
    android:id="@+id/status_bar"
    android:background="@drawable/system_bar_background"
    android:orientation="vertical"
    android:focusable="false"
    android:descendantFocusability="afterDescendants">
    
    <ImageView
        android:id="@+id/notification_lights_out"
        android:layout_width="@dimen/status_bar_icon_size"
        android:layout_height="match_parent"
        android:paddingStart="6dip"
        android:paddingBottom="2dip"
        android:src="@drawable/ic_sysbar_lights_out_dot_small"
        android:scaleType="center"
        android:visibility="gone"/>
        
    <LinearLayout android:id="@+id/status_bar_contents"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingStart="6dp"
        android:paddingEnd="8dp"
        android:orientation="horizontal">
        
        <!-- The alpha of this area is controlled from both PhoneStatusBarTransitions and
             PhoneStatusBar (DISABLE_NOTIFICATION_ICONS). -->
        <!-- 通知区域 -->
        <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
            android:id="@+id/notification_icon_area"
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal" />
        
        <!-- 系统图标区域,如时间,电量等 -->    
        <com.android.keyguard.AlphaOptimizedLinearLayout android:id="@+id/system_icon_area"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal">
            
             <!-- wifi、SIM卡、电量等 -->    
            <include layout="@layout/system_icons" />
            
             <!-- 系统时间 -->    
            <com.android.systemui.statusbar.policy.Clock
                android:id="@+id/clock"
                android:textAppearance="@style/TextAppearance.StatusBar.Clock"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:singleLine="true"
                android:paddingStart="@dimen/status_bar_clock_starting_padding"
                android:paddingEnd="@dimen/status_bar_clock_end_padding"
                android:gravity="center_vertical|start"/>
        </com.android.keyguard.AlphaOptimizedLinearLayout>
    </LinearLayout>
    
    <ViewStub
        android:id="@+id/emergency_cryptkeeper_text"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout="@layout/emergency_cryptkeeper_text"/>
</com.android.systemui.statusbar.phone.PhoneStatusBarView>

关于system_icons布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/system_icons"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:gravity="center_vertical">
    
    <com.android.keyguard.AlphaOptimizedLinearLayout android:id="@+id/statusIcons"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="horizontal"/>
        
    <!-- 系统右边如无sim卡显示等-->
    <include layout="@layout/signal_cluster_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/signal_cluster_margin_start"/>

	<!-- 电量 	battery_percentage_view:电量百分比-->
    <com.android.systemui.BatteryMeterView android:id="@+id/battery"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"/>
</LinearLayout>
statusIcons:
@layout/signal_cluster_view:
 类似资料: