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
This commit is contained in:
@@ -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<StatusBarMobileView> mMobileViews = new ArrayList<>();
|
||||
private final ArrayList<ModernStatusBarMobileView> 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -31,7 +31,7 @@ import kotlinx.coroutines.flow.StateFlow
|
||||
*/
|
||||
interface MobileConnectionsRepository {
|
||||
/** Observable list of current mobile subscriptions */
|
||||
val subscriptionsFlow: Flow<List<SubscriptionInfo>>
|
||||
val subscriptionsFlow: StateFlow<List<SubscriptionInfo>>
|
||||
|
||||
/** Observable for the subscriptionId of the current mobile data connection */
|
||||
val activeMobileDataSubscriptionId: StateFlow<Int>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<Int>,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<List<Int>>,
|
||||
val subscriptionIdsFlow: StateFlow<List<Int>>,
|
||||
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<List<Int>>): MobileIconsViewModel {
|
||||
fun create(subscriptionIdsFlow: StateFlow<List<Int>>): MobileIconsViewModel {
|
||||
return MobileIconsViewModel(
|
||||
subscriptionIdsFlow,
|
||||
interactor,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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<List<SubscriptionInfo>>(listOf())
|
||||
override val subscriptionsFlow: Flow<List<SubscriptionInfo>> = _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<Int, MobileConnectionRepository>()
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -263,12 +263,12 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
||||
private const val SUB_1_ID = 1
|
||||
private val SUB_1 =
|
||||
mock<SubscriptionInfo>().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<SubscriptionInfo>().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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user