[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:
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ class ModernStatusBarWifiView(
|
||||
override fun toString(): String {
|
||||
return "ModernStatusBarWifiView(" +
|
||||
"slot='$slot', " +
|
||||
"isCollecting=${binding.isCollecting()}, " +
|
||||
"visibleState=${StatusBarIconView.getVisibleStateString(visibleState)}); " +
|
||||
"viewString=${super.toString()}"
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -164,6 +164,10 @@ class ModernStatusBarViewTest : SysuiTestCase() {
|
||||
override fun getShouldIconBeVisible(): Boolean {
|
||||
return shouldIconBeVisibleInternal
|
||||
}
|
||||
|
||||
override fun isCollecting(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user