[Settings] Apply the SettingsDataService to the SIM page, roaming

controller

Implement it in 0RoamingPreferenceController
Launch MobileNetworkSettings in SettingsApp by SubSettingLauncher
Launch MobileNetworkSettings by intent

Bug: 257197354
Test: atest RoamingPreferenceControllerTest
Change-Id: Ia2df51ad3a9b2b72bdada05de480e0b05d2d4f43
This commit is contained in:
Zoey Chen
2022-11-03 08:19:00 +00:00
parent 469b708a2a
commit 7dfd3be886
4 changed files with 296 additions and 122 deletions

View File

@@ -39,6 +39,7 @@ import android.util.Log;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.mobile.dataservice.DataServiceUtils;
import com.android.settingslib.mobile.dataservice.MobileNetworkDatabase;
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoDao;
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
@@ -49,6 +50,7 @@ import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
@@ -98,21 +100,29 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
public static MobileNetworkRepository create(Context context,
MobileNetworkCallback mobileNetworkCallback) {
return new MobileNetworkRepository(context, mobileNetworkCallback);
return new MobileNetworkRepository(context, mobileNetworkCallback,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
}
private MobileNetworkRepository(Context context, MobileNetworkCallback mobileNetworkCallback) {
public static MobileNetworkRepository createBySubId(Context context,
MobileNetworkCallback mobileNetworkCallback, int subId) {
return new MobileNetworkRepository(context, mobileNetworkCallback, subId);
}
private MobileNetworkRepository(Context context, MobileNetworkCallback mobileNetworkCallback,
int subId) {
mSubId = subId;
mContext = context;
mCallback = mobileNetworkCallback;
mMobileNetworkDatabase = MobileNetworkDatabase.getInstance(context);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_CREATED);
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
mCallback = mobileNetworkCallback;
mSubscriptionInfoDao = mMobileNetworkDatabase.mSubscriptionInfoDao();
mUiccInfoDao = mMobileNetworkDatabase.mUiccInfoDao();
mMobileNetworkInfoDao = mMobileNetworkDatabase.mMobileNetworkInfoDao();
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
mAirplaneModeObserver = new AirplaneModeObserver(new Handler(Looper.getMainLooper()));
mAirplaneModeSettingUri = Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_CREATED);
mFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
}
@@ -205,6 +215,10 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
return mSubscriptionInfoDao.querySubInfoById(subId);
}
public MobileNetworkInfoEntity queryMobileNetworkInfoBySubId(String subId) {
return mMobileNetworkInfoDao.queryMobileNetworkInfoBySubId(subId);
}
public int getSubInfosCount() {
return mSubscriptionInfoDao.count();
}
@@ -222,26 +236,26 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
for (int i = 0; i < uiccSlotInfos.length; i++) {
UiccSlotInfo curSlotInfo = uiccSlotInfos[i];
if (curSlotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT) {
final int index = i;
mIsEuicc = curSlotInfo.getIsEuicc();
mCardState = curSlotInfo.getCardStateInfo();
mIsRemovable = curSlotInfo.isRemovable();
mCardId = subInfo.getCardId();
Collection<UiccPortInfo> uiccPortInfos = curSlotInfo.getPorts();
for (UiccPortInfo portInfo : uiccPortInfos) {
uiccPortInfos.forEach(portInfo -> {
if (portInfo.getPortIndex() == subInfo.getPortIndex()
&& portInfo.getLogicalSlotIndex() == subInfo.getSimSlotIndex()) {
mPhysicalSlotIndex = i;
mPhysicalSlotIndex = index;
mLogicalSlotIndex = portInfo.getLogicalSlotIndex();
mIsActive = portInfo.isActive();
mPortIndex = portInfo.getPortIndex();
break;
} else if (DEBUG) {
Log.d(TAG,
"Can not get port index and physicalSlotIndex for subId "
+ mSubId);
}
}
});
if (mPhysicalSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
break;
}
@@ -398,7 +412,8 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
MobileNetworkUtils.shouldDisplayNetworkSelectOptions(context, mSubId),
MobileNetworkUtils.isTdscdmaSupported(context, mSubId),
MobileNetworkUtils.activeNetworkIsCellular(context),
SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager)
SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager),
mTelephonyManager.isDataRoamingEnabled()
);
}
@@ -446,9 +461,10 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
}
if (!mSubscriptionInfoMap.isEmpty()) {
mSubscriptionInfoMap.forEach((key, value) -> {
deleteAllInfoBySubId(String.valueOf(key));
});
Iterator<Integer> iterator = mSubscriptionInfoMap.keySet().iterator();
while (iterator.hasNext()) {
deleteAllInfoBySubId(String.valueOf(iterator.next()));
}
}
}
}

View File

@@ -23,7 +23,6 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.UserManager;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -40,8 +39,8 @@ import com.android.settings.Settings.MobileNetworkActivity;
import com.android.settings.SettingsActivity;
import com.android.settings.datausage.BillingCyclePreferenceController;
import com.android.settings.datausage.DataUsageSummaryPreferenceController;
import com.android.settings.network.ActiveSubscriptionsListener;
import com.android.settings.network.CarrierWifiTogglePreferenceController;
import com.android.settings.network.MobileNetworkRepository;
import com.android.settings.network.SubscriptionUtil;
import com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceController;
import com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController;
@@ -50,15 +49,26 @@ import com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenc
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.wifi.WifiPickerTrackerHelper;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.mobile.dataservice.DataServiceUtils;
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
public class MobileNetworkSettings extends AbstractMobileNetworkSettings implements
MobileNetworkRepository.MobileNetworkCallback {
private static final String LOG_TAG = "NetworkSettings";
public static final int REQUEST_CODE_EXIT_ECM = 17;
@@ -66,10 +76,14 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
@VisibleForTesting
static final String KEY_CLICKED_PREF = "key_clicked_pref";
private static final String KEY_ROAMING_PREF = "button_roaming_key";
//String keys for preference lookup
private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
private static final String BUTTON_CDMA_SUBSCRIPTION_KEY = "cdma_subscription_key";
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private TelephonyManager mTelephonyManager;
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -79,9 +93,11 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
private UserManager mUserManager;
private String mClickedPrefKey;
private ActiveSubscriptionsListener mActiveSubscriptionsListener;
private boolean mDropFirstSubscriptionChangeNotify;
private int mActiveSubscriptionsListenerCount;
private MobileNetworkRepository mMobileNetworkRepository;
private List<SubscriptionInfoEntity> mSubInfoEntityList = new ArrayList<>();
private Map<Integer, SubscriptionInfoEntity> mSubscriptionInfoMap = new HashMap<>();
private SubscriptionInfoEntity mSubscriptionInfoEntity;
private MobileNetworkInfoEntity mMobileNetworkInfoEntity;
public MobileNetworkSettings() {
super(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
@@ -138,12 +154,21 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
MobileNetworkUtils.getSearchableSubscriptionId(context));
Log.d(LOG_TAG, "display subId from getArguments(): " + mSubId);
}
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
mMobileNetworkRepository = MobileNetworkRepository.create(context, this);
mExecutor.execute(() -> {
mSubscriptionInfoEntity = mMobileNetworkRepository.getSubInfoById(
String.valueOf(mSubId));
mMobileNetworkInfoEntity =
mMobileNetworkRepository.queryMobileNetworkInfoBySubId(
String.valueOf(mSubId));
});
if (mSubId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return Arrays.asList();
}
return Arrays.asList(
new DataUsageSummaryPreferenceController(getActivity(), getSettingsLifecycle(),
this, mSubId),
new RoamingPreferenceController(context, KEY_ROAMING_PREF, getSettingsLifecycle(),
this, mSubId));
}
@@ -151,28 +176,38 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
public void onAttach(Context context) {
super.onAttach(context);
Intent intent = getIntent();
SubscriptionInfo info = SubscriptionUtil.getSubscriptionOrDefault(context, mSubId);
if (info == null) {
if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
Log.d(LOG_TAG, "Invalid subId request " + mSubId);
return;
}
int oldSubId = mSubId;
updateSubscriptions(info);
// If the subscription has changed or the new intent does not contain the opt in action,
// remove the old discovery dialog. If the activity is being recreated, we will see
// onCreate -> onNewIntent, so the dialog will first be recreated for the old subscription
// and then removed.
if (!MobileNetworkActivity.doesIntentContainOptInAction(intent)) {
removeContactDiscoveryDialog(oldSubId);
}
Intent intent = getIntent();
if (intent != null) {
int updateSubscriptionIndex = intent.getIntExtra(Settings.EXTRA_SUB_ID,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
if (updateSubscriptionIndex != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
int oldSubId = mSubId;
mSubId = updateSubscriptionIndex;
// If the subscription has changed or the new intent does not contain the opt in
// action,
// remove the old discovery dialog. If the activity is being recreated, we will see
// onCreate -> onNewIntent, so the dialog will first be recreated for the old
// subscription
// and then removed.
if (updateSubscriptionIndex != oldSubId
|| !MobileNetworkActivity.doesIntentContainOptInAction(intent)) {
removeContactDiscoveryDialog(oldSubId);
}
// evaluate showing the new discovery dialog if this intent contains an action to
// show the
// opt-in.
if (MobileNetworkActivity.doesIntentContainOptInAction(intent)) {
showContactDiscoveryDialog();
}
}
// evaluate showing the new discovery dialog if this intent contains an action to show the
// opt-in.
if (MobileNetworkActivity.doesIntentContainOptInAction(intent)) {
showContactDiscoveryDialog(
SubscriptionUtil.getSubscriptionOrDefault(context, mSubId));
}
final DataUsageSummaryPreferenceController dataUsageSummaryPreferenceController =
@@ -194,7 +229,13 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
use(MobileDataPreferenceController.class).setWifiPickerTrackerHelper(
new WifiPickerTrackerHelper(getSettingsLifecycle(), context,
null /* WifiPickerTrackerCallback */));
use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId);
final RoamingPreferenceController roamingPreferenceController =
use(RoamingPreferenceController.class);
if (roamingPreferenceController != null) {
roamingPreferenceController.init(getFragmentManager(), mSubId,
mMobileNetworkInfoEntity);
}
use(ApnPreferenceController.class).init(mSubId);
use(CarrierPreferenceController.class).init(mSubId);
use(DataUsagePreferenceController.class).init(mSubId);
@@ -258,68 +299,36 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
@Override
public void onResume() {
super.onResume();
mMobileNetworkRepository.addRegister(this);
// TODO: remove log after fixing b/182326102
Log.d(LOG_TAG, "onResume() subId=" + mSubId);
if (mActiveSubscriptionsListener == null) {
mActiveSubscriptionsListener = new ActiveSubscriptionsListener(
getContext().getMainLooper(), getContext(), mSubId) {
public void onChanged() {
onSubscriptionDetailChanged();
}
};
mDropFirstSubscriptionChangeNotify = true;
}
mActiveSubscriptionsListener.start();
}
private void onSubscriptionDetailChanged() {
if (mDropFirstSubscriptionChangeNotify) {
mDropFirstSubscriptionChangeNotify = false;
Log.d(LOG_TAG, "Callback during onResume()");
return;
}
final SubscriptionInfo subInfo = SubscriptionUtil
.getSubscriptionOrDefault(getContext(), mSubId);
if (subInfo != null) {
if (mSubscriptionInfoEntity != null) {
/**
* Update the title when SIM stats got changed
*/
final Consumer<Activity> renameTitle = activity -> {
if (activity != null && !activity.isFinishing()) {
if (activity instanceof SettingsActivity) {
final CharSequence displayName = SubscriptionUtil
.getUniqueSubscriptionDisplayName(subInfo, activity);
((SettingsActivity)activity).setTitle(displayName);
((SettingsActivity) activity).setTitle(mSubscriptionInfoEntity.uniqueName);
}
}
};
ThreadUtils.postOnMainThread(() -> renameTitle.accept(getActivity()));
ThreadUtils.postOnMainThread(() -> {
renameTitle.accept(getActivity());
redrawPreferenceControllers();
});
}
mActiveSubscriptionsListenerCount++;
if (mActiveSubscriptionsListenerCount != 1) {
return;
}
ThreadUtils.postOnMainThread(() -> {
if (subInfo == null) {
finishFragment();
return;
}
mActiveSubscriptionsListenerCount = 0;
redrawPreferenceControllers();
});
}
@Override
public void onDestroy() {
if (mActiveSubscriptionsListener != null) {
mActiveSubscriptionsListener.stop();
}
super.onDestroy();
mMobileNetworkRepository.removeRegister();
}
@VisibleForTesting
@@ -375,7 +384,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
final MenuItem item = menu.add(Menu.NONE, R.id.edit_sim_name, Menu.NONE,
R.string.mobile_network_sim_name);
item.setIcon(com.android.internal.R.drawable.ic_mode_edit);
@@ -386,7 +395,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
if (menuItem.getItemId() == R.id.edit_sim_name) {
RenameMobileNetworkDialogFragment.newInstance(mSubId).show(
getFragmentManager(), RenameMobileNetworkDialogFragment.TAG);
@@ -422,18 +431,18 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
}
}
private void showContactDiscoveryDialog(SubscriptionInfo info) {
if (info == null) {
Log.d(LOG_TAG, "Invalid subId request " + mSubId);
private void showContactDiscoveryDialog() {
ContactDiscoveryDialogFragment fragment = getContactDiscoveryFragment(mSubId);
if (mSubscriptionInfoEntity == null) {
Log.d(LOG_TAG, "Zoey, showContactDiscoveryDialog, Invalid subId request " + mSubId);
onDestroy();
return;
}
CharSequence carrierName = SubscriptionUtil.getUniqueSubscriptionDisplayName(info,
getContext());
ContactDiscoveryDialogFragment fragment = getContactDiscoveryFragment(mSubId);
if (fragment == null) {
fragment = ContactDiscoveryDialogFragment.newInstance(mSubId, carrierName);
fragment = ContactDiscoveryDialogFragment.newInstance(mSubId,
mSubscriptionInfoEntity.uniqueName);
}
// Only try to show the dialog if it has not already been added, otherwise we may
// accidentally add it multiple times, causing multiple dialogs.
@@ -443,12 +452,53 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
}
}
private void updateSubscriptions(SubscriptionInfo subscription) {
if (subscription == null) {
return;
}
final int subscriptionIndex = subscription.getSubscriptionId();
@Override
public void onAvailableSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
}
mSubId = subscriptionIndex;
@Override
public void onActiveSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
if (DataServiceUtils.shouldUpdateEntityList(mSubInfoEntityList, subInfoEntityList)) {
// Check the current subId is existed or not, if so, finish it.
if (!mSubscriptionInfoMap.isEmpty()) {
// Check each subInfo and remove it in the map based on the new list.
for (SubscriptionInfoEntity entity : subInfoEntityList) {
mSubscriptionInfoMap.remove(Integer.parseInt(entity.subId));
}
Iterator<Integer> iterator = mSubscriptionInfoMap.keySet().iterator();
while (iterator.hasNext()) {
if (iterator.next() == mSubId) {
finishFragment();
return;
}
}
}
mSubInfoEntityList = subInfoEntityList;
mSubInfoEntityList.forEach(entity -> {
int subId = Integer.parseInt(entity.subId);
mSubscriptionInfoMap.put(subId, entity);
if (subId == mSubId) {
mSubscriptionInfoEntity = entity;
onSubscriptionDetailChanged();
}
});
}
}
@Override
public void onAllUiccInfoChanged(List<UiccInfoEntity> uiccInfoEntityList) {
}
@Override
public void onAllMobileNetworkInfoChanged(
List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList) {
}
@Override
public void onAirplaneModeChanged(boolean enabled) {
}
}

View File

@@ -16,6 +16,9 @@
package com.android.settings.network.telephony;
import static androidx.lifecycle.Lifecycle.Event.ON_START;
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
import android.content.Context;
import android.os.PersistableBundle;
import android.provider.Settings;
@@ -24,22 +27,32 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.network.GlobalSettingsChangeListener;
import com.android.settings.network.MobileNetworkRepository;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.mobile.dataservice.DataServiceUtils;
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
import java.util.ArrayList;
import java.util.List;
/**
* Preference controller for "Roaming"
*/
public class RoamingPreferenceController extends TelephonyTogglePreferenceController implements
LifecycleObserver, OnStart, OnStop {
LifecycleObserver, MobileNetworkRepository.MobileNetworkCallback {
private static final String TAG = "RoamingController";
private static final String DIALOG_TAG = "MobileDataDialog";
@@ -47,6 +60,9 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro
private RestrictedSwitchPreference mSwitchPreference;
private TelephonyManager mTelephonyManager;
private CarrierConfigManager mCarrierConfigManager;
protected MobileNetworkRepository mMobileNetworkRepository;
protected LifecycleOwner mLifecycleOwner;
private List<MobileNetworkInfoEntity> mMobileNetworkInfoEntityList = new ArrayList<>();
/**
* There're 2 listeners both activated at the same time.
@@ -59,10 +75,18 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro
@VisibleForTesting
FragmentManager mFragmentManager;
MobileNetworkInfoEntity mMobileNetworkInfoEntity;
public RoamingPreferenceController(Context context, String key) {
public RoamingPreferenceController(Context context, String key, Lifecycle lifecycle,
LifecycleOwner lifecycleOwner, int subId) {
super(context, key);
mSubId = subId;
mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
mMobileNetworkRepository = MobileNetworkRepository.createBySubId(context, this, mSubId);
mLifecycleOwner = lifecycleOwner;
if (lifecycle != null) {
lifecycle.addObserver(this);
}
}
@Override
@@ -75,8 +99,9 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro
return AVAILABLE;
}
@Override
@OnLifecycleEvent(ON_START)
public void onStart() {
mMobileNetworkRepository.addRegister(mLifecycleOwner);
if (mListener == null) {
mListener = new GlobalSettingsChangeListener(mContext,
Settings.Global.DATA_ROAMING) {
@@ -100,8 +125,9 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro
};
}
@Override
@OnLifecycleEvent(ON_STOP)
public void onStop() {
mMobileNetworkRepository.removeRegister();
stopMonitor();
stopMonitorSubIdSpecific();
}
@@ -114,7 +140,7 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro
@Override
public int getAvailabilityStatus(int subId) {
return subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
return mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
? AVAILABLE
: AVAILABLE_UNSEARCHABLE;
}
@@ -135,19 +161,26 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro
@Override
public void updateState(Preference preference) {
super.updateState(preference);
final RestrictedSwitchPreference switchPreference = (RestrictedSwitchPreference) preference;
if (!switchPreference.isDisabledByAdmin()) {
switchPreference.setEnabled(mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID);
switchPreference.setChecked(isChecked());
mSwitchPreference = (RestrictedSwitchPreference) preference;
update();
}
private void update() {
if (mSwitchPreference == null) {
return;
}
if (!mSwitchPreference.isDisabledByAdmin()) {
mSwitchPreference.setEnabled(mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mSwitchPreference.setChecked(isChecked());
}
}
@VisibleForTesting
boolean isDialogNeeded() {
final boolean isRoamingEnabled = mTelephonyManager.isDataRoamingEnabled();
final boolean isRoamingEnabled = mMobileNetworkInfoEntity == null ? false
: mMobileNetworkInfoEntity.isDataRoamingEnabled;
final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(
mSubId);
// Need dialog if we need to turn on roaming and the roaming charge indication is allowed
if (!isRoamingEnabled && (carrierConfig == null || !carrierConfig.getBoolean(
CarrierConfigManager.KEY_DISABLE_CHARGE_INDICATION_BOOL))) {
@@ -158,12 +191,14 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro
@Override
public boolean isChecked() {
return mTelephonyManager.isDataRoamingEnabled();
return mMobileNetworkInfoEntity == null ? false
: mMobileNetworkInfoEntity.isDataRoamingEnabled;
}
public void init(FragmentManager fragmentManager, int subId) {
public void init(FragmentManager fragmentManager, int subId, MobileNetworkInfoEntity entity) {
mFragmentManager = fragmentManager;
mSubId = subId;
mMobileNetworkInfoEntity = entity;
mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return;
@@ -197,4 +232,42 @@ public class RoamingPreferenceController extends TelephonyTogglePreferenceContro
mListenerForSubId = null;
}
}
@VisibleForTesting
public void setMobileNetworkInfoEntity(MobileNetworkInfoEntity mobileNetworkInfoEntity) {
mMobileNetworkInfoEntity = mobileNetworkInfoEntity;
}
@Override
public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
}
@Override
public void onAvailableSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
}
@Override
public void onActiveSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
}
@Override
public void onAllUiccInfoChanged(List<UiccInfoEntity> uiccInfoEntityList) {
}
@Override
public void onAllMobileNetworkInfoChanged(
List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList) {
if (DataServiceUtils.shouldUpdateEntityList(mMobileNetworkInfoEntityList,
mobileNetworkInfoEntityList)) {
mMobileNetworkInfoEntityList = mobileNetworkInfoEntityList;
mMobileNetworkInfoEntityList.forEach(entity -> {
if (Integer.parseInt(entity.subId) == mSubId) {
mMobileNetworkInfoEntity = entity;
update();
refreshSummary(mSwitchPreference);
return;
}
});
}
}
}

View File

@@ -23,12 +23,14 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Looper;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
@@ -36,12 +38,16 @@ import android.telephony.TelephonyManager;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
import org.junit.Before;
import org.junit.Test;
@@ -65,15 +71,25 @@ public class RoamingPreferenceControllerTest {
private FragmentTransaction mFragmentTransaction;
@Mock
private CarrierConfigManager mCarrierConfigManager;
@Mock
private Lifecycle mLifecycle;
@Mock
private LifecycleOwner mLifecycleOwner;
private LifecycleRegistry mLifecycleRegistry;
private RoamingPreferenceController mController;
private RestrictedSwitchPreference mPreference;
private Context mContext;
private MobileNetworkInfoEntity mMobileNetworkInfoEntity;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
if (Looper.myLooper() == null) {
Looper.prepare();
}
mContext = spy(ApplicationProvider.getApplicationContext());
doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
doReturn(mSubscriptionManager).when(mContext).getSystemService(
@@ -87,11 +103,21 @@ public class RoamingPreferenceControllerTest {
doReturn(mFragmentTransaction).when(mFragmentManager).beginTransaction();
mPreference = spy(new RestrictedSwitchPreference(mContext));
mController = spy(new RoamingPreferenceController(mContext, "roaming"));
mController.init(mFragmentManager, SUB_ID);
mController = spy(
new RoamingPreferenceController(mContext, "roaming", mLifecycle, mLifecycleOwner,
SUB_ID));
mLifecycleRegistry = new LifecycleRegistry(mLifecycleOwner);
when(mLifecycleOwner.getLifecycle()).thenReturn(mLifecycleRegistry);
mController.init(mFragmentManager, SUB_ID, mMobileNetworkInfoEntity);
mPreference.setKey(mController.getPreferenceKey());
}
private MobileNetworkInfoEntity setupMobileNetworkInfoEntity(String subId,
boolean isDataRoaming) {
return new MobileNetworkInfoEntity(subId, false, false, true, false, false, false, false,
false, false, false, isDataRoaming);
}
@Test
public void getAvailabilityStatus_validSubId_returnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
@@ -100,9 +126,11 @@ public class RoamingPreferenceControllerTest {
@Test
public void getAvailabilityStatus_invalidSubId_returnUnsearchable() {
mController.init(mFragmentManager, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mController.init(mFragmentManager, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
mMobileNetworkInfoEntity);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
assertThat(mController.getAvailabilityStatus(
SubscriptionManager.INVALID_SUBSCRIPTION_ID)).isEqualTo(
BasePreferenceController.AVAILABLE_UNSEARCHABLE);
}
@@ -111,14 +139,16 @@ public class RoamingPreferenceControllerTest {
final PersistableBundle bundle = new PersistableBundle();
bundle.putBoolean(CarrierConfigManager.KEY_DISABLE_CHARGE_INDICATION_BOOL, false);
doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
doReturn(false).when(mTelephonyManager).isDataRoamingEnabled();
mMobileNetworkInfoEntity = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), false);
mController.setMobileNetworkInfoEntity(mMobileNetworkInfoEntity);
assertThat(mController.isDialogNeeded()).isTrue();
}
@Test
public void isDialogNeeded_roamingEnabled_returnFalse() {
doReturn(true).when(mTelephonyManager).isDataRoamingEnabled();
mMobileNetworkInfoEntity = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
mController.setMobileNetworkInfoEntity(mMobileNetworkInfoEntity);
assertThat(mController.isDialogNeeded()).isFalse();
}
@@ -126,10 +156,10 @@ public class RoamingPreferenceControllerTest {
@Test
@UiThreadTest
public void setChecked_needDialog_showDialog() {
doReturn(false).when(mTelephonyManager).isDataRoamingEnabled();
mMobileNetworkInfoEntity = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), false);
mController.setMobileNetworkInfoEntity(mMobileNetworkInfoEntity);
doReturn(null).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
mController.setChecked(true);
verify(mFragmentManager).beginTransaction();
@@ -137,7 +167,11 @@ public class RoamingPreferenceControllerTest {
@Test
public void updateState_invalidSubId_disabled() {
mController.init(mFragmentManager, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mMobileNetworkInfoEntity = setupMobileNetworkInfoEntity(
String.valueOf(SubscriptionManager.INVALID_SUBSCRIPTION_ID), false);
mController.setMobileNetworkInfoEntity(mMobileNetworkInfoEntity);
mController.init(mFragmentManager, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
mMobileNetworkInfoEntity);
mController.updateState(mPreference);
@@ -146,7 +180,8 @@ public class RoamingPreferenceControllerTest {
@Test
public void updateState_validSubId_enabled() {
doReturn(true).when(mTelephonyManager).isDataRoamingEnabled();
mMobileNetworkInfoEntity = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
mController.setMobileNetworkInfoEntity(mMobileNetworkInfoEntity);
mController.updateState(mPreference);
@@ -191,7 +226,7 @@ public class RoamingPreferenceControllerTest {
@Test
public void getAvailabilityStatus_forceHomeNetworkIsTrue_shouldReturnConditionallyAvailable() {
final PersistableBundle bundle = new PersistableBundle();
bundle.putBoolean(CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL, false);
bundle.putBoolean(CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL, true);
doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);