[SB Refactor] Add logs for view creation and collection.

In the linked bug, it appears as though the MobileIconViewModel has the
correct information but that information isn't being displayed in the
UI. This CL adds some logs around view binding and view updating to
determine at what point viewModel <--> UI the updates are lost.

Bug: 267236367
Test: `adb shell dumpsys activity service
com.android.systemui/.SystemUIService MobileViewLog` -> shows collection
start/stop logs
Test: `adb shell dumpsys activity service
com.android.systemui/.SystemUIService MobileViewLogger` -> shows current
collection status
Test: atest MobileViewLoggerTest

Change-Id: Ic63ada059e82fd06932c8ec076b532228f839ebd
This commit is contained in:
Caitlin Shkuratov
2023-03-02 18:45:00 +00:00
parent 416bbd90e7
commit 3fac1f3366
15 changed files with 322 additions and 24 deletions

View File

@@ -40,6 +40,7 @@ import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger;
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.view.ModernStatusBarWifiView;
@@ -288,10 +289,14 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da
* @param mobileContext possibly mcc/mnc overridden mobile context
* @param subId the subscriptionId for this mobile view
*/
public void addModernMobileView(Context mobileContext, int subId) {
public void addModernMobileView(
Context mobileContext,
MobileViewLogger mobileViewLogger,
int subId) {
Log.d(TAG, "addModernMobileView (subId=" + subId + ")");
ModernStatusBarMobileView view = ModernStatusBarMobileView.constructAndBind(
mobileContext,
mobileViewLogger,
"mobile",
mMobileIconsViewModel.viewModelForSub(subId, mLocation)
);

View File

@@ -569,7 +569,10 @@ public interface StatusBarIconController {
mGroup.addView(view, index, onCreateLayoutParams());
if (mIsInDemoMode) {
mDemoStatusIcons.addModernMobileView(mContext, subId);
mDemoStatusIcons.addModernMobileView(
mContext,
mMobileIconsViewModel.getLogger(),
subId);
}
return view;
@@ -601,6 +604,7 @@ public interface StatusBarIconController {
return ModernStatusBarMobileView
.constructAndBind(
mobileContext,
mMobileIconsViewModel.getLogger(),
slot,
mMobileIconsViewModel.viewModelForSub(subId, mLocation)
);

View File

@@ -17,17 +17,30 @@
package com.android.systemui.statusbar.pipeline.mobile.ui
import android.view.View
import androidx.annotation.VisibleForTesting
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.plugins.log.LogLevel
import com.android.systemui.statusbar.pipeline.dagger.MobileViewLog
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
import java.io.PrintWriter
import javax.inject.Inject
/** Logs for changes with the new mobile views. */
@SysUISingleton
class MobileViewLogger @Inject constructor(
class MobileViewLogger
@Inject
constructor(
@MobileViewLog private val buffer: LogBuffer,
) {
dumpManager: DumpManager,
) : Dumpable {
init {
dumpManager.registerNormalDumpable(this)
}
private val collectionStatuses = mutableMapOf<String, Boolean>()
fun logUiAdapterSubIdsUpdated(subs: List<Int>) {
buffer.log(
@@ -46,6 +59,62 @@ class MobileViewLogger @Inject constructor(
{ "Sub IDs in MobileUiAdapter being sent to icon controller: $str1" },
)
}
fun logNewViewBinding(view: View, viewModel: LocationBasedMobileViewModel) {
buffer.log(
TAG,
LogLevel.INFO,
{
str1 = view.getIdForLogging()
str2 = viewModel.getIdForLogging()
str3 = viewModel.locationName
},
{ "New view binding. viewId=$str1, viewModelId=$str2, viewModelLocation=$str3" },
)
}
fun logCollectionStarted(view: View, viewModel: LocationBasedMobileViewModel) {
collectionStatuses[view.getIdForLogging()] = true
buffer.log(
TAG,
LogLevel.INFO,
{
str1 = view.getIdForLogging()
str2 = viewModel.getIdForLogging()
str3 = viewModel.locationName
},
{ "Collection started. viewId=$str1, viewModelId=$str2, viewModelLocation=$str3" },
)
}
fun logCollectionStopped(view: View, viewModel: LocationBasedMobileViewModel) {
collectionStatuses[view.getIdForLogging()] = false
buffer.log(
TAG,
LogLevel.INFO,
{
str1 = view.getIdForLogging()
str2 = viewModel.getIdForLogging()
str3 = viewModel.locationName
},
{ "Collection stopped. viewId=$str1, viewModelId=$str2, viewModelLocation=$str3" },
)
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.println("Collection statuses per view:---")
collectionStatuses.forEach { viewId, isCollecting ->
pw.println("viewId=$viewId, isCollecting=$isCollecting")
}
}
companion object {
@VisibleForTesting
internal fun Any.getIdForLogging(): String {
// The identityHashCode is guaranteed to be constant for the lifetime of the object.
return Integer.toHexString(System.identityHashCode(this))
}
}
}
private const val TAG = "MobileViewLogger"

View File

@@ -36,8 +36,10 @@ 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.MobileViewLogger
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
@@ -48,6 +50,7 @@ object MobileIconBinder {
fun bind(
view: ViewGroup,
viewModel: LocationBasedMobileViewModel,
logger: MobileViewLogger,
): ModernStatusBarViewBinding {
val mobileGroupView = view.requireViewById<ViewGroup>(R.id.mobile_group)
val activityContainer = view.requireViewById<View>(R.id.inout_container)
@@ -70,8 +73,13 @@ object MobileIconBinder {
val iconTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
val decorTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
var isCollecting: Boolean = false
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
logger.logCollectionStarted(view, viewModel)
isCollecting = true
launch {
visibilityState.collect { state ->
when (state) {
@@ -150,6 +158,13 @@ object MobileIconBinder {
}
launch { decorTint.collect { tint -> dotView.setDecorColor(tint) } }
try {
awaitCancellation()
} finally {
isCollecting = false
logger.logCollectionStopped(view, viewModel)
}
}
}
@@ -175,6 +190,10 @@ object MobileIconBinder {
}
decorTint.value = newTint
}
override fun isCollecting(): Boolean {
return isCollecting
}
}
}
}

View File

@@ -21,6 +21,7 @@ import android.util.AttributeSet
import android.view.LayoutInflater
import com.android.systemui.R
import com.android.systemui.statusbar.StatusBarIconView.getVisibleStateString
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarView
@@ -36,6 +37,7 @@ class ModernStatusBarMobileView(
return "ModernStatusBarMobileView(" +
"slot='$slot', " +
"subId=$subId, " +
"isCollecting=${binding.isCollecting()}, " +
"visibleState=${getVisibleStateString(visibleState)}); " +
"viewString=${super.toString()}"
}
@@ -49,6 +51,7 @@ class ModernStatusBarMobileView(
@JvmStatic
fun constructAndBind(
context: Context,
logger: MobileViewLogger,
slot: String,
viewModel: LocationBasedMobileViewModel,
): ModernStatusBarMobileView {
@@ -57,7 +60,8 @@ class ModernStatusBarMobileView(
as ModernStatusBarMobileView)
.also {
it.subId = viewModel.subscriptionId
it.initView(slot) { MobileIconBinder.bind(it, viewModel) }
it.initView(slot) { MobileIconBinder.bind(it, viewModel, logger) }
logger.logNewViewBinding(it, viewModel)
}
}
}

View File

@@ -26,11 +26,13 @@ import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
*
* @param commonImpl for convenience, this class wraps a base interface that can provides all of the
* common implementations between locations. See [MobileIconViewModel]
* @property locationName the name of the location of this VM, used for logging.
*/
abstract class LocationBasedMobileViewModel(
val commonImpl: MobileIconViewModelCommon,
statusBarPipelineFlags: StatusBarPipelineFlags,
debugTint: Int,
val locationName: String,
) : MobileIconViewModelCommon by commonImpl {
val useDebugColoring: Boolean = statusBarPipelineFlags.useDebugColoring()
@@ -62,18 +64,33 @@ class HomeMobileIconViewModel(
statusBarPipelineFlags: StatusBarPipelineFlags,
) :
MobileIconViewModelCommon,
LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.CYAN)
LocationBasedMobileViewModel(
commonImpl,
statusBarPipelineFlags,
debugTint = Color.CYAN,
locationName = "Home",
)
class QsMobileIconViewModel(
commonImpl: MobileIconViewModelCommon,
statusBarPipelineFlags: StatusBarPipelineFlags,
) :
MobileIconViewModelCommon,
LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.GREEN)
LocationBasedMobileViewModel(
commonImpl,
statusBarPipelineFlags,
debugTint = Color.GREEN,
locationName = "QS",
)
class KeyguardMobileIconViewModel(
commonImpl: MobileIconViewModelCommon,
statusBarPipelineFlags: StatusBarPipelineFlags,
) :
MobileIconViewModelCommon,
LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.MAGENTA)
LocationBasedMobileViewModel(
commonImpl,
statusBarPipelineFlags,
debugTint = Color.MAGENTA,
locationName = "Keyguard",
)

View File

@@ -23,6 +23,7 @@ import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
import javax.inject.Inject
@@ -39,6 +40,7 @@ class MobileIconsViewModel
@Inject
constructor(
val subscriptionIdsFlow: StateFlow<List<Int>>,
val logger: MobileViewLogger,
private val interactor: MobileIconsInteractor,
private val airplaneModeInteractor: AirplaneModeInteractor,
private val constants: ConnectivityConstants,
@@ -79,6 +81,7 @@ constructor(
class Factory
@Inject
constructor(
private val logger: MobileViewLogger,
private val interactor: MobileIconsInteractor,
private val airplaneModeInteractor: AirplaneModeInteractor,
private val constants: ConnectivityConstants,
@@ -88,6 +91,7 @@ constructor(
fun create(subscriptionIdsFlow: StateFlow<List<Int>>): MobileIconsViewModel {
return MobileIconsViewModel(
subscriptionIdsFlow,
logger,
interactor,
airplaneModeInteractor,
constants,

View File

@@ -37,4 +37,7 @@ interface ModernStatusBarViewBinding {
/** Notifies that the decor tint has been updated (used only for the dot). */
fun onDecorTintChanged(newTint: Int)
/** Returns true if the binding between the view and view-model is currently collecting. */
fun isCollecting(): Boolean
}

View File

@@ -36,7 +36,7 @@ open class ModernStatusBarView(context: Context, attrs: AttributeSet?) :
BaseStatusBarFrameLayout(context, attrs) {
private lateinit var slot: String
private lateinit var binding: ModernStatusBarViewBinding
internal lateinit var binding: ModernStatusBarViewBinding
@StatusBarIconView.VisibleState
private var iconVisibleState: Int = STATE_HIDDEN

View File

@@ -34,6 +34,7 @@ import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarV
import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -74,8 +75,12 @@ object WifiViewBinder {
val iconTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
val decorTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
var isCollecting: Boolean = false
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
isCollecting = true
launch {
visibilityState.collect { visibilityState ->
groupView.isVisible = visibilityState == STATE_ICON
@@ -127,6 +132,12 @@ object WifiViewBinder {
airplaneSpacer.isVisible = visible
}
}
try {
awaitCancellation()
} finally {
isCollecting = false
}
}
}
@@ -152,6 +163,10 @@ object WifiViewBinder {
}
decorTint.value = newTint
}
override fun isCollecting(): Boolean {
return isCollecting
}
}
}
}

View File

@@ -38,6 +38,7 @@ class ModernStatusBarWifiView(
override fun toString(): String {
return "ModernStatusBarWifiView(" +
"slot='$slot', " +
"isCollecting=${binding.isCollecting()}, " +
"visibleState=${StatusBarIconView.getVisibleStateString(visibleState)}); " +
"viewString=${super.toString()}"
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright (C) 2023 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
import android.widget.TextView
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.log.LogBufferFactory
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger.Companion.getIdForLogging
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.KeyguardMobileIconViewModel
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModel
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.QsMobileIconViewModel
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import java.io.PrintWriter
import java.io.StringWriter
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.MockitoAnnotations
@SmallTest
class MobileViewLoggerTest : SysuiTestCase() {
private val buffer = LogBufferFactory(DumpManager(), mock()).create("buffer", 10)
private val stringWriter = StringWriter()
private val printWriter = PrintWriter(stringWriter)
private val underTest = MobileViewLogger(buffer, mock())
@Mock private lateinit var flags: StatusBarPipelineFlags
@Mock private lateinit var commonViewModel: MobileIconViewModel
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun collectionStarted_dumpHasInfo() {
val view = TextView(context)
val viewModel = QsMobileIconViewModel(commonViewModel, flags)
underTest.logCollectionStarted(view, viewModel)
val dumpString = getDumpString()
assertThat(dumpString).contains("${view.getIdForLogging()}, isCollecting=true")
}
@Test
fun collectionStarted_multipleViews_dumpHasInfo() {
val view = TextView(context)
val view2 = TextView(context)
val viewModel = QsMobileIconViewModel(commonViewModel, flags)
val viewModel2 = KeyguardMobileIconViewModel(commonViewModel, flags)
underTest.logCollectionStarted(view, viewModel)
underTest.logCollectionStarted(view2, viewModel2)
val dumpString = getDumpString()
assertThat(dumpString).contains("${view.getIdForLogging()}, isCollecting=true")
assertThat(dumpString).contains("${view2.getIdForLogging()}, isCollecting=true")
}
@Test
fun collectionStopped_dumpHasInfo() {
val view = TextView(context)
val view2 = TextView(context)
val viewModel = QsMobileIconViewModel(commonViewModel, flags)
val viewModel2 = KeyguardMobileIconViewModel(commonViewModel, flags)
underTest.logCollectionStarted(view, viewModel)
underTest.logCollectionStarted(view2, viewModel2)
underTest.logCollectionStopped(view, viewModel)
val dumpString = getDumpString()
assertThat(dumpString).contains("${view.getIdForLogging()}, isCollecting=false")
assertThat(dumpString).contains("${view2.getIdForLogging()}, isCollecting=true")
}
private fun getDumpString(): String {
underTest.dump(printWriter, args = arrayOf())
return stringWriter.toString()
}
}

View File

@@ -32,6 +32,7 @@ import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconInteractor
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
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
@@ -60,6 +61,7 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() {
@Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
@Mock private lateinit var tableLogBuffer: TableLogBuffer
@Mock private lateinit var viewLogger: MobileViewLogger
@Mock private lateinit var constants: ConnectivityConstants
private lateinit var interactor: FakeMobileIconInteractor
private lateinit var airplaneModeRepository: FakeAirplaneModeRepository
@@ -94,7 +96,13 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() {
@Test
fun setVisibleState_icon_iconShownDotHidden() {
val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
val view =
ModernStatusBarMobileView.constructAndBind(
context,
viewLogger,
SLOT_NAME,
viewModel,
)
view.setVisibleState(StatusBarIconView.STATE_ICON, /* animate= */ false)
@@ -109,8 +117,13 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() {
@Test
fun setVisibleState_dot_iconHiddenDotShown() {
val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
val view =
ModernStatusBarMobileView.constructAndBind(
context,
viewLogger,
SLOT_NAME,
viewModel,
)
view.setVisibleState(StatusBarIconView.STATE_DOT, /* animate= */ false)
ViewUtils.attachView(view)
@@ -124,8 +137,13 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() {
@Test
fun setVisibleState_hidden_iconAndDotHidden() {
val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
val view =
ModernStatusBarMobileView.constructAndBind(
context,
viewLogger,
SLOT_NAME,
viewModel,
)
view.setVisibleState(StatusBarIconView.STATE_HIDDEN, /* animate= */ false)
ViewUtils.attachView(view)
@@ -142,8 +160,13 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() {
whenever(constants.hasDataCapabilities).thenReturn(false)
createViewModel()
val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
val view =
ModernStatusBarMobileView.constructAndBind(
context,
viewLogger,
SLOT_NAME,
viewModel,
)
ViewUtils.attachView(view)
testableLooper.processAllMessages()
@@ -157,8 +180,13 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() {
whenever(constants.hasDataCapabilities).thenReturn(true)
createViewModel()
val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
val view =
ModernStatusBarMobileView.constructAndBind(
context,
viewLogger,
SLOT_NAME,
viewModel,
)
ViewUtils.attachView(view)
testableLooper.processAllMessages()
@@ -171,8 +199,13 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() {
fun isIconVisible_notAirplaneMode_outputsTrue() {
airplaneModeRepository.setIsAirplaneMode(false)
val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
val view =
ModernStatusBarMobileView.constructAndBind(
context,
viewLogger,
SLOT_NAME,
viewModel,
)
ViewUtils.attachView(view)
testableLooper.processAllMessages()
@@ -185,8 +218,13 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() {
fun isIconVisible_airplaneMode_outputsTrue() {
airplaneModeRepository.setIsAirplaneMode(true)
val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
val view =
ModernStatusBarMobileView.constructAndBind(
context,
viewLogger,
SLOT_NAME,
viewModel,
)
ViewUtils.attachView(view)
testableLooper.processAllMessages()
@@ -198,7 +236,13 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() {
@Test
fun onDarkChanged_iconHasNewColor() {
whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false)
val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
val view =
ModernStatusBarMobileView.constructAndBind(
context,
viewLogger,
SLOT_NAME,
viewModel,
)
ViewUtils.attachView(view)
testableLooper.processAllMessages()
@@ -214,7 +258,13 @@ class ModernStatusBarMobileViewTest : SysuiTestCase() {
@Test
fun setStaticDrawableColor_iconHasNewColor() {
whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false)
val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
val view =
ModernStatusBarMobileView.constructAndBind(
context,
viewLogger,
SLOT_NAME,
viewModel,
)
ViewUtils.attachView(view)
testableLooper.processAllMessages()

View File

@@ -24,6 +24,7 @@ import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirp
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
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.ui.MobileViewLogger
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
@@ -51,6 +52,7 @@ class MobileIconsViewModelTest : SysuiTestCase() {
private lateinit var airplaneModeInteractor: AirplaneModeInteractor
@Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
@Mock private lateinit var constants: ConnectivityConstants
@Mock private lateinit var logger: MobileViewLogger
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
@@ -73,6 +75,7 @@ class MobileIconsViewModelTest : SysuiTestCase() {
underTest =
MobileIconsViewModel(
subscriptionIdsFlow,
logger,
interactor,
airplaneModeInteractor,
constants,

View File

@@ -164,6 +164,10 @@ class ModernStatusBarViewTest : SysuiTestCase() {
override fun getShouldIconBeVisible(): Boolean {
return shouldIconBeVisibleInternal
}
override fun isCollecting(): Boolean {
return true
}
}
}