diff --git a/src/com/android/settings/network/MobileNetworkRepository.java b/src/com/android/settings/network/MobileNetworkRepository.java index 038490f04b6..677e5f4abec 100644 --- a/src/com/android/settings/network/MobileNetworkRepository.java +++ b/src/com/android/settings/network/MobileNetworkRepository.java @@ -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 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 iterator = mSubscriptionInfoMap.keySet().iterator(); + while (iterator.hasNext()) { + deleteAllInfoBySubId(String.valueOf(iterator.next())); + } } } } diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java index a0c96791268..97ba8b8b7de 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java +++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java @@ -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 mSubInfoEntityList = new ArrayList<>(); + private Map 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 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 subInfoEntityList) { + } - mSubId = subscriptionIndex; + @Override + public void onActiveSubInfoChanged(List 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 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 uiccInfoEntityList) { + } + + @Override + public void onAllMobileNetworkInfoChanged( + List mobileNetworkInfoEntityList) { + } + + @Override + public void onAirplaneModeChanged(boolean enabled) { } } diff --git a/src/com/android/settings/network/telephony/RoamingPreferenceController.java b/src/com/android/settings/network/telephony/RoamingPreferenceController.java index eb773129b3f..2ed7d7929bc 100644 --- a/src/com/android/settings/network/telephony/RoamingPreferenceController.java +++ b/src/com/android/settings/network/telephony/RoamingPreferenceController.java @@ -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 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 subInfoEntityList) { + } + + @Override + public void onActiveSubInfoChanged(List subInfoEntityList) { + } + + @Override + public void onAllUiccInfoChanged(List uiccInfoEntityList) { + } + + @Override + public void onAllMobileNetworkInfoChanged( + List mobileNetworkInfoEntityList) { + if (DataServiceUtils.shouldUpdateEntityList(mMobileNetworkInfoEntityList, + mobileNetworkInfoEntityList)) { + mMobileNetworkInfoEntityList = mobileNetworkInfoEntityList; + mMobileNetworkInfoEntityList.forEach(entity -> { + if (Integer.parseInt(entity.subId) == mSubId) { + mMobileNetworkInfoEntity = entity; + update(); + refreshSummary(mSwitchPreference); + return; + } + }); + } + } } diff --git a/tests/unit/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java index 7ff95fbc649..d221280ae48 100644 --- a/tests/unit/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/telephony/RoamingPreferenceControllerTest.java @@ -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);