[Provider model] Internet picker Part II
- Add mobile internet preference with default data subscription. - Make prefrence to show dynamically when data subscription changed. Video exhibition - http://rcll/gcmsphfhJ1UzfPSvjWOuXK/c1B2CtaFz27rlIQ2LSTJmo Code difference - SubscriptionsPreferenceControllerTest.java between robolectric and junit. - https://diff.googleplex.com/#key=1Zm7JGPhoZwY Bug: 172229552 Test: atest SubscriptionsPreferenceControllerTest Change-Id: Ib50c2c51159f60f19631d1a02081eafde3436e94
This commit is contained in:
@@ -21,10 +21,13 @@ import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
|
|||||||
|
|
||||||
import static com.android.settings.network.telephony.MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON;
|
import static com.android.settings.network.telephony.MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.telephony.ServiceState;
|
||||||
import android.telephony.SignalStrength;
|
import android.telephony.SignalStrength;
|
||||||
import android.telephony.SubscriptionInfo;
|
import android.telephony.SubscriptionInfo;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
@@ -46,6 +49,7 @@ import com.android.settings.network.telephony.DataConnectivityListener;
|
|||||||
import com.android.settings.network.telephony.MobileNetworkActivity;
|
import com.android.settings.network.telephony.MobileNetworkActivity;
|
||||||
import com.android.settings.network.telephony.MobileNetworkUtils;
|
import com.android.settings.network.telephony.MobileNetworkUtils;
|
||||||
import com.android.settings.network.telephony.SignalStrengthListener;
|
import com.android.settings.network.telephony.SignalStrengthListener;
|
||||||
|
import com.android.settings.widget.GearPreference;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
import com.android.settingslib.net.SignalStrengthUtil;
|
import com.android.settingslib.net.SignalStrengthUtil;
|
||||||
|
|
||||||
@@ -55,9 +59,15 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This manages a set of Preferences it places into a PreferenceGroup owned by some parent
|
* If the provider model is not enabled, this controller manages a set of Preferences it places into
|
||||||
|
* a PreferenceGroup owned by some parent
|
||||||
* controller class - one for each available subscription. This controller is only considered
|
* controller class - one for each available subscription. This controller is only considered
|
||||||
* available if there are 2 or more subscriptions.
|
* available if there are 2 or more subscriptions.
|
||||||
|
*
|
||||||
|
* If the provider model is enabled, this controller manages preference with data subscription
|
||||||
|
* information and make its state display on preference.
|
||||||
|
* TODO this class will clean up the multiple subscriptions functionality after the provider
|
||||||
|
* model is released.
|
||||||
*/
|
*/
|
||||||
public class SubscriptionsPreferenceController extends AbstractPreferenceController implements
|
public class SubscriptionsPreferenceController extends AbstractPreferenceController implements
|
||||||
LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient,
|
LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient,
|
||||||
@@ -68,16 +78,30 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
private UpdateListener mUpdateListener;
|
private UpdateListener mUpdateListener;
|
||||||
private String mPreferenceGroupKey;
|
private String mPreferenceGroupKey;
|
||||||
private PreferenceGroup mPreferenceGroup;
|
private PreferenceGroup mPreferenceGroup;
|
||||||
private SubscriptionManager mManager;
|
private TelephonyManager mTelephonyManager;
|
||||||
|
private SubscriptionManager mSubscriptionManager;
|
||||||
private SubscriptionsChangeListener mSubscriptionsListener;
|
private SubscriptionsChangeListener mSubscriptionsListener;
|
||||||
private MobileDataEnabledListener mDataEnabledListener;
|
private MobileDataEnabledListener mDataEnabledListener;
|
||||||
private DataConnectivityListener mConnectivityListener;
|
private DataConnectivityListener mConnectivityListener;
|
||||||
private SignalStrengthListener mSignalStrengthListener;
|
private SignalStrengthListener mSignalStrengthListener;
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
final BroadcastReceiver mDataSubscriptionChangedReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
final String action = intent.getAction();
|
||||||
|
if (action.equals(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Map of subscription id to Preference
|
// Map of subscription id to Preference
|
||||||
private Map<Integer, Preference> mSubscriptionPreferences;
|
private Map<Integer, Preference> mSubscriptionPreferences;
|
||||||
private int mStartOrder;
|
private int mStartOrder;
|
||||||
|
private GearPreference mSubsGearPref;
|
||||||
|
|
||||||
|
private SubsPrefCtrlInjector mSubsPrefCtrlInjector;
|
||||||
/**
|
/**
|
||||||
* This interface lets a parent of this class know that some change happened - this could
|
* This interface lets a parent of this class know that some change happened - this could
|
||||||
* either be because overall availability changed, or because we've added/removed/updated some
|
* either be because overall availability changed, or because we've added/removed/updated some
|
||||||
@@ -107,21 +131,37 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
mUpdateListener = updateListener;
|
mUpdateListener = updateListener;
|
||||||
mPreferenceGroupKey = preferenceGroupKey;
|
mPreferenceGroupKey = preferenceGroupKey;
|
||||||
mStartOrder = startOrder;
|
mStartOrder = startOrder;
|
||||||
mManager = context.getSystemService(SubscriptionManager.class);
|
mTelephonyManager = context.getSystemService(TelephonyManager.class);
|
||||||
|
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
|
||||||
mSubscriptionPreferences = new ArrayMap<>();
|
mSubscriptionPreferences = new ArrayMap<>();
|
||||||
mSubscriptionsListener = new SubscriptionsChangeListener(context, this);
|
mSubscriptionsListener = new SubscriptionsChangeListener(context, this);
|
||||||
mDataEnabledListener = new MobileDataEnabledListener(context, this);
|
mDataEnabledListener = new MobileDataEnabledListener(context, this);
|
||||||
mConnectivityListener = new DataConnectivityListener(context, this);
|
mConnectivityListener = new DataConnectivityListener(context, this);
|
||||||
mSignalStrengthListener = new SignalStrengthListener(context, this);
|
mSignalStrengthListener = new SignalStrengthListener(context, this);
|
||||||
lifecycle.addObserver(this);
|
lifecycle.addObserver(this);
|
||||||
|
mSubsPrefCtrlInjector = createSubsPrefCtrlInjector();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerDataSubscriptionChangedReceiver() {
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
|
||||||
|
mContext.registerReceiver(mDataSubscriptionChangedReceiver, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unRegisterDataSubscriptionChangedReceiver() {
|
||||||
|
if (mDataSubscriptionChangedReceiver != null) {
|
||||||
|
mContext.unregisterReceiver(mDataSubscriptionChangedReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnLifecycleEvent(ON_RESUME)
|
@OnLifecycleEvent(ON_RESUME)
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
mSubscriptionsListener.start();
|
mSubscriptionsListener.start();
|
||||||
mDataEnabledListener.start(SubscriptionManager.getDefaultDataSubscriptionId());
|
mDataEnabledListener.start(mSubsPrefCtrlInjector.getDefaultDataSubscriptionId());
|
||||||
mConnectivityListener.start();
|
mConnectivityListener.start();
|
||||||
mSignalStrengthListener.resume();
|
mSignalStrengthListener.resume();
|
||||||
|
registerDataSubscriptionChangedReceiver();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +171,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
mDataEnabledListener.stop();
|
mDataEnabledListener.stop();
|
||||||
mConnectivityListener.stop();
|
mConnectivityListener.stop();
|
||||||
mSignalStrengthListener.pause();
|
mSignalStrengthListener.pause();
|
||||||
|
unRegisterDataSubscriptionChangedReceiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -143,29 +184,116 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
if (mPreferenceGroup == null) {
|
if (mPreferenceGroup == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isAvailable()) {
|
if (!isAvailable()) {
|
||||||
|
if (mSubsGearPref != null) {
|
||||||
|
mPreferenceGroup.removePreference(mSubsGearPref);
|
||||||
|
}
|
||||||
for (Preference pref : mSubscriptionPreferences.values()) {
|
for (Preference pref : mSubscriptionPreferences.values()) {
|
||||||
mPreferenceGroup.removePreference(pref);
|
mPreferenceGroup.removePreference(pref);
|
||||||
}
|
}
|
||||||
|
|
||||||
mSubscriptionPreferences.clear();
|
mSubscriptionPreferences.clear();
|
||||||
mSignalStrengthListener.updateSubscriptionIds(Collections.emptySet());
|
mSignalStrengthListener.updateSubscriptionIds(Collections.emptySet());
|
||||||
mUpdateListener.onChildrenUpdated();
|
mUpdateListener.onChildrenUpdated();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mSubsPrefCtrlInjector.isProviderModelEnabled(mContext)) {
|
||||||
|
updateForProvider();
|
||||||
|
} else {
|
||||||
|
updateForBase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateForProvider() {
|
||||||
|
SubscriptionInfo subInfo = mSubscriptionManager.getDefaultDataSubscriptionInfo();
|
||||||
|
if (subInfo == null) {
|
||||||
|
mPreferenceGroup.removeAll();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mSubsGearPref == null) {
|
||||||
|
mPreferenceGroup.removeAll();
|
||||||
|
mSubsGearPref = new GearPreference(mContext, null);
|
||||||
|
mSubsGearPref.setOnPreferenceClickListener(preference -> {
|
||||||
|
//TODO(b/176141379) Wait for wifiManager#selectCarrier(int subscriptionId)
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
mSubsGearPref.setOnGearClickListener(p ->
|
||||||
|
startMobileNetworkActivity(mContext, subInfo.getSubscriptionId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
mSubsGearPref.setTitle(subInfo.getDisplayName());
|
||||||
|
mSubsGearPref.setOrder(mStartOrder);
|
||||||
|
//TODO(b/176141828) Wait for api provided by system ui.
|
||||||
|
mSubsGearPref.setSummary(getMobilePreferenceSummary());
|
||||||
|
mSubsGearPref.setIcon(getIcon(subInfo.getSubscriptionId()));
|
||||||
|
mPreferenceGroup.addPreference(mSubsGearPref);
|
||||||
|
|
||||||
|
final Set<Integer> activeDataSubIds = new ArraySet<>();
|
||||||
|
activeDataSubIds.add(subInfo.getSubscriptionId());
|
||||||
|
mSignalStrengthListener.updateSubscriptionIds(activeDataSubIds);
|
||||||
|
mUpdateListener.onChildrenUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMobilePreferenceSummary() {
|
||||||
|
//TODO(b/176141828) Waiting for the api provided by system UI.
|
||||||
|
String result = "5G";
|
||||||
|
if (MobileNetworkUtils.activeNetworkIsCellular(mContext)) {
|
||||||
|
result = "Active, " + result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable getIcon(int subId) {
|
||||||
|
final TelephonyManager tmForSubId = mTelephonyManager.createForSubscriptionId(subId);
|
||||||
|
final SignalStrength strength = tmForSubId.getSignalStrength();
|
||||||
|
int level = (strength == null) ? 0 : strength.getLevel();
|
||||||
|
|
||||||
|
int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
|
||||||
|
if (shouldInflateSignalStrength(subId)) {
|
||||||
|
level += 1;
|
||||||
|
numLevels += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean isMobileDataOn = tmForSubId.isDataEnabled();
|
||||||
|
final boolean isActiveCellularNetwork =
|
||||||
|
mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext);
|
||||||
|
final boolean isMobileDataAccessible = tmForSubId.getDataState()
|
||||||
|
== TelephonyManager.DATA_CONNECTED;
|
||||||
|
final ServiceState serviceState = tmForSubId.getServiceState();
|
||||||
|
final boolean isVoiceOutOfService = (serviceState == null)
|
||||||
|
? true
|
||||||
|
: (serviceState.getState() == ServiceState.STATE_OUT_OF_SERVICE);
|
||||||
|
|
||||||
|
Drawable icon = mSubsPrefCtrlInjector.getIcon(mContext, level, numLevels, false);
|
||||||
|
|
||||||
|
if (isActiveCellularNetwork) {
|
||||||
|
icon.setTint(Utils.getColorAccentDefaultColor(mContext));
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
if ((isMobileDataOn && isMobileDataAccessible)
|
||||||
|
|| (!isMobileDataOn && !isVoiceOutOfService)) {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
icon = mContext.getDrawable(R.drawable.ic_signal_strength_zero_bar_no_internet);
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateForBase() {
|
||||||
final Map<Integer, Preference> existingPrefs = mSubscriptionPreferences;
|
final Map<Integer, Preference> existingPrefs = mSubscriptionPreferences;
|
||||||
mSubscriptionPreferences = new ArrayMap<>();
|
mSubscriptionPreferences = new ArrayMap<>();
|
||||||
|
|
||||||
int order = mStartOrder;
|
int order = mStartOrder;
|
||||||
final Set<Integer> activeSubIds = new ArraySet<>();
|
final Set<Integer> activeSubIds = new ArraySet<>();
|
||||||
final int dataDefaultSubId = SubscriptionManager.getDefaultDataSubscriptionId();
|
final int dataDefaultSubId = mSubsPrefCtrlInjector.getDefaultDataSubscriptionId();
|
||||||
for (SubscriptionInfo info : SubscriptionUtil.getActiveSubscriptions(mManager)) {
|
for (SubscriptionInfo info :
|
||||||
|
SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager)) {
|
||||||
final int subId = info.getSubscriptionId();
|
final int subId = info.getSubscriptionId();
|
||||||
// Avoid from showing subscription(SIM)s which has been marked as hidden
|
// Avoid from showing subscription(SIM)s which has been marked as hidden
|
||||||
// For example, only one subscription will be shown when there're multiple
|
// For example, only one subscription will be shown when there're multiple
|
||||||
// subscriptions with same group UUID.
|
// subscriptions with same group UUID.
|
||||||
if (!canSubscriptionBeDisplayed(mContext, subId)) {
|
if (!mSubsPrefCtrlInjector.canSubscriptionBeDisplayed(mContext, subId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
activeSubIds.add(subId);
|
activeSubIds.add(subId);
|
||||||
@@ -181,9 +309,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
pref.setOrder(order++);
|
pref.setOrder(order++);
|
||||||
|
|
||||||
pref.setOnPreferenceClickListener(clickedPref -> {
|
pref.setOnPreferenceClickListener(clickedPref -> {
|
||||||
final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
|
startMobileNetworkActivity(mContext, subId);
|
||||||
intent.putExtra(Settings.EXTRA_SUB_ID, subId);
|
|
||||||
mContext.startActivity(intent);
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -198,6 +324,12 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
mUpdateListener.onChildrenUpdated();
|
mUpdateListener.onChildrenUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void startMobileNetworkActivity(Context context, int subId) {
|
||||||
|
final Intent intent = new Intent(context, MobileNetworkActivity.class);
|
||||||
|
intent.putExtra(Settings.EXTRA_SUB_ID, subId);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
boolean shouldInflateSignalStrength(int subId) {
|
boolean shouldInflateSignalStrength(int subId) {
|
||||||
return SignalStrengthUtil.shouldInflateSignalStrength(mContext, subId);
|
return SignalStrengthUtil.shouldInflateSignalStrength(mContext, subId);
|
||||||
@@ -214,14 +346,9 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
level += 1;
|
level += 1;
|
||||||
numLevels += 1;
|
numLevels += 1;
|
||||||
}
|
}
|
||||||
final boolean showCutOut = !isDefaultForData || !mgr.isDataEnabled();
|
|
||||||
pref.setIcon(getIcon(level, numLevels, showCutOut));
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
final boolean showCutOut = !isDefaultForData || !mgr.isDataEnabled();
|
||||||
Drawable getIcon(int level, int numLevels, boolean cutOut) {
|
pref.setIcon(mSubsPrefCtrlInjector.getIcon(mContext, level, numLevels, showCutOut));
|
||||||
return MobileNetworkUtils.getSignalStrengthIcon(mContext, level, numLevels,
|
|
||||||
NO_CELL_DATA_TYPE_ICON, cutOut);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -236,8 +363,8 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
* If a subscription isn't the default for anything, we just say it is available.
|
* If a subscription isn't the default for anything, we just say it is available.
|
||||||
*/
|
*/
|
||||||
protected String getSummary(int subId, boolean isDefaultForData) {
|
protected String getSummary(int subId, boolean isDefaultForData) {
|
||||||
final int callsDefaultSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
|
final int callsDefaultSubId = mSubsPrefCtrlInjector.getDefaultVoiceSubscriptionId();
|
||||||
final int smsDefaultSubId = SubscriptionManager.getDefaultSmsSubscriptionId();
|
final int smsDefaultSubId = mSubsPrefCtrlInjector.getDefaultSmsSubscriptionId();
|
||||||
|
|
||||||
String line1 = null;
|
String line1 = null;
|
||||||
if (subId == callsDefaultSubId && subId == smsDefaultSubId) {
|
if (subId == callsDefaultSubId && subId == smsDefaultSubId) {
|
||||||
@@ -253,7 +380,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
final TelephonyManager telMgrForSub = mContext.getSystemService(
|
final TelephonyManager telMgrForSub = mContext.getSystemService(
|
||||||
TelephonyManager.class).createForSubscriptionId(subId);
|
TelephonyManager.class).createForSubscriptionId(subId);
|
||||||
final boolean dataEnabled = telMgrForSub.isDataEnabled();
|
final boolean dataEnabled = telMgrForSub.isDataEnabled();
|
||||||
if (dataEnabled && MobileNetworkUtils.activeNetworkIsCellular(mContext)) {
|
if (dataEnabled && mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext)) {
|
||||||
line2 = mContext.getString(R.string.mobile_data_active);
|
line2 = mContext.getString(R.string.mobile_data_active);
|
||||||
} else if (!dataEnabled) {
|
} else if (!dataEnabled) {
|
||||||
line2 = mContext.getString(R.string.mobile_data_off);
|
line2 = mContext.getString(R.string.mobile_data_off);
|
||||||
@@ -274,14 +401,16 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if there are at least 2 available subscriptions.
|
* @return true if there are at least 2 available subscriptions,
|
||||||
|
* or if there is at least 1 available subscription for provider model.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
if (mSubscriptionsListener.isAirplaneModeOn()) {
|
if (mSubscriptionsListener.isAirplaneModeOn()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
List<SubscriptionInfo> subInfoList = SubscriptionUtil.getActiveSubscriptions(mManager);
|
List<SubscriptionInfo> subInfoList =
|
||||||
|
SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager);
|
||||||
if (subInfoList == null) {
|
if (subInfoList == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -290,8 +419,9 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
// For example, only one subscription will be shown when there're multiple
|
// For example, only one subscription will be shown when there're multiple
|
||||||
// subscriptions with same group UUID.
|
// subscriptions with same group UUID.
|
||||||
.filter(subInfo ->
|
.filter(subInfo ->
|
||||||
canSubscriptionBeDisplayed(mContext, subInfo.getSubscriptionId()))
|
mSubsPrefCtrlInjector.canSubscriptionBeDisplayed(mContext,
|
||||||
.count() >= (Utils.isProviderModelEnabled(mContext) ? 1 : 2);
|
subInfo.getSubscriptionId()))
|
||||||
|
.count() >= (mSubsPrefCtrlInjector.isProviderModelEnabled(mContext) ? 1 : 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -307,7 +437,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
@Override
|
@Override
|
||||||
public void onSubscriptionsChanged() {
|
public void onSubscriptionsChanged() {
|
||||||
// See if we need to change which sub id we're using to listen for enabled/disabled changes.
|
// See if we need to change which sub id we're using to listen for enabled/disabled changes.
|
||||||
int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
|
int defaultDataSubId = mSubsPrefCtrlInjector.getDefaultDataSubscriptionId();
|
||||||
if (defaultDataSubId != mDataEnabledListener.getSubId()) {
|
if (defaultDataSubId != mDataEnabledListener.getSubId()) {
|
||||||
mDataEnabledListener.stop();
|
mDataEnabledListener.stop();
|
||||||
mDataEnabledListener.start(defaultDataSubId);
|
mDataEnabledListener.start(defaultDataSubId);
|
||||||
@@ -335,4 +465,65 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
return (SubscriptionUtil.getAvailableSubscription(context,
|
return (SubscriptionUtil.getAvailableSubscription(context,
|
||||||
ProxySubscriptionManager.getInstance(context), subId) != null);
|
ProxySubscriptionManager.getInstance(context), subId) != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubsPrefCtrlInjector createSubsPrefCtrlInjector() {
|
||||||
|
return new SubsPrefCtrlInjector();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To inject necessary data from each static api.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public static class SubsPrefCtrlInjector {
|
||||||
|
/**
|
||||||
|
* Use to inject function and value for class and test class.
|
||||||
|
*/
|
||||||
|
public boolean canSubscriptionBeDisplayed(Context context, int subId) {
|
||||||
|
return (SubscriptionUtil.getAvailableSubscription(context,
|
||||||
|
ProxySubscriptionManager.getInstance(context), subId) != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check SIM be able to display on UI.
|
||||||
|
*/
|
||||||
|
public int getDefaultSmsSubscriptionId() {
|
||||||
|
return SubscriptionManager.getDefaultSmsSubscriptionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get default voice subscription ID.
|
||||||
|
*/
|
||||||
|
public int getDefaultVoiceSubscriptionId() {
|
||||||
|
return SubscriptionManager.getDefaultVoiceSubscriptionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get default data subscription ID.
|
||||||
|
*/
|
||||||
|
public int getDefaultDataSubscriptionId() {
|
||||||
|
return SubscriptionManager.getDefaultDataSubscriptionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirm the current network is cellular and active.
|
||||||
|
*/
|
||||||
|
public boolean isActiveCellularNetwork(Context context) {
|
||||||
|
return MobileNetworkUtils.activeNetworkIsCellular(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirm the flag of Provider Model switch is turned on or not.
|
||||||
|
*/
|
||||||
|
public boolean isProviderModelEnabled(Context context) {
|
||||||
|
return Utils.isProviderModelEnabled(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get signal icon with different signal level.
|
||||||
|
*/
|
||||||
|
public Drawable getIcon(Context context, int level, int numLevels, boolean cutOut) {
|
||||||
|
return MobileNetworkUtils.getSignalStrengthIcon(context, level, numLevels,
|
||||||
|
NO_CELL_DATA_TYPE_ICON, cutOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -1,553 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 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.settings.network;
|
|
||||||
|
|
||||||
import static android.telephony.SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
|
|
||||||
import static android.telephony.SignalStrength.SIGNAL_STRENGTH_GOOD;
|
|
||||||
import static android.telephony.SignalStrength.SIGNAL_STRENGTH_GREAT;
|
|
||||||
import static android.telephony.SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
|
|
||||||
import static android.telephony.SignalStrength.SIGNAL_STRENGTH_POOR;
|
|
||||||
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.doNothing;
|
|
||||||
import static org.mockito.Mockito.doReturn;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.Network;
|
|
||||||
import android.net.NetworkCapabilities;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.telephony.SignalStrength;
|
|
||||||
import android.telephony.SubscriptionInfo;
|
|
||||||
import android.telephony.SubscriptionManager;
|
|
||||||
import android.telephony.TelephonyManager;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.preference.PreferenceCategory;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
|
||||||
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
import org.robolectric.annotation.Config;
|
|
||||||
import org.robolectric.shadows.ShadowSubscriptionManager;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
@Config(shadows = ShadowSubscriptionManager.class)
|
|
||||||
public class SubscriptionsPreferenceControllerTest {
|
|
||||||
private static final String KEY = "preference_group";
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private PreferenceScreen mScreen;
|
|
||||||
@Mock
|
|
||||||
private PreferenceCategory mPreferenceCategory;
|
|
||||||
@Mock
|
|
||||||
private SubscriptionManager mSubscriptionManager;
|
|
||||||
@Mock
|
|
||||||
private ConnectivityManager mConnectivityManager;
|
|
||||||
@Mock
|
|
||||||
private TelephonyManager mTelephonyManager;
|
|
||||||
@Mock
|
|
||||||
private Network mActiveNetwork;
|
|
||||||
@Mock
|
|
||||||
private NetworkCapabilities mCapabilities;
|
|
||||||
@Mock
|
|
||||||
private Drawable mSignalStrengthIcon;
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private LifecycleOwner mLifecycleOwner;
|
|
||||||
private Lifecycle mLifecycle;
|
|
||||||
private SubscriptionsPreferenceController mController;
|
|
||||||
private int mOnChildUpdatedCount;
|
|
||||||
private SubscriptionsPreferenceController.UpdateListener mUpdateListener;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
|
||||||
mLifecycleOwner = () -> mLifecycle;
|
|
||||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
|
||||||
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
|
|
||||||
when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
|
|
||||||
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
|
||||||
when(mConnectivityManager.getActiveNetwork()).thenReturn(mActiveNetwork);
|
|
||||||
when(mConnectivityManager.getNetworkCapabilities(mActiveNetwork)).thenReturn(mCapabilities);
|
|
||||||
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
|
|
||||||
when(mScreen.findPreference(eq(KEY))).thenReturn(mPreferenceCategory);
|
|
||||||
when(mPreferenceCategory.getContext()).thenReturn(mContext);
|
|
||||||
mOnChildUpdatedCount = 0;
|
|
||||||
mUpdateListener = () -> mOnChildUpdatedCount++;
|
|
||||||
|
|
||||||
mController = spy(
|
|
||||||
new SubscriptionsPreferenceController(mContext, mLifecycle, mUpdateListener,
|
|
||||||
KEY, 5));
|
|
||||||
doReturn(true).when(mController).canSubscriptionBeDisplayed(any(), anyInt());
|
|
||||||
doReturn(mSignalStrengthIcon).when(mController).getIcon(anyInt(), anyInt(), anyBoolean());
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
SubscriptionUtil.setActiveSubscriptionsForTesting(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void isAvailable_oneSubscription_availableFalse() {
|
|
||||||
setupMockSubscriptions(1);
|
|
||||||
assertThat(mController.isAvailable()).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void isAvailable_twoSubscriptions_availableTrue() {
|
|
||||||
setupMockSubscriptions(2);
|
|
||||||
assertThat(mController.isAvailable()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void isAvailable_fiveSubscriptions_availableTrue() {
|
|
||||||
setupMockSubscriptions(5);
|
|
||||||
assertThat(mController.isAvailable()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void isAvailable_airplaneModeOn_availableFalse() {
|
|
||||||
setupMockSubscriptions(2);
|
|
||||||
assertThat(mController.isAvailable()).isTrue();
|
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
|
|
||||||
assertThat(mController.isAvailable()).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onAirplaneModeChanged_airplaneModeTurnedOn_eventFired() {
|
|
||||||
setupMockSubscriptions(2);
|
|
||||||
mController.onResume();
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
assertThat(mController.isAvailable()).isTrue();
|
|
||||||
|
|
||||||
final int updateCountBeforeModeChange = mOnChildUpdatedCount;
|
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
|
|
||||||
mController.onAirplaneModeChanged(true);
|
|
||||||
assertThat(mController.isAvailable()).isFalse();
|
|
||||||
assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeModeChange + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onAirplaneModeChanged_airplaneModeTurnedOff_eventFired() {
|
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
|
|
||||||
setupMockSubscriptions(2);
|
|
||||||
mController.onResume();
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
assertThat(mController.isAvailable()).isFalse();
|
|
||||||
|
|
||||||
final int updateCountBeforeModeChange = mOnChildUpdatedCount;
|
|
||||||
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
|
|
||||||
mController.onAirplaneModeChanged(false);
|
|
||||||
assertThat(mController.isAvailable()).isTrue();
|
|
||||||
assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeModeChange + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onSubscriptionsChanged_countBecameTwo_eventFired() {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(2);
|
|
||||||
SubscriptionUtil.setActiveSubscriptionsForTesting(subs.subList(0, 1));
|
|
||||||
mController.onResume();
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
assertThat(mController.isAvailable()).isFalse();
|
|
||||||
|
|
||||||
final int updateCountBeforeSubscriptionChange = mOnChildUpdatedCount;
|
|
||||||
SubscriptionUtil.setActiveSubscriptionsForTesting(subs);
|
|
||||||
mController.onSubscriptionsChanged();
|
|
||||||
assertThat(mController.isAvailable()).isTrue();
|
|
||||||
assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeSubscriptionChange + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onSubscriptionsChanged_countBecameOne_eventFiredAndPrefsRemoved() {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(2);
|
|
||||||
mController.onResume();
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
assertThat(mController.isAvailable()).isTrue();
|
|
||||||
verify(mPreferenceCategory, times(2)).addPreference(any(Preference.class));
|
|
||||||
|
|
||||||
final int updateCountBeforeSubscriptionChange = mOnChildUpdatedCount;
|
|
||||||
SubscriptionUtil.setActiveSubscriptionsForTesting(subs.subList(0, 1));
|
|
||||||
mController.onSubscriptionsChanged();
|
|
||||||
assertThat(mController.isAvailable()).isFalse();
|
|
||||||
assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeSubscriptionChange + 1);
|
|
||||||
|
|
||||||
verify(mPreferenceCategory, times(2)).removePreference(any(Preference.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onSubscriptionsChanged_subscriptionReplaced_preferencesChanged() {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(3);
|
|
||||||
|
|
||||||
// Start out with only sub1 and sub2.
|
|
||||||
SubscriptionUtil.setActiveSubscriptionsForTesting(subs.subList(0, 2));
|
|
||||||
mController.onResume();
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
final ArgumentCaptor<Preference> captor = ArgumentCaptor.forClass(Preference.class);
|
|
||||||
verify(mPreferenceCategory, times(2)).addPreference(captor.capture());
|
|
||||||
assertThat(captor.getAllValues().size()).isEqualTo(2);
|
|
||||||
assertThat(captor.getAllValues().get(0).getTitle()).isEqualTo("sub1");
|
|
||||||
assertThat(captor.getAllValues().get(1).getTitle()).isEqualTo("sub2");
|
|
||||||
|
|
||||||
// Now replace sub2 with sub3, and make sure the old preference was removed and the new
|
|
||||||
// preference was added.
|
|
||||||
final int updateCountBeforeSubscriptionChange = mOnChildUpdatedCount;
|
|
||||||
SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(subs.get(0), subs.get(2)));
|
|
||||||
mController.onSubscriptionsChanged();
|
|
||||||
assertThat(mController.isAvailable()).isTrue();
|
|
||||||
assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeSubscriptionChange + 1);
|
|
||||||
|
|
||||||
verify(mPreferenceCategory).removePreference(captor.capture());
|
|
||||||
assertThat(captor.getValue().getTitle()).isEqualTo("sub2");
|
|
||||||
verify(mPreferenceCategory, times(3)).addPreference(captor.capture());
|
|
||||||
assertThat(captor.getValue().getTitle()).isEqualTo("sub3");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper to create a specified number of subscriptions, display them, and then click on one and
|
|
||||||
* verify that the intent fires and has the right subscription id extra.
|
|
||||||
*
|
|
||||||
* @param subscriptionCount the number of subscriptions
|
|
||||||
* @param selectedPrefIndex index of the subscription to click on
|
|
||||||
*/
|
|
||||||
private void runPreferenceClickTest(final int subscriptionCount, final int selectedPrefIndex) {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(subscriptionCount);
|
|
||||||
final ArgumentCaptor<Preference> prefCaptor = ArgumentCaptor.forClass(Preference.class);
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
verify(mPreferenceCategory, times(subscriptionCount)).addPreference(prefCaptor.capture());
|
|
||||||
final List<Preference> prefs = prefCaptor.getAllValues();
|
|
||||||
final Preference pref = prefs.get(selectedPrefIndex);
|
|
||||||
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
|
||||||
doNothing().when(mContext).startActivity(intentCaptor.capture());
|
|
||||||
pref.getOnPreferenceClickListener().onPreferenceClick(pref);
|
|
||||||
final Intent intent = intentCaptor.getValue();
|
|
||||||
assertThat(intent).isNotNull();
|
|
||||||
assertThat(intent.hasExtra(Settings.EXTRA_SUB_ID)).isTrue();
|
|
||||||
final int subIdFromIntent = intent.getIntExtra(Settings.EXTRA_SUB_ID,
|
|
||||||
INVALID_SUBSCRIPTION_ID);
|
|
||||||
assertThat(subIdFromIntent).isEqualTo(
|
|
||||||
subs.get(selectedPrefIndex).getSubscriptionId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void twoPreferences_firstPreferenceClicked_correctIntentFires() {
|
|
||||||
runPreferenceClickTest(2, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void twoPreferences_secondPreferenceClicked_correctIntentFires() {
|
|
||||||
runPreferenceClickTest(2, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void threePreferences_secondPreferenceClicked_correctIntentFires() {
|
|
||||||
runPreferenceClickTest(3, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void threePreferences_thirdPreferenceClicked_correctIntentFires() {
|
|
||||||
runPreferenceClickTest(3, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getSummary_twoSubsOneDefaultForEverythingDataActive() {
|
|
||||||
setupMockSubscriptions(2);
|
|
||||||
|
|
||||||
ShadowSubscriptionManager.setDefaultSmsSubscriptionId(11);
|
|
||||||
ShadowSubscriptionManager.setDefaultVoiceSubscriptionId(11);
|
|
||||||
when(mTelephonyManager.isDataEnabled()).thenReturn(true);
|
|
||||||
when(mCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true);
|
|
||||||
|
|
||||||
assertThat(mController.getSummary(11, true)).isEqualTo(
|
|
||||||
mContext.getString(R.string.default_for_calls_and_sms) + System.lineSeparator()
|
|
||||||
+ mContext.getString(R.string.mobile_data_active));
|
|
||||||
|
|
||||||
assertThat(mController.getSummary(22, false)).isEqualTo(
|
|
||||||
mContext.getString(R.string.subscription_available));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getSummary_twoSubsOneDefaultForEverythingDataNotActive() {
|
|
||||||
setupMockSubscriptions(2, 1, true);
|
|
||||||
|
|
||||||
ShadowSubscriptionManager.setDefaultSmsSubscriptionId(1);
|
|
||||||
ShadowSubscriptionManager.setDefaultVoiceSubscriptionId(1);
|
|
||||||
|
|
||||||
assertThat(mController.getSummary(1, true)).isEqualTo(
|
|
||||||
mContext.getString(R.string.default_for_calls_and_sms) + System.lineSeparator()
|
|
||||||
+ mContext.getString(R.string.default_for_mobile_data));
|
|
||||||
|
|
||||||
assertThat(mController.getSummary(2, false)).isEqualTo(
|
|
||||||
mContext.getString(R.string.subscription_available));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getSummary_twoSubsOneDefaultForEverythingDataDisabled() {
|
|
||||||
setupMockSubscriptions(2);
|
|
||||||
|
|
||||||
ShadowSubscriptionManager.setDefaultVoiceSubscriptionId(1);
|
|
||||||
ShadowSubscriptionManager.setDefaultSmsSubscriptionId(1);
|
|
||||||
|
|
||||||
assertThat(mController.getSummary(1, true)).isEqualTo(
|
|
||||||
mContext.getString(R.string.default_for_calls_and_sms) + System.lineSeparator()
|
|
||||||
+ mContext.getString(R.string.mobile_data_off));
|
|
||||||
|
|
||||||
assertThat(mController.getSummary(2, false)).isEqualTo(
|
|
||||||
mContext.getString(R.string.subscription_available));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getSummary_twoSubsOneForCallsAndDataOneForSms() {
|
|
||||||
setupMockSubscriptions(2, 1, true);
|
|
||||||
|
|
||||||
ShadowSubscriptionManager.setDefaultSmsSubscriptionId(2);
|
|
||||||
ShadowSubscriptionManager.setDefaultVoiceSubscriptionId(1);
|
|
||||||
|
|
||||||
assertThat(mController.getSummary(1, true)).isEqualTo(
|
|
||||||
mContext.getString(R.string.default_for_calls) + System.lineSeparator()
|
|
||||||
+ mContext.getString(R.string.default_for_mobile_data));
|
|
||||||
|
|
||||||
assertThat(mController.getSummary(2, false)).isEqualTo(
|
|
||||||
mContext.getString(R.string.default_for_sms));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setIcon_nullStrength_noCrash() {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(2);
|
|
||||||
setMockSubSignalStrength(subs, 0, -1);
|
|
||||||
final Preference pref = mock(Preference.class);
|
|
||||||
|
|
||||||
mController.setIcon(pref, 1, true /* isDefaultForData */);
|
|
||||||
verify(mController).getIcon(eq(0), eq(NUM_SIGNAL_STRENGTH_BINS), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setIcon_noSignal_correctLevels() {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(2, 1, true);
|
|
||||||
setMockSubSignalStrength(subs, 0, SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
|
|
||||||
setMockSubSignalStrength(subs, 1, SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
|
|
||||||
setMockSubDataEnabled(subs, 0, true);
|
|
||||||
final Preference pref = mock(Preference.class);
|
|
||||||
|
|
||||||
mController.setIcon(pref, 1, true /* isDefaultForData */);
|
|
||||||
verify(mController).getIcon(eq(0), eq(NUM_SIGNAL_STRENGTH_BINS), eq(false));
|
|
||||||
|
|
||||||
mController.setIcon(pref, 2, false /* isDefaultForData */);
|
|
||||||
verify(mController).getIcon(eq(0), eq(NUM_SIGNAL_STRENGTH_BINS), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setIcon_noSignal_withInflation_correctLevels() {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(2, 1, true);
|
|
||||||
setMockSubSignalStrength(subs, 0, SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
|
|
||||||
setMockSubSignalStrength(subs, 1, SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
|
|
||||||
final Preference pref = mock(Preference.class);
|
|
||||||
doReturn(true).when(mController).shouldInflateSignalStrength(anyInt());
|
|
||||||
|
|
||||||
mController.setIcon(pref, 1, true /* isDefaultForData */);
|
|
||||||
verify(mController).getIcon(eq(1), eq(NUM_SIGNAL_STRENGTH_BINS + 1), eq(false));
|
|
||||||
|
|
||||||
mController.setIcon(pref, 2, false /* isDefaultForData */);
|
|
||||||
verify(mController).getIcon(eq(1), eq(NUM_SIGNAL_STRENGTH_BINS + 1), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setIcon_greatSignal_correctLevels() {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(2, 1, true);
|
|
||||||
setMockSubSignalStrength(subs, 0, SIGNAL_STRENGTH_GREAT);
|
|
||||||
setMockSubSignalStrength(subs, 1, SIGNAL_STRENGTH_GREAT);
|
|
||||||
final Preference pref = mock(Preference.class);
|
|
||||||
|
|
||||||
mController.setIcon(pref, 1, true /* isDefaultForData */);
|
|
||||||
verify(mController).getIcon(eq(4), eq(NUM_SIGNAL_STRENGTH_BINS), eq(false));
|
|
||||||
|
|
||||||
mController.setIcon(pref, 2, false /* isDefaultForData */);
|
|
||||||
verify(mController).getIcon(eq(4), eq(NUM_SIGNAL_STRENGTH_BINS), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onSignalStrengthChanged_subTwoGoesFromGoodToGreat_correctLevels() {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(2);
|
|
||||||
setMockSubSignalStrength(subs, 0, SIGNAL_STRENGTH_POOR);
|
|
||||||
setMockSubSignalStrength(subs, 1, SIGNAL_STRENGTH_GOOD);
|
|
||||||
|
|
||||||
mController.onResume();
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
|
|
||||||
// Now change the signal strength for the 2nd subscription from Good to Great
|
|
||||||
setMockSubSignalStrength(subs, 1, SIGNAL_STRENGTH_GREAT);
|
|
||||||
mController.onSignalStrengthChanged();
|
|
||||||
|
|
||||||
final ArgumentCaptor<Integer> level = ArgumentCaptor.forClass(Integer.class);
|
|
||||||
verify(mController, times(4)).getIcon(level.capture(), eq(NUM_SIGNAL_STRENGTH_BINS),
|
|
||||||
eq(true));
|
|
||||||
assertThat(level.getAllValues().get(0)).isEqualTo(1);
|
|
||||||
assertThat(level.getAllValues().get(1)).isEqualTo(3); // sub2, first time
|
|
||||||
assertThat(level.getAllValues().get(2)).isEqualTo(1);
|
|
||||||
assertThat(level.getAllValues().get(3)).isEqualTo(4); // sub2, after change
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void displayPreference_mobileDataOff_bothSubsHaveCutOut() {
|
|
||||||
setupMockSubscriptions(2, 1, false);
|
|
||||||
|
|
||||||
mController.onResume();
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
|
|
||||||
verify(mController, times(2)).getIcon(eq(SIGNAL_STRENGTH_GOOD),
|
|
||||||
eq(NUM_SIGNAL_STRENGTH_BINS), eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void displayPreference_mobileDataOn_onlyNonDefaultSubHasCutOut() {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(2, 1, true);
|
|
||||||
setMockSubSignalStrength(subs, 1, SIGNAL_STRENGTH_POOR);
|
|
||||||
|
|
||||||
mController.onResume();
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
|
|
||||||
verify(mController).getIcon(eq(SIGNAL_STRENGTH_GOOD), eq(NUM_SIGNAL_STRENGTH_BINS),
|
|
||||||
eq(false));
|
|
||||||
verify(mController).getIcon(eq(SIGNAL_STRENGTH_POOR), eq(NUM_SIGNAL_STRENGTH_BINS),
|
|
||||||
eq(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void displayPreference_subscriptionsWithSameGroupUUID_onlyOneWillBeSeen() {
|
|
||||||
doReturn(false).when(mController).canSubscriptionBeDisplayed(any(), eq(3));
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(3);
|
|
||||||
SubscriptionUtil.setActiveSubscriptionsForTesting(subs.subList(0, 3));
|
|
||||||
|
|
||||||
mController.onResume();
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
|
|
||||||
verify(mPreferenceCategory, times(2)).addPreference(any(Preference.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onMobileDataEnabledChange_mobileDataTurnedOff_bothSubsHaveCutOut() {
|
|
||||||
final List<SubscriptionInfo> subs = setupMockSubscriptions(2, 1, true);
|
|
||||||
|
|
||||||
mController.onResume();
|
|
||||||
mController.displayPreference(mScreen);
|
|
||||||
|
|
||||||
setMockSubDataEnabled(subs, 0, false);
|
|
||||||
mController.onMobileDataEnabledChange();
|
|
||||||
|
|
||||||
final ArgumentCaptor<Boolean> cutOutCaptor = ArgumentCaptor.forClass(Boolean.class);
|
|
||||||
verify(mController, times(4)).getIcon(eq(SIGNAL_STRENGTH_GOOD),
|
|
||||||
eq(NUM_SIGNAL_STRENGTH_BINS), cutOutCaptor.capture());
|
|
||||||
assertThat(cutOutCaptor.getAllValues().get(0)).isEqualTo(false); // sub1, first time
|
|
||||||
assertThat(cutOutCaptor.getAllValues().get(1)).isEqualTo(true);
|
|
||||||
assertThat(cutOutCaptor.getAllValues().get(2)).isEqualTo(true); // sub1, second time
|
|
||||||
assertThat(cutOutCaptor.getAllValues().get(3)).isEqualTo(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<SubscriptionInfo> setupMockSubscriptions(int count) {
|
|
||||||
return setupMockSubscriptions(count, 0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Helper method to setup several mock active subscriptions. The generated subscription id's
|
|
||||||
* start at 1.
|
|
||||||
*
|
|
||||||
* @param count How many subscriptions to create
|
|
||||||
* @param defaultDataSubId The subscription id of the default data subscription - pass
|
|
||||||
* INVALID_SUBSCRIPTION_ID if there should not be one
|
|
||||||
* @param mobileDataEnabled Whether mobile data should be considered enabled for the default
|
|
||||||
* data subscription
|
|
||||||
*/
|
|
||||||
private List<SubscriptionInfo> setupMockSubscriptions(int count, int defaultDataSubId,
|
|
||||||
boolean mobileDataEnabled) {
|
|
||||||
if (defaultDataSubId != INVALID_SUBSCRIPTION_ID) {
|
|
||||||
ShadowSubscriptionManager.setDefaultDataSubscriptionId(defaultDataSubId);
|
|
||||||
}
|
|
||||||
final ArrayList<SubscriptionInfo> infos = new ArrayList<>();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
final int subscriptionId = i + 1;
|
|
||||||
final SubscriptionInfo info = mock(SubscriptionInfo.class);
|
|
||||||
final TelephonyManager mgrForSub = mock(TelephonyManager.class);
|
|
||||||
final SignalStrength signalStrength = mock(SignalStrength.class);
|
|
||||||
|
|
||||||
if (subscriptionId == defaultDataSubId) {
|
|
||||||
when(mgrForSub.isDataEnabled()).thenReturn(mobileDataEnabled);
|
|
||||||
}
|
|
||||||
when(info.getSubscriptionId()).thenReturn(i + 1);
|
|
||||||
when(info.getDisplayName()).thenReturn("sub" + (i + 1));
|
|
||||||
doReturn(mgrForSub).when(mTelephonyManager).createForSubscriptionId(eq(subscriptionId));
|
|
||||||
when(mgrForSub.getSignalStrength()).thenReturn(signalStrength);
|
|
||||||
when(signalStrength.getLevel()).thenReturn(SIGNAL_STRENGTH_GOOD);
|
|
||||||
|
|
||||||
infos.add(info);
|
|
||||||
}
|
|
||||||
SubscriptionUtil.setActiveSubscriptionsForTesting(infos);
|
|
||||||
return infos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to set the signal strength returned for a mock subscription
|
|
||||||
* @param subs The list of subscriptions
|
|
||||||
* @param index The index in of the subscription in |subs| to change
|
|
||||||
* @param level The signal strength level to return for the subscription. Pass -1 to force
|
|
||||||
* return of a null SignalStrength object for the subscription.
|
|
||||||
*/
|
|
||||||
private void setMockSubSignalStrength(List<SubscriptionInfo> subs, int index, int level) {
|
|
||||||
final TelephonyManager mgrForSub =
|
|
||||||
mTelephonyManager.createForSubscriptionId(subs.get(index).getSubscriptionId());
|
|
||||||
if (level == -1) {
|
|
||||||
when(mgrForSub.getSignalStrength()).thenReturn(null);
|
|
||||||
} else {
|
|
||||||
final SignalStrength signalStrength = mgrForSub.getSignalStrength();
|
|
||||||
when(signalStrength.getLevel()).thenReturn(level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setMockSubDataEnabled(List<SubscriptionInfo> subs, int index, boolean enabled) {
|
|
||||||
final TelephonyManager mgrForSub =
|
|
||||||
mTelephonyManager.createForSubscriptionId(subs.get(index).getSubscriptionId());
|
|
||||||
when(mgrForSub.isDataEnabled()).thenReturn(enabled);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,649 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.settings.network;
|
||||||
|
|
||||||
|
import static android.telephony.SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
|
||||||
|
import static android.telephony.SignalStrength.SIGNAL_STRENGTH_GOOD;
|
||||||
|
import static android.telephony.SignalStrength.SIGNAL_STRENGTH_GREAT;
|
||||||
|
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.Network;
|
||||||
|
import android.net.NetworkCapabilities;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.telephony.ServiceState;
|
||||||
|
import android.telephony.SignalStrength;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
import androidx.lifecycle.LifecycleRegistry;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceCategory;
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
import androidx.test.annotation.UiThreadTest;
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
|
||||||
|
import com.android.settings.Utils;
|
||||||
|
import com.android.settings.network.SubscriptionsPreferenceController.SubsPrefCtrlInjector;
|
||||||
|
import com.android.settings.testutils.ResourcesUtils;
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class SubscriptionsPreferenceControllerTest {
|
||||||
|
private static final String KEY = "preference_group";
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private SubscriptionManager mSubscriptionManager;
|
||||||
|
@Mock
|
||||||
|
private ConnectivityManager mConnectivityManager;
|
||||||
|
@Mock
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
@Mock
|
||||||
|
private TelephonyManager mTelephonyManagerForSub;
|
||||||
|
@Mock
|
||||||
|
private Network mActiveNetwork;
|
||||||
|
@Mock
|
||||||
|
private Lifecycle mLifecycle;
|
||||||
|
@Mock
|
||||||
|
private LifecycleOwner mLifecycleOwner;
|
||||||
|
private LifecycleRegistry mLifecycleRegistry;
|
||||||
|
private int mOnChildUpdatedCount;
|
||||||
|
private Context mContext;
|
||||||
|
private SubscriptionsPreferenceController.UpdateListener mUpdateListener;
|
||||||
|
private PreferenceCategory mPreferenceCategory;
|
||||||
|
private PreferenceScreen mPreferenceScreen;
|
||||||
|
private PreferenceManager mPreferenceManager;
|
||||||
|
private NetworkCapabilities mNetworkCapabilities;
|
||||||
|
|
||||||
|
private FakeSubscriptionsPreferenceController mController;
|
||||||
|
private static SubsPrefCtrlInjector sInjector;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||||
|
if (Looper.myLooper() == null) {
|
||||||
|
Looper.prepare();
|
||||||
|
}
|
||||||
|
mLifecycleRegistry = new LifecycleRegistry(mLifecycleOwner);
|
||||||
|
|
||||||
|
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
|
||||||
|
when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
|
||||||
|
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
||||||
|
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
|
||||||
|
when(mConnectivityManager.getActiveNetwork()).thenReturn(mActiveNetwork);
|
||||||
|
when(mConnectivityManager.getNetworkCapabilities(mActiveNetwork))
|
||||||
|
.thenReturn(mNetworkCapabilities);
|
||||||
|
when(mLifecycleOwner.getLifecycle()).thenReturn(mLifecycleRegistry);
|
||||||
|
|
||||||
|
mPreferenceManager = new PreferenceManager(mContext);
|
||||||
|
mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
|
||||||
|
mPreferenceScreen.setInitialExpandedChildrenCount(3);
|
||||||
|
mPreferenceCategory = new PreferenceCategory(mContext);
|
||||||
|
mPreferenceCategory.setKey(KEY);
|
||||||
|
mPreferenceCategory.setOrderingAsAdded(true);
|
||||||
|
mPreferenceScreen.addPreference(mPreferenceCategory);
|
||||||
|
|
||||||
|
mOnChildUpdatedCount = 0;
|
||||||
|
mUpdateListener = () -> mOnChildUpdatedCount++;
|
||||||
|
sInjector = spy(new SubsPrefCtrlInjector());
|
||||||
|
initializeMethod(true, 1, 1, 1, false, false);
|
||||||
|
mController = new FakeSubscriptionsPreferenceController(mContext, mLifecycle,
|
||||||
|
mUpdateListener, KEY, 5);
|
||||||
|
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
SubscriptionUtil.setActiveSubscriptionsForTesting(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isAvailable_oneSubscription_availableFalse() {
|
||||||
|
setupMockSubscriptions(1);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isAvailable_oneSubAndProviderOn_availableTrue() {
|
||||||
|
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
setupMockSubscriptions(1);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isAvailable_twoSubscriptions_availableTrue() {
|
||||||
|
setupMockSubscriptions(2);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isAvailable_fiveSubscriptions_availableTrue() {
|
||||||
|
doReturn(true).when(sInjector).canSubscriptionBeDisplayed(mContext, 0);
|
||||||
|
setupMockSubscriptions(5);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isAvailable_airplaneModeOn_availableFalse() {
|
||||||
|
setupMockSubscriptions(2);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
|
||||||
|
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void onAirplaneModeChanged_airplaneModeTurnedOn_eventFired() {
|
||||||
|
setupMockSubscriptions(2);
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
|
||||||
|
final int updateCountBeforeModeChange = mOnChildUpdatedCount;
|
||||||
|
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
|
||||||
|
|
||||||
|
mController.onAirplaneModeChanged(true);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isFalse();
|
||||||
|
assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeModeChange + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void onAirplaneModeChanged_airplaneModeTurnedOff_eventFired() {
|
||||||
|
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
|
||||||
|
setupMockSubscriptions(2);
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
assertThat(mController.isAvailable()).isFalse();
|
||||||
|
|
||||||
|
final int updateCountBeforeModeChange = mOnChildUpdatedCount;
|
||||||
|
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
|
||||||
|
|
||||||
|
mController.onAirplaneModeChanged(true);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeModeChange + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void onSubscriptionsChanged_countBecameTwo_eventFired() {
|
||||||
|
final List<SubscriptionInfo> subs = setupMockSubscriptions(2);
|
||||||
|
SubscriptionUtil.setActiveSubscriptionsForTesting(subs.subList(0, 1));
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isFalse();
|
||||||
|
|
||||||
|
final int updateCountBeforeSubscriptionChange = mOnChildUpdatedCount;
|
||||||
|
SubscriptionUtil.setActiveSubscriptionsForTesting(subs);
|
||||||
|
|
||||||
|
mController.onSubscriptionsChanged();
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeSubscriptionChange + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void onSubscriptionsChanged_countBecameOne_eventFiredAndPrefsRemoved() {
|
||||||
|
final List<SubscriptionInfo> subs = setupMockSubscriptions(2);
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2);
|
||||||
|
|
||||||
|
final int updateCountBeforeSubscriptionChange = mOnChildUpdatedCount;
|
||||||
|
SubscriptionUtil.setActiveSubscriptionsForTesting(subs.subList(0, 1));
|
||||||
|
|
||||||
|
mController.onSubscriptionsChanged();
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isFalse();
|
||||||
|
assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeSubscriptionChange + 1);
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void onSubscriptionsChanged_subscriptionReplaced_preferencesChanged() {
|
||||||
|
final List<SubscriptionInfo> subs = setupMockSubscriptions(3);
|
||||||
|
|
||||||
|
// Start out with only sub1 and sub2.
|
||||||
|
SubscriptionUtil.setActiveSubscriptionsForTesting(subs.subList(0, 2));
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2);
|
||||||
|
assertThat(mPreferenceCategory.getPreference(0).getTitle()).isEqualTo("sub2");
|
||||||
|
assertThat(mPreferenceCategory.getPreference(1).getTitle()).isEqualTo("sub1");
|
||||||
|
|
||||||
|
// Now replace sub2 with sub3, and make sure the old preference was removed and the new
|
||||||
|
// preference was added.
|
||||||
|
final int updateCountBeforeSubscriptionChange = mOnChildUpdatedCount;
|
||||||
|
SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(subs.get(0), subs.get(2)));
|
||||||
|
mController.onSubscriptionsChanged();
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
assertThat(mOnChildUpdatedCount).isEqualTo(updateCountBeforeSubscriptionChange + 1);
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2);
|
||||||
|
assertThat(mPreferenceCategory.getPreference(0).getTitle()).isEqualTo("sub3");
|
||||||
|
assertThat(mPreferenceCategory.getPreference(1).getTitle()).isEqualTo("sub1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSummary_twoSubsOneDefaultForEverythingDataActive() {
|
||||||
|
setupMockSubscriptions(2);
|
||||||
|
|
||||||
|
doReturn(11).when(sInjector).getDefaultSmsSubscriptionId();
|
||||||
|
doReturn(11).when(sInjector).getDefaultVoiceSubscriptionId();
|
||||||
|
when(mTelephonyManager.isDataEnabled()).thenReturn(true);
|
||||||
|
doReturn(true).when(sInjector).isActiveCellularNetwork(mContext);
|
||||||
|
|
||||||
|
assertThat(mController.getSummary(11, true)).isEqualTo(
|
||||||
|
ResourcesUtils.getResourcesString(mContext, "default_for_calls_and_sms")
|
||||||
|
+ System.lineSeparator()
|
||||||
|
+ ResourcesUtils.getResourcesString(mContext, "mobile_data_active"));
|
||||||
|
|
||||||
|
assertThat(mController.getSummary(22, false)).isEqualTo(
|
||||||
|
ResourcesUtils.getResourcesString(mContext, "subscription_available"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSummary_twoSubsOneDefaultForEverythingDataNotActive() {
|
||||||
|
setupMockSubscriptions(2, 1, true);
|
||||||
|
|
||||||
|
doReturn(1).when(sInjector).getDefaultSmsSubscriptionId();
|
||||||
|
doReturn(1).when(sInjector).getDefaultVoiceSubscriptionId();
|
||||||
|
|
||||||
|
assertThat(mController.getSummary(1, true)).isEqualTo(
|
||||||
|
ResourcesUtils.getResourcesString(mContext, "default_for_calls_and_sms")
|
||||||
|
+ System.lineSeparator()
|
||||||
|
+ ResourcesUtils.getResourcesString(mContext, "default_for_mobile_data"));
|
||||||
|
|
||||||
|
assertThat(mController.getSummary(2, false)).isEqualTo(
|
||||||
|
ResourcesUtils.getResourcesString(mContext, "subscription_available"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSummary_twoSubsOneDefaultForEverythingDataDisabled() {
|
||||||
|
setupMockSubscriptions(2);
|
||||||
|
|
||||||
|
doReturn(1).when(sInjector).getDefaultSmsSubscriptionId();
|
||||||
|
doReturn(1).when(sInjector).getDefaultVoiceSubscriptionId();
|
||||||
|
|
||||||
|
assertThat(mController.getSummary(1, true)).isEqualTo(
|
||||||
|
ResourcesUtils.getResourcesString(mContext, "default_for_calls_and_sms")
|
||||||
|
+ System.lineSeparator()
|
||||||
|
+ ResourcesUtils.getResourcesString(mContext, "mobile_data_off"));
|
||||||
|
|
||||||
|
assertThat(mController.getSummary(2, false)).isEqualTo(
|
||||||
|
ResourcesUtils.getResourcesString(mContext, "subscription_available"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSummary_twoSubsOneForCallsAndDataOneForSms() {
|
||||||
|
setupMockSubscriptions(2, 1, true);
|
||||||
|
|
||||||
|
doReturn(2).when(sInjector).getDefaultSmsSubscriptionId();
|
||||||
|
doReturn(1).when(sInjector).getDefaultVoiceSubscriptionId();
|
||||||
|
|
||||||
|
assertThat(mController.getSummary(1, true)).isEqualTo(
|
||||||
|
ResourcesUtils.getResourcesString(mContext, "default_for_calls")
|
||||||
|
+ System.lineSeparator()
|
||||||
|
+ ResourcesUtils.getResourcesString(mContext, "default_for_mobile_data"));
|
||||||
|
|
||||||
|
assertThat(mController.getSummary(2, false)).isEqualTo(
|
||||||
|
ResourcesUtils.getResourcesString(mContext, "default_for_sms"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void setIcon_greatSignal_correctLevels() {
|
||||||
|
final List<SubscriptionInfo> subs = setupMockSubscriptions(2, 1, true);
|
||||||
|
setMockSubSignalStrength(subs, 0, SIGNAL_STRENGTH_GREAT);
|
||||||
|
setMockSubSignalStrength(subs, 1, SIGNAL_STRENGTH_GREAT);
|
||||||
|
final Preference pref = new Preference(mContext);
|
||||||
|
final Drawable greatDrawWithoutCutOff = mock(Drawable.class);
|
||||||
|
doReturn(greatDrawWithoutCutOff).when(sInjector)
|
||||||
|
.getIcon(mContext, 4, NUM_SIGNAL_STRENGTH_BINS, true);
|
||||||
|
|
||||||
|
mController.setIcon(pref, 1, true /* isDefaultForData */);
|
||||||
|
assertThat(pref.getIcon()).isEqualTo(greatDrawWithoutCutOff);
|
||||||
|
|
||||||
|
final Drawable greatDrawWithCutOff = mock(Drawable.class);
|
||||||
|
doReturn(greatDrawWithCutOff).when(sInjector)
|
||||||
|
.getIcon(mContext, 4, NUM_SIGNAL_STRENGTH_BINS, true);
|
||||||
|
mController.setIcon(pref, 2, false /* isDefaultForData */);
|
||||||
|
assertThat(pref.getIcon()).isEqualTo(greatDrawWithCutOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void displayPreference_providerAndHasSim_showPreference() {
|
||||||
|
final List<SubscriptionInfo> sub = setupMockSubscriptions(1);
|
||||||
|
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(1);
|
||||||
|
assertThat(mPreferenceCategory.getPreference(0).getTitle()).isEqualTo("sub1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void displayPreference_providerAndHasMultiSim_showDataSubPreference() {
|
||||||
|
final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
|
||||||
|
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(1);
|
||||||
|
assertThat(mPreferenceCategory.getPreference(0).getTitle()).isEqualTo("sub1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void displayPreference_providerAndNoSim_noPreference() {
|
||||||
|
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
doReturn(null).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void onAirplaneModeChanged_providerAndHasSim_noPreference() {
|
||||||
|
setupMockSubscriptions(1);
|
||||||
|
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
|
||||||
|
|
||||||
|
mController.onAirplaneModeChanged(true);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isFalse();
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void dataSubscriptionChanged_providerAndHasMultiSim_showSubId1Preference() {
|
||||||
|
final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
|
||||||
|
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
Intent intent = new Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
mController.mDataSubscriptionChangedReceiver.onReceive(mContext, intent);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(1);
|
||||||
|
assertThat(mPreferenceCategory.getPreference(0).getTitle()).isEqualTo("sub1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void dataSubscriptionChanged_providerAndHasMultiSim_showSubId2Preference() {
|
||||||
|
final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
|
||||||
|
final int subId = sub.get(0).getSubscriptionId();
|
||||||
|
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
Intent intent = new Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(1);
|
||||||
|
assertThat(mPreferenceCategory.getPreference(0).getTitle()).isEqualTo("sub1");
|
||||||
|
|
||||||
|
doReturn(sub.get(1)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
|
||||||
|
mController.mDataSubscriptionChangedReceiver.onReceive(mContext, intent);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(1);
|
||||||
|
assertThat(mPreferenceCategory.getPreference(0).getTitle()).isEqualTo("sub2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void getIcon_cellularIsActive_iconColorIsAccentDefaultColor() {
|
||||||
|
final List<SubscriptionInfo> sub = setupMockSubscriptions(1);
|
||||||
|
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
Drawable icon = mock(Drawable.class);
|
||||||
|
doReturn(icon).when(sInjector).getIcon(any(), anyInt(), anyInt(), eq(false));
|
||||||
|
setupGetIconConditions(sub.get(0).getSubscriptionId(), true, true,
|
||||||
|
TelephonyManager.DATA_CONNECTED, ServiceState.STATE_IN_SERVICE);
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
|
||||||
|
verify(icon).setTint(Utils.getColorAccentDefaultColor(mContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void getIcon_dataStateConnectedAndMobileDataOn_iconIsSignalIcon() {
|
||||||
|
final List<SubscriptionInfo> subs = setupMockSubscriptions(1);
|
||||||
|
final int subId = subs.get(0).getSubscriptionId();
|
||||||
|
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
doReturn(subs.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
Drawable icon = mock(Drawable.class);
|
||||||
|
doReturn(icon).when(sInjector).getIcon(any(), anyInt(), anyInt(), eq(false));
|
||||||
|
setupGetIconConditions(subId, false, true,
|
||||||
|
TelephonyManager.DATA_CONNECTED, ServiceState.STATE_IN_SERVICE);
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
Drawable actualIcon = mPreferenceCategory.getPreference(0).getIcon();
|
||||||
|
|
||||||
|
assertThat(icon).isEqualTo(actualIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@UiThreadTest
|
||||||
|
public void getIcon_voiceInServiceAndMobileDataOff_iconIsSignalIcon() {
|
||||||
|
final List<SubscriptionInfo> subs = setupMockSubscriptions(1);
|
||||||
|
final int subId = subs.get(0).getSubscriptionId();
|
||||||
|
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
doReturn(subs.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
Drawable icon = mock(Drawable.class);
|
||||||
|
doReturn(icon).when(sInjector).getIcon(any(), anyInt(), anyInt(), eq(false));
|
||||||
|
|
||||||
|
setupGetIconConditions(subId, false, false,
|
||||||
|
TelephonyManager.DATA_DISCONNECTED, ServiceState.STATE_IN_SERVICE);
|
||||||
|
|
||||||
|
mController.onResume();
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
Drawable actualIcon = mPreferenceCategory.getPreference(0).getIcon();
|
||||||
|
doReturn(TelephonyManager.DATA_CONNECTED).when(mTelephonyManagerForSub).getDataState();
|
||||||
|
|
||||||
|
assertThat(icon).isEqualTo(actualIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupGetIconConditions(int subId, boolean isActiveCellularNetwork,
|
||||||
|
boolean isDataEnable, int dataState, int servicestate) {
|
||||||
|
doReturn(mTelephonyManagerForSub).when(mTelephonyManager).createForSubscriptionId(subId);
|
||||||
|
doReturn(isActiveCellularNetwork).when(sInjector).isActiveCellularNetwork(mContext);
|
||||||
|
doReturn(isDataEnable).when(mTelephonyManagerForSub).isDataEnabled();
|
||||||
|
doReturn(dataState).when(mTelephonyManagerForSub).getDataState();
|
||||||
|
ServiceState ss = mock(ServiceState.class);
|
||||||
|
doReturn(ss).when(mTelephonyManagerForSub).getServiceState();
|
||||||
|
doReturn(servicestate).when(ss).getState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<SubscriptionInfo> setupMockSubscriptions(int count) {
|
||||||
|
return setupMockSubscriptions(count, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Helper method to setup several mock active subscriptions. The generated subscription id's
|
||||||
|
* start at 1.
|
||||||
|
*
|
||||||
|
* @param count How many subscriptions to create
|
||||||
|
* @param defaultDataSubId The subscription id of the default data subscription - pass
|
||||||
|
* INVALID_SUBSCRIPTION_ID if there should not be one
|
||||||
|
* @param mobileDataEnabled Whether mobile data should be considered enabled for the default
|
||||||
|
* data subscription
|
||||||
|
*/
|
||||||
|
private List<SubscriptionInfo> setupMockSubscriptions(int count, int defaultDataSubId,
|
||||||
|
boolean mobileDataEnabled) {
|
||||||
|
if (defaultDataSubId != INVALID_SUBSCRIPTION_ID) {
|
||||||
|
when(sInjector.getDefaultDataSubscriptionId()).thenReturn(defaultDataSubId);
|
||||||
|
}
|
||||||
|
final ArrayList<SubscriptionInfo> infos = new ArrayList<>();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
final int subscriptionId = i + 1;
|
||||||
|
final SubscriptionInfo info = mock(SubscriptionInfo.class);
|
||||||
|
final TelephonyManager mgrForSub = mock(TelephonyManager.class);
|
||||||
|
final SignalStrength signalStrength = mock(SignalStrength.class);
|
||||||
|
|
||||||
|
if (subscriptionId == defaultDataSubId) {
|
||||||
|
when(mgrForSub.isDataEnabled()).thenReturn(mobileDataEnabled);
|
||||||
|
}
|
||||||
|
when(info.getSubscriptionId()).thenReturn(subscriptionId);
|
||||||
|
when(info.getDisplayName()).thenReturn("sub" + (subscriptionId));
|
||||||
|
doReturn(mgrForSub).when(mTelephonyManager).createForSubscriptionId(eq(subscriptionId));
|
||||||
|
when(mgrForSub.getSignalStrength()).thenReturn(signalStrength);
|
||||||
|
when(signalStrength.getLevel()).thenReturn(SIGNAL_STRENGTH_GOOD);
|
||||||
|
doReturn(true).when(sInjector).canSubscriptionBeDisplayed(mContext, subscriptionId);
|
||||||
|
infos.add(info);
|
||||||
|
}
|
||||||
|
SubscriptionUtil.setActiveSubscriptionsForTesting(infos);
|
||||||
|
return infos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to set the signal strength returned for a mock subscription
|
||||||
|
* @param subs The list of subscriptions
|
||||||
|
* @param index The index in of the subscription in |subs| to change
|
||||||
|
* @param level The signal strength level to return for the subscription. Pass -1 to force
|
||||||
|
* return of a null SignalStrength object for the subscription.
|
||||||
|
*/
|
||||||
|
private void setMockSubSignalStrength(List<SubscriptionInfo> subs, int index, int level) {
|
||||||
|
final int subId = subs.get(index).getSubscriptionId();
|
||||||
|
doReturn(mTelephonyManagerForSub).when(mTelephonyManager).createForSubscriptionId(subId);
|
||||||
|
if (level == -1) {
|
||||||
|
when(mTelephonyManagerForSub.getSignalStrength()).thenReturn(null);
|
||||||
|
} else {
|
||||||
|
final SignalStrength signalStrength = mock(SignalStrength.class);
|
||||||
|
doReturn(signalStrength).when(mTelephonyManagerForSub).getSignalStrength();
|
||||||
|
when(signalStrength.getLevel()).thenReturn(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeMethod(boolean isSubscriptionCanBeDisplayed,
|
||||||
|
int defaultSmsSubscriptionId, int defaultVoiceSubscriptionId,
|
||||||
|
int defaultDataSubscriptionId, boolean isActiveCellularNetwork,
|
||||||
|
boolean isProviderModelEnabled) {
|
||||||
|
doReturn(isSubscriptionCanBeDisplayed)
|
||||||
|
.when(sInjector).canSubscriptionBeDisplayed(mContext, eq(anyInt()));
|
||||||
|
doReturn(defaultSmsSubscriptionId).when(sInjector).getDefaultSmsSubscriptionId();
|
||||||
|
doReturn(defaultVoiceSubscriptionId).when(sInjector).getDefaultVoiceSubscriptionId();
|
||||||
|
doReturn(defaultDataSubscriptionId).when(sInjector).getDefaultDataSubscriptionId();
|
||||||
|
doReturn(isActiveCellularNetwork).when(sInjector).isActiveCellularNetwork(mContext);
|
||||||
|
doReturn(isProviderModelEnabled).when(sInjector).isProviderModelEnabled(mContext);
|
||||||
|
doReturn(mock(Drawable.class))
|
||||||
|
.when(sInjector).getIcon(any(), anyInt(), anyInt(), eq(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FakeSubscriptionsPreferenceController
|
||||||
|
extends SubscriptionsPreferenceController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context the context for the UI where we're placing these preferences
|
||||||
|
* @param lifecycle for listening to lifecycle events for the UI
|
||||||
|
* @param updateListener called to let our parent controller know that our
|
||||||
|
* availability has
|
||||||
|
* changed, or that one or more of the preferences we've placed
|
||||||
|
* in the
|
||||||
|
* PreferenceGroup has changed
|
||||||
|
* @param preferenceGroupKey the key used to lookup the PreferenceGroup where Preferences
|
||||||
|
* will
|
||||||
|
* be placed
|
||||||
|
* @param startOrder the order that should be given to the first Preference
|
||||||
|
* placed into
|
||||||
|
* the PreferenceGroup; the second will use startOrder+1, third
|
||||||
|
* will
|
||||||
|
* use startOrder+2, etc. - this is useful for when the parent
|
||||||
|
* wants
|
||||||
|
* to have other preferences in the same PreferenceGroup and wants
|
||||||
|
*/
|
||||||
|
FakeSubscriptionsPreferenceController(Context context, Lifecycle lifecycle,
|
||||||
|
UpdateListener updateListener, String preferenceGroupKey, int startOrder) {
|
||||||
|
super(context, lifecycle, updateListener, preferenceGroupKey, startOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SubsPrefCtrlInjector createSubsPrefCtrlInjector() {
|
||||||
|
return sInjector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user