Android U - statusbar pipeline
写在前面
Android原生从T开始对SystemUI进行MVVM改造,U上状态栏部分进行了修改;第一次出现修改不会删除原有逻辑,而是两版并行,留给其他开发者适配的时间;在下一个大版本可能会删除原有逻辑,只留下MVVM。
新版MVVM放在pipeline目录下,本篇文章对状态栏部分进行分析,以及整理与原有逻辑的对应关系。
SystemUI/packages/SystemUI/src/com/android/systemui/statusbar/pipeline
目前可以切换pipeline的控件为数据信号和wifi,开启位置:
# StatusBarPipelineFlags /** True if we should display the mobile icons using the new status bAR Data pipeline. */ fun useNewMobileIcons(): Boolean = featureFlags.isEnabled(Flags.NEW_STATUS_BAR_MOBILE_ICONS) /** True if we should display the wifi icon using the new status bar data pipeline. */ fun useNewWifiIcon(): Boolean = featureFlags.isEnabled(Flags.NEW_STATUS_BAR_WIFI_ICON)
Mobile
1 data
1.1 model
DataConnectionState.kt 枚举;数据连接状态
1 Connected, 2 Connecting, 3 Disconnected, 4 Disconnecting, 5 Suspended, 6 HandoverInProgress, 7 Unknown, 8 Invalid;
NetworkNameModel.kt ⽹络名称,通过密封接⼝的⽅式声明了三个
密封接⼝:https://www.jianshu.com/p/6d70e3b5d380
通过TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED更新
1 Default 默认,读取[com.android.internal.R.string.lockscreen_carrier_default] 2 IntentDerived intent传过来 3 SimDerived sim卡传过来
ResolvedNetworkType.kt ⽹络类型,从TelephonyDisplayInfo中获取的
1 UnknownNetworkType 2 DefaultNetworkType 3 OverrideNetworkType 4 CarrierMergedNetworkType
SubscriptionModel.kt
[SubscriptionInfo]的SystemUI表⽰。⽬前,我们仅在订阅本⾝上使⽤两个字段:subscriptionId和isOpportunistic。我们需要的任何新字段都可以添加到下⾯并在存储库类中提供
1 subscriptionId : subId 2 isOpportunistic : https://learn.microsoft.com/zh-cn/dotnet/api/android.telephon 3 groupUuid : 合并相同的uuid下的⽹络; NetworkControllerImpl.filterMobileSubscriptionInSameGroup, MobileIconsInteractor.filteredSubscriptions
SystemUiCarrierConfig.kt 给定subId,获取systemUI需要的读取的数据的key
1 inflateSignalStrength 2 showOperatorName
1.2 repository
1.2.1 demo
demo模式下的显⽰,对照下⽅1.2.2 prod去看
1.2.2 prod
MobileConnectionRepositoryImpl和MobileConnectionsRepositoryImpl是下⽅两个接⼝的实现类,具体接收底层数据回调⻅MobileConnectionRepositoryImpl.callbackEvents,对标MobileStatusTracker中注册的回调:
private val callbackEvents: StateFlow = run { val initial = TelephonyCallbackState() callbackFlow { val callback = object : TelephonyCallback(), TelephonyCallback.ServiceStateListener, TelephonyCallback.SignalStrengthsListener, TelephonyCallback.DataConnectionStateListener, TelephonyCallback.DataActivityListener, TelephonyCallback.CarrierNetworkListener, TelephonyCallback.DisplayInfoListener, TelephonyCallback.DataEnabledListener { override fun onServiceStateChanged(serviceState: ServiceState) { logger.logOnServiceStateChanged(serviceState, subId) trySend(CallbackEvent.OnServiceStateChanged(serviceState)) } override fun onSignalStrengthsChanged(signalStrength: SignalStrength) { logger.logOnSignalStrengthsChanged(signalStrength, subId) trySend(CallbackEvent.OnSignalStrengthChanged(signalStrength)) } override fun onDataConnectionStateChanged( dataState: Int, networkType: Int ) { logger.logOnDataConnectionStateChanged(dataState, networkType, subId) trySend(CallbackEvent.OnDataConnectionStateChanged(dataState)) } override fun onDataActivity(direction: Int) { logger.logOnDataActivity(direction, subId) trySend(CallbackEvent.OnDataActivity(direction)) } override fun onCarrierNetworkChange(active: Boolean) { logger.logOnCarrierNetworkChange(active, subId) trySend(CallbackEvent.OnCarrierNetworkChange(active)) } override fun onDisplayInfoChanged( telephonyDisplayInfo: TelephonyDisplayInfo ) { logger.logOnDisplayInfoChanged(telephonyDisplayInfo, subId) trySend(CallbackEvent.OnDisplayInfoChanged(telephonyDisplayInfo)) } override fun onDataEnabledChanged(enabled: Boolean, reason: Int) { logger.logOnDataEnabledChanged(enabled, subId) trySend(CallbackEvent.OnDataEnabledChanged(enabled)) } } telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback) awaitClose { telephonyManager.unregisterTelephonyCallback(callback) } } .scan(initial = initial) { state, event -> state.applyEvent(event) } .stateIn(scope = scope, started = SharingStarted.WhileSubscribed(), initial) }
接收到数据后通知view更新显⽰,⻅下⽅3.4 viewmodel
MobileConnectionRepository
1 subId :subId 2 carrier :See [TelephonyManager.getSimCarrierId] 3 isEmergencyOnly :紧急呼叫,⻅MobileSignalController 4 isRoaming :漫游,⻅MobileSignalController 5 operatorAlphaShort :运营商名字⼩写 6 isInService. :in service,⻅MobileSignalController 7 isGsm. :MobileSignalController中只有在判断是否为cdma时⽤到了, 8 cdmaLevel 9 primaryLevel :两个level放⼀起看⼀下 10 根据aospLevel和qcomLevel去计算,⻅MobileSignalController 11 dataConnectionState. :⻅MobileSignalController.dataConnected,区分了各种状态 12 dataActivityDirection :上下⾏,⻅MobileSignalController 13 carrierNetworkChangeActive :carrierNetworkChangeMode 14 resolvedNetworkType. :override network type 15 numberOfLevels :信号个数 16 dataEnabled :是否开了数据;⻅StatusBarSignalPolicy 17 cdmaRoaming. :cdma是否漫游,TODO 没⻅过 18 networkName :⻅1.1 networknamemodel
MobileConnectionsRepository (TODO 后面再填)
1 subscriptions : 2 activeMobileDataSubscriptionId: 3 activeMobileDataRepository : 4 activeSubChangedInGroupEvent : 5 defaultDataSubId : 6 mobileIsDefault : 7 hasCarrierMergedConnection : 8 defaultConnectionIsValidated : 9 defaultDataSubRatConfig : 10 defaultMobileIconMapping : 11 defaultMobileIconGroup :
FullMobileConnectionRepository.kt 整体的移动通信repo,包含了移动数据的repo(MobileConnectionRepositoryImpl)和运营商合并⽹络的repo(CarrierMergedConnectionRepository);
数据获取从Full repo中读取,Full repo选择mobile或carrierMerged中的⼀个做为activeRepo读取数据
CarrierMergedConnectionRepository.kt 运营商合并⽹络的repo
/** * A repository implementation for a carrier merged (aka VCN) network. A carrier merged network is * delivered to SysUI as a wifi network (see [WifiNetworkModel.CarrierMerged], but is visually * displayed as a mobile network triangle. * * See [android.net.wifi.WifiInfo.isCarrierMerged] for more information. * * See [MobileConnectionRepositoryImpl] for a repository implementation of a typical mobile * connection. */ 运营商合并(⼜名 VCN)⽹络的存储库实现。运营商合并⽹络作为 wifi ⽹络传递到 SysUI 有关更多信息,请参阅 [android.net.wifi.WifiInfo.isCarrierMerged]。 有关典型移动连接的存储库实现,请参阅 [MobileConnectionRepositoryImpl]。
CarrierConfigCoreStartable.kt.
⽤于启动CarrierConfigRepository
CarrierConfigRepository.kt.
给定subId,获取缓存的设置;数据key⻅SystemUiCarrierConfig.
MobileRepositorySwitcher.kt 切换demo模式和真实数据的显⽰.
1 RealRepository 2 │ 3 ├──►RepositorySwitcher──►RealInteractor──►RealViewModel 4 │ 5 DemoRepository
UserSetupRepositoryImpl.kt user,使⽤在MobileIconsInteractor中isUserSetup,⽬前没有使⽤到的地⽅
1.3 others
MobileInputLogger.kt logBuffer
2 domin
2.1 interactor
MobileIconInteractor.kt
1 tableLogBuffer :log 2 activity :上下⾏ 3 mobileIsDefault :See [MobileConnectionsRepository.mobileIsDefault] 4 5 isDataConnected :数据是否连接(判断条件去MobileSignalController中看下) 6 isDefaultConnectionFailed :是否连接失败;⽤于判断是否显⽰错误状态下的SignalDrawable 7 isInService :是否有服务 8 isDefaultDataEnabled :dataEnabled default设置,MobileIconsInterator.active 9 isDataEnabled :dataEnabled 10 alwaysShowDataRatIcon. :是否要⼀直显⽰数据图标; 11 U之前没这个功能,数据图表常驻的;根据需求决定这东西还要不要 12 个⼈理解可直接改成false,具体情况适配时注意下 13 alwaysUseCdmaLevel :cdma是单独判断的,⻅MobileSignalController.isCdma; 14 该变量影响level值的选择 15 个⼈理解可直接改成false,具体情况适配时注意下 16 networkTypeIconGroup :⽹络类型的iconGroup,⻅2.2中NetworkTypeIconGroup 17 networkName :⽹络名称,⻅1.1中NetworkNameModel 18 isEmergencyOnly :仅可紧急通话 19 isRoaming :是否是漫游 20 level :信号强度格数 21 numberOfLevels :最⼤信号格数,4还是5;海外(日本)有此类定制 22 后续可以⽤此处来拓展 23 isForceHidden :强制隐藏信号图标;寻找是不是在icon_blacklist中 24 carrierNetworkChangeActive:对应MobileSignalController.isCarrierNetworkChangeActive
MobileIconsInteractor.kt
1 mobileIsDefault :同上MobileIconInteractor中 2 filteredSubscriptions : 3 activeDataConnectionHasDataEnabled : 4 alwaysShowDataRatIcon :同上MobileIconInteractor中 5 alwaysUseCdmaLevel. :同上MobileIconInteractor中 6 defaultMobileIconMapping : 7 defaultMobileIconGroup : 8 isDefaultConnectionFailed :同上MobileIconInteractor中 9 isUserSetup : 10 isForceHidden :同上MobileIconInteractor中 11 12 fun createMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor 13 ⽤于创建MobileIconInteractor实例
2.2 model
NetworkTypeIconModel.kt 密封类 ⽹络类型图标,根据是否是override type,对应下⽅两种类型
1 val contentDescription: Int 2 val iconId: Int 3 val name: String 4 5 data class DefaultIcon 6 data class OverriddenIcon
3 ui
3.1 binder
MobileIconBinder:更新ModernStatusBarMobileView的显⽰,对标StatusBarMobileView.
区别:StatusBarMobileView中,通过bean类传递最新的信息,每次整体更新view的显⽰,根据计算后是否有变化来决定是否刷新;
MobileIconBinder中,每个不同的变量都通过各⾃注册的监听来回调,只触发各⾃的部分;
此处适配时,对于新增的ui和变量,很多都是多种条件组合判断的;需要将多种条件都放⼊监听中,根据计算后的结果来判断,例如:
1 // Set the activity indicators 2 launch { 3 combine(viewModel.activityInVisible, viewModel.activityOutVi 4 activityIn, activityOut, dataConnected -> 5 if (dataConnected) { 6 if (activityIn && activityOut) { 7 viewModel.leftInOutResId = R.drawable.xxx; 8 viewModel.rightInOutResId = R.drawable.xxx; 9 } else if (activityIn) { 10 viewModel.leftInOutResId = R.drawable.xxx; 11 viewModel.rightInOutResId = R.drawable.xxx; 12 } else if (activityOut) { 13 viewModel.leftInOutResId = R.drawable.xxx; 14 viewModel.rightInOutResId = R.drawable.xxx; 15 } else { 16 viewModel.leftInOutResId = R.drawable.xxx; 17 viewModel.rightInOutResId = R.drawable.xxx; 18 } 19 } 20 leftInOut.setImageResource(transformResId(viewModel.left)); 21 rightInOut.setImageResource(transformResId(viewModel.right)); 22 } 23 }
MobileIconsBinder:提供对外的static⽅法,bind后在每次声明周期为STARTED时更新;
⽬前collect中为空,因为和旧版逻辑适配的原因,此处逻辑在MobileUiAdapter中;后续⼤版本如果移除了旧版逻辑,会迁移⾄此处.
3.2 model
SignalIconModel.kt 打信号格相关的log;选择信号格的图⽚.
⻅2.1中numberOfLevels
/** Convert this model to an [Int] consumable by [SignalDrawable]. */ fun toSignalDrawableState(): Int = if (carrierNetworkChange) { SignalDrawable.getCarrierChangeState(numberOfLevels) } else { SignalDrawable.getState(level, numberOfLevels, showExclamationMark) }
3.3 view
ModernStatusBarMobileView.kt pipeline的信号view;内部逻辑都放到了MobileIconBinder中,剩下布局的加载和⼀些变量获取
companion object { /** * Inflates a new instance of [ModernStatusBarMobileView], binds it to [viewModel], and * returns it. */ @JvmStatic fun constructAndBind( context: Context, logger: MobileViewLogger, slot: String, viewModel: LocationBasedMobileViewModel, ): ModernStatusBarMobileView { return (LayoutInflater.from(context) .inflate(R.layout.status_bar_mobile_signal_group_new, null) as ModernStatusBarMobileView) .also { it.subId = viewModel.subscriptionId it.initView(slot) { MobileIconBinder.bind(it, viewModel, logger) } logger.logNewViewBinding(it, viewModel) } } }
3.4 viewmodel
LocationBasedMobileViewModel.kt 根据location创建三个不同的viewmodel
1 HomeMobileIconViewModel 2 QsMobileIconViewModel 3 KeyguardMobileIconViewModel
MobileIconsViewModel.kt.
MobileIconViewModel.kt
为MobileIconBinder提供数据;binder中监听的变量是从viewmodel中获取的,viewmodel中的变量
通过2.1中interactor获取;
即当信号的数据发⽣变化时,底层数据发⽣变化->通知interactor中变化->通知viewmodel中变化->通知binder去更新显⽰;例如:
# MobileIconBinder.kt // 信号格图标,监听的viewmodel中icon的变化 // Set the icon for the triangle launch { viewModel.icon.distinctUntilChanged().collect { icon -> viewModel.verboseLogger?.logBinderReceivedSignalIcon( view, viewModel.subscriptionId, icon, ) mobileDrawable.level = icon.toSignalDrawableState() } } # MobileIconViewModel.kt val icon: Flow override val icon: Flow = run { val initial = SignalIconModel( level = shownLevel.value, numberOfLevels = iconInteractor.numberOfLevels.value, showExclamationMark = showExclamationMark.value, carrierNetworkChange = iconInteractor.carrierNetworkChangeActive.value, ) combine( shownLevel, iconInteractor.numberOfLevels, showExclamationMark, iconInteractor.carrierNetworkChangeActive, ) { shownLevel, numberOfLevels, showExclamationMark, carrierNetworkChange -> SignalIconModel( shownLevel, numberOfLevels, showExclamationMark, carrierNetworkChange, ) } .distinctUntilChanged() .logDiffsForTable( iconInteractor.tableLogBuffer, columnPrefix = "icon", initialValue = initial, ) .stateIn(scope, SharingStarted.WhileSubscribed(), initial) } # MobileIconInteractor.kt val numberOfLevels: StateFlow override val numberOfLevels: StateFlow = connectionRepository.numberOfLevels.stateIn( scope, SharingStarted.WhileSubscribed(), connectionRepository.numberOfLevels.value, ) # MobileConnectionRepository.kt val numberOfLevels: StateFlow # 最后数据落到底层回调,⻅上⽂中1.2.2
3.5 others
MobileUiAdapter.kt pipeline和旧版的连接,将UI刷新转回到StatusBarIconControllerImpl中;后续如果移除旧版逻辑,可能会移⾛,⻅MobileIconsBinder.
override fun start() { // Only notify the icon controller if we want to *render* the new icons. // Note that this flow may still run if // [statusBarPipelineFlags.runNewMobileIconsBackend] is true because we may want to // get the logging data without rendering. if (statusBarPipelineFlags.useNewMobileIcons()) { scope.launch { isCollecting = true mobileIconsViewModel.subscriptionIdsFlow.collectLatest { logger.logUiAdapterSubIdsSentToIconController(it) lastValue = it iconController.setNewMobileIconSubIds(it) } } } }
MobileViewLogger.kt log.
VerboseMobileViewLogger.kt log.
4 util
MobileMappings.kt ⾥⾯是proxy,提供对外⽅法
1 MobileMappingsProxyImpl 2 # fun mapIconSets(config: Config): Map 3 # fun getDefaultIcons(config: Config): MobileIconGroup 4 # fun getIconKey(displayInfo: TelephonyDisplayInfo): String 5 # fun toIconKey(@NetworkType networkType: Int): String 6 # fun toIconKeyOverride(@NetworkType networkType: Int): String
SubscriptionManagerProxy.kt
1 SubscriptionManagerProxyImpl 2 # fun getDefaultDataSubscriptionId(): Int
Wifi
1 data
1.1 repository
repository层是MVVM框架中⽤于解耦业务逻辑和数据的独⽴的⼀层:
https://www.jianshu.com/p/4679c384acae
1 # WifiRepository.kt 2 3 // 声明变量;具体实现在prod下的两个类中;Disabled开头是禁⽤下的 4 // 对应WifiStatusTracker 5 // wifi是否开启,对应enabled 6 val isWifiEnabled: StateFlow 7 // 对应isWifi 8 val isWifiDefault: StateFlow 9 // 连接变化和中断的回调,对应mNetworkCallback 10 val wifiNetwork: StateFlow 11 // 上下⾏ 12 val wifiActivity: StateFlow
# WifiRepositorySwitcher.kt // 根据demo mode开启状态,切换数据源是真实数据还是demo数据;该类上⽅的注释详细的描述了 /** * Provides the [WifiRepository] interface either through the [DemoWifiRepository] implementation, * or the [WifiRepositoryImpl]'s prod implementation, based on the current demo mode value. In this * way, downstream clients can all consist of real implementations and not care about which * repository is responsible for the data. Graphically: * ``` * RealRepository * │ * ├──►RepositorySwitcher──►RealInteractor──►RealViewModel * │ * DemoRepository * ``` * * When demo mode turns on, every flow will [flatMapLatest] to the current provider's version of * that flow. */
2 domain
2.1 interactor
WifiInteractor.kt.
业务逻辑层,对应MiuiWifiSignalController.java中copyWifiStates(),将wifi变化后的数据传给实际应⽤的bean类中
3 shared
3.1 model
WifiNetworkModel.kt.
sealed class:https://blog.csdn.net/qq_33552379/article/details/125996716,类似枚举,但只能在当前类中去声明
1 Unavailable:wifi不可⽤,WifiManager为null 2 Invalid:wifi信息⽆效 3 Inactive:⽆有效的wifi⽹络 4 CarrierMerged:该模型表⽰我们的 WiFi ⽹络实际上是运营商合并⽹络,这意味着它更像是移动⽹络 5 Active:有效的wifi⽹络
WifiConstants.kt.
alwaysShowIconIfEnabled:是否⼀直显⽰wifi icon;miui⽬前逻辑不需要这个,适配的时候改成false
WifiInputLogger.kt.
为repository提供log⽅法
4 ui
4.1 binder
WifiViewBinder.kt.
根据数据为wifi icon更新UI显⽰,对应StatusBarWifiView.java;
pipeline中UI类替换成了ModernStatusBarWifiView.kt,具体UI显⽰逻辑移到了binder类中return值:改类返回⼀个ModernStatusBarViewBinding对象,实现需要对外提供信息的接⼝;对外提供其他数据可在该接⼝中增加⽅法并实现.
4.2 model
WifiIcon.kt.
sealed class;内部⼦类有两个 Visible和Hidden,在WifiViewBinder和WifiViewModel中使⽤.
4.3 view
ModernStatusBarWifiView.kt.
包含inflate时的布局,其他逻辑都交由binder中处理
4.4 viewmodel
WifiViewModelCommon.kt.
1 // 接⼝,声明变量 2 // wifi icon是否可⻅ 3 val wifiIcon: StateFlow 4 // 上下⾏是否可⻅ 5 val isActivityInViewVisible: Flow 6 val isActivityOutViewVisible: Flow 7 val isActivityContainerVisible: Flow 8 // ⻜⾏模式图标是否可⻅ 9 val isAirplaneSpacerVisible: Flow 10 // 11 val isSignalSpacerVisible: Flow
WifiViewModel.kt.
- 实现了WifiViewModelCommon接⼝;WifiViewModel是单例,不能直接它来控制view;⽽是使⽤LocationBasedWifiViewModel,它其中声明了多个不同情况下的viewmodel
- 如上⽅2.1所述,wifi状态变化的数据被存放在WifiInteractor中;WifiViewModel中使⽤WifiInteractor的数据,计算出控件是否需要显⽰.
// 此处对应wifi icon图⽚的获取; // miui⽬前新增逻辑,在MiuiStatusBarSignalPolicy和MiuiWifiSignalController有定制; // 可通过WifiIcons的引⽤进⾏查找;适配wifi 7、热点等图⽚需要在这⾥ private fun WifiNetworkModel.icon(): WifiIcon { return when (this) { // 不可⽤、⾮wifi情况下隐藏 is WifiNetworkModel.Unavailable -> WifiIcon.Hidden is WifiNetworkModel.Invalid -> WifiIcon.Hidden is WifiNetworkModel.CarrierMerged -> WifiIcon.Hidden is WifiNetworkModel.Inactive -> WifiIcon.Visible( res = WIFI_NO_NETWORK, ContentDescription.Loaded( "${context.getString(WIFI_NO_CONNECTION)},${context.getString(NO_INTERNET)}" ) ) // 可⽤情况下,需要额外增加miui图⽚选择的逻辑 is WifiNetworkModel.Active -> { val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[this.level]) when { this.isValidated -> WifiIcon.Visible( WIFI_FULL_ICONS[this.level], ContentDescription.Loaded(levelDesc), ) else -> WifiIcon.Visible( WIFI_NO_INTERNET_ICONS[this.level], ContentDescription.Loaded( "$levelDesc,${context.getString(NO_INTERNET)}" ), ) } } } }
LocationBasedWifiViewModel.kt
WifiViewModel是单例,不能直接使⽤来操作view显⽰,需通过LocationBasedWifiViewModel中的三个⼦类,来操作不同情况下的view:
HomeWifiViewModel KeyguardWifiViewModel QsWifiViewModel
⽬前看到的区别是打出的log、debug下的tint不同
5 WifiUiAdapter.kt
单例;连接旧版UI和新pipeline数据的adapter类;
⽬前使⽤pipeline时,也需要通过iconManager将icon加⼊iconGroup;
注释标明随着后续pipeline逐渐完善,会优化这⾥
fun bindGroup( statusBarIconGroup: ViewGroup, location: StatusBarLocation, ): LocationBasedWifiViewModel { val locationViewModel = viewModelForLocation(wifiViewModel, statusBarPipelineFlags, location) statusBarIconGroup.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.STARTED) { launch { locationViewModel.wifiIcon.collect { wifiIcon -> // Only notify the icon controller if we want to *render* the new icon. // Note that this flow may still run if // [statusBarPipelineFlags.runNewWifiIconBackend] is true because we may // want to get the logging data without rendering. if ( wifiIcon is WifiIcon.Visible && statusBarPipelineFlags.useNewWifiIcon() ) { iconController.setNewWifiIcon() } } } } } return locationViewModel }
Shared
提供Mobile和Wifi使⽤的公共部分;提供CollapsedStatusBarFragment相关的控制类
1 data
1.1 model
ConnectivitySlots.kt.
1 airplaneSlot 2 mobileSlot 3 wifiSlot 4 ethernetSlot
DataActivityModel.kt 存放上下⾏数据
DefaultConnectionModel.kt
1.2 repository
ConnectivityRepository.kt
forceHiddenSlots :是否强制隐藏slots;当前pipeline中的icon,都有isForceHidden这个变量,信号、Wifi、⻜⾏模式 defaultConnections:default连接对应WifiStatusTracker中的mDefaultNetworkCallback vcnSubId :TODO 没找到好的解释。。使⽤上在MobileIconsInteractor.filteredSubscriptions carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault
2 ui
2.1 binder
CollapsedStatusBarViewBinder.kt
# CollapsedStatusBarFragment.onViewCreated // 此处进⾏bind mCollapsedStatusBarViewBinder.bind( mStatusBar, mCollapsedStatusBarViewModel, mStatusBarVisibilityChangeListener); # CollapsedStatusBarViewBinderImpl // 为viewmodel中的两个变量增加回调 override fun bind( view: View, viewModel: CollapsedStatusBarViewModel, listener: StatusBarVisibilityChangeListener, ) { view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { launch { viewModel.isTransitioningFromLockscreenToOccluded.collect { listener.onStatusBarVisibilityMaybeChanged() } } launch { viewModel.transitionFromLockscreenToDreamStartedEvent.collect { listener.onTransitionFromLockscreenToDreamStarted() } } } } } # CollapsedStatusBarFragment // listener具体实现的位置 private StatusBarVisibilityChangeListener mStatusBarVisibilityChangeListener = new StatusBarVisibilityChangeListener() { @Override public void onStatusBarVisibilityMaybeChanged() { // 触发状态栏visibility的计算 updateStatusBarVisibilities(/* animate= */ true); } @Override public void onTransitionFromLockscreenToDreamStarted() { // 该变量⽤于shouldHideStatusBar()中的判断 mTransitionFromLockscreenToDreamStarted = true; } };
ModernStatusBarViewBinding.kt 为2.2 ModernStatusBarView声明必须实现的接⼝
2.2 view
ModernStatusBarView.kt 新版的mobile和wifi icon的⽗类,提供⼀些公共⽅法
2.3 viewmodel
CollapsedStatusBarViewModel.kt 根据设备状态,控制CollapsedStatusBarFragment的visibility
但是⽬前逻辑没有完全迁过来,当前类中只有两个变量:
1 isTransitioningFromLockscreenToOccluded :如果设备当前正在从锁定屏幕转换为遮挡屏幕 2 transitionFromLockscreenToDreamStartedEvent:每当从锁屏到屏保的转换开始时发出
PS:DreamManager:https://blog.51cto.com/u_16213432/9289886
这两个变量控制的是:
# CollapsedStatusBarFragment.shouldHideStatusBar() // While the status bar is transitioning from lockscreen to an occluded, we don't yet know // if the occluding activity is fullscreen or not. If it *is* fullscreen, we don't want to // briefly show the status bar just to immediately hide it again. So, we wait for the // transition to occluding to finish before allowing us to potentially show the status bar // again. (This status bar is always hidden on keyguard, so it's safe to continue hiding it // during this transition.) See b/273314977. if (mCollapsedStatusBarViewModel.isTransitioningFromLockscreenToOccluded().getValue()) { return true; } # transitionFromLockscreenToDreamStartedEvent⻅2.1 CollapsedStatusBarViewBinder
3 others
ConnectivityConstants.kt
1 hasDataCapabilities :telephonyManager.isDataCapable 2 shouldShowActivityConfig :R.bool.config_showActivity
ConnectivityInputLogger.kt log
LoggerHelper.kt log
写在后面
如果文章中有错误的地方,希望各位大佬们批评指正~
If you like this article, it is written by Johnny Deng.
If not, I don’t know who wrote it.