summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Liu <steveliu@google.com>2019-11-20 01:52:31 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-11-20 01:52:31 +0000
commit970933dfbb153bb05d30f3f67c25fb0b19d89a6e (patch)
tree704f5d86db981556f9597fce811af6c97ad72870
parentafe241c3d4c240f4cd43801315d4a02b2cf7658b (diff)
parent4d315c818814bc3ebd5e5c75062b41724c060a0e (diff)
Merge "Add support of passpoint with SIM credential for dual SIM"
-rw-r--r--service/java/com/android/server/wifi/IMSIParameter.java9
-rw-r--r--service/java/com/android/server/wifi/SIMAccessor.java37
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java6
-rw-r--r--service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java36
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java10
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointManager.java28
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java6
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java12
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointProvider.java71
-rw-r--r--service/java/com/android/server/wifi/util/TelephonyUtil.java190
-rw-r--r--tests/wifitests/Android.bp1
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java4
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java4
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java29
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java12
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java129
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java28
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java87
-rw-r--r--tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java309
19 files changed, 793 insertions, 215 deletions
diff --git a/service/java/com/android/server/wifi/IMSIParameter.java b/service/java/com/android/server/wifi/IMSIParameter.java
index 5754fb132..45279864a 100644
--- a/service/java/com/android/server/wifi/IMSIParameter.java
+++ b/service/java/com/android/server/wifi/IMSIParameter.java
@@ -117,6 +117,15 @@ public class IMSIParameter {
return mImsi.regionMatches(false, 0, mccMnc, 0, checkLength);
}
+ /**
+ * If the IMSI is full length.
+ *
+ * @return true If the length of IMSI is full, false otherwise.
+ */
+ public boolean isFullImsi() {
+ return !mPrefix;
+ }
+
@Override
public boolean equals(Object thatObject) {
if (this == thatObject) {
diff --git a/service/java/com/android/server/wifi/SIMAccessor.java b/service/java/com/android/server/wifi/SIMAccessor.java
deleted file mode 100644
index 13186f1e1..000000000
--- a/service/java/com/android/server/wifi/SIMAccessor.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.android.server.wifi;
-
-import android.content.Context;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class SIMAccessor {
- private final TelephonyManager mTelephonyManager;
- private final SubscriptionManager mSubscriptionManager;
-
- public SIMAccessor(Context context) {
- // TODO(b/132188983): Inject this using WifiInjector
- mTelephonyManager = context.getSystemService(TelephonyManager.class);
- // TODO(b/132188983): Inject this using WifiInjector
- mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
- }
-
- public List<String> getMatchingImsis(IMSIParameter mccMnc) {
- if (mccMnc == null) {
- return null;
- }
- List<String> imsis = new ArrayList<>();
- for (SubscriptionInfo sub : mSubscriptionManager.getActiveSubscriptionInfoList()) {
- String imsi =
- mTelephonyManager.createForSubscriptionId(sub.getSubscriptionId())
- .getSubscriberId();
- if (imsi != null && mccMnc.matchesImsi(imsi)) {
- imsis.add(imsi);
- }
- }
- return imsis.isEmpty() ? null : imsis;
- }
-}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 683db73f6..35fd64c5e 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -134,7 +134,6 @@ public class WifiInjector {
private final WifiPermissionsWrapper mWifiPermissionsWrapper;
private final WifiPermissionsUtil mWifiPermissionsUtil;
private final PasspointManager mPasspointManager;
- private final SIMAccessor mSimAccessor;
private HandlerThread mWifiAwareHandlerThread;
private HandlerThread mRttHandlerThread;
private HalDeviceManager mHalDeviceManager;
@@ -300,11 +299,10 @@ public class WifiInjector {
mWifiNetworkScoreCache, mWifiPermissionsUtil);
mCarrierNetworkEvaluator = new CarrierNetworkEvaluator(mWifiConfigManager,
mCarrierNetworkConfig, mConnectivityLocalLog, this);
- mSimAccessor = new SIMAccessor(mContext);
mPasspointManager = new PasspointManager(mContext, this,
wifiHandler, mWifiNative, mWifiKeyStore, mClock,
- mSimAccessor, new PasspointObjectFactory(), mWifiConfigManager, mWifiConfigStore,
- mWifiMetrics, subscriptionManager);
+ new PasspointObjectFactory(), mWifiConfigManager, mWifiConfigStore,
+ mWifiMetrics, mTelephonyUtil);
mPasspointNetworkEvaluator = new PasspointNetworkEvaluator(
mPasspointManager, mWifiConfigManager, mConnectivityLocalLog,
this, subscriptionManager);
diff --git a/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java b/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java
index bef7a9f9a..56836a4bb 100644
--- a/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java
+++ b/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java
@@ -16,6 +16,8 @@
package com.android.server.wifi.hotspot2;
+import android.text.TextUtils;
+
import com.android.server.wifi.IMSIParameter;
import com.android.server.wifi.hotspot2.anqp.CellularNetwork;
import com.android.server.wifi.hotspot2.anqp.DomainNameElement;
@@ -43,12 +45,12 @@ public class ANQPMatcher {
* @param element The Domain Name ANQP element
* @param fqdn The FQDN to compare against
* @param imsiParam The IMSI parameter of the provider
- * @param simImsiList The list of IMSI from the installed SIM cards that matched provider's
+ * @param simImsi The IMSI from the installed SIM cards that best matched provider's
* IMSI parameter
* @return true if a match is found
*/
public static boolean matchDomainName(DomainNameElement element, String fqdn,
- IMSIParameter imsiParam, List<String> simImsiList) {
+ IMSIParameter imsiParam, String simImsi) {
if (element == null) {
return false;
}
@@ -60,7 +62,7 @@ public class ANQPMatcher {
// Try to retrieve the MCC-MNC string from the domain (for 3GPP network domain) and
// match against the provider's SIM credential.
- if (matchMccMnc(Utils.getMccMnc(Utils.splitDomain(domain)), imsiParam, simImsiList)) {
+ if (matchMccMnc(Utils.getMccMnc(Utils.splitDomain(domain)), imsiParam, simImsi)) {
return true;
}
}
@@ -126,17 +128,17 @@ public class ANQPMatcher {
*
* @param element 3GPP Network ANQP element
* @param imsiParam The IMSI parameter of the provider's SIM credential
- * @param simImsiList The list of IMSI from the installed SIM cards that matched provider's
+ * @param simImsi The IMSI from the installed SIM cards that best matched provider's
* IMSI parameter
* @return true if a matched is found
*/
public static boolean matchThreeGPPNetwork(ThreeGPPNetworkElement element,
- IMSIParameter imsiParam, List<String> simImsiList) {
+ IMSIParameter imsiParam, String simImsi) {
if (element == null) {
return false;
}
for (CellularNetwork network : element.getNetworks()) {
- if (matchCellularNetwork(network, imsiParam, simImsiList)) {
+ if (matchCellularNetwork(network, imsiParam, simImsi)) {
return true;
}
}
@@ -220,17 +222,18 @@ public class ANQPMatcher {
*
* @param network The cellular network that contained list of PLMNs
* @param imsiParam IMSI parameter of the provider
- * @param simImsiList The list of IMSI from the installed SIM cards that matched provider's
+ * @param simImsi The IMSI from the installed SIM cards that best matched provider's
* IMSI parameter
* @return true if a match is found
*/
private static boolean matchCellularNetwork(CellularNetwork network, IMSIParameter imsiParam,
- List<String> simImsiList) {
+ String simImsi) {
for (String plmn : network.getPlmns()) {
- if (matchMccMnc(plmn, imsiParam, simImsiList)) {
+ if (matchMccMnc(plmn, imsiParam, simImsi)) {
return true;
}
}
+
return false;
}
@@ -239,27 +242,22 @@ public class ANQPMatcher {
*
* @param mccMnc The string containing MCC-MNC
* @param imsiParam The IMSI parameter of the provider
- * @param simImsiList The list of IMSI from the installed SIM cards that matched provider's
+ * @param simImsi The IMSI from the installed SIM cards that best matched provider's
* IMSI parameter
* @return true if a match is found
*/
private static boolean matchMccMnc(String mccMnc, IMSIParameter imsiParam,
- List<String> simImsiList) {
- if (imsiParam == null || simImsiList == null || mccMnc == null) {
+ String simImsi) {
+ if (imsiParam == null || TextUtils.isEmpty(simImsi) || mccMnc == null) {
return false;
}
// Match against the IMSI parameter in the provider.
if (!imsiParam.matchesMccMnc(mccMnc)) {
return false;
}
- // Additional check for verifying the match with IMSIs from the SIM cards, since the IMSI
+ // Additional check for verifying the match with IMSI from the SIM card, since the IMSI
// parameter might not contain the full 6-digit MCC MNC (e.g. IMSI parameter is an IMSI
// prefix that contained less than 6-digit of numbers "12345*").
- for (String imsi : simImsiList) {
- if (imsi.startsWith(mccMnc)) {
- return true;
- }
- }
- return false;
+ return simImsi.startsWith(mccMnc);
}
}
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java b/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
index 9e64417d0..1be093eb8 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
@@ -22,9 +22,9 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.internal.util.XmlUtils;
-import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.WifiConfigStore;
import com.android.server.wifi.WifiKeyStore;
+import com.android.server.wifi.util.TelephonyUtil;
import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
@@ -77,7 +77,7 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData {
private static final String XML_TAG_IS_FROM_SUGGESTION = "IsFromSuggestion";
private final WifiKeyStore mKeyStore;
- private final SIMAccessor mSimAccessor;
+ private final TelephonyUtil mTelephonyUtil;
private final DataSource mDataSource;
/**
@@ -99,10 +99,10 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData {
void setProviders(List<PasspointProvider> providers);
}
- PasspointConfigUserStoreData(WifiKeyStore keyStore, SIMAccessor simAccessor,
+ PasspointConfigUserStoreData(WifiKeyStore keyStore, TelephonyUtil telephonyUtil,
DataSource dataSource) {
mKeyStore = keyStore;
- mSimAccessor = simAccessor;
+ mTelephonyUtil = telephonyUtil;
mDataSource = dataSource;
}
@@ -343,7 +343,7 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData {
if (config == null) {
throw new XmlPullParserException("Missing Passpoint configuration");
}
- return new PasspointProvider(config, mKeyStore, mSimAccessor, providerId, creatorUid,
+ return new PasspointProvider(config, mKeyStore, mTelephonyUtil, providerId, creatorUid,
packageName, isFromSuggestion, caCertificateAliases,
clientPrivateKeyAndCertificateAlias, remediationCaCertificateAlias,
hasEverConnected, shared);
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
index bce2f6c69..0d5f9043e 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
@@ -44,13 +44,11 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Process;
import android.os.UserHandle;
-import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import com.android.server.wifi.Clock;
-import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.WifiConfigManager;
import com.android.server.wifi.WifiConfigStore;
import com.android.server.wifi.WifiInjector;
@@ -62,6 +60,7 @@ import com.android.server.wifi.hotspot2.anqp.Constants;
import com.android.server.wifi.hotspot2.anqp.HSOsuProvidersElement;
import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo;
import com.android.server.wifi.util.InformationElementUtil;
+import com.android.server.wifi.util.TelephonyUtil;
import java.io.PrintWriter;
import java.security.cert.X509Certificate;
@@ -106,7 +105,6 @@ public class PasspointManager {
private final PasspointEventHandler mPasspointEventHandler;
private final WifiInjector mWifiInjector;
private final Handler mHandler;
- private final SIMAccessor mSimAccessor;
private final WifiKeyStore mKeyStore;
private final PasspointObjectFactory mObjectFactory;
@@ -118,7 +116,7 @@ public class PasspointManager {
private final WifiMetrics mWifiMetrics;
private final PasspointProvisioner mPasspointProvisioner;
private final AppOpsManager mAppOps;
- private final SubscriptionManager mSubscriptionManager;
+ private final TelephonyUtil mTelephonyUtil;
/**
* Map of package name of an app to the app ops changed listener for the app.
@@ -321,17 +319,16 @@ public class PasspointManager {
}
public PasspointManager(Context context, WifiInjector wifiInjector, Handler handler,
- WifiNative wifiNative, WifiKeyStore keyStore, Clock clock, SIMAccessor simAccessor,
+ WifiNative wifiNative, WifiKeyStore keyStore, Clock clock,
PasspointObjectFactory objectFactory, WifiConfigManager wifiConfigManager,
WifiConfigStore wifiConfigStore,
WifiMetrics wifiMetrics,
- SubscriptionManager subscriptionManager) {
+ TelephonyUtil telephonyUtil) {
mPasspointEventHandler = objectFactory.makePasspointEventHandler(wifiNative,
new CallbackHandler(context));
mWifiInjector = wifiInjector;
mHandler = handler;
mKeyStore = keyStore;
- mSimAccessor = simAccessor;
mObjectFactory = objectFactory;
mProviders = new HashMap<>();
mAnqpCache = objectFactory.makeAnqpCache(clock);
@@ -340,9 +337,9 @@ public class PasspointManager {
mWifiConfigManager = wifiConfigManager;
mWifiMetrics = wifiMetrics;
mProviderIndex = 0;
- mSubscriptionManager = subscriptionManager;
+ mTelephonyUtil = telephonyUtil;
wifiConfigStore.registerStoreData(objectFactory.makePasspointConfigUserStoreData(
- mKeyStore, mSimAccessor, new UserDataSourceHandler()));
+ mKeyStore, mTelephonyUtil, new UserDataSourceHandler()));
wifiConfigStore.registerStoreData(objectFactory.makePasspointConfigSharedStoreData(
new SharedDataSourceHandler()));
mPasspointProvisioner = objectFactory.makePasspointProvisioner(context, wifiNative,
@@ -409,9 +406,10 @@ public class PasspointManager {
}
}
+ mTelephonyUtil.tryUpdateCarrierIdForPasspoint(config);
// Create a provider and install the necessary certificates and keys.
PasspointProvider newProvider = mObjectFactory.makePasspointProvider(config, mKeyStore,
- mSimAccessor, mProviderIndex++, uid, packageName, isFromSuggestion);
+ mTelephonyUtil, mProviderIndex++, uid, packageName, isFromSuggestion);
if (!newProvider.installCertsAndKeys()) {
Log.e(TAG, "Failed to install certificates and keys to keystore");
@@ -588,8 +586,12 @@ public class PasspointManager {
Log.d(TAG, "ANQP entry not found for: " + anqpKey);
return allMatches;
}
+ boolean anyProviderUpdated = false;
for (Map.Entry<String, PasspointProvider> entry : mProviders.entrySet()) {
PasspointProvider provider = entry.getValue();
+ if (provider.tryUpdateCarrierId()) {
+ anyProviderUpdated = true;
+ }
PasspointMatch matchStatus = provider.match(anqpEntry.getElements(),
roamingConsortium);
if (matchStatus == PasspointMatch.HomeProvider
@@ -606,6 +608,9 @@ public class PasspointManager {
allMatches.add(Pair.create(provider, matchStatus));
}
}
+ if (anyProviderUpdated) {
+ mWifiConfigManager.saveToStore(true);
+ }
if (allMatches.size() != 0) {
for (Pair<PasspointProvider, PasspointMatch> match : allMatches) {
Log.d(TAG, String.format("Matched %s to %s as %s", scanResult.SSID,
@@ -955,7 +960,8 @@ public class PasspointManager {
// Note that for legacy configuration, the alias for client private key is the same as the
// alias for the client certificate.
PasspointProvider provider = new PasspointProvider(passpointConfig, mKeyStore,
- mSimAccessor, mProviderIndex++, wifiConfig.creatorUid, null, false,
+ mTelephonyUtil,
+ mProviderIndex++, wifiConfig.creatorUid, null, false,
Arrays.asList(enterpriseConfig.getCaCertificateAlias()),
enterpriseConfig.getClientCertificateAlias(), null, false, false);
mProviders.put(passpointConfig.getHomeSp().getFqdn(), provider);
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java
index 872889f81..3707e1c13 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java
@@ -31,7 +31,6 @@ import com.android.server.wifi.WifiConfigManager;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiNetworkSelector;
import com.android.server.wifi.util.ScanResultUtil;
-import com.android.server.wifi.util.TelephonyUtil;
import java.util.ArrayList;
import java.util.List;
@@ -118,11 +117,6 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva
Pair<PasspointProvider, PasspointMatch> bestProvider =
mPasspointManager.matchProvider(scanResult);
if (bestProvider != null) {
- if (bestProvider.first.isSimCredential()
- && !TelephonyUtil.isSimPresent(mSubscriptionManager)) {
- // Skip providers backed by SIM credential when SIM is not present.
- continue;
- }
candidateList.add(new PasspointNetworkCandidate(
bestProvider.first, bestProvider.second, scanDetail));
}
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java b/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java
index 94be270e2..8c1f68b92 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java
@@ -21,10 +21,10 @@ import android.net.wifi.hotspot2.PasspointConfiguration;
import com.android.org.conscrypt.TrustManagerImpl;
import com.android.server.wifi.Clock;
-import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.WifiKeyStore;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.util.TelephonyUtil;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
@@ -58,9 +58,9 @@ public class PasspointObjectFactory{
* @return {@link PasspointProvider}
*/
public PasspointProvider makePasspointProvider(PasspointConfiguration config,
- WifiKeyStore keyStore, SIMAccessor simAccessor, long providerId, int creatorUid,
+ WifiKeyStore keyStore, TelephonyUtil telephonyUtil, long providerId, int creatorUid,
String packageName, boolean isFromSuggestion) {
- return new PasspointProvider(config, keyStore, simAccessor, providerId, creatorUid,
+ return new PasspointProvider(config, keyStore, telephonyUtil, providerId, creatorUid,
packageName, isFromSuggestion);
}
@@ -68,13 +68,13 @@ public class PasspointObjectFactory{
* Create a {@link PasspointConfigUserStoreData} instance.
*
* @param keyStore Instance of {@link WifiKeyStore}
- * @param simAccessor Instance of {@link SIMAccessor}
+ * @param telephonyUtil Instance of {@link TelephonyUtil}
* @param dataSource Passpoint configuration data source
* @return {@link PasspointConfigUserStoreData}
*/
public PasspointConfigUserStoreData makePasspointConfigUserStoreData(WifiKeyStore keyStore,
- SIMAccessor simAccessor, PasspointConfigUserStoreData.DataSource dataSource) {
- return new PasspointConfigUserStoreData(keyStore, simAccessor, dataSource);
+ TelephonyUtil telephonyUtil, PasspointConfigUserStoreData.DataSource dataSource) {
+ return new PasspointConfigUserStoreData(keyStore, telephonyUtil, dataSource);
}
/**
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
index 111048d2b..f9ef69eb8 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
@@ -25,13 +25,14 @@ import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.Credential.SimCredential;
import android.net.wifi.hotspot2.pps.Credential.UserCredential;
import android.net.wifi.hotspot2.pps.HomeSp;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
+import android.util.Pair;
import com.android.internal.util.ArrayUtils;
import com.android.server.wifi.IMSIParameter;
-import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.WifiKeyStore;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType;
@@ -42,6 +43,7 @@ import com.android.server.wifi.hotspot2.anqp.ThreeGPPNetworkElement;
import com.android.server.wifi.hotspot2.anqp.eap.AuthParam;
import com.android.server.wifi.hotspot2.anqp.eap.NonEAPInnerAuth;
import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium;
+import com.android.server.wifi.util.TelephonyUtil;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
@@ -91,24 +93,26 @@ public class PasspointProvider {
private final String mPackageName;
private final IMSIParameter mImsiParameter;
- private final List<String> mMatchingSIMImsiList;
private final int mEAPMethodID;
private final AuthParam mAuthParam;
+ private final TelephonyUtil mTelephonyUtil;
+ private int mBestGuessCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
private boolean mHasEverConnected;
private boolean mIsShared;
private boolean mIsFromSuggestion;
+
public PasspointProvider(PasspointConfiguration config, WifiKeyStore keyStore,
- SIMAccessor simAccessor, long providerId, int creatorUid, String packageName,
+ TelephonyUtil telephonyUtil, long providerId, int creatorUid, String packageName,
boolean isFromSuggestion) {
- this(config, keyStore, simAccessor, providerId, creatorUid, packageName, isFromSuggestion,
+ this(config, keyStore, telephonyUtil, providerId, creatorUid, packageName, isFromSuggestion,
null, null, null, false, false);
}
public PasspointProvider(PasspointConfiguration config, WifiKeyStore keyStore,
- SIMAccessor simAccessor, long providerId, int creatorUid, String packageName,
+ TelephonyUtil telephonyUtil, long providerId, int creatorUid, String packageName,
boolean isFromSuggestion, List<String> caCertificateAliases,
String clientPrivateKeyAndCertificateAlias,
String remediationCaCertificateAlias,
@@ -125,6 +129,7 @@ public class PasspointProvider {
mHasEverConnected = hasEverConnected;
mIsShared = isShared;
mIsFromSuggestion = isFromSuggestion;
+ mTelephonyUtil = telephonyUtil;
// Setup EAP method and authentication parameter based on the credential.
if (mConfig.getCredential().getUserCredential() != null) {
@@ -132,18 +137,15 @@ public class PasspointProvider {
mAuthParam = new NonEAPInnerAuth(NonEAPInnerAuth.getAuthTypeID(
mConfig.getCredential().getUserCredential().getNonEapInnerMethod()));
mImsiParameter = null;
- mMatchingSIMImsiList = null;
} else if (mConfig.getCredential().getCertCredential() != null) {
mEAPMethodID = EAPConstants.EAP_TLS;
mAuthParam = null;
mImsiParameter = null;
- mMatchingSIMImsiList = null;
} else {
mEAPMethodID = mConfig.getCredential().getSimCredential().getEapType();
mAuthParam = null;
mImsiParameter = IMSIParameter.build(
mConfig.getCredential().getSimCredential().getImsi());
- mMatchingSIMImsiList = simAccessor.getMatchingImsis(mImsiParameter);
}
}
@@ -288,6 +290,34 @@ public class PasspointProvider {
}
/**
+ * Try to update the carrier ID according to the IMSI parameter of passpoint configuration.
+ *
+ * @return true if the carrier ID is updated, otherwise false.
+ */
+ public boolean tryUpdateCarrierId() {
+ return mTelephonyUtil.tryUpdateCarrierIdForPasspoint(mConfig);
+ }
+
+ private @Nullable String getMatchingSimImsi() {
+ String matchingSIMImsi = null;
+ if (mConfig.getCarrierId() != TelephonyManager.UNKNOWN_CARRIER_ID) {
+ matchingSIMImsi = mTelephonyUtil
+ .getMatchingImsi(mConfig.getCarrierId());
+ } else {
+ // Get the IMSI and carrier ID of SIM card which match with the IMSI prefix from
+ // passpoint profile
+ Pair<String, Integer> imsiCarrierIdPair = mTelephonyUtil.getMatchingImsiCarrierId(
+ mConfig.getCredential().getSimCredential().getImsi());
+ if (imsiCarrierIdPair != null) {
+ matchingSIMImsi = imsiCarrierIdPair.first;
+ mBestGuessCarrierId = imsiCarrierIdPair.second;
+ }
+ }
+
+ return matchingSIMImsi;
+ }
+
+ /**
* Return the matching status with the given AP, based on the ANQP elements from the AP.
*
* @param anqpElements ANQP elements from the AP
@@ -296,12 +326,23 @@ public class PasspointProvider {
*/
public PasspointMatch match(Map<ANQPElementType, ANQPElement> anqpElements,
RoamingConsortium roamingConsortium) {
- PasspointMatch providerMatch = matchProviderExceptFor3GPP(anqpElements, roamingConsortium);
+
+ String matchingSimImsi = null;
+ if (mConfig.getCredential().getSimCredential() != null) {
+ matchingSimImsi = getMatchingSimImsi();
+ if (TextUtils.isEmpty(matchingSimImsi)) {
+ Log.d(TAG, "No SIM card for this profile with SIM credential.");
+ return PasspointMatch.None;
+ }
+ }
+
+ PasspointMatch providerMatch = matchProviderExceptFor3GPP(
+ anqpElements, roamingConsortium, matchingSimImsi);
// 3GPP Network matching.
if (providerMatch == PasspointMatch.None && ANQPMatcher.matchThreeGPPNetwork(
(ThreeGPPNetworkElement) anqpElements.get(ANQPElementType.ANQP3GPPNetwork),
- mImsiParameter, mMatchingSIMImsiList)) {
+ mImsiParameter, matchingSimImsi)) {
return PasspointMatch.RoamingProvider;
}
@@ -353,6 +394,11 @@ public class PasspointProvider {
wifiConfig.providerFriendlyName = mConfig.getHomeSp().getFriendlyName();
wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
+ int carrierId = mConfig.getCarrierId();
+ if (carrierId == TelephonyManager.UNKNOWN_CARRIER_ID) {
+ carrierId = mBestGuessCarrierId;
+ }
+ wifiConfig.carrierId = carrierId;
// Set RSN only to tell wpa_supplicant that this network is for Passpoint.
wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
@@ -425,6 +471,7 @@ public class PasspointProvider {
wifiConfig.roamingConsortiumIds, wifiConfig.roamingConsortiumIds.length));
}
passpointConfig.setHomeSp(homeSp);
+ passpointConfig.setCarrierId(wifiConfig.carrierId);
// Setup Credential.
Credential credential = new Credential();
@@ -563,11 +610,11 @@ public class PasspointProvider {
*/
private PasspointMatch matchProviderExceptFor3GPP(
Map<ANQPElementType, ANQPElement> anqpElements,
- RoamingConsortium roamingConsortium) {
+ RoamingConsortium roamingConsortium, String matchingSIMImsi) {
// Domain name matching.
if (ANQPMatcher.matchDomainName(
(DomainNameElement) anqpElements.get(ANQPElementType.ANQPDomName),
- mConfig.getHomeSp().getFqdn(), mImsiParameter, mMatchingSIMImsiList)) {
+ mConfig.getHomeSp().getFqdn(), mImsiParameter, matchingSIMImsi)) {
return PasspointMatch.HomeProvider;
}
diff --git a/service/java/com/android/server/wifi/util/TelephonyUtil.java b/service/java/com/android/server/wifi/util/TelephonyUtil.java
index e9f0a4686..b1dda6dfb 100644
--- a/service/java/com/android/server/wifi/util/TelephonyUtil.java
+++ b/service/java/com/android/server/wifi/util/TelephonyUtil.java
@@ -19,6 +19,8 @@ package com.android.server.wifi.util;
import android.annotation.NonNull;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
+import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.pps.Credential;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -29,6 +31,7 @@ import android.util.Log;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.IMSIParameter;
import com.android.server.wifi.WifiNative;
import java.security.InvalidKeyException;
@@ -37,7 +40,7 @@ import java.security.PublicKey;
import java.util.HashMap;
import java.util.List;
-import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
@@ -99,23 +102,24 @@ public class TelephonyUtil {
* @param config the instance of {@link WifiConfiguration}
* @return the best match SubscriptionId
*/
- public int getBestMatchSubscriptionId(WifiConfiguration config) {
+ public int getBestMatchSubscriptionId(@NonNull WifiConfiguration config) {
+ if (config.isPasspoint()) {
+ return getMatchingSubId(config.carrierId);
+ } else {
+ return getBestMatchSubscriptionIdForEnterprise(config);
+ }
+ }
+
+ private int getMatchingSubId(int carrierId) {
List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
if (subInfoList == null || subInfoList.isEmpty()) {
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
- // Legacy WifiConfiguration without carrier ID
- if (config.carrierId == TelephonyManager.UNKNOWN_CARRIER_ID
- && config.enterpriseConfig != null
- && config.enterpriseConfig.requireSimCredential()) {
- Log.d(TAG, "carrierId is not assigned, using the default data sub.");
- return SubscriptionManager.getDefaultDataSubscriptionId();
- }
int dataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
int matchSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
for (SubscriptionInfo subInfo : subInfoList) {
- if (subInfo.getCarrierId() == config.carrierId) {
+ if (subInfo.getCarrierId() == carrierId) {
matchSubId = subInfo.getSubscriptionId();
if (matchSubId == dataSubId) {
// Priority of Data sub is higher than non data sub.
@@ -123,10 +127,29 @@ public class TelephonyUtil {
}
}
}
- Log.d(TAG, "best match subscription id: " + matchSubId);
+ Log.d(TAG, "matching subId is " + matchSubId);
return matchSubId;
}
+ private int getBestMatchSubscriptionIdForEnterprise(WifiConfiguration config) {
+ if (config.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
+ return getMatchingSubId(config.carrierId);
+ }
+ // Legacy WifiConfiguration without carrier ID
+ if (config.enterpriseConfig == null
+ || !config.enterpriseConfig.requireSimCredential()) {
+ Log.w(TAG, "The legacy config is not using EAP-SIM.");
+ return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ }
+ int dataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
+ if (isSimPresent(dataSubId)) {
+ Log.d(TAG, "carrierId is not assigned, using the default data sub.");
+ return dataSubId;
+ }
+ Log.d(TAG, "data sim is not present.");
+ return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ }
+
/**
* Check if the specified SIM card is in the device.
*
@@ -751,36 +774,28 @@ public class TelephonyUtil {
/**
* Get the carrier type of current SIM.
*
- * @param tm {@link TelephonyManager} instance
+ * @param subId the subscription ID of SIM card.
* @return carrier type of current active sim, {{@link #CARRIER_INVALID_TYPE}} if sim is not
- * ready or {@code tm} is {@code null}
+ * ready.
*/
- public static int getCarrierType(@NonNull TelephonyManager tm) {
- if (tm == null) {
+ private int getCarrierType(int subId) {
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
return CARRIER_INVALID_TYPE;
}
- TelephonyManager defaultDataTm = tm.createForSubscriptionId(
- SubscriptionManager.getDefaultDataSubscriptionId());
+ TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(subId);
- if (defaultDataTm.getSimState() != TelephonyManager.SIM_STATE_READY) {
+ if (specifiedTm.getSimState() != TelephonyManager.SIM_STATE_READY) {
return CARRIER_INVALID_TYPE;
}
// If two APIs return the same carrier ID, then is considered as MNO, otherwise MVNO
- if (defaultDataTm.getCarrierIdFromSimMccMnc() == defaultDataTm.getSimCarrierId()) {
+ if (specifiedTm.getCarrierIdFromSimMccMnc() == specifiedTm.getSimCarrierId()) {
return CARRIER_MNO_TYPE;
}
return CARRIER_MVNO_TYPE;
}
/**
- * Returns true if at least one SIM is present on the device, false otherwise.
- */
- public static boolean isSimPresent(@Nonnull SubscriptionManager sm) {
- return !sm.getActiveSubscriptionInfoList().isEmpty();
- }
-
- /**
* Decorates a pseudonym with the NAI realm, in case it wasn't provided by the server
*
* @param config The instance of WifiConfiguration
@@ -832,4 +847,127 @@ public class TelephonyUtil {
TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(subId);
specifiedTm.resetCarrierKeysForImsiEncryption();
}
+
+ /**
+ * Updates the carrier ID for passpoint configuration with SIM credential.
+ *
+ * @param config The instance of PasspointConfiguration.
+ * @return true if the carrier ID is updated, false otherwise
+ */
+ public boolean tryUpdateCarrierIdForPasspoint(PasspointConfiguration config) {
+ if (config.getCarrierId() != TelephonyManager.UNKNOWN_CARRIER_ID) {
+ return false;
+ }
+
+ Credential.SimCredential simCredential = config.getCredential().getSimCredential();
+ if (simCredential == null) {
+ // carrier ID is not required.
+ return false;
+ }
+
+ IMSIParameter imsiParameter = IMSIParameter.build(simCredential.getImsi());
+ // If the IMSI is not full, the carrier ID can not be matched for sure, so it should
+ // be ignored.
+ if (imsiParameter == null || !imsiParameter.isFullImsi()) {
+ Log.d(TAG, "IMSI is not available or not full");
+ return false;
+ }
+ List<SubscriptionInfo> infos = mSubscriptionManager.getActiveSubscriptionInfoList();
+ if (infos == null) {
+ return false;
+ }
+ // Find the active matching SIM card with the full IMSI from passpoint profile.
+ for (SubscriptionInfo subInfo : infos) {
+ TelephonyManager specifiedTm =
+ mTelephonyManager.createForSubscriptionId(subInfo.getSubscriptionId());
+ String imsi = specifiedTm.getSubscriberId();
+ if (imsiParameter.matchesImsi(imsi)) {
+ config.setCarrierId(subInfo.getCarrierId());
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the IMSI and carrier ID of the SIM card which is matched with the given carrier ID.
+ *
+ * @param carrierId The carrier ID see {@link TelephonyManager.getSimCarrierId}
+ * @return null if there is no matching SIM card, otherwise the IMSI and carrier ID of the
+ * matching SIM card
+ */
+ public @Nullable String getMatchingImsi(int carrierId) {
+ int subId = getMatchingSubId(carrierId);
+ if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ return mTelephonyManager.getSubscriberId(subId);
+ }
+
+ Log.d(TAG, "no active SIM card to match the carrier ID.");
+ return null;
+ }
+
+ /**
+ * Get the IMSI and carrier ID of the SIM card which is matched with the given IMSI
+ * (only prefix of IMSI - mccmnc*) from passpoint profile.
+ *
+ * @param imsiPrefix The IMSI parameter from passpoint profile.
+ * @return null if there is no matching SIM card, otherwise the IMSI and carrier ID of the
+ * matching SIM card
+ */
+ public @Nullable Pair<String, Integer> getMatchingImsiCarrierId(
+ String imsiPrefix) {
+ IMSIParameter imsiParameter = IMSIParameter.build(imsiPrefix);
+ if (imsiParameter == null) {
+ return null;
+ }
+ List<SubscriptionInfo> infos = mSubscriptionManager.getActiveSubscriptionInfoList();
+ if (infos == null) {
+ return null;
+ }
+ int dataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
+ //Pair<IMSI, carrier ID> the IMSI and carrier ID of matched SIM card
+ Pair<String, Integer> matchedPair = null;
+ // matchedDataPair check if the data SIM is matched.
+ Pair<String, Integer> matchedDataPair = null;
+ // matchedMnoPair check if any matched SIM card is MNO.
+ Pair<String, Integer> matchedMnoPair = null;
+
+ // Find the active matched SIM card with the priority order of Data MNO SIM,
+ // Nondata MNO SIM, Data MVNO SIM, Nondata MVNO SIM.
+ for (SubscriptionInfo subInfo : infos) {
+ TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(
+ subInfo.getSubscriptionId());
+ String operatorNumeric = specifiedTm.getSimOperatorNumeric();
+ if (operatorNumeric != null && imsiParameter.matchesMccMnc(operatorNumeric)) {
+ String curImsi = specifiedTm.getSubscriberId();
+ if (TextUtils.isEmpty(curImsi)) {
+ continue;
+ }
+ matchedPair = new Pair<>(curImsi, subInfo.getCarrierId());
+ if (subInfo.getSubscriptionId() == dataSubId) {
+ matchedDataPair = matchedPair;
+ if (getCarrierType(subInfo.getSubscriptionId()) == CARRIER_MNO_TYPE) {
+ Log.d(TAG, "MNO data is matched via IMSI.");
+ return matchedDataPair;
+ }
+ }
+ if (getCarrierType(subInfo.getSubscriptionId()) == CARRIER_MNO_TYPE) {
+ matchedMnoPair = matchedPair;
+ }
+ }
+ }
+
+ if (matchedMnoPair != null) {
+ Log.d(TAG, "MNO sub is matched via IMSI.");
+ return matchedMnoPair;
+ }
+
+ if (matchedDataPair != null) {
+ Log.d(TAG, "MVNO data sub is matched via IMSI.");
+ return matchedDataPair;
+ }
+
+ return matchedPair;
+ }
}
diff --git a/tests/wifitests/Android.bp b/tests/wifitests/Android.bp
index 341ab0982..5dd90c1fc 100644
--- a/tests/wifitests/Android.bp
+++ b/tests/wifitests/Android.bp
@@ -246,7 +246,6 @@ android_test {
"com.android.server.wifi.ScoringParams.*",
"com.android.server.wifi.SelfRecovery",
"com.android.server.wifi.SelfRecovery.*",
- "com.android.server.wifi.SIMAccessor",
"com.android.server.wifi.SoftApManager",
"com.android.server.wifi.SoftApManager.*",
"com.android.server.wifi.SoftApModeConfiguration",
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 2b3491b31..6f59ac264 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -501,6 +501,8 @@ public class ClientModeImplTest extends WifiBaseTest {
add(mock(SubscriptionInfo.class));
}};
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subList);
+ when(mSubscriptionManager.getActiveSubscriptionIdList())
+ .thenReturn(new int[]{DATA_SUBID});
TelephonyUtil tu = new TelephonyUtil(mTelephonyManager, mSubscriptionManager);
mTelephonyUtil = spy(tu);
@@ -1029,7 +1031,7 @@ public class ClientModeImplTest extends WifiBaseTest {
/**
* When the SIM card was removed, if the current wifi connection is using it, the connection
- * should be disconnected.
+ * should be disconnected, otherwise, the connection shouldn't be impacted.
*/
@Test
public void testResetSimWhenConnectedSimRemoved() throws Exception {
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index edbd5cb7e..4ad2a251e 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -4568,6 +4568,8 @@ public class WifiConfigManagerTest extends WifiBaseTest {
add(mock(SubscriptionInfo.class));
}};
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subList);
+ when(mSubscriptionManager.getActiveSubscriptionIdList())
+ .thenReturn(new int[]{DATA_SUBID});
WifiConfiguration network = WifiConfigurationTestUtil.createEapNetwork();
WifiConfiguration simNetwork = WifiConfigurationTestUtil.createEapNetwork(
@@ -4624,6 +4626,8 @@ public class WifiConfigManagerTest extends WifiBaseTest {
add(mock(SubscriptionInfo.class));
}};
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subList);
+ when(mSubscriptionManager.getActiveSubscriptionIdList())
+ .thenReturn(new int[]{DATA_SUBID});
WifiConfiguration peapSimNetwork = WifiConfigurationTestUtil.createEapNetwork(
WifiEnterpriseConfig.Eap.PEAP, WifiEnterpriseConfig.Phase2.SIM);
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java
index 6173ebd09..7a30ae069 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java
@@ -43,7 +43,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -85,11 +84,11 @@ public class ANQPMatcherTest extends WifiBaseTest {
@Test
public void matchDomainNameUsingIMSI() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
- List<String> simImsiList = Arrays.asList(new String[] {"123457890", "123498723"});
+ String simImsi = "123457890";
// 3GPP network domain with MCC=123 and MNC=456.
String[] domains = new String[] {"wlan.mnc457.mcc123.3gppnetwork.org"};
DomainNameElement element = new DomainNameElement(Arrays.asList(domains));
- assertTrue(ANQPMatcher.matchDomainName(element, null, imsiParam, simImsiList));
+ assertTrue(ANQPMatcher.matchDomainName(element, null, imsiParam, simImsi));
}
/**
@@ -304,46 +303,46 @@ public class ANQPMatcherTest extends WifiBaseTest {
@Test
public void matchThreeGPPNetworkWithNullElement() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
- List<String> simImsiList = Arrays.asList(new String[] {"123456789", "123498723"});
- assertFalse(ANQPMatcher.matchThreeGPPNetwork(null, imsiParam, simImsiList));
+ String simImsi = "123456789";
+ assertFalse(ANQPMatcher.matchThreeGPPNetwork(null, imsiParam, simImsi));
}
/**
* Verify that 3GPP network will succeed when the given 3GPP Network ANQP element contained
- * a MCC-MNC that matches the both IMSI parameter and an IMSI from the IMSI list.
+ * a MCC-MNC that matches the both IMSI parameter and a SIM IMSI.
*
* @throws Exception
*/
@Test
public void matchThreeGPPNetwork() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
- List<String> simImsiList = Arrays.asList(new String[] {"123456789", "123498723"});
+ String simImsi = "123456789";
CellularNetwork network = new CellularNetwork(Arrays.asList(new String[] {"123456"}));
ThreeGPPNetworkElement element =
new ThreeGPPNetworkElement(Arrays.asList(new CellularNetwork[] {network}));
// The MCC-MNC provided in 3GPP Network ANQP element matches both IMSI parameter
// and an IMSI from the installed SIM card.
- assertTrue(ANQPMatcher.matchThreeGPPNetwork(element, imsiParam, simImsiList));
+ assertTrue(ANQPMatcher.matchThreeGPPNetwork(element, imsiParam, simImsi));
}
/**
* Verify that 3GPP network will failed when the given 3GPP Network ANQP element contained
- * a MCC-MNC that match the IMSI parameter but not the IMSI list.
+ * a MCC-MNC that match the IMSI parameter but not the SIM IMSI.
*
* @throws Exception
*/
@Test
public void matchThreeGPPNetworkWithoutSimImsiMatch() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
- List<String> simImsiList = Arrays.asList(new String[] {"123457890", "123498723"});
+ String simImsi = "123457890";
CellularNetwork network = new CellularNetwork(Arrays.asList(new String[] {"123456"}));
ThreeGPPNetworkElement element =
new ThreeGPPNetworkElement(Arrays.asList(new CellularNetwork[] {network}));
// The MCC-MNC provided in 3GPP Network ANQP element doesn't match any of the IMSIs
// from the installed SIM card.
- assertFalse(ANQPMatcher.matchThreeGPPNetwork(element, imsiParam, simImsiList));
+ assertFalse(ANQPMatcher.matchThreeGPPNetwork(element, imsiParam, simImsi));
}
/**
@@ -355,13 +354,13 @@ public class ANQPMatcherTest extends WifiBaseTest {
@Test
public void matchThreeGPPNetworkWithImsiParamMismatch() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
- List<String> simImsiList = Arrays.asList(new String[] {"123457890", "123498723"});
+ String simImsi = "123457890";
CellularNetwork network = new CellularNetwork(Arrays.asList(new String[] {"123356"}));
ThreeGPPNetworkElement element =
new ThreeGPPNetworkElement(Arrays.asList(new CellularNetwork[] {network}));
// The MCC-MNC provided in 3GPP Network ANQP element doesn't match the IMSI parameter.
- assertFalse(ANQPMatcher.matchThreeGPPNetwork(element, imsiParam, simImsiList));
+ assertFalse(ANQPMatcher.matchThreeGPPNetwork(element, imsiParam, simImsi));
}
/**
@@ -372,10 +371,10 @@ public class ANQPMatcherTest extends WifiBaseTest {
@Test
public void verifyInvalidDomain() throws Exception {
IMSIParameter imsiParam = new IMSIParameter("1234", true);
- List<String> simImsiList = Arrays.asList(new String[] {"123457890", "123498723"});
+ String simImsi = "123457890";
// 3GPP network domain with MCC=123 and MNC=456.
String[] domains = new String[] {"wlan.mnc457.mccI23.3gppnetwork.org"};
DomainNameElement element = new DomainNameElement(Arrays.asList(domains));
- assertFalse(ANQPMatcher.matchDomainName(element, null, imsiParam, simImsiList));
+ assertFalse(ANQPMatcher.matchDomainName(element, null, imsiParam, simImsi));
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
index 5a30d7164..18f6bf5ce 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
@@ -29,10 +29,10 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
-import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiConfigStore;
import com.android.server.wifi.WifiKeyStore;
+import com.android.server.wifi.util.TelephonyUtil;
import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import org.junit.Before;
@@ -71,7 +71,7 @@ public class PasspointConfigUserStoreDataTest extends WifiBaseTest {
private static final boolean TEST_SHARED = false;
@Mock WifiKeyStore mKeyStore;
- @Mock SIMAccessor mSimAccessor;
+ @Mock TelephonyUtil mTelephonyUtil;
@Mock PasspointConfigUserStoreData.DataSource mDataSource;
PasspointConfigUserStoreData mConfigStoreData;
@@ -79,7 +79,7 @@ public class PasspointConfigUserStoreDataTest extends WifiBaseTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mConfigStoreData = new PasspointConfigUserStoreData(mKeyStore, mSimAccessor, mDataSource);
+ mConfigStoreData = new PasspointConfigUserStoreData(mKeyStore, mTelephonyUtil, mDataSource);
}
/**
@@ -245,12 +245,12 @@ public class PasspointConfigUserStoreDataTest extends WifiBaseTest {
// Setup expected data.
List<PasspointProvider> providerList = new ArrayList<>();
providerList.add(new PasspointProvider(createFullPasspointConfiguration(),
- mKeyStore, mSimAccessor, TEST_PROVIDER_ID, TEST_CREATOR_UID, TEST_CREATOR_PACKAGE,
+ mKeyStore, mTelephonyUtil, TEST_PROVIDER_ID, TEST_CREATOR_UID, TEST_CREATOR_PACKAGE,
false, Arrays.asList(TEST_CA_CERTIFICATE_ALIAS),
TEST_CLIENT_PRIVATE_KEY_AND_CERT_ALIAS, null,
TEST_HAS_EVER_CONNECTED, TEST_SHARED));
- providerList.add(new PasspointProvider(createFullPasspointConfiguration(),
- mKeyStore, mSimAccessor, TEST_PROVIDER_ID_2, TEST_CREATOR_UID, TEST_CREATOR_PACKAGE,
+ providerList.add(new PasspointProvider(createFullPasspointConfiguration(), mKeyStore,
+ mTelephonyUtil, TEST_PROVIDER_ID_2, TEST_CREATOR_UID, TEST_CREATOR_PACKAGE,
true, Arrays.asList(TEST_CA_CERTIFICATE_ALIAS, TEST_CA_CERTIFICATE_ALIAS_2),
TEST_CLIENT_PRIVATE_KEY_AND_CERT_ALIAS, TEST_REMEDIATION_CA_CERTIFICATE_ALIAS,
TEST_HAS_EVER_CONNECTED, TEST_SHARED));
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
index 447d8b13b..ccfb1f0d1 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
@@ -42,12 +42,15 @@ import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.anyMap;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -73,7 +76,9 @@ import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.os.test.TestLooper;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.util.Base64;
import android.util.Pair;
@@ -82,8 +87,6 @@ import androidx.test.filters.SmallTest;
import com.android.server.wifi.ClientModeImpl;
import com.android.server.wifi.Clock;
import com.android.server.wifi.FakeKeys;
-import com.android.server.wifi.IMSIParameter;
-import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiConfigManager;
import com.android.server.wifi.WifiConfigStore;
@@ -101,6 +104,7 @@ import com.android.server.wifi.hotspot2.anqp.I18Name;
import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo;
import com.android.server.wifi.util.InformationElementUtil;
import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium;
+import com.android.server.wifi.util.TelephonyUtil;
import org.junit.Before;
import org.junit.Test;
@@ -111,6 +115,7 @@ import org.mockito.MockitoSession;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
+import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
@@ -137,7 +142,9 @@ public class PasspointManagerTest extends WifiBaseTest {
private static final String TEST_FRIENDLY_NAME2 = "second friendly name";
private static final String TEST_REALM = "realm.test.com";
private static final String TEST_IMSI = "123456*";
- private static final IMSIParameter TEST_IMSI_PARAM = IMSIParameter.build(TEST_IMSI);
+ private static final String FULL_IMSI = "123456789123456";
+ private static final int TEST_CARRIER_ID = 10;
+ private static final int TEST_SUBID = 1;
private static final long TEST_BSSID = 0x112233445566L;
private static final String TEST_SSID = "TestSSID";
@@ -165,7 +172,6 @@ public class PasspointManagerTest extends WifiBaseTest {
@Mock WifiNative mWifiNative;
@Mock WifiKeyStore mWifiKeyStore;
@Mock Clock mClock;
- @Mock SIMAccessor mSimAccessor;
@Mock PasspointObjectFactory mObjectFactory;
@Mock PasspointEventHandler.Callbacks mCallbacks;
@Mock AnqpCache mAnqpCache;
@@ -185,6 +191,7 @@ public class PasspointManagerTest extends WifiBaseTest {
@Mock AppOpsManager mAppOpsManager;
@Mock WifiInjector mWifiInjector;
@Mock ClientModeImpl mClientModeImpl;
+ @Mock TelephonyManager mTelephonyManager;
@Mock SubscriptionManager mSubscriptionManager;
@Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
@@ -193,6 +200,7 @@ public class PasspointManagerTest extends WifiBaseTest {
PasspointManager mManager;
ArgumentCaptor<AppOpsManager.OnOpChangedListener> mAppOpChangedListenerCaptor =
ArgumentCaptor.forClass(AppOpsManager.OnOpChangedListener.class);
+ TelephonyUtil mTelephonyUtil;
/** Sets up test. */
@Before
@@ -215,11 +223,12 @@ public class PasspointManagerTest extends WifiBaseTest {
when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl);
when(mWifiInjector.getWifiNetworkSuggestionsManager())
.thenReturn(mWifiNetworkSuggestionsManager);
+ mTelephonyUtil = new TelephonyUtil(mTelephonyManager, mSubscriptionManager);
mLooper = new TestLooper();
mHandler = new Handler(mLooper.getLooper());
mManager = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative,
- mWifiKeyStore, mClock, mSimAccessor, mObjectFactory, mWifiConfigManager,
- mWifiConfigStore, mWifiMetrics, mSubscriptionManager);
+ mWifiKeyStore, mClock, mObjectFactory, mWifiConfigManager,
+ mWifiConfigStore, mWifiMetrics, mTelephonyUtil);
ArgumentCaptor<PasspointEventHandler.Callbacks> callbacks =
ArgumentCaptor.forClass(PasspointEventHandler.Callbacks.class);
verify(mObjectFactory).makePasspointEventHandler(any(WifiNative.class),
@@ -230,7 +239,7 @@ public class PasspointManagerTest extends WifiBaseTest {
ArgumentCaptor<PasspointConfigUserStoreData.DataSource> userDataSource =
ArgumentCaptor.forClass(PasspointConfigUserStoreData.DataSource.class);
verify(mObjectFactory).makePasspointConfigUserStoreData(
- any(WifiKeyStore.class), any(SIMAccessor.class), userDataSource.capture());
+ any(WifiKeyStore.class), any(TelephonyUtil.class), userDataSource.capture());
mCallbacks = callbacks.getValue();
mSharedDataSource = sharedDataSource.getValue();
mUserDataSource = userDataSource.getValue();
@@ -368,7 +377,7 @@ public class PasspointManagerTest extends WifiBaseTest {
PasspointConfiguration config = createTestConfigWithUserCredential(fqdn, friendlyName);
PasspointProvider provider = createMockProvider(config, wifiConfig);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(provider);
when(provider.getPackageName()).thenReturn(packageName);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
@@ -609,7 +618,7 @@ public class PasspointManagerTest extends WifiBaseTest {
PasspointProvider provider = createMockProvider(config);
when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(config);
@@ -656,7 +665,7 @@ public class PasspointManagerTest extends WifiBaseTest {
TEST_REALM);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(config);
@@ -690,6 +699,47 @@ public class PasspointManagerTest extends WifiBaseTest {
}
/**
+ * Verify that if the passpoint profile has full IMSI, the carrier ID should be updated when
+ * the matched SIM card is present.
+ * @throws Exception
+ */
+ @Test
+ public void addProviderWithValidFullImsiOfSimCredential() throws Exception {
+ PasspointConfiguration config =
+ createTestConfigWithSimCredential(TEST_FQDN, FULL_IMSI, TEST_REALM);
+ X509Certificate[] certArr = new X509Certificate[] {FakeKeys.CA_CERT0};
+ config.getCredential().setCaCertificates(certArr);
+ SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
+ when(subInfo.getSubscriptionId()).thenReturn(TEST_SUBID);
+ when(subInfo.getCarrierId()).thenReturn(TEST_CARRIER_ID);
+ TelephonyManager specifiedTm = mock(TelephonyManager.class);
+ when(mTelephonyManager.createForSubscriptionId(eq(TEST_SUBID))).thenReturn(specifiedTm);
+ when(specifiedTm.getSubscriberId()).thenReturn(FULL_IMSI);
+ List<SubscriptionInfo> subInfoList = new ArrayList<>() {{
+ add(subInfo);
+ }};
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subInfoList);
+ doNothing().when(mCertVerifier).verifyCaCert(any(X509Certificate.class));
+ when(mWifiKeyStore.putCaCertInKeyStore(any(String.class), any(Certificate.class)))
+ .thenReturn(true);
+ PasspointObjectFactory spyFactory = spy(new PasspointObjectFactory());
+ doReturn(mCertVerifier).when(spyFactory).makeCertificateVerifier();
+ PasspointManager ut = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative,
+ mWifiKeyStore, mClock, spyFactory, mWifiConfigManager,
+ mWifiConfigStore, mWifiMetrics, mTelephonyUtil);
+
+ assertTrue(ut.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, true));
+
+ assertEquals(TEST_CARRIER_ID, config.getCarrierId());
+ List<String> fqdnList = new ArrayList<>(){{
+ add(TEST_FQDN);
+ }};
+ assertEquals(TEST_CARRIER_ID,
+ ut.getWifiConfigsForPasspointProfiles(fqdnList).get(0).carrierId);
+
+ }
+
+ /**
* Verify that adding a user saved provider with the same base domain as the existing provider
* will succeed, and verify that the existing provider is replaced by the new provider with
* the new configuration.
@@ -703,7 +753,7 @@ public class PasspointManagerTest extends WifiBaseTest {
TEST_REALM);
PasspointProvider origProvider = createMockProvider(origConfig);
when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(origProvider);
assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(origConfig);
@@ -725,7 +775,7 @@ public class PasspointManagerTest extends WifiBaseTest {
TEST_FRIENDLY_NAME);
PasspointProvider newProvider = createMockProvider(newConfig);
when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(newProvider);
assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(newConfig);
@@ -755,7 +805,7 @@ public class PasspointManagerTest extends WifiBaseTest {
PasspointProvider provider = mock(PasspointProvider.class);
when(provider.installCertsAndKeys()).thenReturn(false);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), eq(false)))
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), eq(false)))
.thenReturn(provider);
assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
@@ -791,7 +841,7 @@ public class PasspointManagerTest extends WifiBaseTest {
config.setUpdateIdentifier(1);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verify(mCertVerifier, never()).verifyCaCert(any(X509Certificate.class));
@@ -932,6 +982,39 @@ public class PasspointManagerTest extends WifiBaseTest {
}
/**
+ * Verify that if the Carrier ID is updated during match, the config should be persisted.
+ */
+ @Test
+ public void getAllMatchingProvidersUpdatedConfigWithFullImsiSimCredential() {
+ // static mocking
+ MockitoSession session =
+ com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
+ InformationElementUtil.class).startMocking();
+ try {
+ PasspointProvider provider = addTestProvider(TEST_FQDN + 0, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE);
+ when(provider.tryUpdateCarrierId()).thenReturn(true);
+ reset(mWifiConfigManager);
+
+ ANQPData entry = new ANQPData(mClock, null);
+ InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
+ vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2;
+
+ when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(entry);
+ when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
+ when(provider.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.HomeProvider);
+
+ List<Pair<PasspointProvider, PasspointMatch>> matchedProviders =
+ mManager.getAllMatchedProviders(createTestScanResult());
+
+ verify(mWifiConfigManager).saveToStore(eq(true));
+
+ } finally {
+ session.finishMocking();
+ }
+ }
+ /**
* Verify that an expected map of FQDN and a list of ScanResult will be returned when provided
* scanResults are matched to installed Passpoint profiles.
*/
@@ -1273,7 +1356,7 @@ public class PasspointManagerTest extends WifiBaseTest {
PasspointProvider provider = createMockProvider(config);
// Verify the provider ID used to create the new provider.
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), eq(providerIndex), eq(TEST_CREATOR_UID),
+ eq(mTelephonyUtil), eq(providerIndex), eq(TEST_CREATOR_UID),
eq(TEST_PACKAGE), eq(false))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
@@ -1625,7 +1708,7 @@ public class PasspointManagerTest extends WifiBaseTest {
TEST_REALM);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(config);
@@ -1667,7 +1750,7 @@ public class PasspointManagerTest extends WifiBaseTest {
when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
when(provider.isFromSuggestion()).thenReturn(true);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(provider);
assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, true));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
@@ -1736,7 +1819,7 @@ public class PasspointManagerTest extends WifiBaseTest {
PasspointProvider origProvider = createMockProvider(origConfig);
when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(origProvider);
assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, true));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
@@ -1770,7 +1853,7 @@ public class PasspointManagerTest extends WifiBaseTest {
when(newProvider.isFromSuggestion()).thenReturn(true);
when(newProvider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(newProvider);
assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE, true));
verify(mWifiConfigManager).removePasspointConfiguredNetwork(
@@ -1801,7 +1884,7 @@ public class PasspointManagerTest extends WifiBaseTest {
PasspointProvider origProvider = createMockProvider(origConfig);
when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(true))).thenReturn(origProvider);
assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, true));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
@@ -1821,7 +1904,7 @@ public class PasspointManagerTest extends WifiBaseTest {
TEST_FRIENDLY_NAME);
PasspointProvider newProvider = createMockProvider(newConfig);
when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(newProvider);
assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE, false));
verify(mWifiConfigManager).removePasspointConfiguredNetwork(
@@ -1852,7 +1935,7 @@ public class PasspointManagerTest extends WifiBaseTest {
PasspointProvider origProvider = createMockProvider(origConfig);
when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
eq(false))).thenReturn(origProvider);
assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(origConfig);
@@ -1875,7 +1958,7 @@ public class PasspointManagerTest extends WifiBaseTest {
when(newProvider.isFromSuggestion()).thenReturn(true);
when(newProvider.getPackageName()).thenReturn(TEST_PACKAGE1);
when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE1),
+ eq(mTelephonyUtil), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE1),
eq(true))).thenReturn(newProvider);
assertFalse(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE1, true));
verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork(
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java
index d5cdd5a96..96a8aac3d 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java
@@ -368,34 +368,6 @@ public class PasspointNetworkEvaluatorTest {
}
/**
- * Verify that null will be returned when matching a SIM credential provider without SIM
- * card installed.
- *
- * @throws Exception
- */
- @Test
- public void evaluateScanMatchingSIMProviderWithoutSIMCard() throws Exception {
- // Setup ScanDetail and match providers.
- List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
- generateScanDetail(TEST_SSID1, TEST_BSSID1)});
- PasspointProvider testProvider = mock(PasspointProvider.class);
- Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create(
- testProvider, PasspointMatch.HomeProvider);
-
- when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
- when(testProvider.isSimCredential()).thenReturn(true);
- // SIM is absent
- when(mSubscriptionManager.getActiveSubscriptionInfoList())
- .thenReturn(Collections.emptyList());
-
- assertEquals(null, mEvaluator.evaluateNetworks(
- scanDetails, null, null, false, false, mOnConnectableListener));
-
- verify(mOnConnectableListener, never()).onConnectable(any(), any(), anyInt());
- verify(testProvider, never()).getWifiConfig();
- }
-
- /**
* Verify that anonymous identity is empty when matching a SIM credential provider with a
* network that supports encrypted IMSI and anonymous identity. The anonymous identity will be
* populated with {@code anonymous@<realm>} by ClientModeImpl's handling of the
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java
index beddb2199..9391abb3f 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java
@@ -19,6 +19,7 @@ package com.android.server.wifi.hotspot2;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
@@ -32,13 +33,12 @@ import android.net.wifi.hotspot2.pps.HomeSp;
import android.net.wifi.hotspot2.pps.UpdateParameter;
import android.text.TextUtils;
import android.util.Base64;
+import android.util.Pair;
import androidx.test.filters.SmallTest;
import com.android.internal.util.ArrayUtils;
import com.android.server.wifi.FakeKeys;
-import com.android.server.wifi.IMSIParameter;
-import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiKeyStore;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
@@ -53,6 +53,7 @@ import com.android.server.wifi.hotspot2.anqp.eap.AuthParam;
import com.android.server.wifi.hotspot2.anqp.eap.EAPMethod;
import com.android.server.wifi.hotspot2.anqp.eap.NonEAPInnerAuth;
import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium;
+import com.android.server.wifi.util.TelephonyUtil;
import org.junit.Before;
import org.junit.Test;
@@ -107,6 +108,7 @@ public class PasspointProviderTest extends WifiBaseTest {
private static final int TEST_EAP_TYPE = WifiEnterpriseConfig.Eap.SIM;
private static final int TEST_SIM_CREDENTIAL_TYPE = EAPConstants.EAP_SIM;
private static final String TEST_IMSI = "1234567890";
+ private static final int VALID_CARRIER_ID = 1;
private enum CredentialType {
USER,
@@ -115,7 +117,7 @@ public class PasspointProviderTest extends WifiBaseTest {
}
@Mock WifiKeyStore mKeyStore;
- @Mock SIMAccessor mSimAccessor;
+ @Mock TelephonyUtil mTelephonyUtil;
@Mock RoamingConsortium mRoamingConsortium;
PasspointProvider mProvider;
X509Certificate mRemediationCaCertificate;
@@ -149,7 +151,7 @@ public class PasspointProviderTest extends WifiBaseTest {
* @return {@link com.android.server.wifi.hotspot2.PasspointProvider}
*/
private PasspointProvider createProvider(PasspointConfiguration config) {
- return new PasspointProvider(config, mKeyStore, mSimAccessor, PROVIDER_ID, CREATOR_UID,
+ return new PasspointProvider(config, mKeyStore, mTelephonyUtil, PROVIDER_ID, CREATOR_UID,
CREATOR_PACKAGE, false);
}
@@ -691,8 +693,8 @@ public class PasspointProviderTest extends WifiBaseTest {
// Setup test provider.
PasspointConfiguration config = generateTestPasspointConfiguration(
CredentialType.SIM, false);
- when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI, false)))
- .thenReturn(Arrays.asList(new String[] {TEST_IMSI}));
+ when(mTelephonyUtil.getMatchingImsiCarrierId(TEST_IMSI))
+ .thenReturn(new Pair<String, Integer>(TEST_IMSI, VALID_CARRIER_ID));
mProvider = createProvider(config);
// Setup Domain Name ANQP element.
@@ -716,8 +718,8 @@ public class PasspointProviderTest extends WifiBaseTest {
// Setup test provider.
PasspointConfiguration config = generateTestPasspointConfiguration(
CredentialType.SIM, false);
- when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI, false)))
- .thenReturn(Arrays.asList(new String[] {TEST_IMSI}));
+ when(mTelephonyUtil.getMatchingImsiCarrierId(TEST_IMSI))
+ .thenReturn(new Pair<String, Integer>(TEST_IMSI, VALID_CARRIER_ID));
mProvider = createProvider(config);
// Setup ANQP elements.
@@ -745,6 +747,9 @@ public class PasspointProviderTest extends WifiBaseTest {
PasspointConfiguration config = generateTestPasspointConfiguration(
CredentialType.SIM, false);
mProvider = createProvider(config);
+ when(mTelephonyUtil.getMatchingImsiCarrierId(
+ eq(config.getCredential().getSimCredential().getImsi())))
+ .thenReturn(new Pair<String, Integer>(TEST_IMSI, VALID_CARRIER_ID));
// Setup Roaming Consortium ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
@@ -919,8 +924,8 @@ public class PasspointProviderTest extends WifiBaseTest {
// Setup test provider.
PasspointConfiguration config = generateTestPasspointConfiguration(
CredentialType.SIM, false);
- when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI, false)))
- .thenReturn(Arrays.asList(new String[] {TEST_IMSI}));
+ when(mTelephonyUtil.getMatchingImsiCarrierId(TEST_IMSI))
+ .thenReturn(new Pair<String, Integer>(TEST_IMSI, VALID_CARRIER_ID));
mProvider = createProvider(config);
// Setup 3GPP Network ANQP element.
@@ -949,8 +954,8 @@ public class PasspointProviderTest extends WifiBaseTest {
// Setup test provider.
PasspointConfiguration config = generateTestPasspointConfiguration(
CredentialType.SIM, false);
- when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI, false)))
- .thenReturn(Arrays.asList(new String[] {TEST_IMSI}));
+ when(mTelephonyUtil.getMatchingImsiCarrierId(TEST_IMSI))
+ .thenReturn(new Pair<String, Integer>(TEST_IMSI, VALID_CARRIER_ID));
mProvider = createProvider(config);
// Setup 3GPP Network ANQP element.
@@ -964,6 +969,64 @@ public class PasspointProviderTest extends WifiBaseTest {
assertEquals(PasspointMatch.RoamingProvider,
mProvider.match(anqpElementMap, mRoamingConsortium));
+ assertEquals(VALID_CARRIER_ID, mProvider.getWifiConfig().carrierId);
+ }
+
+ /**
+ * Verify that when the SIM card matched by carrier ID of profile is absent, it shouldn't
+ * be matched even the profile and ANQP elements are matched.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void matchNothingIfSimMatchedByCarrierIdIsAbsent() throws Exception {
+ // Setup test provider.
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.SIM, false);
+ config.setCarrierId(VALID_CARRIER_ID);
+ when(mTelephonyUtil.getMatchingImsi(eq(VALID_CARRIER_ID)))
+ .thenReturn(null);
+ mProvider = createProvider(config);
+
+ // Setup 3GPP Network ANQP element.
+ Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
+ anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork,
+ createThreeGPPNetworkElement(new String[] {"123456"}));
+
+ // Setup NAI Realm ANQP element with same realm.
+ anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_AKA, null));
+
+ assertEquals(PasspointMatch.None,
+ mProvider.match(anqpElementMap, mRoamingConsortium));
+ }
+
+ /**
+ * Verify that when the SIM card matched by IMSI of profile is absent, it shouldn't be
+ * matched even the profile and ANQP elements are matched.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void matchNothingIfSimMatchedByImsiIsAbsent() throws Exception {
+ // Setup test provider.
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.SIM, false);
+ when(mTelephonyUtil.getMatchingImsiCarrierId(eq(TEST_IMSI)))
+ .thenReturn(null);
+ mProvider = createProvider(config);
+
+ // Setup 3GPP Network ANQP element.
+ Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
+ anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork,
+ createThreeGPPNetworkElement(new String[] {"123456"}));
+
+ // Setup NAI Realm ANQP element with same realm.
+ anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_AKA, null));
+
+ assertEquals(PasspointMatch.None,
+ mProvider.match(anqpElementMap, mRoamingConsortium));
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
index b31bb057e..7e24c8572 100644
--- a/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
@@ -24,6 +24,8 @@ import static org.mockito.Mockito.*;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
+import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.pps.Credential;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -67,8 +69,18 @@ public class TelephonyUtilTest extends WifiBaseTest {
private static final int NON_DATA_SUBID = 2;
private static final int INVALID_SUBID = -1;
private static final int DATA_CARRIER_ID = 10;
+ private static final int PARENT_DATA_CARRIER_ID = 11;
private static final int NON_DATA_CARRIER_ID = 20;
+ private static final int PARENT_NON_DATA_CARRIER_ID = 21;
private static final int DEACTIVE_CARRIER_ID = 30;
+ private static final String MATCH_PREFIX_IMSI = "123456*";
+ private static final String DATA_FULL_IMSI = "123456789123456";
+ private static final String NON_DATA_FULL_IMSI = "123456987654321";
+ private static final String NO_MATCH_FULL_IMSI = "654321123456789";
+ private static final String NO_MATCH_PREFIX_IMSI = "654321*";
+ private static final String DATA_OPERATOR_NUMERIC = "123456";
+ private static final String NON_DATA_OPERATOR_NUMERIC = "123456";
+ private static final String NO_MATCH_OPERATOR_NUMERIC = "654321";
private List<SubscriptionInfo> mSubInfoList;
@@ -109,10 +121,21 @@ public class TelephonyUtilTest extends WifiBaseTest {
doReturn(true).when(
() -> SubscriptionManager.isValidSubscriptionId(NON_DATA_SUBID));
+ when(mTelephonyManager.getSubscriberId(eq(DATA_SUBID))).thenReturn(DATA_FULL_IMSI);
+ when(mTelephonyManager.getSubscriberId(eq(NON_DATA_SUBID))).thenReturn(NON_DATA_FULL_IMSI);
when(mDataSubscriptionInfo.getCarrierId()).thenReturn(DATA_CARRIER_ID);
when(mDataSubscriptionInfo.getSubscriptionId()).thenReturn(DATA_SUBID);
when(mNonDataSubscriptionInfo.getCarrierId()).thenReturn(NON_DATA_CARRIER_ID);
when(mNonDataSubscriptionInfo.getSubscriptionId()).thenReturn(NON_DATA_SUBID);
+ when(mDataTelephonyManager.getSubscriberId()).thenReturn(DATA_FULL_IMSI);
+ when(mNonDataTelephonyManager.getSubscriberId()).thenReturn(NON_DATA_FULL_IMSI);
+ when(mDataTelephonyManager.getSimOperatorNumeric()).thenReturn(DATA_OPERATOR_NUMERIC);
+ when(mNonDataTelephonyManager.getSimOperatorNumeric())
+ .thenReturn(NON_DATA_OPERATOR_NUMERIC);
+ when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
+ when(mNonDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
+ when(mSubscriptionManager.getActiveSubscriptionIdList())
+ .thenReturn(new int[]{DATA_SUBID, NON_DATA_SUBID});
}
@After
@@ -689,6 +712,7 @@ public class TelephonyUtilTest extends WifiBaseTest {
WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork(
WifiEnterpriseConfig.Eap.AKA, WifiEnterpriseConfig.Phase2.NONE);
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null);
+ when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[0]);
assertEquals(INVALID_SUBID, mTelephonyUtil.getBestMatchSubscriptionId(config));
@@ -702,7 +726,7 @@ public class TelephonyUtilTest extends WifiBaseTest {
* The matched Subscription ID should be that of data SIM when carrier ID is not specified.
*/
@Test
- public void getBestMatchSubscriptionIdWithoutCarrierIdFieldForSimConfig() {
+ public void getBestMatchSubscriptionIdForEnterpriseWithoutCarrierIdFieldForSimConfig() {
WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork(
WifiEnterpriseConfig.Eap.AKA, WifiEnterpriseConfig.Phase2.NONE);
@@ -714,7 +738,7 @@ public class TelephonyUtilTest extends WifiBaseTest {
* SIM card and the carrier ID is not specified.
*/
@Test
- public void getBestMatchSubscriptionIdWithoutCarrierIdFieldForNonSimConfig() {
+ public void getBestMatchSubscriptionIdForEnterpriseWithoutCarrierIdFieldForNonSimConfig() {
WifiConfiguration config = new WifiConfiguration();
assertEquals(INVALID_SUBID, mTelephonyUtil.getBestMatchSubscriptionId(config));
@@ -725,7 +749,7 @@ public class TelephonyUtilTest extends WifiBaseTest {
* should be returned.
*/
@Test
- public void getBestMatchSubscriptionIdWithNonDataCarrierId() {
+ public void getBestMatchSubscriptionIdForEnterpriseWithNonDataCarrierId() {
WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork(
WifiEnterpriseConfig.Eap.AKA, WifiEnterpriseConfig.Phase2.NONE);
config.carrierId = NON_DATA_CARRIER_ID;
@@ -737,6 +761,33 @@ public class TelephonyUtilTest extends WifiBaseTest {
}
/**
+ * If the passpoint profile have valid carrier ID, the matching sub ID should be returned.
+ */
+ @Test
+ public void getBestMatchSubscriptionIdForPasspointWithValidCarrierId() {
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork(
+ WifiEnterpriseConfig.Eap.AKA, WifiEnterpriseConfig.Phase2.NONE);
+ config.carrierId = DATA_CARRIER_ID;
+ WifiConfiguration spyConfig = spy(config);
+ doReturn(true).when(spyConfig).isPasspoint();
+
+ assertEquals(DATA_SUBID, mTelephonyUtil.getBestMatchSubscriptionId(spyConfig));
+ }
+
+ /**
+ * If there is no matching SIM card, the matching sub ID should be invalid.
+ */
+ @Test
+ public void getBestMatchSubscriptionIdForPasspointInvalidCarrierId() {
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork(
+ WifiEnterpriseConfig.Eap.AKA, WifiEnterpriseConfig.Phase2.NONE);
+ WifiConfiguration spyConfig = spy(config);
+ doReturn(true).when(spyConfig).isPasspoint();
+
+ assertEquals(INVALID_SUBID, mTelephonyUtil.getBestMatchSubscriptionId(spyConfig));
+ }
+
+ /**
* The matched Subscription ID should be invalid if the SIM card for the specified carrier ID
* is absent.
*/
@@ -748,4 +799,256 @@ public class TelephonyUtilTest extends WifiBaseTest {
assertEquals(INVALID_SUBID, mTelephonyUtil.getBestMatchSubscriptionId(config));
}
+
+ /**
+ * Verify that the result is null if no active SIM is matched.
+ */
+ @Test
+ public void getMatchingImsiCarrierIdWithDeactiveCarrierId() {
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Collections.emptyList());
+
+ assertNull(mTelephonyUtil.getMatchingImsi(DEACTIVE_CARRIER_ID));
+ }
+
+ /**
+ * Verify that if there is SIM card whose carrier ID is the same as the input, the correct IMSI
+ * and carrier ID would be returned.
+ */
+ @Test
+ public void getMatchingImsiCarrierIdWithValidCarrierId() {
+ assertEquals(DATA_FULL_IMSI,
+ mTelephonyUtil.getMatchingImsi(DATA_CARRIER_ID));
+ }
+
+ /**
+ * Verify that if there is no SIM, it should match nothing.
+ */
+ @Test
+ public void getMatchingImsiCarrierIdWithEmptyActiveSubscriptionInfoList() {
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null);
+
+ assertNull(mTelephonyUtil.getMatchingImsiCarrierId(MATCH_PREFIX_IMSI));
+
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Collections.emptyList());
+
+ assertNull(mTelephonyUtil.getMatchingImsiCarrierId(MATCH_PREFIX_IMSI));
+ }
+
+ /**
+ * Verify that if there is no matching SIM, it should match nothing.
+ */
+ @Test
+ public void getMatchingImsiCarrierIdWithNoMatchImsi() {
+ // data SIM is MNO.
+ when(mDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(DATA_CARRIER_ID);
+ when(mDataTelephonyManager.getSimCarrierId()).thenReturn(DATA_CARRIER_ID);
+ // non data SIM is MNO.
+ when(mNonDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(NON_DATA_CARRIER_ID);
+ when(mNonDataTelephonyManager.getSimCarrierId()).thenReturn(NON_DATA_CARRIER_ID);
+
+ assertNull(mTelephonyUtil.getMatchingImsiCarrierId(NO_MATCH_PREFIX_IMSI));
+ }
+
+ /**
+ * Verify that if the matched SIM is the default data SIM and a MNO SIM, the information of it
+ * should be returned.
+ */
+ @Test
+ public void getMatchingImsiCarrierIdForDataAndMnoSimMatch() {
+ // data SIM is MNO.
+ when(mDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(DATA_CARRIER_ID);
+ when(mDataTelephonyManager.getSimCarrierId()).thenReturn(DATA_CARRIER_ID);
+ // non data SIM is MNO.
+ when(mNonDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(NON_DATA_CARRIER_ID);
+ when(mNonDataTelephonyManager.getSimCarrierId()).thenReturn(NON_DATA_CARRIER_ID);
+
+ Pair<String, Integer> ic = mTelephonyUtil.getMatchingImsiCarrierId(MATCH_PREFIX_IMSI);
+
+ assertEquals(new Pair<>(DATA_FULL_IMSI, DATA_CARRIER_ID), ic);
+
+ // non data SIM is MVNO
+ when(mNonDataTelephonyManager.getCarrierIdFromSimMccMnc())
+ .thenReturn(PARENT_NON_DATA_CARRIER_ID);
+ when(mNonDataTelephonyManager.getSimCarrierId()).thenReturn(NON_DATA_CARRIER_ID);
+
+ assertEquals(new Pair<>(DATA_FULL_IMSI, DATA_CARRIER_ID),
+ mTelephonyUtil.getMatchingImsiCarrierId(MATCH_PREFIX_IMSI));
+
+ // non data SIM doesn't match.
+ when(mNonDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(NON_DATA_CARRIER_ID);
+ when(mNonDataTelephonyManager.getSimCarrierId()).thenReturn(NON_DATA_CARRIER_ID);
+ when(mNonDataTelephonyManager.getSubscriberId()).thenReturn(NO_MATCH_FULL_IMSI);
+ when(mNonDataTelephonyManager.getSimOperatorNumeric())
+ .thenReturn(NO_MATCH_OPERATOR_NUMERIC);
+
+ assertEquals(new Pair<>(DATA_FULL_IMSI, DATA_CARRIER_ID),
+ mTelephonyUtil.getMatchingImsiCarrierId(MATCH_PREFIX_IMSI));
+ }
+
+ /**
+ * Verify that if the matched SIM is the default data SIM and a MVNO SIM, and no MNO SIM was
+ * matched, the information of it should be returned.
+ */
+ @Test
+ public void getMatchingImsiCarrierIdForDataAndMvnoSimMatch() {
+ // data SIM is MVNO.
+ when(mDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(PARENT_DATA_CARRIER_ID);
+ when(mDataTelephonyManager.getSimCarrierId()).thenReturn(DATA_CARRIER_ID);
+ // non data SIM is MVNO.
+ when(mNonDataTelephonyManager.getCarrierIdFromSimMccMnc())
+ .thenReturn(PARENT_NON_DATA_CARRIER_ID);
+ when(mNonDataTelephonyManager.getSimCarrierId()).thenReturn(NON_DATA_CARRIER_ID);
+
+ Pair<String, Integer> ic = mTelephonyUtil.getMatchingImsiCarrierId(MATCH_PREFIX_IMSI);
+
+ assertEquals(new Pair<>(DATA_FULL_IMSI, DATA_CARRIER_ID), ic);
+
+ // non data SIM doesn't match.
+ when(mNonDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(NON_DATA_CARRIER_ID);
+ when(mNonDataTelephonyManager.getSimCarrierId()).thenReturn(NON_DATA_CARRIER_ID);
+ when(mNonDataTelephonyManager.getSubscriberId()).thenReturn(NO_MATCH_FULL_IMSI);
+ when(mNonDataTelephonyManager.getSimOperatorNumeric())
+ .thenReturn(NO_MATCH_OPERATOR_NUMERIC);
+
+ assertEquals(new Pair<>(DATA_FULL_IMSI, DATA_CARRIER_ID),
+ mTelephonyUtil.getMatchingImsiCarrierId(MATCH_PREFIX_IMSI));
+ }
+
+ /**
+ * Verify that if the matched SIM is a MNO SIM, even the default data SIM is matched as a MVNO
+ * SIM, the information of MNO SIM still should be returned.
+ */
+ @Test
+ public void getMatchingImsiCarrierIdForNonDataAndMnoSimMatch() {
+ // data SIM is MVNO.
+ when(mDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(PARENT_DATA_CARRIER_ID);
+ when(mDataTelephonyManager.getSimCarrierId()).thenReturn(DATA_CARRIER_ID);
+ // non data SIM is MNO.
+ when(mNonDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(NON_DATA_CARRIER_ID);
+ when(mNonDataTelephonyManager.getSimCarrierId()).thenReturn(NON_DATA_CARRIER_ID);
+
+
+ Pair<String, Integer> ic = mTelephonyUtil.getMatchingImsiCarrierId(MATCH_PREFIX_IMSI);
+
+ assertEquals(new Pair<>(NON_DATA_FULL_IMSI, NON_DATA_CARRIER_ID), ic);
+
+ // data SIM doesn't match
+ when(mDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(DATA_CARRIER_ID);
+ when(mDataTelephonyManager.getSimCarrierId()).thenReturn(DATA_CARRIER_ID);
+ when(mDataTelephonyManager.getSubscriberId()).thenReturn(NO_MATCH_FULL_IMSI);
+ when(mDataTelephonyManager.getSimOperatorNumeric()).thenReturn(NO_MATCH_OPERATOR_NUMERIC);
+
+ assertEquals(new Pair<>(NON_DATA_FULL_IMSI, NON_DATA_CARRIER_ID),
+ mTelephonyUtil.getMatchingImsiCarrierId(MATCH_PREFIX_IMSI));
+ }
+
+ /**
+ * Verify that if only a MVNO SIM is matched, the information of it should be returned.
+ */
+ @Test
+ public void getMatchingImsiCarrierIdForMvnoSimMatch() {
+ // data SIM is MNO, but IMSI doesn't match.
+ when(mDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(DATA_CARRIER_ID);
+ when(mDataTelephonyManager.getSimCarrierId()).thenReturn(DATA_CARRIER_ID);
+ when(mDataTelephonyManager.getSubscriberId()).thenReturn(NO_MATCH_FULL_IMSI);
+ when(mDataTelephonyManager.getSimOperatorNumeric()).thenReturn(NO_MATCH_OPERATOR_NUMERIC);
+ // non data SIM is MVNO.
+ when(mNonDataTelephonyManager.getCarrierIdFromSimMccMnc())
+ .thenReturn(PARENT_NON_DATA_CARRIER_ID);
+ when(mNonDataTelephonyManager.getSimCarrierId()).thenReturn(NON_DATA_CARRIER_ID);
+
+ assertEquals(new Pair<>(NON_DATA_FULL_IMSI, NON_DATA_CARRIER_ID),
+ mTelephonyUtil.getMatchingImsiCarrierId(MATCH_PREFIX_IMSI));
+ }
+
+ /**
+ * Verify that if there is no any SIM card, the carrier ID should be updated.
+ */
+ @Test
+ public void tryUpdateCarrierIdForPasspointWithEmptyActiveSubscriptionList() {
+ PasspointConfiguration config = mock(PasspointConfiguration.class);
+ when(config.getCarrierId()).thenReturn(DATA_CARRIER_ID);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null);
+
+ assertFalse(mTelephonyUtil.tryUpdateCarrierIdForPasspoint(config));
+
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Collections.emptyList());
+
+ assertFalse(mTelephonyUtil.tryUpdateCarrierIdForPasspoint(config));
+ }
+
+ /**
+ * Verify that if the carrier ID has been assigned, it shouldn't be updated.
+ */
+ @Test
+ public void tryUpdateCarrierIdForPasspointWithValidCarrieId() {
+ PasspointConfiguration config = mock(PasspointConfiguration.class);
+ when(config.getCarrierId()).thenReturn(DATA_CARRIER_ID);
+
+ assertFalse(mTelephonyUtil.tryUpdateCarrierIdForPasspoint(config));
+ }
+
+ /**
+ * Verify that if the passpoint profile doesn't have SIM credential, it shouldn't be updated.
+ */
+ @Test
+ public void tryUpdateCarrierIdForPasspointWithNonSimCredential() {
+ Credential credential = mock(Credential.class);
+ PasspointConfiguration spyConfig = spy(new PasspointConfiguration());
+ doReturn(credential).when(spyConfig).getCredential();
+ when(credential.getSimCredential()).thenReturn(null);
+
+ assertFalse(mTelephonyUtil.tryUpdateCarrierIdForPasspoint(spyConfig));
+ }
+
+ /**
+ * Verify that if the passpoint profile only have IMSI prefix(mccmnc*) parameter,
+ * it shouldn't be updated.
+ */
+ @Test
+ public void tryUpdateCarrierIdForPasspointWithPrefixImsi() {
+ Credential credential = mock(Credential.class);
+ PasspointConfiguration spyConfig = spy(new PasspointConfiguration());
+ doReturn(credential).when(spyConfig).getCredential();
+ Credential.SimCredential simCredential = mock(Credential.SimCredential.class);
+ when(credential.getSimCredential()).thenReturn(simCredential);
+ when(simCredential.getImsi()).thenReturn(MATCH_PREFIX_IMSI);
+
+ assertFalse(mTelephonyUtil.tryUpdateCarrierIdForPasspoint(spyConfig));
+ }
+
+ /**
+ * Verify that if the passpoint profile has the full IMSI and wasn't assigned valid
+ * carrier ID, it should be updated.
+ */
+ @Test
+ public void tryUpdateCarrierIdForPasspointWithFullImsiAndActiveSim() {
+ Credential credential = mock(Credential.class);
+ PasspointConfiguration spyConfig = spy(new PasspointConfiguration());
+ doReturn(credential).when(spyConfig).getCredential();
+ Credential.SimCredential simCredential = mock(Credential.SimCredential.class);
+ when(credential.getSimCredential()).thenReturn(simCredential);
+ when(simCredential.getImsi()).thenReturn(DATA_FULL_IMSI);
+
+ assertTrue(mTelephonyUtil.tryUpdateCarrierIdForPasspoint(spyConfig));
+ assertEquals(DATA_CARRIER_ID, spyConfig.getCarrierId());
+ }
+
+ /**
+ * Verify that if there is no SIM card matching the given IMSI, it shouldn't be updated.
+ */
+ @Test
+ public void tryUpdateCarrierIdForPasspointWithFullImsiAndInactiveSim() {
+ Credential credential = mock(Credential.class);
+ PasspointConfiguration spyConfig = spy(new PasspointConfiguration());
+ doReturn(credential).when(spyConfig).getCredential();
+ Credential.SimCredential simCredential = mock(Credential.SimCredential.class);
+ when(credential.getSimCredential()).thenReturn(simCredential);
+ when(simCredential.getImsi()).thenReturn(NO_MATCH_PREFIX_IMSI);
+
+ assertFalse(mTelephonyUtil.tryUpdateCarrierIdForPasspoint(spyConfig));
+ }
}