diff options
15 files changed, 632 insertions, 223 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt index 4d914fe0adef..15fed3244d97 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt @@ -49,9 +49,9 @@ class StatusBarPipelineFlags @Inject constructor(private val featureFlags: Featu featureFlags.isEnabled(Flags.NEW_STATUS_BAR_WIFI_ICON_BACKEND) || useNewWifiIcon() /** - * Returns true if we should apply some coloring to the wifi icon that was rendered with the new + * Returns true if we should apply some coloring to the icons that were rendered with the new * pipeline to help with debugging. */ - fun useWifiDebugColoring(): Boolean = + fun useDebugColoring(): Boolean = featureFlags.isEnabled(Flags.NEW_STATUS_BAR_ICONS_DEBUG_COLORING) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt index ab442b5ab4de..3e81c7c7cefd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.binder import android.content.res.ColorStateList import android.view.View import android.view.View.GONE +import android.view.View.INVISIBLE import android.view.View.VISIBLE import android.view.ViewGroup import android.widget.ImageView @@ -30,7 +31,13 @@ import com.android.settingslib.graph.SignalDrawable import com.android.systemui.R import com.android.systemui.common.ui.binder.IconViewBinder import com.android.systemui.lifecycle.repeatWhenAttached +import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT +import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN +import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel +import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.launch @@ -40,7 +47,8 @@ object MobileIconBinder { fun bind( view: ViewGroup, viewModel: LocationBasedMobileViewModel, - ) { + ): ModernStatusBarViewBinding { + val mobileGroupView = view.requireViewById<ViewGroup>(R.id.mobile_group) val activityContainer = view.requireViewById<View>(R.id.inout_container) val activityIn = view.requireViewById<ImageView>(R.id.mobile_in) val activityOut = view.requireViewById<ImageView>(R.id.mobile_out) @@ -49,12 +57,39 @@ object MobileIconBinder { val mobileDrawable = SignalDrawable(view.context).also { iconView.setImageDrawable(it) } val roamingView = view.requireViewById<ImageView>(R.id.mobile_roaming) val roamingSpace = view.requireViewById<Space>(R.id.mobile_roaming_space) + val dotView = view.requireViewById<StatusBarIconView>(R.id.status_bar_dot) view.isVisible = true iconView.isVisible = true + // TODO(b/238425913): We should log this visibility state. + @StatusBarIconView.VisibleState + val visibilityState: MutableStateFlow<Int> = MutableStateFlow(STATE_HIDDEN) + + val iconTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor) + val decorTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor) + view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.STARTED) { + launch { + visibilityState.collect { state -> + when (state) { + STATE_ICON -> { + mobileGroupView.visibility = VISIBLE + dotView.visibility = GONE + } + STATE_DOT -> { + mobileGroupView.visibility = INVISIBLE + dotView.visibility = VISIBLE + } + STATE_HIDDEN -> { + mobileGroupView.visibility = INVISIBLE + dotView.visibility = INVISIBLE + } + } + } + } + // Set the icon for the triangle launch { viewModel.iconId.distinctUntilChanged().collect { iconId -> @@ -89,15 +124,43 @@ object MobileIconBinder { // Set the tint launch { - viewModel.tint.collect { tint -> + iconTint.collect { tint -> val tintList = ColorStateList.valueOf(tint) iconView.imageTintList = tintList networkTypeView.imageTintList = tintList roamingView.imageTintList = tintList activityIn.imageTintList = tintList activityOut.imageTintList = tintList + dotView.setDecorColor(tint) } } + + launch { decorTint.collect { tint -> dotView.setDecorColor(tint) } } + } + } + + return object : ModernStatusBarViewBinding { + override fun getShouldIconBeVisible(): Boolean { + // If this view model exists, then the icon should be visible. + return true + } + + override fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int) { + visibilityState.value = state + } + + override fun onIconTintChanged(newTint: Int) { + if (viewModel.useDebugColoring) { + return + } + iconTint.value = newTint + } + + override fun onDecorTintChanged(newTint: Int) { + if (viewModel.useDebugColoring) { + return + } + decorTint.value = newTint } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt index e86fee24fe4d..ed9a1884a7b4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt @@ -17,50 +17,20 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.view import android.content.Context -import android.graphics.Rect import android.util.AttributeSet import android.view.LayoutInflater import com.android.systemui.R -import com.android.systemui.statusbar.BaseStatusBarFrameLayout -import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel -import java.util.ArrayList +import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarView class ModernStatusBarMobileView( context: Context, attrs: AttributeSet?, -) : BaseStatusBarFrameLayout(context, attrs) { +) : ModernStatusBarView(context, attrs) { var subId: Int = -1 - private lateinit var slot: String - override fun getSlot() = slot - - override fun onDarkChanged(areas: ArrayList<Rect>?, darkIntensity: Float, tint: Int) { - // TODO - } - - override fun setStaticDrawableColor(color: Int) { - // TODO - } - - override fun setDecorColor(color: Int) { - // TODO - } - - override fun setVisibleState(state: Int, animate: Boolean) { - // TODO - } - - override fun getVisibleState(): Int { - return STATE_ICON - } - - override fun isIconVisible(): Boolean { - return true - } - companion object { /** @@ -77,9 +47,8 @@ class ModernStatusBarMobileView( .inflate(R.layout.status_bar_mobile_signal_group_new, null) as ModernStatusBarMobileView) .also { - it.slot = slot it.subId = viewModel.subscriptionId - MobileIconBinder.bind(it, viewModel) + it.initView(slot) { MobileIconBinder.bind(it, viewModel) } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt index b0dc41f45488..24cd9304f8dd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt @@ -18,11 +18,7 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel import android.graphics.Color import com.android.systemui.statusbar.phone.StatusBarLocation -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOf +import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags /** * A view model for an individual mobile icon that embeds the notion of a [StatusBarLocation]. This @@ -33,50 +29,51 @@ import kotlinx.coroutines.flow.flowOf */ abstract class LocationBasedMobileViewModel( val commonImpl: MobileIconViewModelCommon, - val logger: ConnectivityPipelineLogger, + statusBarPipelineFlags: StatusBarPipelineFlags, + debugTint: Int, ) : MobileIconViewModelCommon by commonImpl { - abstract val tint: Flow<Int> + val useDebugColoring: Boolean = statusBarPipelineFlags.useDebugColoring() + + val defaultColor: Int = + if (useDebugColoring) { + debugTint + } else { + Color.WHITE + } companion object { fun viewModelForLocation( commonImpl: MobileIconViewModelCommon, - logger: ConnectivityPipelineLogger, + statusBarPipelineFlags: StatusBarPipelineFlags, loc: StatusBarLocation, ): LocationBasedMobileViewModel = when (loc) { - StatusBarLocation.HOME -> HomeMobileIconViewModel(commonImpl, logger) - StatusBarLocation.KEYGUARD -> KeyguardMobileIconViewModel(commonImpl, logger) - StatusBarLocation.QS -> QsMobileIconViewModel(commonImpl, logger) + StatusBarLocation.HOME -> + HomeMobileIconViewModel(commonImpl, statusBarPipelineFlags) + StatusBarLocation.KEYGUARD -> + KeyguardMobileIconViewModel(commonImpl, statusBarPipelineFlags) + StatusBarLocation.QS -> QsMobileIconViewModel(commonImpl, statusBarPipelineFlags) } } } class HomeMobileIconViewModel( commonImpl: MobileIconViewModelCommon, - logger: ConnectivityPipelineLogger, -) : MobileIconViewModelCommon, LocationBasedMobileViewModel(commonImpl, logger) { - override val tint: Flow<Int> = - flowOf(Color.CYAN) - .distinctUntilChanged() - .logOutputChange(logger, "HOME tint(${commonImpl.subscriptionId})") -} + statusBarPipelineFlags: StatusBarPipelineFlags, +) : + MobileIconViewModelCommon, + LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.CYAN) class QsMobileIconViewModel( commonImpl: MobileIconViewModelCommon, - logger: ConnectivityPipelineLogger, -) : MobileIconViewModelCommon, LocationBasedMobileViewModel(commonImpl, logger) { - override val tint: Flow<Int> = - flowOf(Color.GREEN) - .distinctUntilChanged() - .logOutputChange(logger, "QS tint(${commonImpl.subscriptionId})") -} + statusBarPipelineFlags: StatusBarPipelineFlags, +) : + MobileIconViewModelCommon, + LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.GREEN) class KeyguardMobileIconViewModel( commonImpl: MobileIconViewModelCommon, - logger: ConnectivityPipelineLogger, -) : MobileIconViewModelCommon, LocationBasedMobileViewModel(commonImpl, logger) { - override val tint: Flow<Int> = - flowOf(Color.MAGENTA) - .distinctUntilChanged() - .logOutputChange(logger, "KEYGUARD tint(${commonImpl.subscriptionId})") -} + statusBarPipelineFlags: StatusBarPipelineFlags, +) : + MobileIconViewModelCommon, + LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.MAGENTA) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt index b9318b181aaf..24370d221ade 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel import androidx.annotation.VisibleForTesting import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.statusbar.phone.StatusBarLocation +import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants @@ -41,6 +42,7 @@ constructor( private val logger: ConnectivityPipelineLogger, private val constants: ConnectivityConstants, @Application private val scope: CoroutineScope, + private val statusBarPipelineFlags: StatusBarPipelineFlags, ) { @VisibleForTesting val mobileIconSubIdCache = mutableMapOf<Int, MobileIconViewModel>() @@ -60,7 +62,11 @@ constructor( ) .also { mobileIconSubIdCache[subId] = it } - return LocationBasedMobileViewModel.viewModelForLocation(common, logger, location) + return LocationBasedMobileViewModel.viewModelForLocation( + common, + statusBarPipelineFlags, + location, + ) } private fun removeInvalidModelsFromCache(subIds: List<Int>) { @@ -75,6 +81,7 @@ constructor( private val logger: ConnectivityPipelineLogger, private val constants: ConnectivityConstants, @Application private val scope: CoroutineScope, + private val statusBarPipelineFlags: StatusBarPipelineFlags, ) { fun create(subscriptionIdsFlow: StateFlow<List<Int>>): MobileIconsViewModel { return MobileIconsViewModel( @@ -83,6 +90,7 @@ constructor( logger, constants, scope, + statusBarPipelineFlags, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewBinding.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewBinding.kt new file mode 100644 index 000000000000..f67876b50233 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewBinding.kt @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.shared.ui.binder + +import com.android.systemui.statusbar.StatusBarIconView + +/** + * Defines interface for an object that acts as the binding between a modern status bar view and its + * view-model. + * + * Users of the view binder classes in the modern status bar pipeline should use this to control the + * binder after it is bound. + */ +interface ModernStatusBarViewBinding { + /** Returns true if the icon should be visible and false otherwise. */ + fun getShouldIconBeVisible(): Boolean + + /** Notifies that the visibility state has changed. */ + fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int) + + /** Notifies that the icon tint has been updated. */ + fun onIconTintChanged(newTint: Int) + + /** Notifies that the decor tint has been updated (used only for the dot). */ + fun onDecorTintChanged(newTint: Int) +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt new file mode 100644 index 000000000000..cc0ec548716d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.shared.ui.view + +import android.content.Context +import android.graphics.Rect +import android.util.AttributeSet +import android.view.Gravity +import com.android.systemui.R +import com.android.systemui.plugins.DarkIconDispatcher +import com.android.systemui.statusbar.BaseStatusBarFrameLayout +import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT +import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN +import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding + +/** + * A new and more modern implementation of [BaseStatusBarFrameLayout] that gets updated by view + * binders communicating via [ModernStatusBarViewBinding]. + */ +open class ModernStatusBarView(context: Context, attrs: AttributeSet?) : + BaseStatusBarFrameLayout(context, attrs) { + + private lateinit var slot: String + private lateinit var binding: ModernStatusBarViewBinding + + @StatusBarIconView.VisibleState + private var iconVisibleState: Int = STATE_HIDDEN + set(value) { + if (field == value) { + return + } + field = value + binding.onVisibilityStateChanged(value) + } + + override fun getSlot() = slot + + override fun onDarkChanged(areas: ArrayList<Rect>?, darkIntensity: Float, tint: Int) { + val newTint = DarkIconDispatcher.getTint(areas, this, tint) + binding.onIconTintChanged(newTint) + binding.onDecorTintChanged(newTint) + } + + override fun setStaticDrawableColor(color: Int) { + binding.onIconTintChanged(color) + } + + override fun setDecorColor(color: Int) { + binding.onDecorTintChanged(color) + } + + override fun setVisibleState(@StatusBarIconView.VisibleState state: Int, animate: Boolean) { + iconVisibleState = state + } + + @StatusBarIconView.VisibleState + override fun getVisibleState(): Int { + return iconVisibleState + } + + override fun isIconVisible(): Boolean { + return binding.getShouldIconBeVisible() + } + + /** + * Initializes this view. + * + * Creates a dot view, and uses [bindingCreator] to get and set the binding. + */ + fun initView(slot: String, bindingCreator: () -> ModernStatusBarViewBinding) { + // The dot view requires [slot] to be set, and the [binding] may require an instantiated dot + // view. So, this is the required order. + this.slot = slot + initDotView() + this.binding = bindingCreator.invoke() + } + + /** + * Creates a [StatusBarIconView] that is always in DOT mode and adds it to this view. + * + * Mostly duplicated from [com.android.systemui.statusbar.StatusBarWifiView] and + * [com.android.systemui.statusbar.StatusBarMobileView]. + */ + private fun initDotView() { + // TODO(b/238425913): Could we just have this dot view be part of the layout with a dot + // drawable so we don't need to inflate it manually? Would that not work with animations? + val dotView = + StatusBarIconView(mContext, slot, null).also { + it.id = R.id.status_bar_dot + // Hard-code this view to always be in the DOT state so that whenever it's visible + // it will show a dot + it.visibleState = STATE_DOT + } + + val width = mContext.resources.getDimensionPixelSize(R.dimen.status_bar_icon_size) + val lp = LayoutParams(width, width) + lp.gravity = Gravity.CENTER_VERTICAL or Gravity.START + addView(dotView, lp) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt index cc67c84772a5..2aff12c8721d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt @@ -30,6 +30,7 @@ import com.android.systemui.statusbar.StatusBarIconView import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON +import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel import kotlinx.coroutines.InternalCoroutinesApi @@ -49,31 +50,12 @@ import kotlinx.coroutines.launch @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") object WifiViewBinder { - /** - * Defines interface for an object that acts as the binding between the view and its view-model. - * - * Users of the [WifiViewBinder] class should use this to control the binder after it is bound. - */ - interface Binding { - /** Returns true if the wifi icon should be visible and false otherwise. */ - fun getShouldIconBeVisible(): Boolean - - /** Notifies that the visibility state has changed. */ - fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int) - - /** Notifies that the icon tint has been updated. */ - fun onIconTintChanged(newTint: Int) - - /** Notifies that the decor tint has been updated (used only for the dot). */ - fun onDecorTintChanged(newTint: Int) - } - /** Binds the view to the view-model, continuing to update the former based on the latter. */ @JvmStatic fun bind( view: ViewGroup, viewModel: LocationBasedWifiViewModel, - ): Binding { + ): ModernStatusBarViewBinding { val groupView = view.requireViewById<ViewGroup>(R.id.wifi_group) val iconView = view.requireViewById<ImageView>(R.id.wifi_signal) val dotView = view.requireViewById<StatusBarIconView>(R.id.status_bar_dot) @@ -148,7 +130,7 @@ object WifiViewBinder { } } - return object : Binding { + return object : ModernStatusBarViewBinding { override fun getShouldIconBeVisible(): Boolean { return viewModel.wifiIcon.value is WifiIcon.Visible } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt index be7782c37cfd..7a734862fe1b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt @@ -16,17 +16,12 @@ package com.android.systemui.statusbar.pipeline.wifi.ui.view +import android.annotation.SuppressLint import android.content.Context -import android.graphics.Rect import android.util.AttributeSet -import android.view.Gravity import android.view.LayoutInflater import com.android.systemui.R -import com.android.systemui.plugins.DarkIconDispatcher -import com.android.systemui.statusbar.BaseStatusBarFrameLayout -import com.android.systemui.statusbar.StatusBarIconView -import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT -import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN +import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarView import com.android.systemui.statusbar.pipeline.wifi.ui.binder.WifiViewBinder import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel @@ -36,83 +31,14 @@ import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWi */ class ModernStatusBarWifiView( context: Context, - attrs: AttributeSet? -) : BaseStatusBarFrameLayout(context, attrs) { - - private lateinit var slot: String - private lateinit var binding: WifiViewBinder.Binding - - @StatusBarIconView.VisibleState - private var iconVisibleState: Int = STATE_HIDDEN - set(value) { - if (field == value) { - return - } - field = value - binding.onVisibilityStateChanged(value) - } - - override fun getSlot() = slot - - override fun onDarkChanged(areas: ArrayList<Rect>?, darkIntensity: Float, tint: Int) { - val newTint = DarkIconDispatcher.getTint(areas, this, tint) - binding.onIconTintChanged(newTint) - binding.onDecorTintChanged(newTint) - } - - override fun setStaticDrawableColor(color: Int) { - binding.onIconTintChanged(color) - } - - override fun setDecorColor(color: Int) { - binding.onDecorTintChanged(color) - } - - override fun setVisibleState(@StatusBarIconView.VisibleState state: Int, animate: Boolean) { - iconVisibleState = state - } - - @StatusBarIconView.VisibleState - override fun getVisibleState(): Int { - return iconVisibleState - } - - override fun isIconVisible(): Boolean { - return binding.getShouldIconBeVisible() - } - - private fun initView( - slotName: String, - wifiViewModel: LocationBasedWifiViewModel, - ) { - slot = slotName - initDotView() - binding = WifiViewBinder.bind(this, wifiViewModel) - } - - // Mostly duplicated from [com.android.systemui.statusbar.StatusBarWifiView]. - private fun initDotView() { - // TODO(b/238425913): Could we just have this dot view be part of - // R.layout.new_status_bar_wifi_group with a dot drawable so we don't need to inflate it - // manually? Would that not work with animations? - val dotView = StatusBarIconView(mContext, slot, null).also { - it.id = R.id.status_bar_dot - // Hard-code this view to always be in the DOT state so that whenever it's visible it - // will show a dot - it.visibleState = STATE_DOT - } - - val width = mContext.resources.getDimensionPixelSize(R.dimen.status_bar_icon_size) - val lp = LayoutParams(width, width) - lp.gravity = Gravity.CENTER_VERTICAL or Gravity.START - addView(dotView, lp) - } - + attrs: AttributeSet?, +) : ModernStatusBarView(context, attrs) { companion object { /** * Inflates a new instance of [ModernStatusBarWifiView], binds it to a view model, and * returns it. */ + @SuppressLint("InflateParams") @JvmStatic fun constructAndBind( context: Context, @@ -123,7 +49,7 @@ class ModernStatusBarWifiView( LayoutInflater.from(context).inflate(R.layout.new_status_bar_wifi_group, null) as ModernStatusBarWifiView ).also { - it.initView(slot, wifiViewModel) + it.initView(slot) { WifiViewBinder.bind(it, wifiViewModel) } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt index a4615cc897cf..02c3a652cc8d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt @@ -47,7 +47,7 @@ abstract class LocationBasedWifiViewModel( /** True if the airplane spacer view should be visible. */ val isAirplaneSpacerVisible: Flow<Boolean>, ) { - val useDebugColoring: Boolean = statusBarPipelineFlags.useWifiDebugColoring() + val useDebugColoring: Boolean = statusBarPipelineFlags.useDebugColoring() val defaultColor: Int = if (useDebugColoring) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt new file mode 100644 index 000000000000..a2c1209f5a40 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.mobile.ui.view + +import android.content.res.ColorStateList +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.testing.TestableLooper.RunWithLooper +import android.testing.ViewUtils +import android.view.View +import android.widget.ImageView +import androidx.test.filters.SmallTest +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags +import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconInteractor +import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel +import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModel +import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.QsMobileIconViewModel +import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants +import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@RunWithLooper(setAsMainLooper = true) +@OptIn(ExperimentalCoroutinesApi::class) +class ModernStatusBarMobileViewTest : SysuiTestCase() { + + private lateinit var testableLooper: TestableLooper + private val testDispatcher = UnconfinedTestDispatcher() + private val testScope = TestScope(testDispatcher) + + @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags + @Mock private lateinit var tableLogBuffer: TableLogBuffer + @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var constants: ConnectivityConstants + + private lateinit var viewModel: LocationBasedMobileViewModel + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + testableLooper = TestableLooper.get(this) + + val interactor = FakeMobileIconInteractor(tableLogBuffer) + + val viewModelCommon = + MobileIconViewModel( + subscriptionId = 1, + interactor, + logger, + constants, + testScope.backgroundScope, + ) + viewModel = QsMobileIconViewModel(viewModelCommon, statusBarPipelineFlags) + } + + // Note: The following tests are more like integration tests, since they stand up a full + // [WifiViewModel] and test the interactions between the view, view-binder, and view-model. + + @Test + fun setVisibleState_icon_iconShownDotHidden() { + val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) + + view.setVisibleState(StatusBarIconView.STATE_ICON, /* animate= */ false) + + ViewUtils.attachView(view) + testableLooper.processAllMessages() + + assertThat(view.getGroupView().visibility).isEqualTo(View.VISIBLE) + assertThat(view.getDotView().visibility).isEqualTo(View.GONE) + + ViewUtils.detachView(view) + } + + @Test + fun setVisibleState_dot_iconHiddenDotShown() { + val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) + + view.setVisibleState(StatusBarIconView.STATE_DOT, /* animate= */ false) + + ViewUtils.attachView(view) + testableLooper.processAllMessages() + + assertThat(view.getGroupView().visibility).isEqualTo(View.INVISIBLE) + assertThat(view.getDotView().visibility).isEqualTo(View.VISIBLE) + + ViewUtils.detachView(view) + } + + @Test + fun setVisibleState_hidden_iconAndDotHidden() { + val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) + + view.setVisibleState(StatusBarIconView.STATE_HIDDEN, /* animate= */ false) + + ViewUtils.attachView(view) + testableLooper.processAllMessages() + + assertThat(view.getGroupView().visibility).isEqualTo(View.INVISIBLE) + assertThat(view.getDotView().visibility).isEqualTo(View.INVISIBLE) + + ViewUtils.detachView(view) + } + + @Test + fun isIconVisible_alwaysTrue() { + val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) + + ViewUtils.attachView(view) + testableLooper.processAllMessages() + + assertThat(view.isIconVisible).isTrue() + + ViewUtils.detachView(view) + } + + @Test + fun onDarkChanged_iconHasNewColor() { + whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false) + val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) + ViewUtils.attachView(view) + testableLooper.processAllMessages() + + val color = 0x12345678 + view.onDarkChanged(arrayListOf(), 1.0f, color) + testableLooper.processAllMessages() + + assertThat(view.getIconView().imageTintList).isEqualTo(ColorStateList.valueOf(color)) + + ViewUtils.detachView(view) + } + + @Test + fun setStaticDrawableColor_iconHasNewColor() { + whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false) + val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel) + ViewUtils.attachView(view) + testableLooper.processAllMessages() + + val color = 0x23456789 + view.setStaticDrawableColor(color) + testableLooper.processAllMessages() + + assertThat(view.getIconView().imageTintList).isEqualTo(ColorStateList.valueOf(color)) + + ViewUtils.detachView(view) + } + + private fun View.getGroupView(): View { + return this.requireViewById(R.id.mobile_group) + } + + private fun View.getIconView(): ImageView { + return this.requireViewById(R.id.mobile_signal) + } + + private fun View.getDotView(): View { + return this.requireViewById(R.id.status_bar_dot) + } +} + +private const val SLOT_NAME = "TestSlotName" diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt index 043d55a73076..c960a06e6bb2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt @@ -20,6 +20,7 @@ import androidx.test.filters.SmallTest import com.android.settingslib.mobile.TelephonyIcons import com.android.systemui.SysuiTestCase import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconInteractor import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModelTest.Companion.defaultSignal import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants @@ -45,6 +46,7 @@ class LocationBasedMobileIconViewModelTest : SysuiTestCase() { private lateinit var qsIcon: QsMobileIconViewModel private lateinit var keyguardIcon: KeyguardMobileIconViewModel private lateinit var interactor: FakeMobileIconInteractor + @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags @Mock private lateinit var logger: ConnectivityPipelineLogger @Mock private lateinit var constants: ConnectivityConstants @Mock private lateinit var tableLogBuffer: TableLogBuffer @@ -68,9 +70,9 @@ class LocationBasedMobileIconViewModelTest : SysuiTestCase() { commonImpl = MobileIconViewModel(SUB_1_ID, interactor, logger, constants, testScope.backgroundScope) - homeIcon = HomeMobileIconViewModel(commonImpl, logger) - qsIcon = QsMobileIconViewModel(commonImpl, logger) - keyguardIcon = KeyguardMobileIconViewModel(commonImpl, logger) + homeIcon = HomeMobileIconViewModel(commonImpl, statusBarPipelineFlags) + qsIcon = QsMobileIconViewModel(commonImpl, statusBarPipelineFlags) + keyguardIcon = KeyguardMobileIconViewModel(commonImpl, statusBarPipelineFlags) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt index d6cb76260f0b..58b50c7e7e6d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.phone.StatusBarLocation +import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy @@ -45,6 +46,7 @@ class MobileIconsViewModelTest : SysuiTestCase() { private lateinit var underTest: MobileIconsViewModel private val interactor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock()) + @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags @Mock private lateinit var logger: ConnectivityPipelineLogger @Mock private lateinit var constants: ConnectivityConstants @@ -67,6 +69,7 @@ class MobileIconsViewModelTest : SysuiTestCase() { logger, constants, testScope.backgroundScope, + statusBarPipelineFlags, ) interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt new file mode 100644 index 000000000000..3fe69837a761 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.shared.ui.view + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper.RunWithLooper +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT +import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN +import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON +import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@RunWithLooper(setAsMainLooper = true) +class ModernStatusBarViewTest : SysuiTestCase() { + + private lateinit var binding: TestBinding + + @Test + fun initView_hasCorrectSlot() { + val view = ModernStatusBarView(context, null) + val binding = TestBinding() + + view.initView("slotName") { binding } + + assertThat(view.slot).isEqualTo("slotName") + } + + @Test + fun getVisibleState_icon_returnsIcon() { + val view = createAndInitView() + + view.setVisibleState(STATE_ICON, /* animate= */ false) + + assertThat(view.visibleState).isEqualTo(STATE_ICON) + } + + @Test + fun getVisibleState_dot_returnsDot() { + val view = createAndInitView() + + view.setVisibleState(STATE_DOT, /* animate= */ false) + + assertThat(view.visibleState).isEqualTo(STATE_DOT) + } + + @Test + fun getVisibleState_hidden_returnsHidden() { + val view = createAndInitView() + + view.setVisibleState(STATE_HIDDEN, /* animate= */ false) + + assertThat(view.visibleState).isEqualTo(STATE_HIDDEN) + } + + @Test + fun onDarkChanged_bindingReceivesIconAndDecorTint() { + val view = createAndInitView() + + view.onDarkChanged(arrayListOf(), 1.0f, 0x12345678) + + assertThat(binding.iconTint).isEqualTo(0x12345678) + assertThat(binding.decorTint).isEqualTo(0x12345678) + } + + @Test + fun setStaticDrawableColor_bindingReceivesIconTint() { + val view = createAndInitView() + + view.setStaticDrawableColor(0x12345678) + + assertThat(binding.iconTint).isEqualTo(0x12345678) + } + + @Test + fun setDecorColor_bindingReceivesDecorColor() { + val view = createAndInitView() + + view.setDecorColor(0x23456789) + + assertThat(binding.decorTint).isEqualTo(0x23456789) + } + + @Test + fun isIconVisible_usesBinding_true() { + val view = createAndInitView() + + binding.shouldIconBeVisibleInternal = true + + assertThat(view.isIconVisible).isEqualTo(true) + } + + @Test + fun isIconVisible_usesBinding_false() { + val view = createAndInitView() + + binding.shouldIconBeVisibleInternal = false + + assertThat(view.isIconVisible).isEqualTo(false) + } + + private fun createAndInitView(): ModernStatusBarView { + val view = ModernStatusBarView(context, null) + binding = TestBinding() + view.initView(SLOT_NAME) { binding } + return view + } + + inner class TestBinding : ModernStatusBarViewBinding { + var iconTint: Int? = null + var decorTint: Int? = null + var onVisibilityStateChangedCalled: Boolean = false + + var shouldIconBeVisibleInternal: Boolean = true + + override fun onIconTintChanged(newTint: Int) { + iconTint = newTint + } + + override fun onDecorTintChanged(newTint: Int) { + decorTint = newTint + } + + override fun onVisibilityStateChanged(state: Int) { + onVisibilityStateChangedCalled = true + } + + override fun getShouldIconBeVisible(): Boolean { + return shouldIconBeVisibleInternal + } + } +} + +private const val SLOT_NAME = "TestSlotName" diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt index 59c10cd6df7c..b8ace2f04a61 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.pipeline.wifi.ui.view import android.content.res.ColorStateList -import android.graphics.Rect import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper @@ -27,7 +26,6 @@ import android.widget.ImageView import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase -import com.android.systemui.lifecycle.InstantTaskExecutorRule import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN @@ -52,8 +50,6 @@ import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import org.junit.Before -import org.junit.Ignore -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock @@ -70,7 +66,8 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() { private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags @Mock private lateinit var logger: ConnectivityPipelineLogger - @Mock private lateinit var tableLogBuffer: TableLogBuffer + @Mock + private lateinit var tableLogBuffer: TableLogBuffer @Mock private lateinit var connectivityConstants: ConnectivityConstants @Mock @@ -83,9 +80,6 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() { private lateinit var scope: CoroutineScope private lateinit var airplaneModeViewModel: AirplaneModeViewModel - @JvmField @Rule - val instantTaskExecutor = InstantTaskExecutorRule() - @Before fun setUp() { MockitoAnnotations.initMocks(this) @@ -118,40 +112,6 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() { ).home } - @Test - fun constructAndBind_hasCorrectSlot() { - val view = ModernStatusBarWifiView.constructAndBind(context, "slotName", viewModel) - - assertThat(view.slot).isEqualTo("slotName") - } - - @Test - fun getVisibleState_icon_returnsIcon() { - val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel) - - view.setVisibleState(STATE_ICON, /* animate= */ false) - - assertThat(view.visibleState).isEqualTo(STATE_ICON) - } - - @Test - fun getVisibleState_dot_returnsDot() { - val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel) - - view.setVisibleState(STATE_DOT, /* animate= */ false) - - assertThat(view.visibleState).isEqualTo(STATE_DOT) - } - - @Test - fun getVisibleState_hidden_returnsHidden() { - val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel) - - view.setVisibleState(STATE_HIDDEN, /* animate= */ false) - - assertThat(view.visibleState).isEqualTo(STATE_HIDDEN) - } - // Note: The following tests are more like integration tests, since they stand up a full // [WifiViewModel] and test the interactions between the view, view-binder, and view-model. @@ -235,24 +195,24 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() { } @Test - @Ignore("b/262660044") fun onDarkChanged_iconHasNewColor() { - whenever(statusBarPipelineFlags.useWifiDebugColoring()).thenReturn(false) + whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false) val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel) ViewUtils.attachView(view) testableLooper.processAllMessages() - val areas = ArrayList(listOf(Rect(0, 0, 1000, 1000))) val color = 0x12345678 - view.onDarkChanged(areas, 1.0f, color) + view.onDarkChanged(arrayListOf(), 1.0f, color) testableLooper.processAllMessages() assertThat(view.getIconView().imageTintList).isEqualTo(ColorStateList.valueOf(color)) + + ViewUtils.detachView(view) } @Test fun setStaticDrawableColor_iconHasNewColor() { - whenever(statusBarPipelineFlags.useWifiDebugColoring()).thenReturn(false) + whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false) val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel) ViewUtils.attachView(view) testableLooper.processAllMessages() @@ -262,6 +222,8 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() { testableLooper.processAllMessages() assertThat(view.getIconView().imageTintList).isEqualTo(ColorStateList.valueOf(color)) + + ViewUtils.detachView(view) } private fun View.getIconGroupView(): View { |