Merge "[ProviderModel] Use category to separate physical SIM and e-SIM" into sc-dev am: c968a80ff6 am: 67551e8dd2 am: fe8f6a1c99

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/14732243

Change-Id: If6761df2973935dde4080c29899314bdbccc92d6
This commit is contained in:
Zoey Chen
2021-06-01 03:21:17 +00:00
committed by Automerger Merge Worker
12 changed files with 1366 additions and 4 deletions

View File

@@ -19,8 +19,12 @@ package com.android.settings.network;
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 @@ import java.util.List;
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 @@ public class MobileNetworkListFragment extends DashboardFragment {
@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) {

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -36,6 +36,7 @@ import android.util.Log;
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 @@ public class SubscriptionUtil {
*
* @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 @@ public class SubscriptionUtil {
}
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();
}
}