Merge "[ProviderModel] Use category to separate physical SIM and e-SIM" into sc-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bb38fcc..4c0f811 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -13248,6 +13248,22 @@
<string name="carrier_wifi_offload_summary">Allow Google Fi to use W+ networks to improve speed and coverage</string>
<!-- Title for merged carrier Wi-Fi network information. [CHAR LIMIT=NONE] -->
<string name="carrier_wifi_network_title">W+ network</string>
+ <!-- Provider Model: title of SIM category -->
+ <string name="sim_category_title">SIM</string>
+ <!-- Provider Model: title of Downloaded category. [CHAR LIMIT=50] -->
+ <string name="downloaded_sim_category_title">DOWNLOADED SIM</string>
+ <!-- Provider Model: summary of Active in SIM category. [CHAR LIMIT=50] -->
+ <string name="sim_category_active_sim">Active</string>
+ <!-- Provider Model: summary of Inactive in SIM category. [CHAR LIMIT=50] -->
+ <string name="sim_category_inactive_sim">Inactive</string>
+ <!-- Provider Model: summary of default config. [CHAR LIMIT=50] -->
+ <string name="sim_category_default_active_sim">\u0020/ Default for <xliff:g name="default_sim_config" example=" / Default for calls">%1$s</xliff:g></string>
+ <!-- Provider Model: summary of default call. [CHAR LIMIT=50] -->
+ <string name="default_active_sim_calls">calls</string>
+ <!-- Provider Model: summary of default SMS. [CHAR LIMIT=50] -->
+ <string name="default_active_sim_sms">SMS</string>
+ <!-- Provider Model: summary of default mobile data. [CHAR LIMIT=50] -->
+ <string name="default_active_sim_mobile_data">mobile data</string>
<!-- Summary text separator for preferences including a short description
(eg. "Connected / 5G"). [CHAR LIMIT=50] -->
diff --git a/res/xml/network_provider_sims_list.xml b/res/xml/network_provider_sims_list.xml
new file mode 100644
index 0000000..0f866f1
--- /dev/null
+++ b/res/xml/network_provider_sims_list.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/provider_network_settings_title">
+
+ <PreferenceCategory
+ android:key="provider_model_sim_category"
+ android:title="@string/sim_category_title"
+ android:order="20"
+ settings:controller="com.android.settings.network.NetworkProviderSimsCategoryController"/>
+
+ <PreferenceCategory
+ android:key="provider_model_downloaded_sim_category"
+ android:title="@string/downloaded_sim_category_title"
+ android:order="25"
+ settings:controller=
+ "com.android.settings.network.NetworkProviderDownloadedSimsCategoryController"
+ settings:allowDividerAbove="true"/>
+
+ <com.android.settingslib.RestrictedPreference
+ android:key="add_more"
+ settings:isPreferenceVisible="false"
+ settings:userRestriction="no_config_mobile_networks"
+ settings:useAdminDisabledSummary="true"
+ settings:searchable="false"
+ android:title="@string/mobile_network_list_add_more"
+ android:icon="@drawable/ic_menu_add_activated_tint"
+ android:order="100">
+ <intent android:action="android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION">
+ <extra android:name="android.telephony.euicc.extra.FORCE_PROVISION"
+ android:value="true"/>
+ </intent>
+ </com.android.settingslib.RestrictedPreference>
+</PreferenceScreen>
diff --git a/src/com/android/settings/network/MobileNetworkListFragment.java b/src/com/android/settings/network/MobileNetworkListFragment.java
index c27775d..1767c1c 100644
--- a/src/com/android/settings/network/MobileNetworkListFragment.java
+++ b/src/com/android/settings/network/MobileNetworkListFragment.java
@@ -19,8 +19,12 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.UserManager;
+import android.provider.SearchIndexableResource;
+
+import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -33,9 +37,16 @@
public class MobileNetworkListFragment extends DashboardFragment {
private static final String LOG_TAG = "NetworkListFragment";
+ static final String KEY_PREFERENCE_CATEGORY_SIM = "provider_model_sim_category";
+ @VisibleForTesting
+ static final String KEY_PREFERENCE_CATEGORY_DOWNLOADED_SIM =
+ "provider_model_downloaded_sim_category";
+
@Override
protected int getPreferenceScreenResId() {
- return R.xml.mobile_network_list;
+ return Utils.isProviderModelEnabled(getContext())
+ ? R.xml.network_provider_sims_list
+ : R.xml.mobile_network_list;
}
@Override
@@ -51,12 +62,39 @@
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
- controllers.add(new MobileNetworkListController(getContext(), getLifecycle()));
+
+ if (Utils.isProviderModelEnabled(getContext())) {
+ NetworkProviderSimsCategoryController simCategoryPrefCtrl =
+ new NetworkProviderSimsCategoryController(context, KEY_PREFERENCE_CATEGORY_SIM);
+ simCategoryPrefCtrl.init(getSettingsLifecycle());
+ controllers.add(simCategoryPrefCtrl);
+
+ NetworkProviderDownloadedSimsCategoryController downloadedSimsCategoryCtrl =
+ new NetworkProviderDownloadedSimsCategoryController(context,
+ KEY_PREFERENCE_CATEGORY_DOWNLOADED_SIM);
+ downloadedSimsCategoryCtrl.init(getSettingsLifecycle());
+ controllers.add(downloadedSimsCategoryCtrl);
+ } else {
+ controllers.add(new MobileNetworkListController(getContext(), getLifecycle()));
+ }
+
return controllers;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.mobile_network_list) {
+ new BaseSearchIndexProvider() {
+
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+ boolean enabled) {
+ final ArrayList<SearchIndexableResource> result = new ArrayList<>();
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = Utils.isProviderModelEnabled(context)
+ ? R.xml.network_provider_sims_list
+ : R.xml.mobile_network_list;
+ result.add(sir);
+ return result;
+ }
@Override
protected boolean isPageSearchEnabled(Context context) {
diff --git a/src/com/android/settings/network/NetworkProviderDownloadedSimListController.java b/src/com/android/settings/network/NetworkProviderDownloadedSimListController.java
new file mode 100644
index 0000000..43bdd80
--- /dev/null
+++ b/src/com/android/settings/network/NetworkProviderDownloadedSimListController.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.provider.Settings;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.ArrayMap;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.network.telephony.MobileNetworkActivity;
+import com.android.settings.network.telephony.MobileNetworkUtils;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class NetworkProviderDownloadedSimListController extends
+ AbstractPreferenceController implements
+ LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
+ private static final String TAG = "NetworkProviderDownloadedSimListCtrl";
+ private static final String KEY_PREFERENCE_CATEGORY_DOWNLOADED_SIM =
+ "provider_model_downloaded_sim_category";
+ private static final String KEY_PREFERENCE_DOWNLOADED_SIM =
+ "provider_model_downloaded_sim_list";
+ private static final String KEY_ADD_MORE = "add_more";
+
+ private SubscriptionManager mSubscriptionManager;
+ private SubscriptionsChangeListener mChangeListener;
+ private PreferenceCategory mPreferenceCategory;
+ private Map<Integer, Preference> mPreferences;
+
+ public NetworkProviderDownloadedSimListController(Context context, Lifecycle lifecycle) {
+ super(context);
+ mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
+ mChangeListener = new SubscriptionsChangeListener(context, this);
+ mPreferences = new ArrayMap<>();
+ lifecycle.addObserver(this);
+ }
+
+ @OnLifecycleEvent(ON_RESUME)
+ public void onResume() {
+ mChangeListener.start();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
+ mContext.registerReceiver(mDataSubscriptionChangedReceiver, filter);
+ update();
+ }
+
+ @OnLifecycleEvent(ON_PAUSE)
+ public void onPause() {
+ mChangeListener.stop();
+ if (mDataSubscriptionChangedReceiver != null) {
+ mContext.unregisterReceiver(mDataSubscriptionChangedReceiver);
+ }
+ }
+
+ @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();
+ }
+ }
+ };
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreferenceCategory = screen.findPreference(KEY_PREFERENCE_CATEGORY_DOWNLOADED_SIM);
+ screen.findPreference(KEY_ADD_MORE).setVisible(
+ MobileNetworkUtils.showEuiccSettings(mContext));
+ update();
+ }
+
+ private void update() {
+ if (mPreferenceCategory == null) {
+ return;
+ }
+
+ final Map<Integer, Preference> existingPreferences = mPreferences;
+ mPreferences = new ArrayMap<>();
+
+ final List<SubscriptionInfo> subscriptions = getAvailableDownloadedSubscriptions();
+ for (SubscriptionInfo info : subscriptions) {
+ final int subId = info.getSubscriptionId();
+ Preference pref = existingPreferences.remove(subId);
+ if (pref == null) {
+ pref = new Preference(mPreferenceCategory.getContext());
+ mPreferenceCategory.addPreference(pref);
+ }
+ final CharSequence displayName = SubscriptionUtil.getUniqueSubscriptionDisplayName(
+ info, mContext);
+ pref.setTitle(displayName);
+ pref.setSummary(getSummary(subId));
+
+ pref.setOnPreferenceClickListener(clickedPref -> {
+ final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
+ intent.putExtra(Settings.EXTRA_SUB_ID, info.getSubscriptionId());
+ mContext.startActivity(intent);
+ return true;
+ });
+ mPreferences.put(subId, pref);
+ }
+ for (Preference pref : existingPreferences.values()) {
+ mPreferenceCategory.removePreference(pref);
+ }
+ }
+
+ public CharSequence getSummary(int subId) {
+ if (mSubscriptionManager.isActiveSubscriptionId(subId)) {
+ CharSequence config = SubscriptionUtil.getDefaultSimConfig(mContext, subId);
+ CharSequence summary = mContext.getResources().getString(
+ R.string.sim_category_active_sim);
+ if (config == null) {
+ return summary;
+ } else {
+ final StringBuilder activeSim = new StringBuilder();
+ activeSim.append(summary).append(config);
+ return activeSim;
+ }
+ } else {
+ return mContext.getString(R.string.sim_category_inactive_sim);
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!getAvailableDownloadedSubscriptions().isEmpty()) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_PREFERENCE_DOWNLOADED_SIM;
+ }
+
+ private List<SubscriptionInfo> getAvailableDownloadedSubscriptions() {
+ List<SubscriptionInfo> subList = new ArrayList<>();
+ for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mContext)) {
+ if (info.isEmbedded()) {
+ subList.add(info);
+ }
+ }
+ return subList;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ refreshSummary(mPreferenceCategory);
+ update();
+ }
+
+ @Override
+ public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
+ }
+
+ @Override
+ public void onSubscriptionsChanged() {
+ update();
+ }
+
+ @VisibleForTesting
+ protected int getDefaultVoiceSubscriptionId() {
+ return SubscriptionManager.getDefaultVoiceSubscriptionId();
+ }
+
+ @VisibleForTesting
+ protected int getDefaultSmsSubscriptionId() {
+ return SubscriptionManager.getDefaultSmsSubscriptionId();
+ }
+
+ @VisibleForTesting
+ protected int getDefaultDataSubscriptionId() {
+ return SubscriptionManager.getDefaultDataSubscriptionId();
+ }
+}
diff --git a/src/com/android/settings/network/NetworkProviderDownloadedSimsCategoryController.java b/src/com/android/settings/network/NetworkProviderDownloadedSimsCategoryController.java
new file mode 100644
index 0000000..199740f
--- /dev/null
+++ b/src/com/android/settings/network/NetworkProviderDownloadedSimsCategoryController.java
@@ -0,0 +1,52 @@
+package com.android.settings.network;
+
+import android.content.Context;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.widget.PreferenceCategoryController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+
+public class NetworkProviderDownloadedSimsCategoryController extends
+ PreferenceCategoryController implements LifecycleObserver {
+
+ private static final String KEY_PREFERENCE_CATEGORY_DOWNLOADED_SIM =
+ "provider_model_downloaded_sim_category";
+ private NetworkProviderDownloadedSimListController mNetworkProviderDownloadedSimListController;
+
+ public NetworkProviderDownloadedSimsCategoryController(Context context, String key) {
+ super(context, key);
+ }
+
+ public void init(Lifecycle lifecycle) {
+ mNetworkProviderDownloadedSimListController = createDownloadedSimListController(lifecycle);
+ }
+
+ @VisibleForTesting
+ protected NetworkProviderDownloadedSimListController createDownloadedSimListController(
+ Lifecycle lifecycle) {
+ return new NetworkProviderDownloadedSimListController(mContext, lifecycle);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ if (mNetworkProviderDownloadedSimListController == null
+ || !mNetworkProviderDownloadedSimListController.isAvailable()) {
+ return CONDITIONALLY_UNAVAILABLE;
+ } else {
+ return AVAILABLE;
+ }
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ PreferenceCategory preferenceCategory = screen.findPreference(
+ KEY_PREFERENCE_CATEGORY_DOWNLOADED_SIM);
+ preferenceCategory.setVisible(isAvailable());
+ mNetworkProviderDownloadedSimListController.displayPreference(screen);
+ }
+}
diff --git a/src/com/android/settings/network/NetworkProviderSimListController.java b/src/com/android/settings/network/NetworkProviderSimListController.java
new file mode 100644
index 0000000..814a461
--- /dev/null
+++ b/src/com/android/settings/network/NetworkProviderSimListController.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.provider.Settings;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.ArrayMap;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.network.telephony.MobileNetworkActivity;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class NetworkProviderSimListController extends AbstractPreferenceController implements
+ LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
+ private static final String TAG = "NetworkProviderSimListCtrl";
+ private static final String KEY_PREFERENCE_CATEGORY_SIM = "provider_model_sim_category";
+ private static final String KEY_PREFERENCE_SIM = "provider_model_sim_list";
+
+ private SubscriptionManager mSubscriptionManager;
+ private SubscriptionsChangeListener mChangeListener;
+ private PreferenceCategory mPreferenceCategory;
+ private Map<Integer, Preference> mPreferences;
+
+ public NetworkProviderSimListController(Context context, Lifecycle lifecycle) {
+ super(context);
+ mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
+ mChangeListener = new SubscriptionsChangeListener(context, this);
+ mPreferences = new ArrayMap<>();
+ lifecycle.addObserver(this);
+ }
+
+ @OnLifecycleEvent(ON_RESUME)
+ public void onResume() {
+ mChangeListener.start();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
+ mContext.registerReceiver(mDataSubscriptionChangedReceiver, filter);
+ update();
+ }
+
+ @OnLifecycleEvent(ON_PAUSE)
+ public void onPause() {
+ mChangeListener.stop();
+ if (mDataSubscriptionChangedReceiver != null) {
+ mContext.unregisterReceiver(mDataSubscriptionChangedReceiver);
+ }
+ }
+
+ @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();
+ }
+ }
+ };
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreferenceCategory = screen.findPreference(KEY_PREFERENCE_CATEGORY_SIM);
+ update();
+ }
+
+ private void update() {
+ if (mPreferenceCategory == null) {
+ return;
+ }
+
+ final Map<Integer, Preference> existingPreferences = mPreferences;
+ mPreferences = new ArrayMap<>();
+
+ final List<SubscriptionInfo> subscriptions = getAvailablePhysicalSubscription();
+ for (SubscriptionInfo info : subscriptions) {
+ final int subId = info.getSubscriptionId();
+ Preference pref = existingPreferences.remove(subId);
+ if (pref == null) {
+ pref = new Preference(mPreferenceCategory.getContext());
+ mPreferenceCategory.addPreference(pref);
+ }
+ final CharSequence displayName = SubscriptionUtil.getUniqueSubscriptionDisplayName(
+ info, mContext);
+ pref.setTitle(displayName);
+ pref.setSummary(getSummary(subId, displayName));
+
+ pref.setOnPreferenceClickListener(clickedPref -> {
+ if (!mSubscriptionManager.isActiveSubscriptionId(subId)
+ && !SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager)) {
+ SubscriptionUtil.startToggleSubscriptionDialogActivity(mContext, subId,
+ true);
+ } else {
+ final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
+ intent.putExtra(Settings.EXTRA_SUB_ID, info.getSubscriptionId());
+ mContext.startActivity(intent);
+ }
+ return true;
+ });
+ mPreferences.put(subId, pref);
+ }
+ for (Preference pref : existingPreferences.values()) {
+ mPreferenceCategory.removePreference(pref);
+ }
+ }
+
+ public CharSequence getSummary(int subId, CharSequence displayName) {
+ if (mSubscriptionManager.isActiveSubscriptionId(subId)) {
+ CharSequence config = SubscriptionUtil.getDefaultSimConfig(mContext, subId);
+ CharSequence summary = mContext.getResources().getString(
+ R.string.sim_category_active_sim);
+ if (config == null) {
+ return summary;
+ } else {
+ final StringBuilder activeSim = new StringBuilder();
+ activeSim.append(summary).append(config);
+ return activeSim;
+ }
+ } else if (SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager)) {
+ return mContext.getString(R.string.sim_category_inactive_sim);
+ } else {
+ return mContext.getString(R.string.mobile_network_tap_to_activate, displayName);
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!getAvailablePhysicalSubscription().isEmpty()) {
+ return true;
+ }
+ return false;
+ }
+
+ @VisibleForTesting
+ protected List<SubscriptionInfo> getAvailablePhysicalSubscription() {
+ List<SubscriptionInfo> subList = new ArrayList<>();
+ for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mContext)) {
+ if (!info.isEmbedded()) {
+ subList.add(info);
+ break;
+ }
+ }
+ return subList;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_PREFERENCE_SIM;
+ }
+
+ @Override
+ public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
+ }
+
+ @Override
+ public void onSubscriptionsChanged() {
+ update();
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ refreshSummary(mPreferenceCategory);
+ update();
+ }
+
+ @VisibleForTesting
+ protected int getDefaultVoiceSubscriptionId() {
+ return SubscriptionManager.getDefaultVoiceSubscriptionId();
+ }
+
+ @VisibleForTesting
+ protected int getDefaultSmsSubscriptionId() {
+ return SubscriptionManager.getDefaultSmsSubscriptionId();
+ }
+
+ @VisibleForTesting
+ protected int getDefaultDataSubscriptionId() {
+ return SubscriptionManager.getDefaultDataSubscriptionId();
+ }
+}
diff --git a/src/com/android/settings/network/NetworkProviderSimsCategoryController.java b/src/com/android/settings/network/NetworkProviderSimsCategoryController.java
new file mode 100644
index 0000000..e27575a
--- /dev/null
+++ b/src/com/android/settings/network/NetworkProviderSimsCategoryController.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import android.content.Context;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.widget.PreferenceCategoryController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+
+public class NetworkProviderSimsCategoryController extends PreferenceCategoryController implements
+ LifecycleObserver {
+
+ private static final String KEY_PREFERENCE_CATEGORY_SIM = "provider_model_sim_category";
+ private NetworkProviderSimListController mNetworkProviderSimListController;
+
+ public NetworkProviderSimsCategoryController(Context context, String key) {
+ super(context, key);
+ }
+
+ public void init(Lifecycle lifecycle) {
+ mNetworkProviderSimListController = createSimListController(lifecycle);
+ }
+
+ @VisibleForTesting
+ protected NetworkProviderSimListController createSimListController(
+ Lifecycle lifecycle) {
+ return new NetworkProviderSimListController(mContext, lifecycle);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ if (mNetworkProviderSimListController == null
+ || !mNetworkProviderSimListController.isAvailable()) {
+ return CONDITIONALLY_UNAVAILABLE;
+ } else {
+ return AVAILABLE;
+ }
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ PreferenceCategory preferenceCategory = screen.findPreference(KEY_PREFERENCE_CATEGORY_SIM);
+ preferenceCategory.setVisible(isAvailable());
+ mNetworkProviderSimListController.displayPreference(screen);
+ }
+}
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 4ba7fc9..e7dd5e9 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -36,6 +36,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.internal.telephony.MccTable;
+import com.android.settings.R;
import com.android.settings.network.telephony.DeleteEuiccSubscriptionDialogActivity;
import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity;
import com.android.settingslib.DeviceInfoUtils;
@@ -343,7 +344,6 @@
*
* @return map of active subscription ids to diaplay names.
*/
- @VisibleForTesting
public static CharSequence getUniqueSubscriptionDisplayName(
SubscriptionInfo info, Context context) {
if (info == null) {
@@ -585,4 +585,56 @@
}
return null;
}
+
+ public static CharSequence getDefaultSimConfig(Context context, int subId) {
+ boolean isDefaultCall = subId == getDefaultVoiceSubscriptionId();
+ boolean isDefaultSms = subId == getDefaultSmsSubscriptionId();
+ boolean isDefaultData = subId == getDefaultDataSubscriptionId();
+
+ if (!isDefaultData && !isDefaultCall && !isDefaultSms) {
+ return null;
+ }
+
+ final StringBuilder defaultConfig = new StringBuilder();
+ if (isDefaultData) {
+ defaultConfig.append(
+ getResForDefaultConfig(context, R.string.default_active_sim_mobile_data))
+ .append(", ");
+ }
+
+ if (isDefaultCall) {
+ defaultConfig.append(getResForDefaultConfig(context, R.string.default_active_sim_calls))
+ .append(", ");
+ }
+
+ if (isDefaultSms) {
+ defaultConfig.append(getResForDefaultConfig(context, R.string.default_active_sim_sms))
+ .append(", ");
+ }
+
+ // Do not add ", " for the last config.
+ defaultConfig.setLength(defaultConfig.length() - 2);
+
+ final String summary = context.getResources().getString(
+ R.string.sim_category_default_active_sim,
+ defaultConfig);
+
+ return summary;
+ }
+
+ private static String getResForDefaultConfig(Context context, int resId) {
+ return context.getResources().getString(resId);
+ }
+
+ private static int getDefaultVoiceSubscriptionId() {
+ return SubscriptionManager.getDefaultVoiceSubscriptionId();
+ }
+
+ private static int getDefaultSmsSubscriptionId() {
+ return SubscriptionManager.getDefaultSmsSubscriptionId();
+ }
+
+ private static int getDefaultDataSubscriptionId() {
+ return SubscriptionManager.getDefaultDataSubscriptionId();
+ }
}
diff --git a/tests/unit/src/com/android/settings/network/NetworkProviderDownloadedSimListControllerTest.java b/tests/unit/src/com/android/settings/network/NetworkProviderDownloadedSimListControllerTest.java
new file mode 100644
index 0000000..939bf34
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/NetworkProviderDownloadedSimListControllerTest.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import static androidx.lifecycle.Lifecycle.Event;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Looper;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.testutils.ResourcesUtils;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+public class NetworkProviderDownloadedSimListControllerTest {
+
+ private static final int SUB_ID = 1;
+ private static final String KEY_PREFERENCE_DOWNLOADED_SIM =
+ "provider_model_downloaded_sim_list";
+ private static final String KEY_ADD_MORE = "add_more";
+ private static final String DISPLAY_NAME = "Sub 1";
+
+ @Mock
+ private SubscriptionManager mSubscriptionManager;
+ @Mock
+ private SubscriptionInfo mSubscriptionInfo;
+ @Mock
+ private Lifecycle mLifecycle;
+ @Mock
+ private LifecycleOwner mLifecycleOwner;
+ private LifecycleRegistry mLifecycleRegistry;
+
+ private MockNetworkProviderDownloadedSimListController mController;
+ private PreferenceManager mPreferenceManager;
+ private PreferenceScreen mPreferenceScreen;
+ private Preference mPreference;
+ private Preference mAddMorePreference;
+
+ private Context mContext;
+
+ /**
+ * Mock the MockNetworkProviderDownloadedSimListController that allows one to set a
+ * default voice, SMS and mobile data subscription ID.
+ */
+ @SuppressWarnings("ClassCanBeStatic")
+ private class MockNetworkProviderDownloadedSimListController extends
+ com.android.settings.network.NetworkProviderDownloadedSimListController {
+ public MockNetworkProviderDownloadedSimListController(Context context,
+ Lifecycle lifecycle) {
+ super(context, lifecycle);
+ }
+
+ private int mDefaultVoiceSubscriptionId;
+ private int mDefaultSmsSubscriptionId;
+ private int mDefaultDataSubscriptionId;
+
+ @Override
+ protected int getDefaultVoiceSubscriptionId() {
+ return mDefaultVoiceSubscriptionId;
+ }
+
+ @Override
+ protected int getDefaultSmsSubscriptionId() {
+ return mDefaultSmsSubscriptionId;
+ }
+
+ @Override
+ protected int getDefaultDataSubscriptionId() {
+ return mDefaultDataSubscriptionId;
+ }
+
+ public void setDefaultVoiceSubscriptionId(int subscriptionId) {
+ mDefaultVoiceSubscriptionId = subscriptionId;
+ }
+
+ public void setDefaultSmsSubscriptionId(int subscriptionId) {
+ mDefaultSmsSubscriptionId = subscriptionId;
+ }
+
+ public void setDefaultDataSubscriptionId(int subscriptionId) {
+ mDefaultDataSubscriptionId = subscriptionId;
+ }
+
+ }
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
+
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ mPreferenceManager = new PreferenceManager(mContext);
+ mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
+ mPreference = new Preference(mContext);
+ mPreference.setKey(KEY_PREFERENCE_DOWNLOADED_SIM);
+ mController = new MockNetworkProviderDownloadedSimListController(mContext, mLifecycle);
+ mAddMorePreference = new Preference(mContext);
+ mAddMorePreference.setKey(KEY_ADD_MORE);
+ mAddMorePreference.setVisible(true);
+ mLifecycleRegistry = new LifecycleRegistry(mLifecycleOwner);
+ when(mLifecycleOwner.getLifecycle()).thenReturn(mLifecycleRegistry);
+ }
+
+ private void displayPreferenceWithLifecycle() {
+ mLifecycleRegistry.addObserver(mController);
+ mPreferenceScreen.addPreference(mPreference);
+ mPreferenceScreen.addPreference(mAddMorePreference);
+ mController.displayPreference(mPreferenceScreen);
+ mLifecycleRegistry.handleLifecycleEvent(Event.ON_RESUME);
+ }
+
+ private void setupSubscriptionInfoList(int subId, String displayName,
+ SubscriptionInfo subscriptionInfo) {
+ when(subscriptionInfo.getSubscriptionId()).thenReturn(subId);
+ doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(subId);
+ when(subscriptionInfo.getDisplayName()).thenReturn(displayName);
+ when(subscriptionInfo.isEmbedded()).thenReturn(true);
+ }
+
+ private String setSummaryResId(String resName) {
+ return ResourcesUtils.getResourcesString(mContext, resName);
+ }
+
+ @Test
+ @UiThreadTest
+ public void getSummary_inactiveESim() {
+ setupSubscriptionInfoList(SUB_ID, DISPLAY_NAME, mSubscriptionInfo);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(new ArrayList<>());
+ when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(new ArrayList<>());
+ doReturn(false).when(mSubscriptionManager).isActiveSubscriptionId(SUB_ID);
+
+ displayPreferenceWithLifecycle();
+ String summary = setSummaryResId("sim_category_inactive_sim");
+
+ assertTrue(TextUtils.equals(mController.getSummary(SUB_ID), summary));
+ }
+
+ @Test
+ @UiThreadTest
+ public void getSummary_defaultCalls() {
+ mController.setDefaultVoiceSubscriptionId(SUB_ID);
+ setupSubscriptionInfoList(SUB_ID, DISPLAY_NAME, mSubscriptionInfo);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
+ Arrays.asList(mSubscriptionInfo));
+ when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(
+ Arrays.asList(mSubscriptionInfo));
+ doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(SUB_ID);
+
+ displayPreferenceWithLifecycle();
+ CharSequence defaultCall = SubscriptionUtil.getDefaultSimConfig(mContext, SUB_ID);
+ final StringBuilder summary = new StringBuilder();
+ summary.append(setSummaryResId("sim_category_active_sim"))
+ .append(defaultCall);
+
+ assertTrue(TextUtils.equals(mController.getSummary(SUB_ID), summary));
+ }
+
+ @Test
+ @UiThreadTest
+ public void getSummary_defaultCallsAndMobileData() {
+ mController.setDefaultVoiceSubscriptionId(SUB_ID);
+ mController.setDefaultDataSubscriptionId(SUB_ID);
+ setupSubscriptionInfoList(SUB_ID, DISPLAY_NAME, mSubscriptionInfo);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
+ Arrays.asList(mSubscriptionInfo));
+ when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(
+ Arrays.asList(mSubscriptionInfo));
+ doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(SUB_ID);
+
+ displayPreferenceWithLifecycle();
+ CharSequence defaultCall = SubscriptionUtil.getDefaultSimConfig(mContext, SUB_ID);
+ final StringBuilder summary = new StringBuilder();
+ summary.append(setSummaryResId("sim_category_active_sim"))
+ .append(defaultCall);
+
+ assertTrue(TextUtils.equals(mController.getSummary(SUB_ID), summary));
+ }
+
+}
diff --git a/tests/unit/src/com/android/settings/network/NetworkProviderDownloadedSimsCategoryControllerTest.java b/tests/unit/src/com/android/settings/network/NetworkProviderDownloadedSimsCategoryControllerTest.java
new file mode 100644
index 0000000..e34b489
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/NetworkProviderDownloadedSimsCategoryControllerTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Looper;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class NetworkProviderDownloadedSimsCategoryControllerTest {
+
+ private static final String KEY_PREFERENCE_CATEGORY_DOWNLOADED_SIM =
+ "provider_model_downloaded_sim_category";
+
+ @Mock
+ private NetworkProviderDownloadedSimListController mNetworkProviderDownloadedSimListController;
+ @Mock
+ private PreferenceCategory mPreferenceCategory;
+ @Mock
+ private Lifecycle mLifecycle;
+
+ private Context mContext;
+ private NetworkProviderDownloadedSimsCategoryController mCategoryController;
+
+ private PreferenceManager mPreferenceManager;
+ private PreferenceScreen mPreferenceScreen;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mCategoryController = new NetworkProviderDownloadedSimsCategoryController(
+ mContext, KEY_PREFERENCE_CATEGORY_DOWNLOADED_SIM) {
+ @Override
+ protected NetworkProviderDownloadedSimListController createDownloadedSimListController(
+ Lifecycle lifecycle) {
+ return mNetworkProviderDownloadedSimListController;
+ }
+ };
+
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ mPreferenceManager = new PreferenceManager(mContext);
+ mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
+ when(mPreferenceCategory.getKey()).thenReturn(KEY_PREFERENCE_CATEGORY_DOWNLOADED_SIM);
+ when(mPreferenceCategory.getPreferenceCount()).thenReturn(1);
+ mPreferenceScreen.addPreference(mPreferenceCategory);
+ }
+
+ @Test
+ public void getAvailabilityStatus_returnUnavailable() {
+ mNetworkProviderDownloadedSimListController = null;
+
+ assertThat(mCategoryController.getAvailabilityStatus()).isEqualTo(
+ CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Test
+ public void displayPreference_isVisible() {
+ when(mNetworkProviderDownloadedSimListController.isAvailable()).thenReturn(true);
+ mCategoryController.init(mLifecycle);
+ mCategoryController.displayPreference(mPreferenceScreen);
+
+ assertEquals(mPreferenceCategory.isVisible(), true);
+ }
+}
diff --git a/tests/unit/src/com/android/settings/network/NetworkProviderSimListControllerTest.java b/tests/unit/src/com/android/settings/network/NetworkProviderSimListControllerTest.java
new file mode 100644
index 0000000..3b0a40a
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/NetworkProviderSimListControllerTest.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import static androidx.lifecycle.Lifecycle.Event;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Looper;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.text.TextUtils;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
+import androidx.preference.PreferenceManager;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.testutils.ResourcesUtils;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+public class NetworkProviderSimListControllerTest {
+
+ private static final int SUB_ID_1 = 1;
+ private static final String KEY_PREFERENCE_SIM_LIST = "provider_model_sim_list";
+ private static final String DISPLAY_NAME_1 = "Sub 1";
+
+ @Mock
+ private SubscriptionManager mSubscriptionManager;
+ @Mock
+ private SubscriptionInfo mSubscriptionInfo;
+ @Mock
+ private Lifecycle mLifecycle;
+ @Mock
+ private LifecycleOwner mLifecycleOwner;
+ private LifecycleRegistry mLifecycleRegistry;
+
+ private MockNetworkProviderSimListController mController;
+ private PreferenceManager mPreferenceManager;
+ private PreferenceScreen mPreferenceScreen;
+ private Preference mPreference;
+
+ private Context mContext;
+
+ /**
+ * Mock the NetworkProviderSimListController that allows one to set a default voice,
+ * SMS and mobile data subscription ID.
+ */
+ @SuppressWarnings("ClassCanBeStatic")
+ private class MockNetworkProviderSimListController extends
+ com.android.settings.network.NetworkProviderSimListController {
+ public MockNetworkProviderSimListController(Context context, Lifecycle lifecycle) {
+ super(context, lifecycle);
+ }
+
+ private int mDefaultVoiceSubscriptionId;
+ private int mDefaultSmsSubscriptionId;
+ private int mDefaultDataSubscriptionId;
+
+ @Override
+ protected int getDefaultVoiceSubscriptionId() {
+ return mDefaultVoiceSubscriptionId;
+ }
+
+ @Override
+ protected int getDefaultSmsSubscriptionId() {
+ return mDefaultSmsSubscriptionId;
+ }
+
+ @Override
+ protected int getDefaultDataSubscriptionId() {
+ return mDefaultDataSubscriptionId;
+ }
+
+ public void setDefaultVoiceSubscriptionId(int subscriptionId) {
+ mDefaultVoiceSubscriptionId = subscriptionId;
+ }
+
+ public void setDefaultSmsSubscriptionId(int subscriptionId) {
+ mDefaultSmsSubscriptionId = subscriptionId;
+ }
+
+ public void setDefaultDataSubscriptionId(int subscriptionId) {
+ mDefaultDataSubscriptionId = subscriptionId;
+ }
+
+ }
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
+
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ mPreferenceManager = new PreferenceManager(mContext);
+ mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
+ mPreference = new Preference(mContext);
+ mPreference.setKey(KEY_PREFERENCE_SIM_LIST);
+ mController = new MockNetworkProviderSimListController(mContext, mLifecycle);
+ mLifecycleRegistry = new LifecycleRegistry(mLifecycleOwner);
+ when(mLifecycleOwner.getLifecycle()).thenReturn(mLifecycleRegistry);
+ }
+
+ private void displayPreferenceWithLifecycle() {
+ mLifecycleRegistry.addObserver(mController);
+ mPreferenceScreen.addPreference(mPreference);
+ mController.displayPreference(mPreferenceScreen);
+ mLifecycleRegistry.handleLifecycleEvent(Event.ON_RESUME);
+ }
+
+ private void setupSubscriptionInfoList(int subId, String displayName,
+ SubscriptionInfo subscriptionInfo) {
+ when(subscriptionInfo.getSubscriptionId()).thenReturn(subId);
+ doReturn(subscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(subId);
+ when(subscriptionInfo.getDisplayName()).thenReturn(displayName);
+ when(subscriptionInfo.isEmbedded()).thenReturn(false);
+ }
+
+ private String setSummaryResId(String resName, String value) {
+ return ResourcesUtils.getResourcesString(mContext, resName, value);
+ }
+
+ @Test
+ @UiThreadTest
+ public void getSummary_tapToActivePSim() {
+ setupSubscriptionInfoList(SUB_ID_1, DISPLAY_NAME_1, mSubscriptionInfo);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(new ArrayList<>());
+ when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(new ArrayList<>());
+ doReturn(false).when(mSubscriptionManager).isActiveSubscriptionId(SUB_ID_1);
+
+ displayPreferenceWithLifecycle();
+ String summary = setSummaryResId("mobile_network_tap_to_activate", DISPLAY_NAME_1);
+
+ assertTrue(TextUtils.equals(mController.getSummary(SUB_ID_1, DISPLAY_NAME_1), summary));
+ }
+
+
+ @Test
+ @UiThreadTest
+ public void getSummary_inactivePSim() {
+ setupSubscriptionInfoList(SUB_ID_1, DISPLAY_NAME_1, mSubscriptionInfo);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(new ArrayList<>());
+ when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(new ArrayList<>());
+ doReturn(false).when(mSubscriptionManager).isActiveSubscriptionId(SUB_ID_1);
+ doReturn(true).when(mSubscriptionManager).canDisablePhysicalSubscription();
+
+ displayPreferenceWithLifecycle();
+ String summary = setSummaryResId("sim_category_inactive_sim", null);
+
+ assertTrue(TextUtils.equals(mController.getSummary(SUB_ID_1, DISPLAY_NAME_1), summary));
+ }
+
+ @Test
+ @UiThreadTest
+ public void getSummary_defaultCalls() {
+ mController.setDefaultVoiceSubscriptionId(SUB_ID_1);
+ setupSubscriptionInfoList(SUB_ID_1, DISPLAY_NAME_1, mSubscriptionInfo);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
+ Arrays.asList(mSubscriptionInfo));
+ when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(
+ Arrays.asList(mSubscriptionInfo));
+ doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(SUB_ID_1);
+
+ displayPreferenceWithLifecycle();
+ CharSequence defaultCall = SubscriptionUtil.getDefaultSimConfig(mContext, SUB_ID_1);
+ final StringBuilder summary = new StringBuilder();
+ summary.append(setSummaryResId("sim_category_active_sim", null))
+ .append(defaultCall);
+
+ assertTrue(TextUtils.equals(mController.getSummary(SUB_ID_1, DISPLAY_NAME_1), summary));
+ }
+
+ @Test
+ @UiThreadTest
+ public void getSummary_defaultCallsAndSms() {
+ mController.setDefaultVoiceSubscriptionId(SUB_ID_1);
+ mController.setDefaultSmsSubscriptionId(SUB_ID_1);
+ setupSubscriptionInfoList(SUB_ID_1, DISPLAY_NAME_1, mSubscriptionInfo);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
+ Arrays.asList(mSubscriptionInfo));
+ when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(
+ Arrays.asList(mSubscriptionInfo));
+ doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(SUB_ID_1);
+
+ displayPreferenceWithLifecycle();
+ CharSequence defaultCall = SubscriptionUtil.getDefaultSimConfig(mContext, SUB_ID_1);
+ final StringBuilder summary = new StringBuilder();
+ summary.append(setSummaryResId("sim_category_active_sim", null))
+ .append(defaultCall);
+
+ assertTrue(TextUtils.equals(mController.getSummary(SUB_ID_1, DISPLAY_NAME_1), summary));
+ }
+
+}
diff --git a/tests/unit/src/com/android/settings/network/NetworkProviderSimsCategoryControllerTest.java b/tests/unit/src/com/android/settings/network/NetworkProviderSimsCategoryControllerTest.java
new file mode 100644
index 0000000..cfa376b
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/NetworkProviderSimsCategoryControllerTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Looper;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class NetworkProviderSimsCategoryControllerTest {
+
+ private static final String KEY_PREFERENCE_CATEGORY_SIM = "provider_model_sim_category";
+
+ @Mock
+ private NetworkProviderSimListController mNetworkProviderSimListController;
+ @Mock
+ private PreferenceCategory mPreferenceCategory;
+ @Mock
+ private Lifecycle mLifecycle;
+
+ private Context mContext;
+ private NetworkProviderSimsCategoryController mCategoryController;
+
+ private PreferenceManager mPreferenceManager;
+ private PreferenceScreen mPreferenceScreen;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mCategoryController = new NetworkProviderSimsCategoryController(
+ mContext, KEY_PREFERENCE_CATEGORY_SIM) {
+ @Override
+ protected NetworkProviderSimListController createSimListController(
+ Lifecycle lifecycle) {
+ return mNetworkProviderSimListController;
+ }
+ };
+
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ mPreferenceManager = new PreferenceManager(mContext);
+ mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
+ when(mPreferenceCategory.getKey()).thenReturn(KEY_PREFERENCE_CATEGORY_SIM);
+ when(mPreferenceCategory.getPreferenceCount()).thenReturn(1);
+ mPreferenceScreen.addPreference(mPreferenceCategory);
+ }
+
+ @Test
+ public void getAvailabilityStatus_returnUnavailable() {
+ mNetworkProviderSimListController = null;
+
+ assertThat(mCategoryController.getAvailabilityStatus()).isEqualTo(
+ CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Test
+ public void displayPreference_isVisible() {
+ when(mNetworkProviderSimListController.isAvailable()).thenReturn(true);
+ mCategoryController.init(mLifecycle);
+ mCategoryController.displayPreference(mPreferenceScreen);
+
+ assertEquals(mPreferenceCategory.isVisible(), true);
+ }
+}