Merge changes I88baa0eb,Ic63ada05,I5e7eb52c,Ifd28e920 into tm-qpr-dev
* changes: [SB Refactor] Add verbose logging about values received by the binder. [SB Refactor] Add logs for view creation and collection. [SB Refactor] Define a MobileViewLogger and move the UI logs there. [SB Refactor] Minor logging changes to StatusBarIconController etc.
This commit is contained in:
committed by
Android (Google) Code Review
commit
89a037dbed
@@ -93,6 +93,16 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
|
||||
@IntDef({STATE_ICON, STATE_DOT, STATE_HIDDEN})
|
||||
public @interface VisibleState { }
|
||||
|
||||
/** Returns a human-readable string of {@link VisibleState}. */
|
||||
public static String getVisibleStateString(@VisibleState int state) {
|
||||
switch(state) {
|
||||
case STATE_ICON: return "ICON";
|
||||
case STATE_DOT: return "DOT";
|
||||
case STATE_HIDDEN: return "HIDDEN";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
private static final String TAG = "StatusBarIconView";
|
||||
private static final Property<StatusBarIconView, Float> ICON_APPEAR_AMOUNT
|
||||
= new FloatProperty<StatusBarIconView>("iconAppearAmount") {
|
||||
@@ -561,7 +571,8 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StatusBarIconView("
|
||||
+ "slot='" + mSlot + " alpha=" + getAlpha() + " icon=" + mIcon
|
||||
+ "slot='" + mSlot + "' alpha=" + getAlpha() + " icon=" + mIcon
|
||||
+ " visibleState=" + getVisibleStateString(getVisibleState())
|
||||
+ " iconColor=#" + Integer.toHexString(mIconColor)
|
||||
+ " notification=" + mNotification + ')';
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -79,6 +79,18 @@ public class StatusBarIconHolder {
|
||||
private @IconType int mType = TYPE_ICON;
|
||||
private int mTag = 0;
|
||||
|
||||
/** Returns a human-readable string representing the given type. */
|
||||
public static String getTypeString(@IconType int type) {
|
||||
switch(type) {
|
||||
case TYPE_ICON: return "ICON";
|
||||
case TYPE_WIFI: return "WIFI_OLD";
|
||||
case TYPE_MOBILE: return "MOBILE_OLD";
|
||||
case TYPE_MOBILE_NEW: return "MOBILE_NEW";
|
||||
case TYPE_WIFI_NEW: return "WIFI_NEW";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
private StatusBarIconHolder() {
|
||||
}
|
||||
|
||||
@@ -230,4 +242,11 @@ public class StatusBarIconHolder {
|
||||
public int getTag() {
|
||||
return mTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StatusBarIconHolder(type=" + getTypeString(mType)
|
||||
+ " tag=" + getTag()
|
||||
+ " visible=" + isVisible() + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** A class holding the list of all the system icons that could be shown in the status bar. */
|
||||
public class StatusBarIconList {
|
||||
@@ -302,7 +303,7 @@ public class StatusBarIconList {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("(%s) %s", mName, subSlotsString());
|
||||
return String.format("(%s) holder=%s %s", mName, mHolder, subSlotsString());
|
||||
}
|
||||
|
||||
private String subSlotsString() {
|
||||
@@ -310,7 +311,10 @@ public class StatusBarIconList {
|
||||
return "";
|
||||
}
|
||||
|
||||
return "" + mSubSlots.size() + " subSlots";
|
||||
return "| " + mSubSlots.size() + " subSlots: "
|
||||
+ mSubSlots.stream()
|
||||
.map(StatusBarIconHolder::toString)
|
||||
.collect(Collectors.joining("|"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.dagger
|
||||
|
||||
import javax.inject.Qualifier
|
||||
|
||||
/** Logs for changes with the new mobile views. */
|
||||
@Qualifier
|
||||
@MustBeDocumented
|
||||
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class MobileViewLog
|
||||
@@ -148,5 +148,19 @@ abstract class StatusBarPipelineModule {
|
||||
fun provideMobileInputLogBuffer(factory: LogBufferFactory): LogBuffer {
|
||||
return factory.create("MobileInputLog", 100)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@MobileViewLog
|
||||
fun provideMobileViewLogBuffer(factory: LogBufferFactory): LogBuffer {
|
||||
return factory.create("MobileViewLog", 100)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@VerboseMobileViewLog
|
||||
fun provideVerboseMobileViewLogBuffer(factory: LogBufferFactory): LogBuffer {
|
||||
return factory.create("VerboseMobileViewLog", 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.dagger
|
||||
|
||||
import javax.inject.Qualifier
|
||||
|
||||
/** Logs for **verbose** changes with the new mobile views. */
|
||||
@Qualifier
|
||||
@MustBeDocumented
|
||||
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class VerboseMobileViewLog
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.pipeline.mobile.shared
|
||||
package com.android.systemui.statusbar.pipeline.mobile.data
|
||||
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
@@ -133,24 +133,6 @@ constructor(
|
||||
)
|
||||
}
|
||||
|
||||
fun logUiAdapterSubIdsUpdated(subs: List<Int>) {
|
||||
buffer.log(
|
||||
TAG,
|
||||
LogLevel.INFO,
|
||||
{ str1 = subs.toString() },
|
||||
{ "Sub IDs in MobileUiAdapter updated internally: $str1" },
|
||||
)
|
||||
}
|
||||
|
||||
fun logUiAdapterSubIdsSentToIconController(subs: List<Int>) {
|
||||
buffer.log(
|
||||
TAG,
|
||||
LogLevel.INFO,
|
||||
{ str1 = subs.toString() },
|
||||
{ "Sub IDs in MobileUiAdapter being sent to icon controller: $str1" },
|
||||
)
|
||||
}
|
||||
|
||||
fun logCarrierConfigChanged(subId: Int) {
|
||||
buffer.log(
|
||||
TAG,
|
||||
@@ -30,8 +30,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
|
||||
import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
|
||||
import java.io.PrintWriter
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
|
||||
@@ -47,7 +48,6 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameMo
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
|
||||
import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -45,11 +45,11 @@ import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.log.table.logDiffsForTable
|
||||
import com.android.systemui.statusbar.pipeline.dagger.MobileSummaryLog
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController
|
||||
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
|
||||
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
|
||||
import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel
|
||||
import java.io.PrintWriter
|
||||
import javax.inject.Inject
|
||||
@@ -55,17 +54,14 @@ constructor(
|
||||
interactor: MobileIconsInteractor,
|
||||
private val iconController: StatusBarIconController,
|
||||
private val iconsViewModelFactory: MobileIconsViewModel.Factory,
|
||||
private val logger: MobileInputLogger,
|
||||
private val logger: MobileViewLogger,
|
||||
@Application private val scope: CoroutineScope,
|
||||
private val statusBarPipelineFlags: StatusBarPipelineFlags,
|
||||
) : CoreStartable {
|
||||
private val mobileSubIds: Flow<List<Int>> =
|
||||
interactor.filteredSubscriptions
|
||||
.mapLatest { subscriptions ->
|
||||
subscriptions.map { subscriptionModel -> subscriptionModel.subscriptionId }
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.onEach { logger.logUiAdapterSubIdsUpdated(it) }
|
||||
interactor.filteredSubscriptions.mapLatest { subscriptions ->
|
||||
subscriptions.map { subscriptionModel -> subscriptionModel.subscriptionId }
|
||||
}
|
||||
|
||||
/**
|
||||
* We expose the list of tracked subscriptions as a flow of a list of ints, where each int is
|
||||
@@ -75,7 +71,10 @@ constructor(
|
||||
* NOTE: this should go away as the view presenter learns more about this data pipeline
|
||||
*/
|
||||
private val mobileSubIdsState: StateFlow<List<Int>> =
|
||||
mobileSubIds.stateIn(scope, SharingStarted.WhileSubscribed(), listOf())
|
||||
mobileSubIds
|
||||
.distinctUntilChanged()
|
||||
.onEach { logger.logUiAdapterSubIdsUpdated(it) }
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), listOf())
|
||||
|
||||
/** In order to keep the logs tame, we will reuse the same top-level mobile icons view model */
|
||||
val mobileIconsViewModel = iconsViewModelFactory.create(mobileSubIdsState)
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.view.View
|
||||
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(
|
||||
@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(
|
||||
TAG,
|
||||
LogLevel.INFO,
|
||||
{ str1 = subs.toString() },
|
||||
{ "Sub IDs in MobileUiAdapter updated internally: $str1" },
|
||||
)
|
||||
}
|
||||
|
||||
fun logUiAdapterSubIdsSentToIconController(subs: List<Int>) {
|
||||
buffer.log(
|
||||
TAG,
|
||||
LogLevel.INFO,
|
||||
{ str1 = subs.toString() },
|
||||
{ "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 {
|
||||
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"
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.view.View
|
||||
import com.android.systemui.common.shared.model.Icon
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.plugins.log.LogBuffer
|
||||
import com.android.systemui.plugins.log.LogLevel
|
||||
import com.android.systemui.statusbar.pipeline.dagger.VerboseMobileViewLog
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger.Companion.getIdForLogging
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Logs for **verbose** changes with the new mobile views.
|
||||
*
|
||||
* This is a hopefully temporary log until we resolve some open bugs (b/267236367, b/269565345,
|
||||
* b/270300839).
|
||||
*/
|
||||
@SysUISingleton
|
||||
class VerboseMobileViewLogger
|
||||
@Inject
|
||||
constructor(
|
||||
@VerboseMobileViewLog private val buffer: LogBuffer,
|
||||
) {
|
||||
fun logBinderReceivedSignalIcon(parentView: View, subId: Int, icon: SignalIconModel) {
|
||||
buffer.log(
|
||||
TAG,
|
||||
LogLevel.VERBOSE,
|
||||
{
|
||||
str1 = parentView.getIdForLogging()
|
||||
int1 = subId
|
||||
int2 = icon.level
|
||||
bool1 = icon.showExclamationMark
|
||||
},
|
||||
{
|
||||
"Binder[subId=$int1, viewId=$str1] received new signal icon: " +
|
||||
"level=$int2 showExclamation=$bool1"
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fun logBinderReceivedNetworkTypeIcon(parentView: View, subId: Int, icon: Icon.Resource?) {
|
||||
buffer.log(
|
||||
TAG,
|
||||
LogLevel.VERBOSE,
|
||||
{
|
||||
str1 = parentView.getIdForLogging()
|
||||
int1 = subId
|
||||
bool1 = icon != null
|
||||
int2 = icon?.res ?: -1
|
||||
},
|
||||
{
|
||||
"Binder[subId=$int1, viewId=$str1] received new network type icon: " +
|
||||
if (bool1) "resId=$int2" else "null"
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private const val TAG = "VerboseMobileViewLogger"
|
||||
@@ -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) {
|
||||
@@ -96,6 +104,11 @@ object MobileIconBinder {
|
||||
// Set the icon for the triangle
|
||||
launch {
|
||||
viewModel.icon.distinctUntilChanged().collect { icon ->
|
||||
viewModel.verboseLogger?.logBinderReceivedSignalIcon(
|
||||
view,
|
||||
viewModel.subscriptionId,
|
||||
icon,
|
||||
)
|
||||
mobileDrawable.level =
|
||||
SignalDrawable.getState(
|
||||
icon.level,
|
||||
@@ -114,6 +127,11 @@ object MobileIconBinder {
|
||||
// Set the network type icon
|
||||
launch {
|
||||
viewModel.networkTypeIcon.distinctUntilChanged().collect { dataTypeId ->
|
||||
viewModel.verboseLogger?.logBinderReceivedNetworkTypeIcon(
|
||||
view,
|
||||
viewModel.subscriptionId,
|
||||
dataTypeId,
|
||||
)
|
||||
dataTypeId?.let { IconViewBinder.bind(dataTypeId, networkTypeView) }
|
||||
networkTypeView.visibility = if (dataTypeId != null) VISIBLE else GONE
|
||||
}
|
||||
@@ -150,6 +168,13 @@ object MobileIconBinder {
|
||||
}
|
||||
|
||||
launch { decorTint.collect { tint -> dotView.setDecorColor(tint) } }
|
||||
|
||||
try {
|
||||
awaitCancellation()
|
||||
} finally {
|
||||
isCollecting = false
|
||||
logger.logCollectionStopped(view, viewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +200,10 @@ object MobileIconBinder {
|
||||
}
|
||||
decorTint.value = newTint
|
||||
}
|
||||
|
||||
override fun isCollecting(): Boolean {
|
||||
return isCollecting
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.content.Context
|
||||
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
|
||||
@@ -31,6 +33,15 @@ class ModernStatusBarMobileView(
|
||||
|
||||
var subId: Int = -1
|
||||
|
||||
override fun toString(): String {
|
||||
return "ModernStatusBarMobileView(" +
|
||||
"slot='$slot', " +
|
||||
"subId=$subId, " +
|
||||
"isCollecting=${binding.isCollecting()}, " +
|
||||
"visibleState=${getVisibleStateString(visibleState)}); " +
|
||||
"viewString=${super.toString()}"
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
@@ -40,6 +51,7 @@ class ModernStatusBarMobileView(
|
||||
@JvmStatic
|
||||
fun constructAndBind(
|
||||
context: Context,
|
||||
logger: MobileViewLogger,
|
||||
slot: String,
|
||||
viewModel: LocationBasedMobileViewModel,
|
||||
): ModernStatusBarMobileView {
|
||||
@@ -48,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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,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.StatusBarPipelineFlags
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.VerboseMobileViewLogger
|
||||
|
||||
/**
|
||||
* A view model for an individual mobile icon that embeds the notion of a [StatusBarLocation]. This
|
||||
@@ -26,11 +27,15 @@ 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.
|
||||
* @property verboseLogger an optional logger to log extremely verbose view updates.
|
||||
*/
|
||||
abstract class LocationBasedMobileViewModel(
|
||||
val commonImpl: MobileIconViewModelCommon,
|
||||
statusBarPipelineFlags: StatusBarPipelineFlags,
|
||||
debugTint: Int,
|
||||
val locationName: String,
|
||||
val verboseLogger: VerboseMobileViewLogger?,
|
||||
) : MobileIconViewModelCommon by commonImpl {
|
||||
val useDebugColoring: Boolean = statusBarPipelineFlags.useDebugColoring()
|
||||
|
||||
@@ -45,11 +50,16 @@ abstract class LocationBasedMobileViewModel(
|
||||
fun viewModelForLocation(
|
||||
commonImpl: MobileIconViewModelCommon,
|
||||
statusBarPipelineFlags: StatusBarPipelineFlags,
|
||||
verboseMobileViewLogger: VerboseMobileViewLogger,
|
||||
loc: StatusBarLocation,
|
||||
): LocationBasedMobileViewModel =
|
||||
when (loc) {
|
||||
StatusBarLocation.HOME ->
|
||||
HomeMobileIconViewModel(commonImpl, statusBarPipelineFlags)
|
||||
HomeMobileIconViewModel(
|
||||
commonImpl,
|
||||
statusBarPipelineFlags,
|
||||
verboseMobileViewLogger,
|
||||
)
|
||||
StatusBarLocation.KEYGUARD ->
|
||||
KeyguardMobileIconViewModel(commonImpl, statusBarPipelineFlags)
|
||||
StatusBarLocation.QS -> QsMobileIconViewModel(commonImpl, statusBarPipelineFlags)
|
||||
@@ -60,20 +70,41 @@ abstract class LocationBasedMobileViewModel(
|
||||
class HomeMobileIconViewModel(
|
||||
commonImpl: MobileIconViewModelCommon,
|
||||
statusBarPipelineFlags: StatusBarPipelineFlags,
|
||||
verboseMobileViewLogger: VerboseMobileViewLogger,
|
||||
) :
|
||||
MobileIconViewModelCommon,
|
||||
LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.CYAN)
|
||||
LocationBasedMobileViewModel(
|
||||
commonImpl,
|
||||
statusBarPipelineFlags,
|
||||
debugTint = Color.CYAN,
|
||||
locationName = "Home",
|
||||
verboseMobileViewLogger,
|
||||
)
|
||||
|
||||
class QsMobileIconViewModel(
|
||||
commonImpl: MobileIconViewModelCommon,
|
||||
statusBarPipelineFlags: StatusBarPipelineFlags,
|
||||
) :
|
||||
MobileIconViewModelCommon,
|
||||
LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.GREEN)
|
||||
LocationBasedMobileViewModel(
|
||||
commonImpl,
|
||||
statusBarPipelineFlags,
|
||||
debugTint = Color.GREEN,
|
||||
locationName = "QS",
|
||||
// Only do verbose logging for the Home location.
|
||||
verboseLogger = null,
|
||||
)
|
||||
|
||||
class KeyguardMobileIconViewModel(
|
||||
commonImpl: MobileIconViewModelCommon,
|
||||
statusBarPipelineFlags: StatusBarPipelineFlags,
|
||||
) :
|
||||
MobileIconViewModelCommon,
|
||||
LocationBasedMobileViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.MAGENTA)
|
||||
LocationBasedMobileViewModel(
|
||||
commonImpl,
|
||||
statusBarPipelineFlags,
|
||||
debugTint = Color.MAGENTA,
|
||||
locationName = "Keyguard",
|
||||
// Only do verbose logging for the Home location.
|
||||
verboseLogger = null,
|
||||
)
|
||||
|
||||
@@ -49,7 +49,7 @@ interface MobileIconViewModelCommon {
|
||||
val contentDescription: Flow<ContentDescription>
|
||||
val roaming: Flow<Boolean>
|
||||
/** The RAT icon (LTE, 3G, 5G, etc) to be displayed. Null if we shouldn't show anything */
|
||||
val networkTypeIcon: Flow<Icon?>
|
||||
val networkTypeIcon: Flow<Icon.Resource?>
|
||||
val activityInVisible: Flow<Boolean>
|
||||
val activityOutVisible: Flow<Boolean>
|
||||
val activityContainerVisible: Flow<Boolean>
|
||||
@@ -161,7 +161,7 @@ constructor(
|
||||
)
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
|
||||
|
||||
override val networkTypeIcon: Flow<Icon?> =
|
||||
override val networkTypeIcon: Flow<Icon.Resource?> =
|
||||
combine(
|
||||
iconInteractor.networkTypeIconGroup,
|
||||
showNetworkTypeIcon,
|
||||
|
||||
@@ -23,6 +23,8 @@ 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.VerboseMobileViewLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
|
||||
import javax.inject.Inject
|
||||
@@ -39,6 +41,8 @@ class MobileIconsViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
val subscriptionIdsFlow: StateFlow<List<Int>>,
|
||||
val logger: MobileViewLogger,
|
||||
private val verboseLogger: VerboseMobileViewLogger,
|
||||
private val interactor: MobileIconsInteractor,
|
||||
private val airplaneModeInteractor: AirplaneModeInteractor,
|
||||
private val constants: ConnectivityConstants,
|
||||
@@ -66,6 +70,7 @@ constructor(
|
||||
return LocationBasedMobileViewModel.viewModelForLocation(
|
||||
common,
|
||||
statusBarPipelineFlags,
|
||||
verboseLogger,
|
||||
location,
|
||||
)
|
||||
}
|
||||
@@ -79,6 +84,8 @@ constructor(
|
||||
class Factory
|
||||
@Inject
|
||||
constructor(
|
||||
private val logger: MobileViewLogger,
|
||||
private val verboseLogger: VerboseMobileViewLogger,
|
||||
private val interactor: MobileIconsInteractor,
|
||||
private val airplaneModeInteractor: AirplaneModeInteractor,
|
||||
private val constants: ConnectivityConstants,
|
||||
@@ -88,6 +95,8 @@ constructor(
|
||||
fun create(subscriptionIdsFlow: StateFlow<List<Int>>): MobileIconsViewModel {
|
||||
return MobileIconsViewModel(
|
||||
subscriptionIdsFlow,
|
||||
logger,
|
||||
verboseLogger,
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.statusbar.StatusBarIconView
|
||||
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
|
||||
@@ -33,6 +34,15 @@ class ModernStatusBarWifiView(
|
||||
context: Context,
|
||||
attrs: AttributeSet?,
|
||||
) : ModernStatusBarView(context, attrs) {
|
||||
|
||||
override fun toString(): String {
|
||||
return "ModernStatusBarWifiView(" +
|
||||
"slot='$slot', " +
|
||||
"isCollecting=${binding.isCollecting()}, " +
|
||||
"visibleState=${StatusBarIconView.getVisibleStateString(visibleState)}); " +
|
||||
"viewString=${super.toString()}"
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Inflates a new instance of [ModernStatusBarWifiView], binds it to a view model, and
|
||||
@@ -45,12 +55,9 @@ class ModernStatusBarWifiView(
|
||||
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) }
|
||||
}
|
||||
return (LayoutInflater.from(context).inflate(R.layout.new_status_bar_wifi_group, null)
|
||||
as ModernStatusBarWifiView)
|
||||
.also { it.initView(slot) { WifiViewBinder.bind(it, wifiViewModel) } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.pipeline.mobile.shared
|
||||
package com.android.systemui.statusbar.pipeline.mobile.data
|
||||
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
@@ -24,8 +24,8 @@ import androidx.test.filters.SmallTest
|
||||
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig
|
||||
import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
||||
@@ -27,13 +27,13 @@ import com.android.systemui.demomode.DemoModeController
|
||||
import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.log.table.TableLogBufferFactory
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoModeMobileConnectionDataSource
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.validMobileEvent
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl
|
||||
import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
|
||||
|
||||
@@ -53,6 +53,7 @@ import android.telephony.TelephonyManager.NETWORK_TYPE_LTE
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
|
||||
@@ -65,7 +66,6 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrier
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
|
||||
import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
|
||||
|
||||
@@ -37,12 +37,12 @@ import com.android.settingslib.mobile.MobileMappings
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.log.table.TableLogBufferFactory
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.tableBufferLogName
|
||||
import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModelTest.Companion.defaultSignal
|
||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
@@ -84,7 +85,7 @@ class LocationBasedMobileIconViewModelTest : SysuiTestCase() {
|
||||
testScope.backgroundScope,
|
||||
)
|
||||
|
||||
homeIcon = HomeMobileIconViewModel(commonImpl, statusBarPipelineFlags)
|
||||
homeIcon = HomeMobileIconViewModel(commonImpl, statusBarPipelineFlags, mock())
|
||||
qsIcon = QsMobileIconViewModel(commonImpl, statusBarPipelineFlags)
|
||||
keyguardIcon = KeyguardMobileIconViewModel(commonImpl, statusBarPipelineFlags)
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ 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.ui.VerboseMobileViewLogger
|
||||
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 +53,8 @@ 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
|
||||
@Mock private lateinit var verboseLogger: VerboseMobileViewLogger
|
||||
|
||||
private val testDispatcher = UnconfinedTestDispatcher()
|
||||
private val testScope = TestScope(testDispatcher)
|
||||
@@ -73,6 +77,8 @@ class MobileIconsViewModelTest : SysuiTestCase() {
|
||||
underTest =
|
||||
MobileIconsViewModel(
|
||||
subscriptionIdsFlow,
|
||||
logger,
|
||||
verboseLogger,
|
||||
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