Merge "[Wi-Fi] Support multi-SIM for SIM dependent EAP methods"

This commit is contained in:
Arc Wang
2020-07-31 00:58:01 +00:00
committed by Android (Google) Code Review
7 changed files with 336 additions and 5 deletions

View File

@@ -35,6 +35,8 @@ import android.os.IBinder;
import android.os.UserManager;
import android.security.Credentials;
import android.security.KeyStore;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.text.Editable;
import android.text.InputType;
import android.text.SpannableString;
@@ -77,7 +79,9 @@ import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
/**
@@ -157,7 +161,8 @@ public class WifiConfigController2 implements TextWatcher,
private ScrollView mDialogContainer;
private Spinner mSecuritySpinner;
private Spinner mEapMethodSpinner;
@VisibleForTesting Spinner mEapMethodSpinner;
@VisibleForTesting Spinner mEapSimSpinner; // For EAP-SIM, EAP-AKA and EAP-AKA-PRIME.
private Spinner mEapCaCertSpinner;
private Spinner mEapOcspSpinner;
private TextView mEapDomainView;
@@ -202,6 +207,8 @@ public class WifiConfigController2 implements TextWatcher,
private final WifiManager mWifiManager;
private final List<SubscriptionInfo> mActiveSubscriptionInfos = new ArrayList<>();
public WifiConfigController2(WifiConfigUiBase2 parent, View view, WifiEntry wifiEntry,
int mode) {
mConfigUi = parent;
@@ -690,6 +697,12 @@ public class WifiConfigController2 implements TextWatcher,
break;
}
if (config.enterpriseConfig.isAuthenticationSimBased()
&& mActiveSubscriptionInfos.size() > 0) {
config.carrierId = mActiveSubscriptionInfos
.get(mEapSimSpinner.getSelectedItemPosition()).getCarrierId();
}
String caCert = (String) mEapCaCertSpinner.getSelectedItem();
config.enterpriseConfig.setCaCertificateAliases(null);
config.enterpriseConfig.setCaPath(null);
@@ -964,6 +977,7 @@ public class WifiConfigController2 implements TextWatcher,
initiateEnterpriseNetworkUi = true;
mEapMethodSpinner = (Spinner) mView.findViewById(R.id.method);
mEapMethodSpinner.setOnItemSelectedListener(this);
mEapSimSpinner = (Spinner) mView.findViewById(R.id.sim);
mPhase2Spinner = (Spinner) mView.findViewById(R.id.phase2);
mPhase2Spinner.setOnItemSelectedListener(this);
mEapCaCertSpinner = (Spinner) mView.findViewById(R.id.ca_cert);
@@ -1001,6 +1015,8 @@ public class WifiConfigController2 implements TextWatcher,
}
if (refreshCertificates) {
loadSims();
loadCertificates(
mEapCaCertSpinner,
Credentials.CA_CERTIFICATE,
@@ -1022,10 +1038,10 @@ public class WifiConfigController2 implements TextWatcher,
// Modifying an existing network
if (initiateEnterpriseNetworkUi && mWifiEntry != null && mWifiEntry.isSaved()) {
WifiEnterpriseConfig enterpriseConfig = mWifiEntry.getWifiConfiguration()
.enterpriseConfig;
int eapMethod = enterpriseConfig.getEapMethod();
int phase2Method = enterpriseConfig.getPhase2Method();
final WifiConfiguration wifiConfig = mWifiEntry.getWifiConfiguration();
final WifiEnterpriseConfig enterpriseConfig = wifiConfig.enterpriseConfig;
final int eapMethod = enterpriseConfig.getEapMethod();
final int phase2Method = enterpriseConfig.getPhase2Method();
mEapMethodSpinner.setSelection(eapMethod);
showEapFieldsByMethod(eapMethod);
switch (eapMethod) {
@@ -1073,6 +1089,16 @@ public class WifiConfigController2 implements TextWatcher,
default:
break;
}
if (enterpriseConfig.isAuthenticationSimBased()) {
for (int i = 0; i < mActiveSubscriptionInfos.size(); i++) {
if (wifiConfig.carrierId == mActiveSubscriptionInfos.get(i).getCarrierId()) {
mEapSimSpinner.setSelection(i);
break;
}
}
}
if (!TextUtils.isEmpty(enterpriseConfig.getCaPath())) {
setSelection(mEapCaCertSpinner, mUseSystemCertsString);
} else {
@@ -1161,6 +1187,7 @@ public class WifiConfigController2 implements TextWatcher,
mView.findViewById(R.id.l_ocsp).setVisibility(View.VISIBLE);
mView.findViewById(R.id.password_layout).setVisibility(View.VISIBLE);
mView.findViewById(R.id.show_password_layout).setVisibility(View.VISIBLE);
mView.findViewById(R.id.l_sim).setVisibility(View.VISIBLE);
Context context = mConfigUi.getContext();
switch (eapMethod) {
@@ -1171,12 +1198,14 @@ public class WifiConfigController2 implements TextWatcher,
setDomainInvisible();
setAnonymousIdentInvisible();
setUserCertInvisible();
mView.findViewById(R.id.l_sim).setVisibility(View.GONE);
break;
case WIFI_EAP_METHOD_TLS:
mView.findViewById(R.id.l_user_cert).setVisibility(View.VISIBLE);
setPhase2Invisible();
setAnonymousIdentInvisible();
setPasswordInvisible();
mView.findViewById(R.id.l_sim).setVisibility(View.GONE);
break;
case WIFI_EAP_METHOD_PEAP:
// Reset adapter if needed
@@ -1198,6 +1227,7 @@ public class WifiConfigController2 implements TextWatcher,
mView.findViewById(R.id.l_phase2).setVisibility(View.VISIBLE);
mView.findViewById(R.id.l_anonymous).setVisibility(View.VISIBLE);
setUserCertInvisible();
mView.findViewById(R.id.l_sim).setVisibility(View.GONE);
break;
case WIFI_EAP_METHOD_SIM:
case WIFI_EAP_METHOD_AKA:
@@ -1235,11 +1265,13 @@ public class WifiConfigController2 implements TextWatcher,
mEapIdentityView.setText("");
mView.findViewById(R.id.l_identity).setVisibility(View.GONE);
setPasswordInvisible();
mView.findViewById(R.id.l_sim).setVisibility(View.VISIBLE);
} else {
mView.findViewById(R.id.l_identity).setVisibility(View.VISIBLE);
mView.findViewById(R.id.l_anonymous).setVisibility(View.VISIBLE);
mView.findViewById(R.id.password_layout).setVisibility(View.VISIBLE);
mView.findViewById(R.id.show_password_layout).setVisibility(View.VISIBLE);
mView.findViewById(R.id.l_sim).setVisibility(View.GONE);
}
}
@@ -1402,6 +1434,44 @@ public class WifiConfigController2 implements TextWatcher,
return KeyStore.getInstance();
}
@VisibleForTesting
void loadSims() {
List<SubscriptionInfo> activeSubscriptionInfos = mContext
.getSystemService(SubscriptionManager.class).getActiveSubscriptionInfoList();
if (activeSubscriptionInfos == null) {
activeSubscriptionInfos = Collections.EMPTY_LIST;
}
mActiveSubscriptionInfos.clear();
// De-duplicates active subscriptions and caches in mActiveSubscriptionInfos.
for (SubscriptionInfo newInfo : activeSubscriptionInfos) {
for (SubscriptionInfo cachedInfo : mActiveSubscriptionInfos) {
if (newInfo.getCarrierId() == cachedInfo.getCarrierId()) {
continue;
}
}
mActiveSubscriptionInfos.add(newInfo);
}
// Shows disabled 'No SIM' when there is no active subscription.
if (mActiveSubscriptionInfos.size() == 0) {
final String[] noSim = new String[]{mContext.getString(R.string.wifi_no_sim_card)};
mEapSimSpinner.setAdapter(getSpinnerAdapter(noSim));
mEapSimSpinner.setSelection(0 /* position */);
mEapSimSpinner.setEnabled(false);
return;
}
// Shows display name of each active subscription.
final String[] displayNames = mActiveSubscriptionInfos.stream().map(
SubscriptionInfo::getDisplayName).toArray(String[]::new);
mEapSimSpinner.setAdapter(getSpinnerAdapter(displayNames));
mEapSimSpinner.setSelection(0 /* position */);
if (displayNames.length == 1) {
mEapSimSpinner.setEnabled(false);
}
}
@VisibleForTesting
void loadCertificates(
Spinner spinner,

View File

@@ -23,8 +23,10 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.settings.SettingsEnums;
import android.content.AsyncQueryHandler;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -41,9 +43,14 @@ import android.net.NetworkRequest;
import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.net.Uri;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.provider.Telephony.CarrierId;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
import android.util.Log;
@@ -97,6 +104,7 @@ import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;
@@ -132,6 +140,8 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle
@VisibleForTesting
static final String KEY_SSID_PREF = "ssid";
@VisibleForTesting
static final String KEY_EAP_SIM_SUBSCRIPTION_PREF = "eap_sim_subscription";
@VisibleForTesting
static final String KEY_MAC_ADDRESS_PREF = "mac_address";
@VisibleForTesting
static final String KEY_IP_ADDRESS_PREF = "ip_address";
@@ -169,6 +179,7 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle
private Preference mFrequencyPref;
private Preference mSecurityPref;
private Preference mSsidPref;
private Preference mEapSimSubscriptionPref;
private Preference mMacAddressPref;
private Preference mIpAddressPref;
private Preference mGatewayPref;
@@ -186,6 +197,35 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle
private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
.clearCapabilities().addTransportType(TRANSPORT_WIFI).build();
private CarrierIdAsyncQueryHandler mCarrierIdAsyncQueryHandler;
private static final int TOKEN_QUERY_CARRIER_ID_AND_UPDATE_SIM_SUMMARY = 1;
private static final int COLUMN_CARRIER_NAME = 0;
private class CarrierIdAsyncQueryHandler extends AsyncQueryHandler {
private CarrierIdAsyncQueryHandler(Context context) {
super(context.getContentResolver());
}
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
if (token == TOKEN_QUERY_CARRIER_ID_AND_UPDATE_SIM_SUMMARY) {
if (mContext == null || cursor == null || !cursor.moveToFirst()) {
if (cursor != null) {
cursor.close();
}
mEapSimSubscriptionPref.setSummary(R.string.wifi_require_sim_card_to_connect);
return;
}
mEapSimSubscriptionPref.setSummary(mContext.getString(
R.string.wifi_require_specific_sim_card_to_connect,
cursor.getString(COLUMN_CARRIER_NAME)));
cursor.close();
return;
}
}
}
// Must be run on the UI thread since it directly manipulates UI state.
private final NetworkCallback mNetworkCallback = new NetworkCallback() {
@Override
@@ -335,6 +375,7 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle
mSecurityPref = screen.findPreference(KEY_SECURITY_PREF);
mSsidPref = screen.findPreference(KEY_SSID_PREF);
mEapSimSubscriptionPref = screen.findPreference(KEY_EAP_SIM_SUBSCRIPTION_PREF);
mMacAddressPref = screen.findPreference(KEY_MAC_ADDRESS_PREF);
mIpAddressPref = screen.findPreference(KEY_IP_ADDRESS_PREF);
mGatewayPref = screen.findPreference(KEY_GATEWAY_PREF);
@@ -506,6 +547,8 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle
refreshIpLayerInfo();
// SSID Pref
refreshSsid();
// EAP SIM subscription
refreshEapSimSubscription();
// MAC Address Pref
refreshMacAddress();
}
@@ -627,6 +670,62 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle
}
}
private void refreshEapSimSubscription() {
mEapSimSubscriptionPref.setVisible(false);
if (mWifiEntry.getSecurity() != WifiEntry.SECURITY_EAP) {
return;
}
final WifiConfiguration config = mWifiEntry.getWifiConfiguration();
if (config == null || config.enterpriseConfig == null) {
return;
}
if (!config.enterpriseConfig.isAuthenticationSimBased()) {
return;
}
mEapSimSubscriptionPref.setVisible(true);
// Checks if the SIM subscription is active.
final List<SubscriptionInfo> activeSubscriptionInfos = mContext
.getSystemService(SubscriptionManager.class).getActiveSubscriptionInfoList();
final int defaultDataSubscriptionId = SubscriptionManager.getDefaultDataSubscriptionId();
if (activeSubscriptionInfos != null) {
for (SubscriptionInfo subscriptionInfo : activeSubscriptionInfos) {
if (config.carrierId == subscriptionInfo.getCarrierId()) {
mEapSimSubscriptionPref.setSummary(subscriptionInfo.getDisplayName());
return;
}
// When it's UNKNOWN_CARRIER_ID, devices connects it with the SIM subscription of
// defaultDataSubscriptionId.
if (config.carrierId == TelephonyManager.UNKNOWN_CARRIER_ID
&& defaultDataSubscriptionId == subscriptionInfo.getSubscriptionId()) {
mEapSimSubscriptionPref.setSummary(subscriptionInfo.getDisplayName());
return;
}
}
}
if (config.carrierId == TelephonyManager.UNKNOWN_CARRIER_ID) {
mEapSimSubscriptionPref.setSummary(R.string.wifi_no_related_sim_card);
return;
}
// The Wi-Fi network has specified carrier id, query carrier name from CarrierIdProvider.
if (mCarrierIdAsyncQueryHandler == null) {
mCarrierIdAsyncQueryHandler = new CarrierIdAsyncQueryHandler(mContext);
}
mCarrierIdAsyncQueryHandler.cancelOperation(TOKEN_QUERY_CARRIER_ID_AND_UPDATE_SIM_SUMMARY);
mCarrierIdAsyncQueryHandler.startQuery(TOKEN_QUERY_CARRIER_ID_AND_UPDATE_SIM_SUMMARY,
null /* cookie */,
CarrierId.All.CONTENT_URI,
new String[]{CarrierId.CARRIER_NAME},
CarrierId.CARRIER_ID + "=?",
new String[] {Integer.toString(config.carrierId)},
null /* orderBy */);
}
private void refreshMacAddress() {
final String macAddress = mWifiEntry.getMacAddress();
if (TextUtils.isEmpty(macAddress)) {