[SB Refactor] Remove the wifi-specific parts from ModernStatusBarView.
Bug: 238425913 Test: verify wifi icon still tints correctly Test: atest ModernStatusBarViewTest ModernStatusBarWifiViewTest Change-Id: I86a2ca1b7ddf05dc2942faf178e702abd1d5738f
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarWifiView
|
||||
<com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/wifi_combo"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -25,4 +25,4 @@
|
||||
|
||||
<include layout="@layout/status_bar_wifi_group_inner" />
|
||||
|
||||
</com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarWifiView>
|
||||
</com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView>
|
||||
|
||||
@@ -42,7 +42,7 @@ import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconStat
|
||||
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView;
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel;
|
||||
import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarWifiView;
|
||||
import com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView;
|
||||
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -55,7 +55,7 @@ import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconsBinde
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView;
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel;
|
||||
import com.android.systemui.statusbar.pipeline.wifi.ui.WifiUiAdapter;
|
||||
import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarWifiView;
|
||||
import com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView;
|
||||
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel;
|
||||
import com.android.systemui.util.Assert;
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ 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
|
||||
@@ -28,17 +27,13 @@ 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
|
||||
import com.android.systemui.statusbar.pipeline.wifi.ui.binder.WifiViewBinder
|
||||
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel
|
||||
|
||||
/**
|
||||
* A new and more modern implementation of [com.android.systemui.statusbar.StatusBarWifiView] that
|
||||
* is updated by [WifiViewBinder].
|
||||
* A new and more modern implementation of [BaseStatusBarFrameLayout] that gets updated by view
|
||||
* binders communicating via [ModernStatusBarViewBinding].
|
||||
*/
|
||||
class ModernStatusBarWifiView(
|
||||
context: Context,
|
||||
attrs: AttributeSet?
|
||||
) : BaseStatusBarFrameLayout(context, attrs) {
|
||||
open class ModernStatusBarView(context: Context, attrs: AttributeSet?) :
|
||||
BaseStatusBarFrameLayout(context, attrs) {
|
||||
|
||||
private lateinit var slot: String
|
||||
private lateinit var binding: ModernStatusBarViewBinding
|
||||
@@ -82,50 +77,39 @@ class ModernStatusBarWifiView(
|
||||
return binding.getShouldIconBeVisible()
|
||||
}
|
||||
|
||||
private fun initView(
|
||||
slotName: String,
|
||||
wifiViewModel: LocationBasedWifiViewModel,
|
||||
) {
|
||||
slot = slotName
|
||||
/**
|
||||
* 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()
|
||||
binding = WifiViewBinder.bind(this, wifiViewModel)
|
||||
this.binding = bindingCreator.invoke()
|
||||
}
|
||||
|
||||
// Mostly duplicated from [com.android.systemui.statusbar.StatusBarWifiView].
|
||||
/**
|
||||
* 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
|
||||
// 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
|
||||
}
|
||||
// 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)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Inflates a new instance of [ModernStatusBarWifiView], binds it to a view model, and
|
||||
* returns it.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun constructAndBind(
|
||||
context: Context,
|
||||
slot: String,
|
||||
wifiViewModel: LocationBasedWifiViewModel,
|
||||
): ModernStatusBarWifiView {
|
||||
return (
|
||||
LayoutInflater.from(context).inflate(R.layout.new_status_bar_wifi_group, null)
|
||||
as ModernStatusBarWifiView
|
||||
).also {
|
||||
it.initView(slot, wifiViewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.wifi.ui.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import com.android.systemui.R
|
||||
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
|
||||
|
||||
/**
|
||||
* A new and more modern implementation of [com.android.systemui.statusbar.StatusBarWifiView] that
|
||||
* is updated by [WifiViewBinder].
|
||||
*/
|
||||
class ModernStatusBarWifiView(
|
||||
context: Context,
|
||||
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,
|
||||
slot: String,
|
||||
wifiViewModel: LocationBasedWifiViewModel,
|
||||
): ModernStatusBarWifiView {
|
||||
return (
|
||||
LayoutInflater.from(context).inflate(R.layout.new_status_bar_wifi_group, null)
|
||||
as ModernStatusBarWifiView
|
||||
).also {
|
||||
it.initView(slot) { WifiViewBinder.bind(it, wifiViewModel) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -40,7 +38,6 @@ import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneMod
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
|
||||
import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarWifiView
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
|
||||
@@ -54,7 +51,6 @@ 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
|
||||
@@ -71,7 +67,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
|
||||
@@ -84,9 +81,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)
|
||||
@@ -119,40 +113,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.
|
||||
|
||||
@@ -243,9 +203,8 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() {
|
||||
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))
|
||||
|
||||
Reference in New Issue
Block a user