Create Configuration overrides for MCC/MNC values

SystemUI currently only shows the RAT type indicator for the active
network, which may change. At the same time, the Resources system does
not track the active mobile network, which means that
`context.getResources().getConfiguration()` may return a `Configuration`
object with an incorrect MCC/MNC for the current active subscription.

This CL creates a `MobileContextProvider` class, which will lazily
generate `Context`s with a correctly overridden MCC/MNC, so that
resource overlays properly load individual carrier iconography when the
active data subscription changes.

We also will load each individual mobile icon with the proper context,
in case there is ever a need to show the RAT type indicator for multiple
subscriptions at once.

Lastly, this CL adds a new "mccmnc" arg string to demo mode so that we
can easily validate RAT type indicator overlays.

Test: atest MobileContextProviderTest
Test: use the new `mccmnc` string in sysui demo mode to manually verify
Fixes: 240555502
Change-Id: If1f7d31a46f19f335b9545ca33638786a423ba0d
This commit is contained in:
Evan Laird
2022-08-31 16:54:52 -04:00
parent 3315391bf7
commit acf1eebc40
7 changed files with 368 additions and 52 deletions

View File

@@ -78,6 +78,9 @@ public class MobileStatusTracker {
* Config the MobileStatusTracker to start or stop monitoring platform signals.
*/
public void setListening(boolean listening) {
if (mListening == listening) {
return;
}
mListening = listening;
if (listening) {
mPhone.registerTelephonyCallback(mReceiverHandler::post, mTelephonyCallback);

View File

@@ -38,6 +38,7 @@ import com.android.settingslib.graph.SignalDrawable;
import com.android.systemui.DualToneHandler;
import com.android.systemui.R;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
import java.util.ArrayList;
@@ -64,6 +65,15 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver,
/**
* Designated constructor
*
* This view is special, in that it is the only view in SystemUI that allows for a configuration
* override on a MCC/MNC-basis. This means that for every mobile view inflated, we have to
* construct a context with that override, since the resource system doesn't have a way to
* handle this for us.
*
* @param context A context with resources configured by MCC/MNC
* @param slot The string key defining which slot this icon refers to. Always "mobile" for the
* mobile icon
*/
public static StatusBarMobileView fromContext(
Context context,

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2022 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.connectivity.ui
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.telephony.SubscriptionInfo
import android.view.ContextThemeWrapper
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.demomode.DemoMode
import com.android.systemui.demomode.DemoMode.COMMAND_NETWORK
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.connectivity.NetworkController
import com.android.systemui.statusbar.connectivity.SignalCallback
import java.io.PrintWriter
import javax.inject.Inject
/**
* Every subscriptionId can have its own CarrierConfig associated with it, so we have to create our
* own [Configuration] and track resources based on the full set of available mcc-mnc combinations.
*
* (for future reference: b/240555502 is the initiating bug for this)
*/
@SysUISingleton
class MobileContextProvider
@Inject
constructor(
networkController: NetworkController,
dumpManager: DumpManager,
private val demoModeController: DemoModeController,
) : Dumpable, DemoMode {
private val subscriptions = mutableMapOf<Int, SubscriptionInfo>()
private val signalCallback =
object : SignalCallback {
override fun setSubs(subs: List<SubscriptionInfo>) {
subscriptions.clear()
subs.forEach { info -> subscriptions[info.subscriptionId] = info }
}
}
// These should always be null when not in demo mode
private var demoMcc: Int? = null
private var demoMnc: Int? = null
init {
networkController.addCallback(signalCallback)
dumpManager.registerDumpable(this)
demoModeController.addCallback(this)
}
/**
* @return a context with the MCC/MNC [Configuration] values corresponding to this
* subscriptionId
*/
fun getMobileContextForSub(subId: Int, context: Context): Context {
if (demoModeController.isInDemoMode) {
return createMobileContextForDemoMode(context)
}
// Fail back to the given context if no sub exists
val info = subscriptions[subId] ?: return context
return createCarrierConfigContext(context, info.mcc, info.mnc)
}
/** For Demo mode (for now), just apply the same MCC/MNC override for all subIds */
private fun createMobileContextForDemoMode(context: Context): Context {
return createCarrierConfigContext(context, demoMcc ?: 0, demoMnc ?: 0)
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.println(
"Subscriptions below will be inflated with a configuration context with " +
"MCC/MNC overrides"
)
subscriptions.forEach { (subId, info) ->
pw.println(" Subscription with subId($subId) with MCC/MNC(${info.mcc}/${info.mnc})")
}
pw.println(" MCC override: ${demoMcc ?: "(none)"}")
pw.println(" MNC override: ${demoMnc ?: "(none)"}")
}
override fun demoCommands(): List<String> {
return listOf(COMMAND_NETWORK)
}
override fun onDemoModeFinished() {
demoMcc = null
demoMnc = null
}
override fun dispatchDemoCommand(command: String, args: Bundle) {
val mccmnc = args.getString("mccmnc") ?: return
// Only length 5/6 strings are valid
if (!(mccmnc.length == 5 || mccmnc.length == 6)) {
return
}
// MCC is always the first 3 digits, and mnc is the last 2 or 3
demoMcc = mccmnc.subSequence(0, 3).toString().toInt()
demoMnc = mccmnc.subSequence(3, mccmnc.length).toString().toInt()
}
companion object {
/**
* Creates a context based on this [SubscriptionInfo]'s MCC/MNC values, allowing the overlay
* system to properly load different carrier's iconography
*/
private fun createCarrierConfigContext(context: Context, mcc: Int, mnc: Int): Context {
// Copy the existing configuration
val c = Configuration(context.resources.configuration)
c.mcc = mcc
c.mnc = mnc
return ContextThemeWrapper(context, context.theme).also { ctx ->
ctx.applyOverrideConfiguration(c)
}
}
}
}

View File

@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.os.Bundle;
@@ -29,13 +31,13 @@ import android.widget.LinearLayout;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.R;
import com.android.systemui.demomode.DemoMode;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.StatusBarMobileView;
import com.android.systemui.statusbar.StatusBarWifiView;
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;
@@ -49,7 +51,6 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da
private final LinearLayout mStatusIcons;
private final ArrayList<StatusBarMobileView> mMobileViews = new ArrayList<>();
private final int mIconSize;
private final FeatureFlags mFeatureFlags;
private StatusBarWifiView mWifiView;
private boolean mDemoMode;
@@ -57,14 +58,12 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da
public DemoStatusIcons(
LinearLayout statusIcons,
int iconSize,
FeatureFlags featureFlags
int iconSize
) {
super(statusIcons.getContext());
mStatusIcons = statusIcons;
mIconSize = iconSize;
mColor = DarkIconDispatcher.DEFAULT_ICON_TINT;
mFeatureFlags = featureFlags;
if (statusIcons instanceof StatusIconContainer) {
setShouldRestrictIcons(((StatusIconContainer) statusIcons).isRestrictingIcons());
@@ -253,9 +252,13 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da
}
}
public void addMobileView(MobileIconState state) {
/**
* Add a new mobile icon view
*/
public void addMobileView(MobileIconState state, Context mobileContext) {
Log.d(TAG, "addMobileView: ");
StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, state.slot);
StatusBarMobileView view = StatusBarMobileView
.fromContext(mobileContext, state.slot);
view.applyMobileState(state);
view.setStaticDrawableColor(mColor);
@@ -265,19 +268,24 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da
addView(view, getChildCount(), createLayoutParams());
}
public void updateMobileState(MobileIconState state) {
Log.d(TAG, "updateMobileState: ");
// If the view for this subId exists already, use it
/**
* 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
* update it, since the context (and thus the {@link Configuration}) may have changed
*/
public void updateMobileState(MobileIconState state, Context mobileContext) {
Log.d(TAG, "updateMobileState: " + state);
// The mobile config provided by MobileContextProvider could have changed; always recreate
for (int i = 0; i < mMobileViews.size(); i++) {
StatusBarMobileView view = mMobileViews.get(i);
if (view.getState().subId == state.subId) {
view.applyMobileState(state);
return;
removeView(view);
}
}
// Else we have to add it
addMobileView(state);
// Add the replacement or new icon
addMobileView(state, mobileContext);
}
public void onRemoveIcon(StatusIconDisplayable view) {

View File

@@ -36,7 +36,6 @@ import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.demomode.DemoModeCommandReceiver;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.BaseStatusBarWifiView;
@@ -44,6 +43,7 @@ import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.StatusBarMobileView;
import com.android.systemui.statusbar.StatusBarWifiView;
import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.CallIndicatorIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
@@ -70,6 +70,7 @@ public interface StatusBarIconController {
void addIconGroup(IconManager iconManager);
/** */
void removeIconGroup(IconManager iconManager);
/** Refresh the state of an IconManager by recreating the views */
void refreshIconGroup(IconManager iconManager);
/** */
@@ -82,21 +83,25 @@ public interface StatusBarIconController {
void setSignalIcon(String slot, WifiIconState state);
/** */
void setMobileIcons(String slot, List<MobileIconState> states);
/**
* Display the no calling & SMS icons.
*/
void setCallStrengthIcons(String slot, List<CallIndicatorIconState> states);
/**
* Display the no calling & SMS icons.
*/
void setNoCallingIcons(String slot, List<CallIndicatorIconState> states);
public void setIconVisibility(String slot, boolean b);
/**
* Sets the live region mode for the icon
* @see android.view.View#setAccessibilityLiveRegion(int)
* @param slot Icon slot to set region for
*
* @param slot Icon slot to set region for
* @param accessibilityLiveRegion live region mode for the icon
* @see android.view.View#setAccessibilityLiveRegion(int)
*/
void setIconAccessibilityLiveRegion(String slot, int accessibilityLiveRegion);
@@ -115,8 +120,8 @@ public interface StatusBarIconController {
static ArraySet<String> getIconHideList(Context context, String hideListStr) {
ArraySet<String> ret = new ArraySet<>();
String[] hideList = hideListStr == null
? context.getResources().getStringArray(R.array.config_statusBarIconsToExclude)
: hideListStr.split(",");
? context.getResources().getStringArray(R.array.config_statusBarIconsToExclude)
: hideListStr.split(",");
for (String slot : hideList) {
if (!TextUtils.isEmpty(slot)) {
ret.add(slot);
@@ -134,11 +139,14 @@ public interface StatusBarIconController {
public DarkIconManager(
LinearLayout linearLayout,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider,
MobileContextProvider mobileContextProvider,
DarkIconDispatcher darkIconDispatcher) {
super(linearLayout, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
super(linearLayout,
statusBarPipelineFlags,
wifiViewModelProvider,
mobileContextProvider);
mIconHPadding = mContext.getResources().getDimensionPixelSize(
R.dimen.status_bar_icon_padding);
mDarkIconDispatcher = darkIconDispatcher;
@@ -195,41 +203,49 @@ public interface StatusBarIconController {
@SysUISingleton
public static class Factory {
private final FeatureFlags mFeatureFlags;
private final StatusBarPipelineFlags mStatusBarPipelineFlags;
private final Provider<WifiViewModel> mWifiViewModelProvider;
private final MobileContextProvider mMobileContextProvider;
private final DarkIconDispatcher mDarkIconDispatcher;
@Inject
public Factory(
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider,
MobileContextProvider mobileContextProvider,
DarkIconDispatcher darkIconDispatcher) {
mFeatureFlags = featureFlags;
mStatusBarPipelineFlags = statusBarPipelineFlags;
mWifiViewModelProvider = wifiViewModelProvider;
mMobileContextProvider = mobileContextProvider;
mDarkIconDispatcher = darkIconDispatcher;
}
public DarkIconManager create(LinearLayout group) {
return new DarkIconManager(
group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider,
group,
mStatusBarPipelineFlags,
mWifiViewModelProvider,
mMobileContextProvider,
mDarkIconDispatcher);
}
}
}
/** */
/**
*
*/
class TintedIconManager extends IconManager {
private int mColor;
public TintedIconManager(
ViewGroup group,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider) {
super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
Provider<WifiViewModel> wifiViewModelProvider,
MobileContextProvider mobileContextProvider) {
super(group,
statusBarPipelineFlags,
wifiViewModelProvider,
mobileContextProvider);
}
@Override
@@ -261,23 +277,26 @@ public interface StatusBarIconController {
@SysUISingleton
public static class Factory {
private final FeatureFlags mFeatureFlags;
private final StatusBarPipelineFlags mStatusBarPipelineFlags;
private final Provider<WifiViewModel> mWifiViewModelProvider;
private final MobileContextProvider mMobileContextProvider;
@Inject
public Factory(
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider) {
mFeatureFlags = featureFlags;
Provider<WifiViewModel> wifiViewModelProvider,
MobileContextProvider mobileContextProvider) {
mStatusBarPipelineFlags = statusBarPipelineFlags;
mWifiViewModelProvider = wifiViewModelProvider;
mMobileContextProvider = mobileContextProvider;
}
public TintedIconManager create(ViewGroup group) {
return new TintedIconManager(
group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider);
group,
mStatusBarPipelineFlags,
mWifiViewModelProvider,
mMobileContextProvider);
}
}
}
@@ -287,9 +306,9 @@ public interface StatusBarIconController {
*/
class IconManager implements DemoModeCommandReceiver {
protected final ViewGroup mGroup;
private final FeatureFlags mFeatureFlags;
private final StatusBarPipelineFlags mStatusBarPipelineFlags;
private final Provider<WifiViewModel> mWifiViewModelProvider;
private final MobileContextProvider mMobileContextProvider;
protected final Context mContext;
protected final int mIconSize;
// Whether or not these icons show up in dumpsys
@@ -305,13 +324,13 @@ public interface StatusBarIconController {
public IconManager(
ViewGroup group,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider) {
Provider<WifiViewModel> wifiViewModelProvider,
MobileContextProvider mobileContextProvider) {
mGroup = group;
mFeatureFlags = featureFlags;
mStatusBarPipelineFlags = statusBarPipelineFlags;
mWifiViewModelProvider = wifiViewModelProvider;
mMobileContextProvider = mobileContextProvider;
mContext = group.getContext();
mIconSize = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_icon_size);
@@ -403,12 +422,15 @@ public interface StatusBarIconController {
@VisibleForTesting
protected StatusBarMobileView addMobileIcon(int index, String slot, MobileIconState state) {
StatusBarMobileView view = onCreateStatusBarMobileView(slot);
// Use the `subId` field as a key to query for the correct context
StatusBarMobileView view = onCreateStatusBarMobileView(state.subId, slot);
view.applyMobileState(state);
mGroup.addView(view, index, onCreateLayoutParams());
if (mIsInDemoMode) {
mDemoStatusIcons.addMobileView(state);
Context mobileContext = mMobileContextProvider
.getMobileContextForSub(state.subId, mContext);
mDemoStatusIcons.addMobileView(state, mobileContext);
}
return view;
}
@@ -427,8 +449,10 @@ public interface StatusBarIconController {
mContext, slot, mWifiViewModelProvider.get());
}
private StatusBarMobileView onCreateStatusBarMobileView(String slot) {
StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, slot);
private StatusBarMobileView onCreateStatusBarMobileView(int subId, String slot) {
Context mobileContext = mMobileContextProvider.getMobileContextForSub(subId, mContext);
StatusBarMobileView view = StatusBarMobileView
.fromContext(mobileContext, slot);
return view;
}
@@ -516,7 +540,9 @@ public interface StatusBarIconController {
}
if (mIsInDemoMode) {
mDemoStatusIcons.updateMobileState(state);
Context mobileContext = mMobileContextProvider
.getMobileContextForSub(state.subId, mContext);
mDemoStatusIcons.updateMobileState(state, mobileContext);
}
}
@@ -553,7 +579,7 @@ public interface StatusBarIconController {
}
protected DemoStatusIcons createDemoStatusIcons() {
return new DemoStatusIcons((LinearLayout) mGroup, mIconSize, mFeatureFlags);
return new DemoStatusIcons((LinearLayout) mGroup, mIconSize);
}
}
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright (C) 2022 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.connectivity.ui
import android.telephony.SubscriptionInfo
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.connectivity.NetworkController
import com.android.systemui.statusbar.connectivity.SignalCallback
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@SmallTest
class MobileContextProviderTest : SysuiTestCase() {
@Mock private lateinit var networkController: NetworkController
@Mock private lateinit var dumpManager: DumpManager
@Mock private lateinit var demoModeController: DemoModeController
private lateinit var provider: MobileContextProvider
private lateinit var signalCallback: SignalCallback
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
provider =
MobileContextProvider(
networkController,
dumpManager,
demoModeController,
)
signalCallback = withArgCaptor { verify(networkController).addCallback(capture()) }
}
@Test
fun test_oneSubscription_contextHasMccMnc() {
// GIVEN there is one SubscriptionInfo
signalCallback.setSubs(listOf(SUB_1))
// WHEN we ask for a mobile context
val ctx = provider.getMobileContextForSub(SUB_1_ID, context)
// THEN the configuration of that context reflect this subscription's MCC/MNC override
val config = ctx.resources.configuration
assertThat(config.mcc).isEqualTo(SUB_1_MCC)
assertThat(config.mnc).isEqualTo(SUB_1_MNC)
}
@Test
fun test_twoSubscriptions_eachContextReflectsMccMnc() {
// GIVEN there are two SubscriptionInfos
signalCallback.setSubs(listOf(SUB_1, SUB_2))
// WHEN we ask for a mobile context for each sub
val ctx1 = provider.getMobileContextForSub(SUB_1_ID, context)
val ctx2 = provider.getMobileContextForSub(SUB_2_ID, context)
// THEN the configuration of each context reflect this subscription's MCC/MNC override
val config1 = ctx1.resources.configuration
assertThat(config1.mcc).isEqualTo(SUB_1_MCC)
assertThat(config1.mnc).isEqualTo(SUB_1_MNC)
val config2 = ctx2.resources.configuration
assertThat(config2.mcc).isEqualTo(SUB_2_MCC)
assertThat(config2.mnc).isEqualTo(SUB_2_MNC)
}
@Test
fun test_requestingContextForNonexistentSubscription_returnsGivenContext() {
// GIVEN no SubscriptionInfos
signalCallback.setSubs(listOf())
// WHEN we ask for a mobile context for an unknown subscription
val ctx = provider.getMobileContextForSub(SUB_1_ID, context)
// THEN we get the original context back
assertThat(ctx).isEqualTo(context)
}
private val SUB_1_ID = 1
private val SUB_1_MCC = 123
private val SUB_1_MNC = 456
private val SUB_1 =
mock<SubscriptionInfo>().also {
whenever(it.subscriptionId).thenReturn(SUB_1_ID)
whenever(it.mcc).thenReturn(SUB_1_MCC)
whenever(it.mnc).thenReturn(SUB_1_MNC)
}
private val SUB_2_ID = 2
private val SUB_2_MCC = 666
private val SUB_2_MNC = 777
private val SUB_2 =
mock<SubscriptionInfo>().also {
whenever(it.subscriptionId).thenReturn(SUB_2_ID)
whenever(it.mcc).thenReturn(SUB_2_MCC)
whenever(it.mnc).thenReturn(SUB_2_MNC)
}
}

View File

@@ -20,7 +20,10 @@ import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
@@ -30,12 +33,12 @@ import android.widget.LinearLayout;
import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.StatusBarMobileView;
import com.android.systemui.statusbar.StatusBarWifiView;
import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider;
import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
@@ -55,15 +58,19 @@ import javax.inject.Provider;
@SmallTest
public class StatusBarIconControllerTest extends LeakCheckedTest {
private MobileContextProvider mMobileContextProvider = mock(MobileContextProvider.class);
@Before
public void setup() {
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
// For testing, ignore context overrides
when(mMobileContextProvider.getMobileContextForSub(anyInt(), any())).thenReturn(mContext);
}
@Test
public void testSetCalledOnAdd_IconManager() {
LinearLayout layout = new LinearLayout(mContext);
TestIconManager manager = new TestIconManager(layout);
TestIconManager manager = new TestIconManager(layout, mMobileContextProvider);
testCallOnAdd_forManager(manager);
}
@@ -72,9 +79,9 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
LinearLayout layout = new LinearLayout(mContext);
TestDarkIconManager manager = new TestDarkIconManager(
layout,
mock(FeatureFlags.class),
mock(StatusBarPipelineFlags.class),
() -> mock(WifiViewModel.class),
mMobileContextProvider,
mock(DarkIconDispatcher.class));
testCallOnAdd_forManager(manager);
}
@@ -114,11 +121,14 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
TestDarkIconManager(
LinearLayout group,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider,
MobileContextProvider contextProvider,
DarkIconDispatcher darkIconDispatcher) {
super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider,
super(group,
statusBarPipelineFlags,
wifiViewModelProvider,
contextProvider,
darkIconDispatcher);
}
@@ -153,11 +163,11 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
}
private static class TestIconManager extends IconManager implements TestableIconManager {
TestIconManager(ViewGroup group) {
TestIconManager(ViewGroup group, MobileContextProvider contextProvider) {
super(group,
mock(FeatureFlags.class),
mock(StatusBarPipelineFlags.class),
() -> mock(WifiViewModel.class));
() -> mock(WifiViewModel.class),
contextProvider);
}
@Override