diff options
| author | 2023-03-06 19:02:41 +0000 | |
|---|---|---|
| committer | 2023-03-06 19:02:41 +0000 | |
| commit | 89a037dbed0b6b18db23011fb108520954916237 (patch) | |
| tree | 4aeaae28eeffa5b32888e86ccfd04317a3a3dff9 | |
| parent | 110c9c118d0e857125ba096dcbde61a7f44b43cb (diff) | |
| parent | f1214c529b4f1e09fc6a884548e4f96ae22fee0a (diff) | |
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.
34 files changed, 621 insertions, 71 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index c35c5c522798..77550038c94a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -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 + ')'; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index c72eb054c62c..39b5b5a4cef8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -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) ); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java index 11863627218e..04cc8ce792d1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java @@ -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) ); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java index f6c0da8da8c0..833cb93f62e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java @@ -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() + ")"; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java index 8800b05fadb7..565481a20d95 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java @@ -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("|")); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileViewLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileViewLog.kt new file mode 100644 index 000000000000..e594a8a5efd9 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileViewLog.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt index 44647515a6e5..adfea80715a2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt @@ -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) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/VerboseMobileViewLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/VerboseMobileViewLog.kt new file mode 100644 index 000000000000..b98789807dd3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/VerboseMobileViewLog.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt index 3cbd2b76c248..159f689de370 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt @@ -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, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt index bb3b9b2166c3..efdce062bb37 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt index 96b96f14d6aa..e182bc66081a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt index 53a208cd171e..f97e41c018f4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt index da63ab10f733..075e6ec11ae7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt @@ -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) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLogger.kt new file mode 100644 index 000000000000..90dff23c637c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLogger.kt @@ -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" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/VerboseMobileViewLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/VerboseMobileViewLogger.kt new file mode 100644 index 000000000000..f67bc8f14447 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/VerboseMobileViewLogger.kt @@ -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" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt index db585e68d185..5b7d45b55c5c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt @@ -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 + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt index ed9a1884a7b4..4144293d5ccd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt @@ -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) } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt index 8e103f7bee2f..f775940140cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt @@ -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, + ) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt index 049627899eff..dbb534b24471 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt @@ -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, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt index 8cb52af336da..2b90065284d0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt @@ -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, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewBinding.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewBinding.kt index f67876b50233..81f8683411ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewBinding.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/ModernStatusBarViewBinding.kt @@ -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 } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt index b1e28129a690..1a1340484bfc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt index 2aff12c8721d..9e8c814ca2a9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt @@ -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 + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt index 7a734862fe1b..f23e10287164 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt @@ -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) } } } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLoggerTest.kt index 86529dce948a..35dea60b1a1f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLoggerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLoggerTest.kt @@ -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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt index 0145103d55e1..dfef62e95eda 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt @@ -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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt index 17502f28a479..07c8cee9a3d4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt @@ -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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt index b2577e349da7..bd5a4d7f7385 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt @@ -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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt index 09b7a66c925d..68b1cda62f4c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt @@ -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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt new file mode 100644 index 000000000000..4aa48d6f25f1 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt @@ -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() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt index e68a3970ae93..7420db2e895e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt @@ -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() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt index f9830309252d..a6d915243f60 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt @@ -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) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt index 4628f8410245..ddb7f4d88d30 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt @@ -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, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt index e4c8fd0cd8a1..b4039d906810 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt @@ -164,6 +164,10 @@ class ModernStatusBarViewTest : SysuiTestCase() { override fun getShouldIconBeVisible(): Boolean { return shouldIconBeVisibleInternal } + + override fun isCollecting(): Boolean { + return true + } } } |