Merge "[Wi-Fi] Support multi-SIM for SIM dependent EAP methods" into rvc-qpr-dev am: edd587c2a6
am: 48d768b00c
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/12167384 Change-Id: I559cee4b76432f72cab16b926ad7d8a2f87abedc
This commit is contained in:
@@ -37,6 +37,8 @@ import android.os.IBinder;
|
|||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.security.Credentials;
|
import android.security.Credentials;
|
||||||
import android.security.KeyStore;
|
import android.security.KeyStore;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
@@ -77,7 +79,9 @@ import java.net.Inet4Address;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -163,7 +167,8 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
|
|
||||||
private ScrollView mDialogContainer;
|
private ScrollView mDialogContainer;
|
||||||
private Spinner mSecuritySpinner;
|
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 mEapCaCertSpinner;
|
||||||
private Spinner mEapOcspSpinner;
|
private Spinner mEapOcspSpinner;
|
||||||
private TextView mEapDomainView;
|
private TextView mEapDomainView;
|
||||||
@@ -209,6 +214,8 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
|
|
||||||
private final WifiManager mWifiManager;
|
private final WifiManager mWifiManager;
|
||||||
|
|
||||||
|
private final List<SubscriptionInfo> mActiveSubscriptionInfos = new ArrayList<>();
|
||||||
|
|
||||||
public WifiConfigController(WifiConfigUiBase parent, View view, AccessPoint accessPoint,
|
public WifiConfigController(WifiConfigUiBase parent, View view, AccessPoint accessPoint,
|
||||||
int mode) {
|
int mode) {
|
||||||
this (parent, view, accessPoint, mode, true /* requestFocus */);
|
this (parent, view, accessPoint, mode, true /* requestFocus */);
|
||||||
@@ -804,6 +811,12 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.enterpriseConfig.isAuthenticationSimBased()
|
||||||
|
&& mActiveSubscriptionInfos.size() > 0) {
|
||||||
|
config.carrierId = mActiveSubscriptionInfos
|
||||||
|
.get(mEapSimSpinner.getSelectedItemPosition()).getCarrierId();
|
||||||
|
}
|
||||||
|
|
||||||
config.setIpConfiguration(
|
config.setIpConfiguration(
|
||||||
new IpConfiguration(mIpAssignment, mProxySettings,
|
new IpConfiguration(mIpAssignment, mProxySettings,
|
||||||
mStaticIpConfiguration, mHttpProxy));
|
mStaticIpConfiguration, mHttpProxy));
|
||||||
@@ -987,6 +1000,7 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
initiateEnterpriseNetworkUi = true;
|
initiateEnterpriseNetworkUi = true;
|
||||||
mEapMethodSpinner = (Spinner) mView.findViewById(R.id.method);
|
mEapMethodSpinner = (Spinner) mView.findViewById(R.id.method);
|
||||||
mEapMethodSpinner.setOnItemSelectedListener(this);
|
mEapMethodSpinner.setOnItemSelectedListener(this);
|
||||||
|
mEapSimSpinner = (Spinner) mView.findViewById(R.id.sim);
|
||||||
mPhase2Spinner = (Spinner) mView.findViewById(R.id.phase2);
|
mPhase2Spinner = (Spinner) mView.findViewById(R.id.phase2);
|
||||||
mPhase2Spinner.setOnItemSelectedListener(this);
|
mPhase2Spinner.setOnItemSelectedListener(this);
|
||||||
mEapCaCertSpinner = (Spinner) mView.findViewById(R.id.ca_cert);
|
mEapCaCertSpinner = (Spinner) mView.findViewById(R.id.ca_cert);
|
||||||
@@ -1023,6 +1037,8 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (refreshCertificates) {
|
if (refreshCertificates) {
|
||||||
|
loadSims();
|
||||||
|
|
||||||
loadCertificates(
|
loadCertificates(
|
||||||
mEapCaCertSpinner,
|
mEapCaCertSpinner,
|
||||||
Credentials.CA_CERTIFICATE,
|
Credentials.CA_CERTIFICATE,
|
||||||
@@ -1044,9 +1060,10 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
|
|
||||||
// Modifying an existing network
|
// Modifying an existing network
|
||||||
if (initiateEnterpriseNetworkUi && mAccessPoint != null && mAccessPoint.isSaved()) {
|
if (initiateEnterpriseNetworkUi && mAccessPoint != null && mAccessPoint.isSaved()) {
|
||||||
WifiEnterpriseConfig enterpriseConfig = mAccessPoint.getConfig().enterpriseConfig;
|
final WifiConfiguration wifiConfig = mAccessPoint.getConfig();
|
||||||
int eapMethod = enterpriseConfig.getEapMethod();
|
final WifiEnterpriseConfig enterpriseConfig = wifiConfig.enterpriseConfig;
|
||||||
int phase2Method = enterpriseConfig.getPhase2Method();
|
final int eapMethod = enterpriseConfig.getEapMethod();
|
||||||
|
final int phase2Method = enterpriseConfig.getPhase2Method();
|
||||||
mEapMethodSpinner.setSelection(eapMethod);
|
mEapMethodSpinner.setSelection(eapMethod);
|
||||||
showEapFieldsByMethod(eapMethod);
|
showEapFieldsByMethod(eapMethod);
|
||||||
switch (eapMethod) {
|
switch (eapMethod) {
|
||||||
@@ -1094,6 +1111,16 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
default:
|
default:
|
||||||
break;
|
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())) {
|
if (!TextUtils.isEmpty(enterpriseConfig.getCaPath())) {
|
||||||
setSelection(mEapCaCertSpinner, mUseSystemCertsString);
|
setSelection(mEapCaCertSpinner, mUseSystemCertsString);
|
||||||
} else {
|
} else {
|
||||||
@@ -1182,6 +1209,7 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
mView.findViewById(R.id.l_ocsp).setVisibility(View.VISIBLE);
|
mView.findViewById(R.id.l_ocsp).setVisibility(View.VISIBLE);
|
||||||
mView.findViewById(R.id.password_layout).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.show_password_layout).setVisibility(View.VISIBLE);
|
||||||
|
mView.findViewById(R.id.l_sim).setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
Context context = mConfigUi.getContext();
|
Context context = mConfigUi.getContext();
|
||||||
switch (eapMethod) {
|
switch (eapMethod) {
|
||||||
@@ -1192,12 +1220,14 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
setDomainInvisible();
|
setDomainInvisible();
|
||||||
setAnonymousIdentInvisible();
|
setAnonymousIdentInvisible();
|
||||||
setUserCertInvisible();
|
setUserCertInvisible();
|
||||||
|
mView.findViewById(R.id.l_sim).setVisibility(View.GONE);
|
||||||
break;
|
break;
|
||||||
case WIFI_EAP_METHOD_TLS:
|
case WIFI_EAP_METHOD_TLS:
|
||||||
mView.findViewById(R.id.l_user_cert).setVisibility(View.VISIBLE);
|
mView.findViewById(R.id.l_user_cert).setVisibility(View.VISIBLE);
|
||||||
setPhase2Invisible();
|
setPhase2Invisible();
|
||||||
setAnonymousIdentInvisible();
|
setAnonymousIdentInvisible();
|
||||||
setPasswordInvisible();
|
setPasswordInvisible();
|
||||||
|
mView.findViewById(R.id.l_sim).setVisibility(View.GONE);
|
||||||
break;
|
break;
|
||||||
case WIFI_EAP_METHOD_PEAP:
|
case WIFI_EAP_METHOD_PEAP:
|
||||||
// Reset adapter if needed
|
// Reset adapter if needed
|
||||||
@@ -1219,6 +1249,7 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
mView.findViewById(R.id.l_phase2).setVisibility(View.VISIBLE);
|
mView.findViewById(R.id.l_phase2).setVisibility(View.VISIBLE);
|
||||||
mView.findViewById(R.id.l_anonymous).setVisibility(View.VISIBLE);
|
mView.findViewById(R.id.l_anonymous).setVisibility(View.VISIBLE);
|
||||||
setUserCertInvisible();
|
setUserCertInvisible();
|
||||||
|
mView.findViewById(R.id.l_sim).setVisibility(View.GONE);
|
||||||
break;
|
break;
|
||||||
case WIFI_EAP_METHOD_SIM:
|
case WIFI_EAP_METHOD_SIM:
|
||||||
case WIFI_EAP_METHOD_AKA:
|
case WIFI_EAP_METHOD_AKA:
|
||||||
@@ -1255,11 +1286,13 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
mEapIdentityView.setText("");
|
mEapIdentityView.setText("");
|
||||||
mView.findViewById(R.id.l_identity).setVisibility(View.GONE);
|
mView.findViewById(R.id.l_identity).setVisibility(View.GONE);
|
||||||
setPasswordInvisible();
|
setPasswordInvisible();
|
||||||
|
mView.findViewById(R.id.l_sim).setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
mView.findViewById(R.id.l_identity).setVisibility(View.VISIBLE);
|
mView.findViewById(R.id.l_identity).setVisibility(View.VISIBLE);
|
||||||
mView.findViewById(R.id.l_anonymous).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.password_layout).setVisibility(View.VISIBLE);
|
||||||
mView.findViewById(R.id.show_password_layout).setVisibility(View.VISIBLE);
|
mView.findViewById(R.id.show_password_layout).setVisibility(View.VISIBLE);
|
||||||
|
mView.findViewById(R.id.l_sim).setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1422,6 +1455,44 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
return KeyStore.getInstance();
|
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
|
@VisibleForTesting
|
||||||
void loadCertificates(
|
void loadCertificates(
|
||||||
Spinner spinner,
|
Spinner spinner,
|
||||||
|
@@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import static org.mockito.Mockito.anyString;
|
import static org.mockito.Mockito.anyString;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.robolectric.Shadows.shadowOf;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
@@ -35,6 +36,9 @@ import android.net.wifi.WifiEnterpriseConfig.Phase2;
|
|||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.ServiceSpecificException;
|
import android.os.ServiceSpecificException;
|
||||||
import android.security.KeyStore;
|
import android.security.KeyStore;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
@@ -58,6 +62,9 @@ import org.robolectric.RuntimeEnvironment;
|
|||||||
import org.robolectric.Shadows;
|
import org.robolectric.Shadows;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.shadows.ShadowInputMethodManager;
|
import org.robolectric.shadows.ShadowInputMethodManager;
|
||||||
|
import org.robolectric.shadows.ShadowSubscriptionManager;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(shadows = ShadowConnectivityManager.class)
|
@Config(shadows = ShadowConnectivityManager.class)
|
||||||
@@ -73,6 +80,7 @@ public class WifiConfigControllerTest {
|
|||||||
private KeyStore mKeyStore;
|
private KeyStore mKeyStore;
|
||||||
private View mView;
|
private View mView;
|
||||||
private Spinner mHiddenSettingsSpinner;
|
private Spinner mHiddenSettingsSpinner;
|
||||||
|
private ShadowSubscriptionManager mShadowSubscriptionManager;
|
||||||
|
|
||||||
public WifiConfigController mController;
|
public WifiConfigController mController;
|
||||||
private static final String HEX_PSK = "01234567012345670123456701234567012345670123456701234567"
|
private static final String HEX_PSK = "01234567012345670123456701234567012345670123456701234567"
|
||||||
@@ -97,6 +105,7 @@ public class WifiConfigControllerTest {
|
|||||||
final Spinner ipSettingsSpinner = mView.findViewById(R.id.ip_settings);
|
final Spinner ipSettingsSpinner = mView.findViewById(R.id.ip_settings);
|
||||||
mHiddenSettingsSpinner = mView.findViewById(R.id.hidden_settings);
|
mHiddenSettingsSpinner = mView.findViewById(R.id.hidden_settings);
|
||||||
ipSettingsSpinner.setSelection(DHCP);
|
ipSettingsSpinner.setSelection(DHCP);
|
||||||
|
mShadowSubscriptionManager = shadowOf(mContext.getSystemService(SubscriptionManager.class));
|
||||||
|
|
||||||
mController = new TestWifiConfigController(mConfigUiBase, mView, mAccessPoint,
|
mController = new TestWifiConfigController(mConfigUiBase, mView, mAccessPoint,
|
||||||
WifiConfigUiBase.MODE_CONNECT);
|
WifiConfigUiBase.MODE_CONNECT);
|
||||||
@@ -599,4 +608,41 @@ public class WifiConfigControllerTest {
|
|||||||
|
|
||||||
assertThat(advButton.getVisibility()).isEqualTo(View.GONE);
|
assertThat(advButton.getVisibility()).isEqualTo(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadSims_noSim_simSpinnerDefaultNoSim() {
|
||||||
|
when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_EAP);
|
||||||
|
mController = new TestWifiConfigController(mConfigUiBase, mView, mAccessPoint,
|
||||||
|
WifiConfigUiBase.MODE_CONNECT);
|
||||||
|
final Spinner eapMethodSpinner = mock(Spinner.class);
|
||||||
|
when(eapMethodSpinner.getSelectedItemPosition()).thenReturn(
|
||||||
|
WifiConfigController2.WIFI_EAP_METHOD_SIM);
|
||||||
|
mController.mEapMethodSpinner = eapMethodSpinner;
|
||||||
|
|
||||||
|
mController.loadSims();
|
||||||
|
|
||||||
|
final WifiConfiguration wifiConfiguration = mController.getConfig();
|
||||||
|
assertThat(wifiConfiguration.carrierId).isEqualTo(TelephonyManager.UNKNOWN_CARRIER_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadSims_oneSim_simSpinnerDefaultSubscription() {
|
||||||
|
when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_EAP);
|
||||||
|
final SubscriptionInfo subscriptionInfo = mock(SubscriptionInfo.class);
|
||||||
|
final int carrierId = 6;
|
||||||
|
when(subscriptionInfo.getCarrierId()).thenReturn(carrierId);
|
||||||
|
when(subscriptionInfo.getCarrierName()).thenReturn("FAKE-CARRIER");
|
||||||
|
mShadowSubscriptionManager.setActiveSubscriptionInfoList(Arrays.asList(subscriptionInfo));
|
||||||
|
mController = new TestWifiConfigController(mConfigUiBase, mView, mAccessPoint,
|
||||||
|
WifiConfigUiBase.MODE_CONNECT);
|
||||||
|
final Spinner eapMethodSpinner = mock(Spinner.class);
|
||||||
|
when(eapMethodSpinner.getSelectedItemPosition()).thenReturn(
|
||||||
|
WifiConfigController2.WIFI_EAP_METHOD_SIM);
|
||||||
|
mController.mEapMethodSpinner = eapMethodSpinner;
|
||||||
|
|
||||||
|
mController.loadSims();
|
||||||
|
|
||||||
|
final WifiConfiguration wifiConfiguration = mController.getConfig();
|
||||||
|
assertThat(wifiConfiguration.carrierId).isEqualTo(carrierId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user