Merge changes Iafe111bf,Ie9d8e935

* changes:
  update CdmaApnPreferenceController
  Add network selection preferences
This commit is contained in:
Lei Yu
2018-10-26 00:28:30 +00:00
committed by Android (Google) Code Review
16 changed files with 730 additions and 1158 deletions

View File

@@ -0,0 +1,143 @@
/*
* Copyright (C) 2018 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.telephony;
import static android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.Looper;
import android.os.PersistableBundle;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.SettingsActivity;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.network.ApnSettings;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
/**
* Preference controller for "Apn settings"
*/
public class ApnPreferenceController extends BasePreferenceController implements
LifecycleObserver, OnStart, OnStop {
@VisibleForTesting
CarrierConfigManager mCarrierConfigManager;
private int mSubId;
private Preference mPreference;
private DpcApnEnforcedObserver mDpcApnEnforcedObserver;
public ApnPreferenceController(Context context, String key) {
super(context, key);
mCarrierConfigManager = new CarrierConfigManager(context);
mDpcApnEnforcedObserver = new DpcApnEnforcedObserver(new Handler(Looper.getMainLooper()));
}
@Override
public int getAvailabilityStatus() {
final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
final boolean isCdmaApn = MobileNetworkUtils.isCdmaOptions(mContext, mSubId)
&& carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL);
final boolean isGsmApn = MobileNetworkUtils.isGsmOptions(mContext, mSubId)
&& carrierConfig.getBoolean(CarrierConfigManager.KEY_APN_EXPAND_BOOL);
return carrierConfig != null
&& (isCdmaApn || isGsmApn)
? AVAILABLE
: CONDITIONALLY_UNAVAILABLE;
}
@Override
public void onStart() {
mDpcApnEnforcedObserver.register(mContext);
}
@Override
public void onStop() {
mDpcApnEnforcedObserver.unRegister(mContext);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
((RestrictedPreference) mPreference).setDisabledByAdmin(
MobileNetworkUtils.isDpcApnEnforced(mContext)
? RestrictedLockUtilsInternal.getDeviceOwner(mContext)
: null);
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (getPreferenceKey().equals(preference.getKey())) {
// This activity runs in phone process, we must use intent to start
final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
// This will setup the Home and Search affordance
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, true);
intent.putExtra(ApnSettings.SUB_ID, mSubId);
mContext.startActivity(intent);
return true;
}
return false;
}
public void init(int subId) {
mSubId = subId;
}
@VisibleForTesting
void setPreference(Preference preference) {
mPreference = preference;
}
private class DpcApnEnforcedObserver extends ContentObserver {
DpcApnEnforcedObserver(Handler handler) {
super(handler);
}
public void register(Context context) {
context.getContentResolver().registerContentObserver(ENFORCE_MANAGED_URI, false, this);
}
public void unRegister(Context context) {
context.getContentResolver().unregisterContentObserver(this);
}
@Override
public void onChange(boolean selfChange) {
updateState(mPreference);
}
}
}

View File

@@ -1,180 +0,0 @@
/*
* Copyright (C) 2018 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.telephony;
import android.content.Context;
import android.content.Intent;
import android.os.PersistableBundle;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
/**
* List of Network-specific settings screens.
*/
public class GsmUmtsOptions {
private static final String LOG_TAG = "GsmUmtsOptions";
private CarrierConfigManager mCarrierConfigManager;
private RestrictedPreference mButtonAPNExpand;
private Preference mCategoryAPNExpand;
Preference mCarrierSettingPref;
private NetworkOperators mNetworkOperator;
private static final String BUTTON_APN_EXPAND_KEY = "button_gsm_apn_key";
private static final String CATEGORY_APN_EXPAND_KEY = "category_gsm_apn_key";
private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
public static final String EXTRA_SUB_ID = "sub_id";
private PreferenceFragmentCompat mPrefFragment;
private PreferenceScreen mPrefScreen;
public GsmUmtsOptions(PreferenceFragmentCompat prefFragment, PreferenceScreen prefScreen,
final int subId) {
final Context context = prefFragment.getContext();
mPrefFragment = prefFragment;
mPrefScreen = prefScreen;
mCarrierConfigManager = new CarrierConfigManager(context);
mPrefFragment.addPreferencesFromResource(R.xml.gsm_umts_options);
mButtonAPNExpand = (RestrictedPreference) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
mCategoryAPNExpand = mPrefScreen.findPreference(CATEGORY_APN_EXPAND_KEY);
mNetworkOperator = (NetworkOperators) mPrefScreen
.findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
mCarrierSettingPref = mPrefScreen.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
mNetworkOperator.initialize();
update(subId);
}
// Unlike mPrefFragment or mPrefScreen, subId may change during lifecycle of GsmUmtsOptions.
// When that happens, we update GsmUmtsOptions with new parameters.
protected void update(final int subId) {
boolean addAPNExpand = true;
boolean addNetworkOperatorsCategory = true;
boolean addCarrierSettings = true;
final TelephonyManager telephonyManager = TelephonyManager.from(mPrefFragment.getContext())
.createForSubscriptionId(subId);
//TODO(b/115429509): Get phone from subId
Phone phone = null;
if (phone == null) return;
if (telephonyManager.getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
log("Not a GSM phone");
addAPNExpand = false;
mNetworkOperator.setEnabled(false);
} else {
log("Not a CDMA phone");
PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
// Determine which options to display. For GSM these are defaulted to true in
// CarrierConfigManager, but they maybe overriden by DefaultCarrierConfigService or a
// carrier app.
// Note: these settings used to be controlled with overlays in
// Telephony/res/values/config.xml
if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_APN_EXPAND_BOOL)
&& mCategoryAPNExpand != null) {
addAPNExpand = false;
}
if (!carrierConfig.getBoolean(
CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL)) {
addNetworkOperatorsCategory = false;
}
if (carrierConfig.getBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL)) {
if (phone.isCspPlmnEnabled()) {
log("[CSP] Enabling Operator Selection menu.");
mNetworkOperator.setEnabled(true);
} else {
log("[CSP] Disabling Operator Selection menu.");
addNetworkOperatorsCategory = false;
}
}
// Read platform settings for carrier settings
addCarrierSettings = carrierConfig.getBoolean(
CarrierConfigManager.KEY_CARRIER_SETTINGS_ENABLE_BOOL);
}
// Making no assumptions of whether they are added or removed at this point.
// Calling add or remove explicitly to make sure they are updated.
if (addAPNExpand) {
log("update: addAPNExpand");
mButtonAPNExpand.setDisabledByAdmin(
MobileNetworkUtils.isDpcApnEnforced(mButtonAPNExpand.getContext())
? RestrictedLockUtilsInternal.getDeviceOwner(
mButtonAPNExpand.getContext())
: null);
mButtonAPNExpand.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
MetricsLogger.action(mButtonAPNExpand.getContext(),
MetricsEvent.ACTION_MOBILE_NETWORK_APN_SETTINGS);
// We need to build the Intent by hand as the Preference Framework
// does not allow to add an Intent with some extras into a Preference
// XML file
final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
// This will setup the Home and Search affordance
intent.putExtra(":settings:show_fragment_as_subsetting", true);
intent.putExtra(EXTRA_SUB_ID, subId);
mPrefFragment.startActivity(intent);
return true;
}
});
mPrefScreen.addPreference(mCategoryAPNExpand);
} else {
mPrefScreen.removePreference(mCategoryAPNExpand);
}
if (addNetworkOperatorsCategory) {
mPrefScreen.addPreference(mNetworkOperator);
mNetworkOperator.update(subId);
} else {
mPrefScreen.removePreference(mNetworkOperator);
}
if (addCarrierSettings) {
mPrefScreen.addPreference(mCarrierSettingPref);
} else {
mPrefScreen.removePreference(mCarrierSettingPref);
}
}
protected boolean preferenceTreeClick(Preference preference) {
return mNetworkOperator.preferenceTreeClick(preference);
}
protected void log(String s) {
android.util.Log.d(LOG_TAG, s);
}
}

View File

@@ -45,7 +45,6 @@ import android.view.MenuItem;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
@@ -57,14 +56,17 @@ import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.network.telephony.cdma.CdmaApnPreferenceController;
import com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceController;
import com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController;
import com.android.settings.network.telephony.gsm.AutoSelectPreferenceController;
import com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
@@ -125,9 +127,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
private ImsManager mImsMgr;
private boolean mOkClicked;
//GsmUmts options and Cdma options
GsmUmtsOptions mGsmUmtsOptions;
private String mClickedPrefKey;
private boolean mShow4GForLTE;
private boolean mIsGlobalCdma;
@@ -156,9 +155,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
/** TODO: Refactor and get rid of the if's using subclasses */
if (preference.getKey().equals(BUTTON_4G_LTE_KEY)) {
return true;
} else if (mGsmUmtsOptions != null &&
mGsmUmtsOptions.preferenceTreeClick(preference) == true) {
return true;
} else if (TextUtils.equals(key, BUTTON_CDMA_SYSTEM_SELECT_KEY)
|| TextUtils.equals(key, BUTTON_CDMA_SUBSCRIPTION_KEY)) {
if (mTelephonyManager.getEmergencyCallbackMode()) {
@@ -210,7 +206,7 @@ public class MobileNetworkFragment extends DashboardFragment implements
use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId);
use(CdmaApnPreferenceController.class).init(mSubId);
use(ApnPreferenceController.class).init(mSubId);
use(CarrierPreferenceController.class).init(mSubId);
use(DataUsagePreferenceController.class).init(mSubId);
use(PreferredNetworkModePreferenceController.class).init(mSubId);
@@ -219,6 +215,15 @@ public class MobileNetworkFragment extends DashboardFragment implements
use(EuiccPreferenceController.class).init(mSubId);
use(WifiCallingPreferenceController.class).init(mSubId);
final OpenNetworkSelectPagePreferenceController openNetworkSelectPagePreferenceController =
use(OpenNetworkSelectPagePreferenceController.class).init(mSubId);
final AutoSelectPreferenceController autoSelectPreferenceController =
use(AutoSelectPreferenceController.class)
.init(mSubId)
.addListener(openNetworkSelectPagePreferenceController);
use(PreferenceCategoryController.class).setChildren(
Arrays.asList(autoSelectPreferenceController));
mCdmaSystemSelectPreferenceController = use(CdmaSystemSelectPreferenceController.class);
mCdmaSystemSelectPreferenceController.init(getPreferenceManager(), mSubId);
mCdmaSubscriptionPreferenceController = use(CdmaSubscriptionPreferenceController.class);
@@ -468,10 +473,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
if (ps != null) {
ps.setEnabled(hasActiveSubscriptions);
}
ps = findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
if (ps != null) {
ps.setEnabled(hasActiveSubscriptions);
}
ps = findPreference(BUTTON_CARRIER_SETTINGS_KEY);
if (ps != null) {
ps.setEnabled(hasActiveSubscriptions);
@@ -480,20 +481,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
if (ps != null) {
ps.setEnabled(hasActiveSubscriptions);
}
ps = findPreference(NetworkOperators.BUTTON_AUTO_SELECT_KEY);
if (ps != null) {
ps.setSummary(null);
if (mTelephonyManager.getServiceState().getRoaming()) {
ps.setEnabled(true);
} else {
ps.setEnabled(!mOnlyAutoSelectInHomeNW);
if (mOnlyAutoSelectInHomeNW) {
ps.setSummary(getResources().getString(
R.string.manual_mode_disallowed_summary,
mTelephonyManager.getSimOperatorName()));
}
}
}
}
@Override
@@ -605,17 +592,7 @@ public class MobileNetworkFragment extends DashboardFragment implements
updateGsmUmtsOptions(this, prefSet, mSubId);
PreferenceCategory networkOperatorCategory =
(PreferenceCategory) prefSet.findPreference(
NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
Preference carrierSettings = prefSet.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
if (networkOperatorCategory != null) {
if (enable) {
networkOperatorCategory.setEnabled(true);
} else {
prefSet.removePreference(networkOperatorCategory);
}
}
if (carrierSettings != null) {
prefSet.removePreference(carrierSettings);
}
@@ -688,12 +665,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
if (preference == null) {
return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
} else if (preference == preferenceScreen
.findPreference(NetworkOperators.BUTTON_AUTO_SELECT_KEY)) {
return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_AUTO_SELECT_NETWORK_TOGGLE;
} else if (preference == preferenceScreen
.findPreference(NetworkOperators.BUTTON_NETWORK_SELECT_KEY)) {
return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK;
} else if (preference == preferenceScreen
.findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY)) {
return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_CDMA_SYSTEM_SELECT;
@@ -715,11 +686,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
// We don't want to re-create GsmUmtsOptions if already exists. Otherwise, the
// preferences inside it will also be re-created which causes unexpected behavior.
// For example, the open dialog gets dismissed or detached after pause / resume.
if (mGsmUmtsOptions == null) {
mGsmUmtsOptions = new GsmUmtsOptions(prefFragment, prefScreen, subId);
} else {
mGsmUmtsOptions.update(subId);
}
}
private static Intent buildPhoneAccountConfigureIntent(

View File

@@ -29,6 +29,8 @@ import android.os.SystemProperties;
import android.provider.Settings;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -275,15 +277,43 @@ public class MobileNetworkUtils {
return false;
}
/**
* return {@code true} if we need show Gsm related settings
*/
public static boolean isGsmOptions(Context context, int subId) {
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return false;
}
if (isGsmBasicOptions(context, subId)) {
return true;
}
final int settingsNetworkMode = android.provider.Settings.Global.getInt(
context.getContentResolver(),
android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId,
Phone.PREFERRED_NT_MODE);
if (isWorldMode(context, subId)) {
if (settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO
|| settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA) {
return true;
} else if (settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA
&& !MobileNetworkUtils.isTdscdmaSupported(context, subId)) {
return true;
}
}
return false;
}
private static boolean isGsmBasicOptions(Context context, int subId) {
final TelephonyManager telephonyManager = TelephonyManager.from(context)
.createForSubscriptionId(subId);
final PersistableBundle carrierConfig = context.getSystemService(
CarrierConfigManager.class).getConfigForSubId(subId);
if (telephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) {
return true;
} else if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
return true;
}
return false;
@@ -318,6 +348,39 @@ public class MobileNetworkUtils {
return worldModeOn;
}
/**
* Return {@code true} if we need show settings for network selection(i.e. Verizon)
*/
public static boolean shouldDisplayNetworkSelectOptions(Context context, int subId) {
final TelephonyManager telephonyManager = TelephonyManager.from(context)
.createForSubscriptionId(subId);
final PersistableBundle carrierConfig = context.getSystemService(
CarrierConfigManager.class).getConfigForSubId(subId);
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
|| !carrierConfig.getBoolean(
CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL)
|| (carrierConfig.getBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL)
&& !telephonyManager.isManualNetworkSelectionAllowed())) {
return false;
}
if (isGsmBasicOptions(context, subId)) {
return true;
}
final int settingsNetworkMode = android.provider.Settings.Global.getInt(
context.getContentResolver(),
android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId,
Phone.PREFERRED_NT_MODE);
if (isWorldMode(context, subId)) {
if (settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA) {
return true;
}
}
return false;
}
public static boolean isShow4GForLTE(Context context) {
//TODO(b/117882862): move this to framework
try {

View File

@@ -1,301 +0,0 @@
/*
* Copyright (C) 2018 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.telephony;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.Toast;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.TwoStatePreference;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settingslib.utils.ThreadUtils;
/**
* "Networks" settings UI for the Phone app.
*/
public class NetworkOperators extends PreferenceCategory
implements Preference.OnPreferenceChangeListener {
private static final String LOG_TAG = "NetworkOperators";
private static final boolean DBG = true;
private static final int EVENT_AUTO_SELECT_DONE = 100;
private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 200;
//String keys for preference lookup
public static final String BUTTON_NETWORK_SELECT_KEY = "button_network_select_key";
public static final String BUTTON_AUTO_SELECT_KEY = "button_auto_select_key";
public static final String BUTTON_CHOOSE_NETWORK_KEY = "button_choose_network_key";
public static final String CATEGORY_NETWORK_OPERATORS_KEY = "network_operators_category_key";
//preference objects
private NetworkSelectListPreference mNetworkSelect;
private TwoStatePreference mAutoSelect;
private Preference mChooseNetwork;
private ProgressDialog mProgressDialog;
private int mSubId;
private TelephonyManager mTelephonyManager;
// There's two sets of Auto-Select UI in this class.
// If {@code com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI} set as true
// {@link mChooseNetwork} will be used, otherwise {@link mNetworkSelect} will be used.
boolean mEnableNewManualSelectNetworkUI;
public NetworkOperators(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NetworkOperators(Context context) {
super(context);
}
/**
* Initialize NetworkOperators instance.
*/
public void initialize() {
mEnableNewManualSelectNetworkUI = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
mAutoSelect = (TwoStatePreference) findPreference(BUTTON_AUTO_SELECT_KEY);
mChooseNetwork = findPreference(BUTTON_CHOOSE_NETWORK_KEY);
mNetworkSelect = (NetworkSelectListPreference) findPreference(BUTTON_NETWORK_SELECT_KEY);
if (mEnableNewManualSelectNetworkUI) {
removePreference(mNetworkSelect);
} else {
removePreference(mChooseNetwork);
}
mProgressDialog = new ProgressDialog(getContext());
mTelephonyManager = TelephonyManager.from(getContext());
}
/**
* Update NetworkOperators instance if like subId is updated.
*
* @param subId Corresponding subscription ID of this network.
*/
protected void update(final int subId) {
mSubId = subId;
mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
if (mAutoSelect != null) {
mAutoSelect.setOnPreferenceChangeListener(this);
}
if (mEnableNewManualSelectNetworkUI) {
if (mChooseNetwork != null) {
ServiceState ss = mTelephonyManager.getServiceState();
if (ss != null && ss.getState() == ServiceState.STATE_IN_SERVICE) {
mChooseNetwork.setSummary(mTelephonyManager.getNetworkOperatorName());
} else {
mChooseNetwork.setSummary(R.string.network_disconnected);
}
}
} else {
if (mNetworkSelect != null) {
mNetworkSelect.initialize(mSubId, this, mProgressDialog);
}
}
getNetworkSelectionMode();
}
/**
* Implemented to support onPreferenceChangeListener to look for preference
* changes specifically on auto select button.
*
* @param preference is the preference to be changed, should be auto select button.
* @param newValue should be the value of whether autoSelect is checked.
*/
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == mAutoSelect) {
boolean autoSelect = (Boolean) newValue;
if (DBG) logd("onPreferenceChange autoSelect: " + String.valueOf(autoSelect));
selectNetworkAutomatic(autoSelect);
MetricsLogger.action(getContext(),
MetricsEvent.ACTION_MOBILE_NETWORK_AUTO_SELECT_NETWORK_TOGGLE, autoSelect);
return true;
}
return false;
}
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_AUTO_SELECT_DONE:
mAutoSelect.setEnabled(true);
dismissProgressBar();
boolean isSuccessed = (boolean) msg.obj;
if (isSuccessed) {
if (DBG) logd("automatic network selection: succeeded!");
displayNetworkSelectionSucceeded();
} else {
if (DBG) logd("automatic network selection: failed!");
displayNetworkSelectionFailed();
}
break;
case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
int networkSelectionMode = msg.arg1;
if (networkSelectionMode == TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN) {
if (DBG) logd("get network selection mode: failed!");
} else {
boolean autoSelect = networkSelectionMode
== TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
if (DBG) {
logd("get network selection mode: "
+ (autoSelect ? "auto" : "manual") + " selection");
}
if (mAutoSelect != null) {
mAutoSelect.setChecked(autoSelect);
}
if (mEnableNewManualSelectNetworkUI) {
if (mChooseNetwork != null) {
mChooseNetwork.setEnabled(!autoSelect);
}
} else {
if (mNetworkSelect != null) {
mNetworkSelect.setEnabled(!autoSelect);
}
}
}
}
return;
}
};
// Used by both mAutoSelect and mNetworkSelect buttons.
protected void displayNetworkSelectionFailed() {
Toast.makeText(getContext(), R.string.connect_later, Toast.LENGTH_LONG).show();
}
// Used by both mAutoSelect and mNetworkSelect buttons.
protected void displayNetworkSelectionSucceeded() {
Toast.makeText(getContext(), R.string.registration_done, Toast.LENGTH_LONG).show();
}
private void selectNetworkAutomatic(boolean autoSelect) {
if (DBG) logd("selectNetworkAutomatic: " + String.valueOf(autoSelect));
if (autoSelect) {
if (mEnableNewManualSelectNetworkUI) {
if (mChooseNetwork != null) {
mChooseNetwork.setEnabled(!autoSelect);
}
} else {
if (mNetworkSelect != null) {
mNetworkSelect.setEnabled(!autoSelect);
}
}
if (DBG) logd("select network automatically...");
showAutoSelectProgressBar();
mAutoSelect.setEnabled(false);
if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
ThreadUtils.postOnBackgroundThread(() -> {
mTelephonyManager.setNetworkSelectionModeAutomatic();
// Because TelephonyManager#setNetworkSelectionModeAutomatic doesn't have a
// return value, we query the current network selection mode to tell if the
// TelephonyManager#setNetworkSelectionModeAutomatic is successed.
int networkSelectionMode = mTelephonyManager.getNetworkSelectionMode();
Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
msg.obj = networkSelectionMode == TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
msg.sendToTarget();
});
}
} else {
if (mEnableNewManualSelectNetworkUI) {
if (mChooseNetwork != null) {
// Open the choose Network page automatically when user turn off the auto-select
openChooseNetworkPage();
}
} else {
if (mNetworkSelect != null) {
mNetworkSelect.onClick();
}
}
}
}
protected void getNetworkSelectionMode() {
if (DBG) logd("getting network selection mode...");
ThreadUtils.postOnBackgroundThread(() -> {
int networkSelectionMode = mTelephonyManager.getNetworkSelectionMode();
Message msg = mHandler.obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE);
msg.arg1 = networkSelectionMode;
msg.sendToTarget();
});
}
private void dismissProgressBar() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}
private void showAutoSelectProgressBar() {
mProgressDialog.setMessage(
getContext().getResources().getString(R.string.register_automatically));
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.setCancelable(false);
mProgressDialog.setIndeterminate(true);
mProgressDialog.show();
}
/**
* Open the Choose network page via {@alink NetworkSelectSettingActivity}
*/
public void openChooseNetworkPage() {
//TODO(b/114749736): Build intent without calling static method
Intent intent = new Intent();
getContext().startActivity(intent);
}
protected boolean preferenceTreeClick(Preference preference) {
if (mEnableNewManualSelectNetworkUI) {
if (DBG) logd("enable New AutoSelectNetwork UI");
if (preference == mChooseNetwork) {
openChooseNetworkPage();
}
return (preference == mAutoSelect || preference == mChooseNetwork);
} else {
return (preference == mAutoSelect || preference == mNetworkSelect);
}
}
private void logd(String msg) {
Log.d(LOG_TAG, "[NetworksList] " + msg);
}
private void loge(String msg) {
Log.e(LOG_TAG, "[NetworksList] " + msg);
}
}

View File

@@ -1,506 +0,0 @@
/*
* Copyright (C) 2018 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.telephony;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.BidiFormatter;
import android.text.TextDirectionHeuristics;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.OperatorInfo;
import com.android.settings.R;
import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
/**
* "Networks" preference in "Mobile network" settings UI for the Phone app.
* It's used to manually search and choose mobile network. Enabled only when
* autoSelect preference is turned off.
*/
public class NetworkSelectListPreference extends ListPreference
implements DialogInterface.OnCancelListener,
Preference.OnPreferenceChangeListener{
private static final String LOG_TAG = "networkSelect";
private static final boolean DBG = true;
private static final int EVENT_MANUALLY_NETWORK_SELECTION_DONE = 1;
private static final int EVENT_NETWORK_SCAN_RESULTS = 2;
private static final int EVENT_NETWORK_SCAN_COMPLETED = 3;
private static final int EVENT_NETWORK_SCAN_ERROR = 4;
//dialog ids
private static final int DIALOG_NETWORK_SELECTION = 100;
private static final int DIALOG_NETWORK_LIST_LOAD = 200;
private final ExecutorService mNetworkScanExecutor = Executors.newFixedThreadPool(1);
private List<CellInfo> mCellInfoList;
private CellInfo mCellInfo;
private int mSubId;
private TelephonyManager mTelephonyManager;
private NetworkScanHelper mNetworkScanHelper;
private NetworkOperators mNetworkOperators;
private List<String> mForbiddenPlmns;
private ProgressDialog mProgressDialog;
public NetworkSelectListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NetworkSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onClick() {
showProgressDialog(DIALOG_NETWORK_LIST_LOAD);
TelephonyManager telephonyManager = (TelephonyManager)
getContext().getSystemService(Context.TELEPHONY_SERVICE);
new AsyncTask<Void, Void, List<String>>() {
@Override
protected List<String> doInBackground(Void... voids) {
String[] forbiddenPlmns = telephonyManager.getForbiddenPlmns();
return forbiddenPlmns != null ? Arrays.asList(forbiddenPlmns) : null;
}
@Override
protected void onPostExecute(List<String> result) {
mForbiddenPlmns = result;
loadNetworksList();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_MANUALLY_NETWORK_SELECTION_DONE:
if (DBG) logd("hideProgressPanel");
dismissProgressDialog();
boolean isSuccessed = (boolean) msg.obj;
if (isSuccessed) {
if (DBG) {
logd("manual network selection: succeeded! "
+ getNetworkTitle(mCellInfo));
}
mNetworkOperators.displayNetworkSelectionSucceeded();
} else {
if (DBG) logd("manual network selection: failed!");
mNetworkOperators.displayNetworkSelectionFailed();
}
mNetworkOperators.getNetworkSelectionMode();
break;
case EVENT_NETWORK_SCAN_RESULTS:
List<CellInfo> results = (List<CellInfo>) msg.obj;
results.removeIf(cellInfo -> cellInfo == null);
mCellInfoList = new ArrayList<>(results);
if (DBG) logd("CALLBACK_SCAN_RESULTS" + mCellInfoList.toString());
break;
case EVENT_NETWORK_SCAN_COMPLETED:
if (DBG) logd("scan complete, load the cellInfosList");
dismissProgressDialog();
networksListLoaded();
break;
case EVENT_NETWORK_SCAN_ERROR:
dismissProgressDialog();
displayNetworkQueryFailed();
mNetworkOperators.getNetworkSelectionMode();
break;
}
return;
}
};
private final NetworkScanHelper.NetworkScanCallback mCallback =
new NetworkScanHelper.NetworkScanCallback() {
public void onResults(List<CellInfo> results) {
if (DBG) logd("get scan results: " + results.toString());
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
msg.sendToTarget();
}
public void onComplete() {
if (DBG) logd("network scan completed.");
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
msg.sendToTarget();
}
public void onError(int error) {
if (DBG) logd("network scan error.");
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR);
msg.sendToTarget();
}
};
@Override
//implemented for DialogInterface.OnCancelListener
public void onCancel(DialogInterface dialog) {
if (DBG) logd("user manually close the dialog");
mNetworkScanHelper.stopNetworkQuery();
// If cancelled, we query NetworkSelectMode and update states of AutoSelect button.
mNetworkOperators.getNetworkSelectionMode();
}
//TODO(b/114749736): move this logic to preference controller
protected void onDialogClosed(boolean positiveResult) {
// If dismissed, we query NetworkSelectMode and update states of AutoSelect button.
if (!positiveResult) {
mNetworkOperators.getNetworkSelectionMode();
}
}
// This initialize method needs to be called for this preference to work properly.
protected void initialize(int subId, NetworkOperators networkOperators,
ProgressDialog progressDialog) {
mSubId = subId;
mNetworkOperators = networkOperators;
// This preference should share the same progressDialog with networkOperators category.
mProgressDialog = progressDialog;
mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
mNetworkScanHelper = new NetworkScanHelper(
mTelephonyManager, mCallback, mNetworkScanExecutor);
setSummary(mTelephonyManager.getNetworkOperatorName());
setOnPreferenceChangeListener(this);
}
@Override
protected void onPrepareForRemoval() {
destroy();
super.onPrepareForRemoval();
}
private void destroy() {
dismissProgressDialog();
if (mNetworkScanHelper != null) {
mNetworkScanHelper.stopNetworkQuery();
}
mNetworkScanExecutor.shutdown();
}
private void displayEmptyNetworkList() {
Toast.makeText(getContext(), R.string.empty_networks_list, Toast.LENGTH_LONG).show();
}
private void displayNetworkQueryFailed() {
Toast.makeText(getContext(), R.string.network_query_error, Toast.LENGTH_LONG).show();
}
private void loadNetworksList() {
if (DBG) logd("load networks list...");
mNetworkScanHelper.startNetworkScan(
NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS);
}
private void networksListLoaded() {
if (DBG) logd("networks list loaded");
mNetworkOperators.getNetworkSelectionMode();
if (mCellInfoList != null) {
// create a preference for each item in the list.
// just use the operator name instead of the mildly
// confusing mcc/mnc.
List<CharSequence> networkEntriesList = new ArrayList<>();
List<CharSequence> networkEntryValuesList = new ArrayList<>();
for (CellInfo cellInfo: mCellInfoList) {
// Display each operator name only once.
String networkTitle = getNetworkTitle(cellInfo);
if (CellInfoUtil.isForbidden(cellInfo, mForbiddenPlmns)) {
networkTitle += " "
+ getContext().getResources().getString(R.string.forbidden_network);
}
networkEntriesList.add(networkTitle);
networkEntryValuesList.add(getOperatorNumeric(cellInfo));
}
setEntries(networkEntriesList.toArray(new CharSequence[networkEntriesList.size()]));
setEntryValues(networkEntryValuesList.toArray(
new CharSequence[networkEntryValuesList.size()]));
super.onClick();
} else {
displayEmptyNetworkList();
}
}
private void dismissProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
try {
mProgressDialog.dismiss();
} catch (IllegalArgumentException ex) {
loge("Can't close the progress dialog " + ex);
}
}
}
private void showProgressDialog(int id) {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(getContext());
} else {
// Dismiss progress bar if it's showing now.
dismissProgressDialog();
}
switch (id) {
case DIALOG_NETWORK_SELECTION:
final String networkSelectMsg = getContext().getResources()
.getString(R.string.register_on_network,
getNetworkTitle(mCellInfo));
mProgressDialog.setMessage(networkSelectMsg);
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.setCancelable(false);
mProgressDialog.setIndeterminate(true);
break;
case DIALOG_NETWORK_LIST_LOAD:
mProgressDialog.setMessage(
getContext().getResources().getString(R.string.load_networks_progress));
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.setCancelable(true);
mProgressDialog.setIndeterminate(false);
mProgressDialog.setOnCancelListener(this);
break;
default:
}
mProgressDialog.show();
}
/**
* Implemented to support onPreferenceChangeListener to look for preference
* changes specifically on this button.
*
* @param preference is the preference to be changed, should be network select button.
* @param newValue should be the value of the selection as index of operators.
*/
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
int operatorIndex = findIndexOfValue((String) newValue);
mCellInfo = mCellInfoList.get(operatorIndex);
if (DBG) logd("selected network: " + mCellInfo.toString());
MetricsLogger.action(getContext(),
MetricsEvent.ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK);
if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
ThreadUtils.postOnBackgroundThread(() -> {
final OperatorInfo operatorInfo = getOperatorInfoFromCellInfo(mCellInfo);
if (DBG) logd("manually selected network: " + operatorInfo.toString());
boolean isSuccessed = mTelephonyManager.setNetworkSelectionModeManual(
operatorInfo, true /* persistSelection */);
Message msg = mHandler.obtainMessage(EVENT_MANUALLY_NETWORK_SELECTION_DONE);
msg.obj = isSuccessed;
msg.sendToTarget();
});
} else {
loge("Error selecting network, subscription Id is invalid " + mSubId);
}
return true;
}
/**
* Returns the title of the network obtained in the manual search.
*
* @param cellInfo contains the information of the network.
* @return Long Name if not null/empty, otherwise Short Name if not null/empty,
* else MCCMNC string.
*/
private String getNetworkTitle(CellInfo cellInfo) {
OperatorInfo ni = getOperatorInfoFromCellInfo(cellInfo);
if (!TextUtils.isEmpty(ni.getOperatorAlphaLong())) {
return ni.getOperatorAlphaLong();
} else if (!TextUtils.isEmpty(ni.getOperatorAlphaShort())) {
return ni.getOperatorAlphaShort();
} else {
BidiFormatter bidiFormatter = BidiFormatter.getInstance();
return bidiFormatter.unicodeWrap(ni.getOperatorNumeric(), TextDirectionHeuristics.LTR);
}
}
/**
* Returns the operator numeric (MCCMNC) obtained in the manual search.
*
* @param cellInfo contains the information of the network.
* @return MCCMNC string.
*/
private String getOperatorNumeric(CellInfo cellInfo) {
return getOperatorInfoFromCellInfo(cellInfo).getOperatorNumeric();
}
/**
* Wrap a cell info into an operator info.
*/
private OperatorInfo getOperatorInfoFromCellInfo(CellInfo cellInfo) {
OperatorInfo oi;
if (cellInfo instanceof CellInfoLte) {
CellInfoLte lte = (CellInfoLte) cellInfo;
oi = new OperatorInfo(
(String) lte.getCellIdentity().getOperatorAlphaLong(),
(String) lte.getCellIdentity().getOperatorAlphaShort(),
lte.getCellIdentity().getMobileNetworkOperator());
} else if (cellInfo instanceof CellInfoWcdma) {
CellInfoWcdma wcdma = (CellInfoWcdma) cellInfo;
oi = new OperatorInfo(
(String) wcdma.getCellIdentity().getOperatorAlphaLong(),
(String) wcdma.getCellIdentity().getOperatorAlphaShort(),
wcdma.getCellIdentity().getMobileNetworkOperator());
} else if (cellInfo instanceof CellInfoGsm) {
CellInfoGsm gsm = (CellInfoGsm) cellInfo;
oi = new OperatorInfo(
(String) gsm.getCellIdentity().getOperatorAlphaLong(),
(String) gsm.getCellIdentity().getOperatorAlphaShort(),
gsm.getCellIdentity().getMobileNetworkOperator());
} else if (cellInfo instanceof CellInfoCdma) {
CellInfoCdma cdma = (CellInfoCdma) cellInfo;
oi = new OperatorInfo(
(String) cdma.getCellIdentity().getOperatorAlphaLong(),
(String) cdma.getCellIdentity().getOperatorAlphaShort(),
"" /* operator numeric */);
} else {
oi = new OperatorInfo("", "", "");
}
return oi;
}
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
// No need to save instance state since it's persistent
return superState;
}
final SavedState myState = new SavedState(superState);
myState.mDialogListEntries = getEntries();
myState.mDialogListEntryValues = getEntryValues();
myState.mCellInfoList = mCellInfoList;
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
if (getEntries() == null && myState.mDialogListEntries != null) {
setEntries(myState.mDialogListEntries);
}
if (getEntryValues() == null && myState.mDialogListEntryValues != null) {
setEntryValues(myState.mDialogListEntryValues);
}
if (mCellInfoList == null && myState.mCellInfoList != null) {
mCellInfoList = myState.mCellInfoList;
}
super.onRestoreInstanceState(myState.getSuperState());
}
/**
* We save entries, entryValues and operatorInfoList into bundle.
* At onCreate of fragment, dialog will be restored if it was open. In this case,
* we need to restore entries, entryValues and operatorInfoList. Without those information,
* onPreferenceChange will fail if user select network from the dialog.
*/
private static class SavedState extends BaseSavedState {
CharSequence[] mDialogListEntries;
CharSequence[] mDialogListEntryValues;
List<CellInfo> mCellInfoList;
SavedState(Parcel source) {
super(source);
final ClassLoader boot = Object.class.getClassLoader();
mDialogListEntries = source.readCharSequenceArray();
mDialogListEntryValues = source.readCharSequenceArray();
mCellInfoList = source.readParcelableList(mCellInfoList, boot);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeCharSequenceArray(mDialogListEntries);
dest.writeCharSequenceArray(mDialogListEntryValues);
dest.writeParcelableList(mCellInfoList, flags);
}
SavedState(Parcelable superState) {
super(superState);
}
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
private void logd(String msg) {
Log.d(LOG_TAG, "[NetworksList] " + msg);
}
private void loge(String msg) {
Log.e(LOG_TAG, "[NetworksList] " + msg);
}
}

View File

@@ -81,7 +81,7 @@ public class NetworkSelectSettings extends DashboardFragment {
@VisibleForTesting
TelephonyManager mTelephonyManager;
private List<String> mForbiddenPlmns;
private boolean mShow4GForLTE = true;
private boolean mShow4GForLTE = false;
private NetworkScanHelper mNetworkScanHelper;
private final ExecutorService mNetworkScanExecutor = Executors.newFixedThreadPool(1);
private MetricsFeatureProvider mMetricsFeatureProvider;
@@ -95,7 +95,6 @@ public class NetworkSelectSettings extends DashboardFragment {
com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
mSubId = getArguments().getInt(MobileSettingsActivity.KEY_SUBSCRIPTION_ID);
addPreferencesFromResource(R.xml.choose_network);
mConnectedPreferenceCategory =
(PreferenceCategory) findPreference(PREF_KEY_CONNECTED_NETWORK_OPERATOR);
mPreferenceCategory =
@@ -389,6 +388,7 @@ public class NetworkSelectSettings extends DashboardFragment {
}
private void stopNetworkQuery() {
setProgressBarVisible(false);
if (mNetworkScanHelper != null) {
mNetworkScanHelper.stopNetworkQuery();
}

View File

@@ -1,87 +0,0 @@
/*
* Copyright (C) 2018 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.telephony.cdma;
import android.content.Context;
import android.content.Intent;
import android.os.PersistableBundle;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.SettingsActivity;
import com.android.settings.network.ApnSettings;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
/**
* Preference controller for "CDMA Apn"
*/
public class CdmaApnPreferenceController extends CdmaBasePreferenceController {
private static final String CATEGORY_KEY = "category_cdma_apn_key";
@VisibleForTesting
CarrierConfigManager mCarrierConfigManager;
public CdmaApnPreferenceController(Context context, String key) {
super(context, key);
mCarrierConfigManager = new CarrierConfigManager(context);
}
@Override
public int getAvailabilityStatus() {
final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
return carrierConfig != null
&& carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_APN_SETTING_CDMA_BOOL)
&& MobileNetworkUtils.isCdmaOptions(mContext, mSubId)
? AVAILABLE
: CONDITIONALLY_UNAVAILABLE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
if (isAvailable()) {
((RestrictedPreference) mPreference).setDisabledByAdmin(
MobileNetworkUtils.isDpcApnEnforced(mContext)
? RestrictedLockUtilsInternal.getDeviceOwner(mContext)
: null);
} else {
screen.findPreference(CATEGORY_KEY).setVisible(false);
}
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (getPreferenceKey().equals(preference.getKey())) {
// This activity runs in phone process, we must use intent to start
final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
// This will setup the Home and Search affordance
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, true);
intent.putExtra(ApnSettings.SUB_ID, mSubId);
mContext.startActivity(intent);
return true;
}
return false;
}
}

View File

@@ -0,0 +1,135 @@
/*
* Copyright (C) 2018 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.telephony.gsm;
import android.content.Context;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.network.telephony.MobileSettingsActivity;
import com.android.settings.network.telephony.NetworkSelectSettings;
import java.util.ArrayList;
import java.util.List;
/**
* Preference controller for "Auto Select Network"
*/
public class AutoSelectPreferenceController extends TogglePreferenceController {
private int mSubId;
private TelephonyManager mTelephonyManager;
private boolean mOnlyAutoSelectInHome;
private List<OnNetworkSelectModeListener> mListeners;
public AutoSelectPreferenceController(Context context, String key) {
super(context, key);
mTelephonyManager = context.getSystemService(TelephonyManager.class);
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
mListeners = new ArrayList<>();
}
@Override
public int getAvailabilityStatus() {
return MobileNetworkUtils.shouldDisplayNetworkSelectOptions(mContext,mSubId)
? AVAILABLE
: CONDITIONALLY_UNAVAILABLE;
}
@Override
public boolean isChecked() {
return mTelephonyManager.getNetworkSelectionMode()
== TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
preference.setSummary(null);
if (mTelephonyManager.getServiceState().getRoaming()) {
preference.setEnabled(true);
} else {
preference.setEnabled(!mOnlyAutoSelectInHome);
if (mOnlyAutoSelectInHome) {
preference.setSummary(mContext.getString(
R.string.manual_mode_disallowed_summary,
mTelephonyManager.getSimOperatorName()));
}
}
}
@Override
public boolean setChecked(boolean isChecked) {
if (isChecked) {
mTelephonyManager.setNetworkSelectionModeAutomatic();
for (OnNetworkSelectModeListener lsn : mListeners) {
lsn.onNetworkSelectModeChanged();
}
// Manually check whether it is successfully
return mTelephonyManager.getNetworkSelectionMode()
== TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
} else {
final Bundle bundle = new Bundle();
bundle.putInt(MobileSettingsActivity.KEY_SUBSCRIPTION_ID, mSubId);
new SubSettingLauncher(mContext)
.setDestination(NetworkSelectSettings.class.getName())
.setSourceMetricsCategory(MetricsProto.MetricsEvent.MOBILE_NETWORK_SELECT)
.setTitleRes(R.string.choose_network_title)
.setArguments(bundle)
.launch();
return false;
}
}
public AutoSelectPreferenceController init(int subId) {
mSubId = subId;
mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
final PersistableBundle carrierConfig = mContext.getSystemService(
CarrierConfigManager.class).getConfigForSubId(mSubId);
mOnlyAutoSelectInHome = carrierConfig.getBoolean(
CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL);
return this;
}
public AutoSelectPreferenceController addListener(OnNetworkSelectModeListener lsn) {
mListeners.add(lsn);
return this;
}
/**
* Callback when network select mode is changed
*
* @see TelephonyManager#getNetworkSelectionMode()
*/
public interface OnNetworkSelectModeListener {
void onNetworkSelectModeChanged();
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2018 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.telephony.gsm;
import android.content.Context;
import android.os.Bundle;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.network.telephony.MobileSettingsActivity;
import com.android.settings.network.telephony.NetworkSelectSettings;
/**
* Preference controller for "Open network select"
*/
public class OpenNetworkSelectPagePreferenceController extends BasePreferenceController implements
AutoSelectPreferenceController.OnNetworkSelectModeListener {
private int mSubId;
private TelephonyManager mTelephonyManager;
private Preference mPreference;
public OpenNetworkSelectPagePreferenceController(Context context, String key) {
super(context, key);
mTelephonyManager = context.getSystemService(TelephonyManager.class);
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
@Override
public int getAvailabilityStatus() {
return MobileNetworkUtils.shouldDisplayNetworkSelectOptions(mContext, mSubId)
? AVAILABLE
: CONDITIONALLY_UNAVAILABLE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
preference.setEnabled(mTelephonyManager.getNetworkSelectionMode()
!= TelephonyManager.NETWORK_SELECTION_MODE_AUTO);
}
@Override
public CharSequence getSummary() {
final ServiceState ss = mTelephonyManager.getServiceState();
if (ss != null && ss.getState() == ServiceState.STATE_IN_SERVICE) {
return mTelephonyManager.getNetworkOperatorName();
} else {
return mContext.getString(R.string.network_disconnected);
}
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
final Bundle bundle = new Bundle();
bundle.putInt(MobileSettingsActivity.KEY_SUBSCRIPTION_ID, mSubId);
new SubSettingLauncher(mContext)
.setDestination(NetworkSelectSettings.class.getName())
.setSourceMetricsCategory(MetricsProto.MetricsEvent.MOBILE_NETWORK_SELECT)
.setTitleRes(R.string.choose_network_title)
.setArguments(bundle)
.launch();
return true;
}
return false;
}
public OpenNetworkSelectPagePreferenceController init(int subId) {
mSubId = subId;
mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
return this;
}
@Override
public void onNetworkSelectModeChanged() {
updateState(mPreference);
}
}