From cc43d6a8782210bd2284114e7e805078958749c4 Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Thu, 1 Dec 2022 17:25:23 -0500 Subject: [PATCH] Support new pipeline demo mode in the old view presenter Adds support for the new mobile pipeline's demo mode to the old front end. Note that this is kind of hacky because we actually don't have to do anything to support demo mode, since it's implemented entirely at the level of the repository. However, due to the fact that the old implementation of demo mode added a special view, `DemoStatusIcons`, that overlays the regular icons, we have to suport the new pipeline in _that_ icon container. Test: manual Bug: 249790009 Change-Id: Ib02a1eb6f6abaec113a15045f9bd0b151d2a773f --- .../statusbar/phone/DemoStatusIcons.java | 48 ++++++++++++++++++- .../phone/StatusBarIconController.java | 11 +++-- .../phone/StatusBarIconControllerImpl.java | 5 ++ .../repository/MobileConnectionRepository.kt | 2 + .../repository/MobileConnectionsRepository.kt | 2 +- .../demo/DemoMobileConnectionsRepository.kt | 2 +- .../prod/MobileConnectionRepositoryImpl.kt | 2 +- .../ui/view/ModernStatusBarMobileView.kt | 3 ++ .../ui/viewmodel/MobileIconsViewModel.kt | 6 +-- .../FakeMobileConnectionRepository.kt | 2 +- .../FakeMobileConnectionsRepository.kt | 6 +-- .../interactor/MobileIconInteractorTest.kt | 2 +- .../interactor/MobileIconsInteractorTest.kt | 8 ++-- 13 files changed, 77 insertions(+), 22 deletions(-) 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 1169d3f21e280..c7be2193e9b54 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,8 @@ 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.view.ModernStatusBarMobileView; +import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel; import java.util.ArrayList; import java.util.List; @@ -50,20 +52,25 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da private final LinearLayout mStatusIcons; private final ArrayList mMobileViews = new ArrayList<>(); + private final ArrayList mModernMobileViews = new ArrayList<>(); private final int mIconSize; private StatusBarWifiView mWifiView; private boolean mDemoMode; private int mColor; + private final MobileIconsViewModel mMobileIconsViewModel; + public DemoStatusIcons( LinearLayout statusIcons, + MobileIconsViewModel mobileIconsViewModel, int iconSize ) { super(statusIcons.getContext()); mStatusIcons = statusIcons; mIconSize = iconSize; mColor = DarkIconDispatcher.DEFAULT_ICON_TINT; + mMobileIconsViewModel = mobileIconsViewModel; if (statusIcons instanceof StatusIconContainer) { setShouldRestrictIcons(((StatusIconContainer) statusIcons).isRestrictingIcons()); @@ -71,7 +78,7 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da setShouldRestrictIcons(false); } setLayoutParams(mStatusIcons.getLayoutParams()); - setPadding(mStatusIcons.getPaddingLeft(),mStatusIcons.getPaddingTop(), + setPadding(mStatusIcons.getPaddingLeft(), mStatusIcons.getPaddingTop(), mStatusIcons.getPaddingRight(), mStatusIcons.getPaddingBottom()); setOrientation(mStatusIcons.getOrientation()); setGravity(Gravity.CENTER_VERTICAL); // no LL.getGravity() @@ -115,6 +122,8 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da public void onDemoModeFinished() { mDemoMode = false; mStatusIcons.setVisibility(View.VISIBLE); + mModernMobileViews.clear(); + mMobileViews.clear(); setVisibility(View.GONE); } @@ -268,6 +277,24 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da addView(view, getChildCount(), createLayoutParams()); } + /** + * Add a {@link ModernStatusBarMobileView} + * @param mobileContext possibly mcc/mnc overridden mobile context + * @param subId the subscriptionId for this mobile view + */ + public void addModernMobileView(Context mobileContext, int subId) { + Log.d(TAG, "addModernMobileView (subId=" + subId + ")"); + ModernStatusBarMobileView view = ModernStatusBarMobileView.constructAndBind( + mobileContext, + "mobile", + mMobileIconsViewModel.viewModelForSub(subId) + ); + + // mobile always goes at the end + mModernMobileViews.add(view); + addView(view, getChildCount(), createLayoutParams()); + } + /** * Apply an update to a mobile icon view for the given {@link MobileIconState}. For * compatibility with {@link MobileContextProvider}, we have to recreate the view every time we @@ -292,12 +319,19 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da if (view.getSlot().equals("wifi")) { removeView(mWifiView); mWifiView = null; - } else { + } else if (view instanceof StatusBarMobileView) { StatusBarMobileView mobileView = matchingMobileView(view); if (mobileView != null) { removeView(mobileView); mMobileViews.remove(mobileView); } + } else if (view instanceof ModernStatusBarMobileView) { + ModernStatusBarMobileView mobileView = matchingModernMobileView( + (ModernStatusBarMobileView) view); + if (mobileView != null) { + removeView(mobileView); + mModernMobileViews.remove(mobileView); + } } } @@ -316,6 +350,16 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da return null; } + private ModernStatusBarMobileView matchingModernMobileView(ModernStatusBarMobileView other) { + for (ModernStatusBarMobileView v : mModernMobileViews) { + if (v.getSubId() == other.getSubId()) { + return v; + } + } + + return null; + } + private LayoutParams createLayoutParams() { return new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize); } 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 0a0ded24ef306..df3ab493a4dae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java @@ -536,8 +536,7 @@ public interface StatusBarIconController { mGroup.addView(view, index, onCreateLayoutParams()); if (mIsInDemoMode) { - // TODO (b/249790009): demo mode should be handled at the data layer in the - // new pipeline + mDemoStatusIcons.addModernMobileView(mContext, subId); } return view; @@ -565,11 +564,13 @@ public interface StatusBarIconController { private ModernStatusBarMobileView onCreateModernStatusBarMobileView( String slot, int subId) { + Context mobileContext = mMobileContextProvider.getMobileContextForSub(subId, mContext); return ModernStatusBarMobileView .constructAndBind( - mContext, + mobileContext, slot, - mMobileIconsViewModel.viewModelForSub(subId)); + mMobileIconsViewModel.viewModelForSub(subId) + ); } protected LinearLayout.LayoutParams onCreateLayoutParams() { @@ -704,7 +705,7 @@ public interface StatusBarIconController { } protected DemoStatusIcons createDemoStatusIcons() { - return new DemoStatusIcons((LinearLayout) mGroup, mIconSize); + return new DemoStatusIcons((LinearLayout) mGroup, mMobileIconsViewModel, mIconSize); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java index 674e5747e331b..9fbe6cbc0e326 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java @@ -276,6 +276,11 @@ public class StatusBarIconControllerImpl implements Tunable, String slotName = mContext.getString(com.android.internal.R.string.status_bar_mobile); Slot mobileSlot = mStatusBarIconList.getSlot(slotName); + // Because of the way we cache the icon holders, we need to remove everything any time + // we get a new set of subscriptions. This might change in the future, but is required + // to support demo mode for now + removeAllIconsForSlot(slotName); + Collections.reverse(subIds); for (Integer subId : subIds) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt index f09456342f78f..90e531ce49dac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt @@ -36,6 +36,8 @@ import kotlinx.coroutines.flow.StateFlow * eventually becomes a single icon in the status bar. */ interface MobileConnectionRepository { + /** The subscriptionId that this connection represents */ + val subId: Int /** * A flow that aggregates all necessary callbacks from [TelephonyCallback] into a single * listener + model. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt index 14200f090c87c..7684b762fe552 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt @@ -31,7 +31,7 @@ import kotlinx.coroutines.flow.StateFlow */ interface MobileConnectionsRepository { /** Observable list of current mobile subscriptions */ - val subscriptionsFlow: Flow> + val subscriptionsFlow: StateFlow> /** Observable for the subscriptionId of the current mobile data connection */ val activeMobileDataSubscriptionId: StateFlow diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt index 5f2feb26b739a..eeb68e778ad9a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt @@ -268,7 +268,7 @@ private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetwork else -> DefaultNetworkType(toNetworkType()) } -class DemoMobileConnectionRepository(val subId: Int) : MobileConnectionRepository { +class DemoMobileConnectionRepository(override val subId: Int) : MobileConnectionRepository { override val subscriptionModelFlow = MutableStateFlow(MobileSubscriptionModel()) override val dataEnabled = MutableStateFlow(true) 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 4c1cf4a3ed08b..fc0eefe0599a5 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 @@ -58,7 +58,7 @@ import kotlinx.coroutines.flow.stateIn @OptIn(ExperimentalCoroutinesApi::class) class MobileConnectionRepositoryImpl( private val context: Context, - private val subId: Int, + override val subId: Int, private val telephonyManager: TelephonyManager, private val globalSettings: GlobalSettings, defaultDataSubId: StateFlow, 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 ec4fa9ca8128f..0ab7bcd968444 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 @@ -32,6 +32,8 @@ class ModernStatusBarMobileView( attrs: AttributeSet?, ) : BaseStatusBarFrameLayout(context, attrs) { + var subId: Int = -1 + private lateinit var slot: String override fun getSlot() = slot @@ -76,6 +78,7 @@ class ModernStatusBarMobileView( as ModernStatusBarMobileView) .also { it.slot = slot + it.subId = viewModel.subscriptionId MobileIconBinder.bind(it, viewModel) } } 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 24c1db995d50c..2349cb7c5d801 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,7 +23,7 @@ import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMob import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import javax.inject.Inject import kotlinx.coroutines.InternalCoroutinesApi -import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.StateFlow /** * View model for describing the system's current mobile cellular connections. The result is a list @@ -33,7 +33,7 @@ import kotlinx.coroutines.flow.Flow class MobileIconsViewModel @Inject constructor( - val subscriptionIdsFlow: Flow>, + val subscriptionIdsFlow: StateFlow>, private val interactor: MobileIconsInteractor, private val logger: ConnectivityPipelineLogger, ) { @@ -51,7 +51,7 @@ constructor( private val interactor: MobileIconsInteractor, private val logger: ConnectivityPipelineLogger, ) { - fun create(subscriptionIdsFlow: Flow>): MobileIconsViewModel { + fun create(subscriptionIdsFlow: StateFlow>): MobileIconsViewModel { return MobileIconsViewModel( subscriptionIdsFlow, interactor, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt index 288f54c7d03c0..b06d41b8d5965 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileSubscriptionModel import kotlinx.coroutines.flow.MutableStateFlow -class FakeMobileConnectionRepository : MobileConnectionRepository { +class FakeMobileConnectionRepository(override val subId: Int) : MobileConnectionRepository { private val _subscriptionsModelFlow = MutableStateFlow(MobileSubscriptionModel()) override val subscriptionModelFlow = _subscriptionsModelFlow diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt index 533d5d9d5b4a3..e21ab21de6f0c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt @@ -20,12 +20,11 @@ import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import com.android.settingslib.mobile.MobileMappings.Config import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow class FakeMobileConnectionsRepository : MobileConnectionsRepository { private val _subscriptionsFlow = MutableStateFlow>(listOf()) - override val subscriptionsFlow: Flow> = _subscriptionsFlow + override val subscriptionsFlow = _subscriptionsFlow private val _activeMobileDataSubscriptionId = MutableStateFlow(INVALID_SUBSCRIPTION_ID) override val activeMobileDataSubscriptionId = _activeMobileDataSubscriptionId @@ -41,7 +40,8 @@ class FakeMobileConnectionsRepository : MobileConnectionsRepository { private val subIdRepos = mutableMapOf() override fun getRepoForSubId(subId: Int): MobileConnectionRepository { - return subIdRepos[subId] ?: FakeMobileConnectionRepository().also { subIdRepos[subId] = it } + return subIdRepos[subId] + ?: FakeMobileConnectionRepository(subId).also { subIdRepos[subId] = it } } private val _globalMobileDataSettingChangedEvent = MutableStateFlow(Unit) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt index 7fc1c0f6272cd..9d7d0ed0db084 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt @@ -49,7 +49,7 @@ class MobileIconInteractorTest : SysuiTestCase() { private lateinit var underTest: MobileIconInteractor private val mobileMappingsProxy = FakeMobileMappingsProxy() private val mobileIconsInteractor = FakeMobileIconsInteractor(mobileMappingsProxy) - private val connectionRepository = FakeMobileConnectionRepository() + private val connectionRepository = FakeMobileConnectionRepository(SUB_1_ID) private val scope = CoroutineScope(IMMEDIATE) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt index b56dcd7525579..5cdfcfd6d1e69 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt @@ -263,12 +263,12 @@ class MobileIconsInteractorTest : SysuiTestCase() { private const val SUB_1_ID = 1 private val SUB_1 = mock().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) } - private val CONNECTION_1 = FakeMobileConnectionRepository() + private val CONNECTION_1 = FakeMobileConnectionRepository(SUB_1_ID) private const val SUB_2_ID = 2 private val SUB_2 = mock().also { whenever(it.subscriptionId).thenReturn(SUB_2_ID) } - private val CONNECTION_2 = FakeMobileConnectionRepository() + private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID) private const val SUB_3_ID = 3 private val SUB_3_OPP = @@ -276,7 +276,7 @@ class MobileIconsInteractorTest : SysuiTestCase() { whenever(it.subscriptionId).thenReturn(SUB_3_ID) whenever(it.isOpportunistic).thenReturn(true) } - private val CONNECTION_3 = FakeMobileConnectionRepository() + private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID) private const val SUB_4_ID = 4 private val SUB_4_OPP = @@ -284,6 +284,6 @@ class MobileIconsInteractorTest : SysuiTestCase() { whenever(it.subscriptionId).thenReturn(SUB_4_ID) whenever(it.isOpportunistic).thenReturn(true) } - private val CONNECTION_4 = FakeMobileConnectionRepository() + private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID) } }