Loading src/com/android/settings/network/SubscriptionsPreferenceController.java +218 −27 Original line number Diff line number Diff line Loading @@ -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 android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.drawable.Drawable; import android.provider.Settings; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; Loading @@ -46,6 +49,7 @@ import com.android.settings.network.telephony.DataConnectivityListener; import com.android.settings.network.telephony.MobileNetworkActivity; import com.android.settings.network.telephony.MobileNetworkUtils; import com.android.settings.network.telephony.SignalStrengthListener; import com.android.settings.widget.GearPreference; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.net.SignalStrengthUtil; Loading @@ -55,9 +59,15 @@ import java.util.Map; 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 * 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 LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient, Loading @@ -68,16 +78,30 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl private UpdateListener mUpdateListener; private String mPreferenceGroupKey; private PreferenceGroup mPreferenceGroup; private SubscriptionManager mManager; private TelephonyManager mTelephonyManager; private SubscriptionManager mSubscriptionManager; private SubscriptionsChangeListener mSubscriptionsListener; private MobileDataEnabledListener mDataEnabledListener; private DataConnectivityListener mConnectivityListener; 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 private Map<Integer, Preference> mSubscriptionPreferences; private int mStartOrder; private GearPreference mSubsGearPref; private SubsPrefCtrlInjector mSubsPrefCtrlInjector; /** * 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 Loading Loading @@ -107,21 +131,37 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl mUpdateListener = updateListener; mPreferenceGroupKey = preferenceGroupKey; mStartOrder = startOrder; mManager = context.getSystemService(SubscriptionManager.class); mTelephonyManager = context.getSystemService(TelephonyManager.class); mSubscriptionManager = context.getSystemService(SubscriptionManager.class); mSubscriptionPreferences = new ArrayMap<>(); mSubscriptionsListener = new SubscriptionsChangeListener(context, this); mDataEnabledListener = new MobileDataEnabledListener(context, this); mConnectivityListener = new DataConnectivityListener(context, this); mSignalStrengthListener = new SignalStrengthListener(context, 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) public void onResume() { mSubscriptionsListener.start(); mDataEnabledListener.start(SubscriptionManager.getDefaultDataSubscriptionId()); mDataEnabledListener.start(mSubsPrefCtrlInjector.getDefaultDataSubscriptionId()); mConnectivityListener.start(); mSignalStrengthListener.resume(); registerDataSubscriptionChangedReceiver(); update(); } Loading @@ -131,6 +171,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl mDataEnabledListener.stop(); mConnectivityListener.stop(); mSignalStrengthListener.pause(); unRegisterDataSubscriptionChangedReceiver(); } @Override Loading @@ -143,29 +184,116 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl if (mPreferenceGroup == null) { return; } if (!isAvailable()) { if (mSubsGearPref != null) { mPreferenceGroup.removePreference(mSubsGearPref); } for (Preference pref : mSubscriptionPreferences.values()) { mPreferenceGroup.removePreference(pref); } mSubscriptionPreferences.clear(); mSignalStrengthListener.updateSubscriptionIds(Collections.emptySet()); mUpdateListener.onChildrenUpdated(); 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; mSubscriptionPreferences = new ArrayMap<>(); int order = mStartOrder; final Set<Integer> activeSubIds = new ArraySet<>(); final int dataDefaultSubId = SubscriptionManager.getDefaultDataSubscriptionId(); for (SubscriptionInfo info : SubscriptionUtil.getActiveSubscriptions(mManager)) { final int dataDefaultSubId = mSubsPrefCtrlInjector.getDefaultDataSubscriptionId(); for (SubscriptionInfo info : SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager)) { final int subId = info.getSubscriptionId(); // Avoid from showing subscription(SIM)s which has been marked as hidden // For example, only one subscription will be shown when there're multiple // subscriptions with same group UUID. if (!canSubscriptionBeDisplayed(mContext, subId)) { if (!mSubsPrefCtrlInjector.canSubscriptionBeDisplayed(mContext, subId)) { continue; } activeSubIds.add(subId); Loading @@ -181,9 +309,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl pref.setOrder(order++); pref.setOnPreferenceClickListener(clickedPref -> { final Intent intent = new Intent(mContext, MobileNetworkActivity.class); intent.putExtra(Settings.EXTRA_SUB_ID, subId); mContext.startActivity(intent); startMobileNetworkActivity(mContext, subId); return true; }); Loading @@ -198,6 +324,12 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl 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 boolean shouldInflateSignalStrength(int subId) { return SignalStrengthUtil.shouldInflateSignalStrength(mContext, subId); Loading @@ -214,14 +346,9 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl level += 1; numLevels += 1; } final boolean showCutOut = !isDefaultForData || !mgr.isDataEnabled(); pref.setIcon(getIcon(level, numLevels, showCutOut)); } @VisibleForTesting Drawable getIcon(int level, int numLevels, boolean cutOut) { return MobileNetworkUtils.getSignalStrengthIcon(mContext, level, numLevels, NO_CELL_DATA_TYPE_ICON, cutOut); final boolean showCutOut = !isDefaultForData || !mgr.isDataEnabled(); pref.setIcon(mSubsPrefCtrlInjector.getIcon(mContext, level, numLevels, showCutOut)); } /** Loading @@ -236,8 +363,8 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl * If a subscription isn't the default for anything, we just say it is available. */ protected String getSummary(int subId, boolean isDefaultForData) { final int callsDefaultSubId = SubscriptionManager.getDefaultVoiceSubscriptionId(); final int smsDefaultSubId = SubscriptionManager.getDefaultSmsSubscriptionId(); final int callsDefaultSubId = mSubsPrefCtrlInjector.getDefaultVoiceSubscriptionId(); final int smsDefaultSubId = mSubsPrefCtrlInjector.getDefaultSmsSubscriptionId(); String line1 = null; if (subId == callsDefaultSubId && subId == smsDefaultSubId) { Loading @@ -253,7 +380,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl final TelephonyManager telMgrForSub = mContext.getSystemService( TelephonyManager.class).createForSubscriptionId(subId); final boolean dataEnabled = telMgrForSub.isDataEnabled(); if (dataEnabled && MobileNetworkUtils.activeNetworkIsCellular(mContext)) { if (dataEnabled && mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext)) { line2 = mContext.getString(R.string.mobile_data_active); } else if (!dataEnabled) { line2 = mContext.getString(R.string.mobile_data_off); Loading @@ -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 public boolean isAvailable() { if (mSubscriptionsListener.isAirplaneModeOn()) { return false; } List<SubscriptionInfo> subInfoList = SubscriptionUtil.getActiveSubscriptions(mManager); List<SubscriptionInfo> subInfoList = SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager); if (subInfoList == null) { return false; } Loading @@ -290,8 +419,9 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl // For example, only one subscription will be shown when there're multiple // subscriptions with same group UUID. .filter(subInfo -> canSubscriptionBeDisplayed(mContext, subInfo.getSubscriptionId())) .count() >= (Utils.isProviderModelEnabled(mContext) ? 1 : 2); mSubsPrefCtrlInjector.canSubscriptionBeDisplayed(mContext, subInfo.getSubscriptionId())) .count() >= (mSubsPrefCtrlInjector.isProviderModelEnabled(mContext) ? 1 : 2); } @Override Loading @@ -307,7 +437,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl @Override public void onSubscriptionsChanged() { // 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()) { mDataEnabledListener.stop(); mDataEnabledListener.start(defaultDataSubId); Loading Loading @@ -335,4 +465,65 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl return (SubscriptionUtil.getAvailableSubscription(context, 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); } } } No newline at end of file tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java→tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java +649 −0 File changed and moved.Preview size limit exceeded, changes collapsed. Show changes Loading
src/com/android/settings/network/SubscriptionsPreferenceController.java +218 −27 Original line number Diff line number Diff line Loading @@ -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 android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.drawable.Drawable; import android.provider.Settings; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; Loading @@ -46,6 +49,7 @@ import com.android.settings.network.telephony.DataConnectivityListener; import com.android.settings.network.telephony.MobileNetworkActivity; import com.android.settings.network.telephony.MobileNetworkUtils; import com.android.settings.network.telephony.SignalStrengthListener; import com.android.settings.widget.GearPreference; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.net.SignalStrengthUtil; Loading @@ -55,9 +59,15 @@ import java.util.Map; 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 * 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 LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient, Loading @@ -68,16 +78,30 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl private UpdateListener mUpdateListener; private String mPreferenceGroupKey; private PreferenceGroup mPreferenceGroup; private SubscriptionManager mManager; private TelephonyManager mTelephonyManager; private SubscriptionManager mSubscriptionManager; private SubscriptionsChangeListener mSubscriptionsListener; private MobileDataEnabledListener mDataEnabledListener; private DataConnectivityListener mConnectivityListener; 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 private Map<Integer, Preference> mSubscriptionPreferences; private int mStartOrder; private GearPreference mSubsGearPref; private SubsPrefCtrlInjector mSubsPrefCtrlInjector; /** * 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 Loading Loading @@ -107,21 +131,37 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl mUpdateListener = updateListener; mPreferenceGroupKey = preferenceGroupKey; mStartOrder = startOrder; mManager = context.getSystemService(SubscriptionManager.class); mTelephonyManager = context.getSystemService(TelephonyManager.class); mSubscriptionManager = context.getSystemService(SubscriptionManager.class); mSubscriptionPreferences = new ArrayMap<>(); mSubscriptionsListener = new SubscriptionsChangeListener(context, this); mDataEnabledListener = new MobileDataEnabledListener(context, this); mConnectivityListener = new DataConnectivityListener(context, this); mSignalStrengthListener = new SignalStrengthListener(context, 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) public void onResume() { mSubscriptionsListener.start(); mDataEnabledListener.start(SubscriptionManager.getDefaultDataSubscriptionId()); mDataEnabledListener.start(mSubsPrefCtrlInjector.getDefaultDataSubscriptionId()); mConnectivityListener.start(); mSignalStrengthListener.resume(); registerDataSubscriptionChangedReceiver(); update(); } Loading @@ -131,6 +171,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl mDataEnabledListener.stop(); mConnectivityListener.stop(); mSignalStrengthListener.pause(); unRegisterDataSubscriptionChangedReceiver(); } @Override Loading @@ -143,29 +184,116 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl if (mPreferenceGroup == null) { return; } if (!isAvailable()) { if (mSubsGearPref != null) { mPreferenceGroup.removePreference(mSubsGearPref); } for (Preference pref : mSubscriptionPreferences.values()) { mPreferenceGroup.removePreference(pref); } mSubscriptionPreferences.clear(); mSignalStrengthListener.updateSubscriptionIds(Collections.emptySet()); mUpdateListener.onChildrenUpdated(); 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; mSubscriptionPreferences = new ArrayMap<>(); int order = mStartOrder; final Set<Integer> activeSubIds = new ArraySet<>(); final int dataDefaultSubId = SubscriptionManager.getDefaultDataSubscriptionId(); for (SubscriptionInfo info : SubscriptionUtil.getActiveSubscriptions(mManager)) { final int dataDefaultSubId = mSubsPrefCtrlInjector.getDefaultDataSubscriptionId(); for (SubscriptionInfo info : SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager)) { final int subId = info.getSubscriptionId(); // Avoid from showing subscription(SIM)s which has been marked as hidden // For example, only one subscription will be shown when there're multiple // subscriptions with same group UUID. if (!canSubscriptionBeDisplayed(mContext, subId)) { if (!mSubsPrefCtrlInjector.canSubscriptionBeDisplayed(mContext, subId)) { continue; } activeSubIds.add(subId); Loading @@ -181,9 +309,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl pref.setOrder(order++); pref.setOnPreferenceClickListener(clickedPref -> { final Intent intent = new Intent(mContext, MobileNetworkActivity.class); intent.putExtra(Settings.EXTRA_SUB_ID, subId); mContext.startActivity(intent); startMobileNetworkActivity(mContext, subId); return true; }); Loading @@ -198,6 +324,12 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl 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 boolean shouldInflateSignalStrength(int subId) { return SignalStrengthUtil.shouldInflateSignalStrength(mContext, subId); Loading @@ -214,14 +346,9 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl level += 1; numLevels += 1; } final boolean showCutOut = !isDefaultForData || !mgr.isDataEnabled(); pref.setIcon(getIcon(level, numLevels, showCutOut)); } @VisibleForTesting Drawable getIcon(int level, int numLevels, boolean cutOut) { return MobileNetworkUtils.getSignalStrengthIcon(mContext, level, numLevels, NO_CELL_DATA_TYPE_ICON, cutOut); final boolean showCutOut = !isDefaultForData || !mgr.isDataEnabled(); pref.setIcon(mSubsPrefCtrlInjector.getIcon(mContext, level, numLevels, showCutOut)); } /** Loading @@ -236,8 +363,8 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl * If a subscription isn't the default for anything, we just say it is available. */ protected String getSummary(int subId, boolean isDefaultForData) { final int callsDefaultSubId = SubscriptionManager.getDefaultVoiceSubscriptionId(); final int smsDefaultSubId = SubscriptionManager.getDefaultSmsSubscriptionId(); final int callsDefaultSubId = mSubsPrefCtrlInjector.getDefaultVoiceSubscriptionId(); final int smsDefaultSubId = mSubsPrefCtrlInjector.getDefaultSmsSubscriptionId(); String line1 = null; if (subId == callsDefaultSubId && subId == smsDefaultSubId) { Loading @@ -253,7 +380,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl final TelephonyManager telMgrForSub = mContext.getSystemService( TelephonyManager.class).createForSubscriptionId(subId); final boolean dataEnabled = telMgrForSub.isDataEnabled(); if (dataEnabled && MobileNetworkUtils.activeNetworkIsCellular(mContext)) { if (dataEnabled && mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext)) { line2 = mContext.getString(R.string.mobile_data_active); } else if (!dataEnabled) { line2 = mContext.getString(R.string.mobile_data_off); Loading @@ -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 public boolean isAvailable() { if (mSubscriptionsListener.isAirplaneModeOn()) { return false; } List<SubscriptionInfo> subInfoList = SubscriptionUtil.getActiveSubscriptions(mManager); List<SubscriptionInfo> subInfoList = SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager); if (subInfoList == null) { return false; } Loading @@ -290,8 +419,9 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl // For example, only one subscription will be shown when there're multiple // subscriptions with same group UUID. .filter(subInfo -> canSubscriptionBeDisplayed(mContext, subInfo.getSubscriptionId())) .count() >= (Utils.isProviderModelEnabled(mContext) ? 1 : 2); mSubsPrefCtrlInjector.canSubscriptionBeDisplayed(mContext, subInfo.getSubscriptionId())) .count() >= (mSubsPrefCtrlInjector.isProviderModelEnabled(mContext) ? 1 : 2); } @Override Loading @@ -307,7 +437,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl @Override public void onSubscriptionsChanged() { // 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()) { mDataEnabledListener.stop(); mDataEnabledListener.start(defaultDataSubId); Loading Loading @@ -335,4 +465,65 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl return (SubscriptionUtil.getAvailableSubscription(context, 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); } } } No newline at end of file
tests/robotests/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java→tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java +649 −0 File changed and moved.Preview size limit exceeded, changes collapsed. Show changes