summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java83
-rw-r--r--service/java/com/android/server/wifi/SavedNetworkEvaluator.java20
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java16
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java16
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java24
-rw-r--r--service/java/com/android/server/wifi/util/TelephonyUtil.java225
6 files changed, 238 insertions, 146 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 720b3dccb..68dfe083e 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -89,7 +89,6 @@ import android.os.WorkSource;
import android.provider.Settings;
import android.system.OsConstants;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -233,6 +232,8 @@ public class ClientModeImpl extends StateMachine {
private int mLastSignalLevel = -1;
private String mLastBssid;
private int mLastNetworkId; // The network Id we successfully joined
+ // The subId used by WifiConfiguration with SIM credential which was connected successfully
+ private int mLastSubId;
private boolean mIpReachabilityDisconnectEnabled = true;
@@ -676,16 +677,10 @@ public class ClientModeImpl extends StateMachine {
*/
public static final WorkSource WIFI_WORK_SOURCE = new WorkSource(Process.WIFI_UID);
- private TelephonyManager mTelephonyManager;
- private TelephonyManager getTelephonyManager() {
- if (mTelephonyManager == null) {
- mTelephonyManager = mWifiInjector.makeTelephonyManager();
- }
- return mTelephonyManager;
- }
-
private final BatteryStatsManager mBatteryStatsManager;
+ private final TelephonyUtil mTelephonyUtil;
+
private final String mTcpBufferSizes;
// Used for debug and stats gathering
@@ -711,7 +706,8 @@ public class ClientModeImpl extends StateMachine {
LinkProbeManager linkProbeManager,
BatteryStatsManager batteryStatsManager,
SupplicantStateTracker supplicantStateTracker,
- MboOceController mboOceController) {
+ MboOceController mboOceController,
+ TelephonyUtil telephonyUtil) {
super(TAG, looper);
mWifiInjector = wifiInjector;
mWifiMetrics = mWifiInjector.getWifiMetrics();
@@ -728,6 +724,7 @@ public class ClientModeImpl extends StateMachine {
mWifiTrafficPoller = wifiTrafficPoller;
mLinkProbeManager = linkProbeManager;
mMboOceController = mboOceController;
+ mTelephonyUtil = telephonyUtil;
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
mBatteryStatsManager = batteryStatsManager;
@@ -759,6 +756,7 @@ public class ClientModeImpl extends StateMachine {
mNetworkInfo.setIsAvailable(false);
mLastBssid = null;
mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+ mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
mLastSignalLevel = -1;
mCountryCode = countryCode;
@@ -1726,6 +1724,7 @@ public class ClientModeImpl extends StateMachine {
pw.println("mLastSignalLevel " + mLastSignalLevel);
pw.println("mLastBssid " + mLastBssid);
pw.println("mLastNetworkId " + mLastNetworkId);
+ pw.println("mLastSubId " + mLastSubId);
pw.println("mOperationalMode " + mOperationalMode);
pw.println("mUserWantsSuspendOpt " + mUserWantsSuspendOpt);
pw.println("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
@@ -2597,6 +2596,7 @@ public class ClientModeImpl extends StateMachine {
mLastLinkLayerStats = null;
registerDisconnected();
mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+ mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
mWifiScoreCard.resetConnectionState();
updateL2KeyAndGroupHint();
}
@@ -3294,6 +3294,7 @@ public class ClientModeImpl extends StateMachine {
// Initialize data structures
mLastBssid = null;
mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+ mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
mLastSignalLevel = -1;
mWifiInfo.setMacAddress(mWifiNative.getMacAddress(mInterfaceName));
// TODO: b/79504296 This broadcast has been deprecated and should be removed
@@ -3635,12 +3636,12 @@ public class ClientModeImpl extends StateMachine {
// For SIM & AKA/AKA' EAP method Only, get identity from ICC
if (mTargetWifiConfiguration != null
&& mTargetWifiConfiguration.networkId == netId
- && TelephonyUtil.isSimConfig(mTargetWifiConfiguration)) {
+ && mTargetWifiConfiguration.enterpriseConfig != null
+ && mTargetWifiConfiguration.enterpriseConfig
+ .requireSimCredential()) {
// Pair<identity, encrypted identity>
- Pair<String, String> identityPair =
- TelephonyUtil.getSimIdentity(getTelephonyManager(),
- new TelephonyUtil(), mTargetWifiConfiguration,
- mWifiInjector.getCarrierNetworkConfig());
+ Pair<String, String> identityPair = mTelephonyUtil
+ .getSimIdentity(mTargetWifiConfiguration);
Log.i(TAG, "SUP_REQUEST_IDENTITY: identityPair=" + identityPair);
if (identityPair != null && identityPair.first != null) {
mWifiNative.simIdentityResponse(mInterfaceName, identityPair.first,
@@ -3747,12 +3748,12 @@ public class ClientModeImpl extends StateMachine {
Log.i(TAG, "Connecting with " + currentMacAddress + " as the mac address");
if (config.enterpriseConfig != null
- && TelephonyUtil.isSimEapMethod(config.enterpriseConfig.getEapMethod())
+ && config.enterpriseConfig.requireSimCredential()
&& mWifiInjector.getCarrierNetworkConfig()
.isCarrierEncryptionInfoAvailable()
&& TextUtils.isEmpty(config.enterpriseConfig.getAnonymousIdentity())) {
- String anonAtRealm = TelephonyUtil.getAnonymousIdentityWith3GppRealm(
- getTelephonyManager());
+ String anonAtRealm = mTelephonyUtil
+ .getAnonymousIdentityWith3GppRealm(config);
// Use anonymous@<realm> when pseudonym is not available
config.enterpriseConfig.setAnonymousIdentity(anonAtRealm);
}
@@ -3873,15 +3874,15 @@ public class ClientModeImpl extends StateMachine {
// We need to get the updated pseudonym from supplicant for EAP-SIM/AKA/AKA'
if (config.enterpriseConfig != null
- && TelephonyUtil.isSimEapMethod(
- config.enterpriseConfig.getEapMethod())) {
+ && config.enterpriseConfig.requireSimCredential()) {
+ mLastSubId = mTelephonyUtil.getBestMatchSubscriptionId(config);
String anonymousIdentity =
mWifiNative.getEapAnonymousIdentity(mInterfaceName);
if (!TextUtils.isEmpty(anonymousIdentity)
&& !TelephonyUtil
.isAnonymousAtRealmIdentity(anonymousIdentity)) {
- String decoratedPseudonym = TelephonyUtil
- .decoratePseudonymWith3GppRealm(getTelephonyManager(),
+ String decoratedPseudonym = mTelephonyUtil
+ .decoratePseudonymWith3GppRealm(config,
anonymousIdentity);
if (decoratedPseudonym != null) {
anonymousIdentity = decoratedPseudonym;
@@ -4098,10 +4099,7 @@ public class ClientModeImpl extends StateMachine {
case WifiEnterpriseConfig.Eap.AKA:
case WifiEnterpriseConfig.Eap.AKA_PRIME:
if (errorCode == WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED) {
- getTelephonyManager()
- .createForSubscriptionId(
- SubscriptionManager.getDefaultDataSubscriptionId())
- .resetCarrierKeysForImsiEncryption();
+ mTelephonyUtil.resetCarrierKeysForImsiEncryption(targetedNetwork);
}
break;
@@ -4527,11 +4525,14 @@ public class ClientModeImpl extends StateMachine {
&& mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
WifiConfiguration config =
mWifiConfigManager.getConfiguredNetwork(mLastNetworkId);
- if (TelephonyUtil.isSimConfig(config)) {
+ if (config.enterpriseConfig != null
+ && config.enterpriseConfig.requireSimCredential()
+ && !mTelephonyUtil.isSimPresent(mLastSubId)) {
+ // check if the removed sim card is associated with current config
mWifiMetrics.logStaEvent(StaEvent.TYPE_FRAMEWORK_DISCONNECT,
StaEvent.DISCONNECT_RESET_SIM_NETWORKS);
- // TODO(b/132385576): STA may immediately connect back to the network
- // that we just disconnected from
+ // TODO(b/132385576): STA may immediately connect back to the
+ // network that we just disconnected from
mWifiNative.disconnect(mInterfaceName);
transitionTo(mDisconnectingState);
}
@@ -5358,8 +5359,8 @@ public class ClientModeImpl extends StateMachine {
}
void handleGsmAuthRequest(SimAuthRequestData requestData) {
- if (mTargetWifiConfiguration == null
- || mTargetWifiConfiguration.networkId
+ if (mTargetWifiConfiguration != null
+ && mTargetWifiConfiguration.networkId
== requestData.networkId) {
logd("id matches targetWifiConfiguration");
} else {
@@ -5379,16 +5380,16 @@ public class ClientModeImpl extends StateMachine {
* 3. 3GPP TS 11.11 2G_authentication [RAND]
* [SRES][Cipher Key Kc]
*/
- String response =
- TelephonyUtil.getGsmSimAuthResponse(requestData.data, getTelephonyManager());
+ String response = mTelephonyUtil
+ .getGsmSimAuthResponse(requestData.data, mTargetWifiConfiguration);
if (response == null) {
// In case of failure, issue may be due to sim type, retry as No.2 case
- response = TelephonyUtil.getGsmSimpleSimAuthResponse(requestData.data,
- getTelephonyManager());
+ response = mTelephonyUtil
+ .getGsmSimpleSimAuthResponse(requestData.data, mTargetWifiConfiguration);
if (response == null) {
// In case of failure, issue may be due to sim type, retry as No.3 case
- response = TelephonyUtil.getGsmSimpleSimNoLengthAuthResponse(requestData.data,
- getTelephonyManager());
+ response = mTelephonyUtil.getGsmSimpleSimNoLengthAuthResponse(
+ requestData.data, mTargetWifiConfiguration);
}
}
if (response == null || response.length() == 0) {
@@ -5401,8 +5402,8 @@ public class ClientModeImpl extends StateMachine {
}
void handle3GAuthRequest(SimAuthRequestData requestData) {
- if (mTargetWifiConfiguration == null
- || mTargetWifiConfiguration.networkId
+ if (mTargetWifiConfiguration != null
+ && mTargetWifiConfiguration.networkId
== requestData.networkId) {
logd("id matches targetWifiConfiguration");
} else {
@@ -5410,8 +5411,8 @@ public class ClientModeImpl extends StateMachine {
return;
}
- SimAuthResponseData response =
- TelephonyUtil.get3GAuthResponse(requestData, getTelephonyManager());
+ SimAuthResponseData response = mTelephonyUtil
+ .get3GAuthResponse(requestData, mTargetWifiConfiguration);
if (response != null) {
mWifiNative.simAuthResponse(
mInterfaceName, response.type, response.response);
diff --git a/service/java/com/android/server/wifi/SavedNetworkEvaluator.java b/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
index f4635ab68..0437dc49a 100644
--- a/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
+++ b/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
-import android.telephony.SubscriptionManager;
import android.util.LocalLog;
import com.android.internal.annotations.VisibleForTesting;
@@ -39,7 +38,7 @@ public class SavedNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluat
private final Clock mClock;
private final LocalLog mLocalLog;
private final WifiConnectivityHelper mConnectivityHelper;
- private final SubscriptionManager mSubscriptionManager;
+ private final TelephonyUtil mTelephonyUtil;
private final int mRssiScoreSlope;
private final int mRssiScoreOffset;
private final int mSameBssidAward;
@@ -59,13 +58,13 @@ public class SavedNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluat
SavedNetworkEvaluator(final Context context, ScoringParams scoringParams,
WifiConfigManager configManager, Clock clock,
LocalLog localLog, WifiConnectivityHelper connectivityHelper,
- SubscriptionManager subscriptionManager) {
+ TelephonyUtil telephonyUtil) {
mScoringParams = scoringParams;
mWifiConfigManager = configManager;
mClock = clock;
mLocalLog = localLog;
mConnectivityHelper = connectivityHelper;
- mSubscriptionManager = subscriptionManager;
+ mTelephonyUtil = telephonyUtil;
mRssiScoreSlope = context.getResources().getInteger(
R.integer.config_wifi_framework_RSSI_SCORE_SLOPE);
@@ -235,10 +234,15 @@ public class SavedNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluat
+ " has specified BSSID " + network.BSSID + ". Skip "
+ scanResult.BSSID);
continue;
- } else if (TelephonyUtil.isSimConfig(network)
- && !TelephonyUtil.isSimPresent(mSubscriptionManager)) {
- // Don't select if security type is EAP SIM/AKA/AKA' when SIM is not present.
- continue;
+ } else if (network.enterpriseConfig != null
+ && network.enterpriseConfig.requireSimCredential()) {
+ int subId = mTelephonyUtil.getBestMatchSubscriptionId(network);
+ if (!mTelephonyUtil.isSimPresent(subId)) {
+ // Don't select if security type is EAP SIM/AKA/AKA' when SIM is not present.
+ localLog("No SIM card is good for Network "
+ + WifiNetworkSelector.toNetworkString(network));
+ continue;
+ }
}
int score = calculateBssidScore(scanResult, network, currentNetwork, currentBssid,
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 657e05708..958a9f1b0 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -41,7 +41,6 @@ import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
-import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.LocalLog;
@@ -275,7 +274,6 @@ public class WifiConfigManager {
private final Clock mClock;
private final UserManager mUserManager;
private final BackupManagerProxy mBackupManagerProxy;
- private final TelephonyManager mTelephonyManager;
private final WifiKeyStore mWifiKeyStore;
private final WifiConfigStore mWifiConfigStore;
private final WifiPermissionsUtil mWifiPermissionsUtil;
@@ -284,6 +282,7 @@ public class WifiConfigManager {
private final MacAddressUtil mMacAddressUtil;
private boolean mConnectedMacRandomzationSupported;
private final Mac mMac;
+ private final TelephonyUtil mTelephonyUtil;
/**
* Local log used for debugging any WifiConfigManager issues.
@@ -394,7 +393,7 @@ public class WifiConfigManager {
*/
WifiConfigManager(
Context context, Clock clock, UserManager userManager,
- TelephonyManager telephonyManager, WifiKeyStore wifiKeyStore,
+ TelephonyUtil telephonyUtil, WifiKeyStore wifiKeyStore,
WifiConfigStore wifiConfigStore,
WifiPermissionsUtil wifiPermissionsUtil,
WifiPermissionsWrapper wifiPermissionsWrapper,
@@ -409,7 +408,7 @@ public class WifiConfigManager {
mClock = clock;
mUserManager = userManager;
mBackupManagerProxy = new BackupManagerProxy();
- mTelephonyManager = telephonyManager;
+ mTelephonyUtil = telephonyUtil;
mWifiKeyStore = wifiKeyStore;
mWifiConfigStore = wifiConfigStore;
mWifiPermissionsUtil = wifiPermissionsUtil;
@@ -1148,6 +1147,7 @@ public class WifiConfigManager {
// Copy over macRandomizationSetting
internalConfig.macRandomizationSetting = externalConfig.macRandomizationSetting;
+ internalConfig.carrierId = externalConfig.carrierId;
}
/**
@@ -2978,13 +2978,13 @@ public class WifiConfigManager {
public void resetSimNetworks() {
if (mVerboseLoggingEnabled) localLog("resetSimNetworks");
for (WifiConfiguration config : getInternalConfiguredNetworks()) {
- if (!TelephonyUtil.isSimConfig(config)) {
+ if (config.enterpriseConfig == null
+ || !config.enterpriseConfig.requireSimCredential()) {
continue;
}
if (config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.PEAP) {
- Pair<String, String> currentIdentity = TelephonyUtil.getSimIdentity(
- mTelephonyManager, new TelephonyUtil(), config,
- mWifiInjector.getCarrierNetworkConfig());
+ Pair<String, String> currentIdentity =
+ mTelephonyUtil.getSimIdentity(config);
if (mVerboseLoggingEnabled) {
Log.d(TAG, "New identity for config " + config + ": " + currentIdentity);
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 13f6a8267..89151ea3e 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -56,6 +56,7 @@ import com.android.server.wifi.p2p.WifiP2pMetrics;
import com.android.server.wifi.p2p.WifiP2pMonitor;
import com.android.server.wifi.p2p.WifiP2pNative;
import com.android.server.wifi.rtt.RttMetrics;
+import com.android.server.wifi.util.TelephonyUtil;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
import com.android.server.wifi.wificond.IWificond;
@@ -154,6 +155,7 @@ public class WifiInjector {
private BssidBlocklistMonitor mBssidBlocklistMonitor;
private final MacAddressUtil mMacAddressUtil;
private final MboOceController mMboOceController;
+ private final TelephonyUtil mTelephonyUtil;
public WifiInjector(Context context) {
if (context == null) {
@@ -245,9 +247,10 @@ public class WifiInjector {
WifiConfigStore.createSharedFile(mFrameworkFacade.isNiapModeOn(mContext)));
SubscriptionManager subscriptionManager =
mContext.getSystemService(SubscriptionManager.class);
+ mTelephonyUtil = new TelephonyUtil(makeTelephonyManager(), subscriptionManager);
// Config Manager
mWifiConfigManager = new WifiConfigManager(mContext, mClock,
- mUserManager, makeTelephonyManager(),
+ mUserManager, mTelephonyUtil,
mWifiKeyStore, mWifiConfigStore, mWifiPermissionsUtil,
mWifiPermissionsWrapper, this, new NetworkListSharedStoreData(mContext),
new NetworkListUserStoreData(mContext),
@@ -270,9 +273,10 @@ public class WifiInjector {
mWifiMetrics.setWifiNetworkSelector(mWifiNetworkSelector);
mSavedNetworkEvaluator = new SavedNetworkEvaluator(mContext, mScoringParams,
mWifiConfigManager, mClock, mConnectivityLocalLog, mWifiConnectivityHelper,
- subscriptionManager);
+ mTelephonyUtil);
mWifiNetworkSuggestionsManager = new WifiNetworkSuggestionsManager(mContext, wifiHandler,
- this, mWifiPermissionsUtil, mWifiConfigManager, mWifiConfigStore, mWifiMetrics);
+ this, mWifiPermissionsUtil, mWifiConfigManager, mWifiConfigStore, mWifiMetrics,
+ mTelephonyUtil);
mNetworkSuggestionEvaluator = new NetworkSuggestionEvaluator(mWifiNetworkSuggestionsManager,
mWifiConfigManager, mConnectivityLocalLog);
mScoredNetworkEvaluator = new ScoredNetworkEvaluator(context, wifiHandler,
@@ -313,7 +317,7 @@ public class WifiInjector {
this, mBackupManagerProxy, mCountryCode, mWifiNative,
new WrongPasswordNotifier(mContext, mFrameworkFacade),
mSarManager, mWifiTrafficPoller, mLinkProbeManager, mBatteryStats,
- supplicantStateTracker, mMboOceController);
+ supplicantStateTracker, mMboOceController, mTelephonyUtil);
mActiveModeWarden = new ActiveModeWarden(this, wifiLooper,
mWifiNative, new DefaultModeManager(mContext), mBatteryStats, mWifiDiagnostics,
mContext, mClientModeImpl, mSettingsStore, mFrameworkFacade, mWifiPermissionsUtil);
@@ -502,6 +506,10 @@ public class WifiInjector {
return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
}
+ public TelephonyUtil getTelephonyUtil() {
+ return mTelephonyUtil;
+ }
+
public WifiStateTracker getWifiStateTracker() {
return mWifiStateTracker;
}
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index b94f91da4..0d400c576 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -52,6 +52,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.server.wifi.util.ExternalCallbackTracker;
+import com.android.server.wifi.util.TelephonyUtil;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.wifi.R;
@@ -113,6 +114,7 @@ public class WifiNetworkSuggestionsManager {
private final WifiMetrics mWifiMetrics;
private final WifiInjector mWifiInjector;
private final FrameworkFacade mFrameworkFacade;
+ private final TelephonyUtil mTelephonyUtil;
/**
* Per app meta data to store network suggestions, status, etc for each app providing network
@@ -406,7 +408,8 @@ public class WifiNetworkSuggestionsManager {
WifiPermissionsUtil wifiPermissionsUtil,
WifiConfigManager wifiConfigManager,
WifiConfigStore wifiConfigStore,
- WifiMetrics wifiMetrics) {
+ WifiMetrics wifiMetrics,
+ TelephonyUtil telephonyUtil) {
mContext = context;
mResources = context.getResources();
mHandler = handler;
@@ -419,6 +422,7 @@ public class WifiNetworkSuggestionsManager {
mWifiPermissionsUtil = wifiPermissionsUtil;
mWifiConfigManager = wifiConfigManager;
mWifiMetrics = wifiMetrics;
+ mTelephonyUtil = telephonyUtil;
// register the data store for serializing/deserializing data.
wifiConfigStore.registerStoreData(
@@ -1000,7 +1004,23 @@ public class WifiNetworkSuggestionsManager {
Set<ExtendedWifiNetworkSuggestion> approvedExtNetworkSuggestions =
extNetworkSuggestions
.stream()
- .filter(n -> n.perAppInfo.hasUserApproved)
+ .filter(n -> {
+ if (!n.perAppInfo.hasUserApproved) {
+ return false;
+ }
+ WifiConfiguration config = n.wns.wifiConfiguration;
+ if (config != null && config.enterpriseConfig != null
+ && config.enterpriseConfig.requireSimCredential()) {
+ int subId = mTelephonyUtil.getBestMatchSubscriptionId(config);
+ if (!mTelephonyUtil.isSimPresent(subId)) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "No SIM is matched, ignore the config.");
+ }
+ return false;
+ }
+ }
+ return true;
+ })
.collect(Collectors.toSet());
// If there is no active notification, check if we need to get approval for any of the apps
// & send a notification for one of them. If there are multiple packages awaiting approval,
diff --git a/service/java/com/android/server/wifi/util/TelephonyUtil.java b/service/java/com/android/server/wifi/util/TelephonyUtil.java
index a80c18cf6..60921725e 100644
--- a/service/java/com/android/server/wifi/util/TelephonyUtil.java
+++ b/service/java/com/android/server/wifi/util/TelephonyUtil.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.telephony.ImsiEncryptionInfo;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -28,13 +29,14 @@ import android.util.Log;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.wifi.CarrierNetworkConfig;
import com.android.server.wifi.WifiNative;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import javax.annotation.Nonnull;
import javax.crypto.BadPaddingException;
@@ -78,34 +80,83 @@ public class TelephonyUtil {
private static final int START_KC_POS = START_SRES_POS + SRES_LEN;
private static final int KC_LEN = 8;
+ private final TelephonyManager mTelephonyManager;
+ private final SubscriptionManager mSubscriptionManager;
+
+ /**
+ * Gets the instance of TelephonyUtil.
+ * @param telephonyManager Instance of {@link TelephonyManager}
+ * @param subscriptionManager Instance of {@link SubscriptionManager}
+ * @return The instance of TelephonyUtil
+ */
+ public TelephonyUtil(@NonNull TelephonyManager telephonyManager,
+ @NonNull SubscriptionManager subscriptionManager) {
+ mTelephonyManager = telephonyManager;
+ mSubscriptionManager = subscriptionManager;
+ }
+
+ /**
+ * Gets the SubscriptionId of SIM card which is from the carrier specified in config.
+ * @param config the instance of {@link WifiConfiguration}
+ * @return the best match SubscriptionId
+ */
+ public int getBestMatchSubscriptionId(WifiConfiguration config) {
+ 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) {
+ matchSubId = subInfo.getSubscriptionId();
+ if (matchSubId == dataSubId) {
+ // Priority of Data sub is higher than non data sub.
+ break;
+ }
+ }
+ }
+ Log.d(TAG, "best match subscription id: " + matchSubId);
+ return matchSubId;
+ }
+
+ /**
+ * Check if the specified SIM card is in the device.
+ *
+ * @param subId subscription ID of SIM card in the device.
+ * @return true if the subId is active, otherwise false.
+ */
+ public boolean isSimPresent(int subId) {
+ return Arrays.stream(mSubscriptionManager.getActiveSubscriptionIdList())
+ .anyMatch(id -> id == subId);
+ }
/**
* Get the identity for the current SIM or null if the SIM is not available
*
- * @param tm TelephonyManager instance
* @param config WifiConfiguration that indicates what sort of authentication is necessary
- * @param telephonyUtil TelephonyUtil instance
- * @param carrierNetworkConfig CarrierNetworkConfig instance
* @return Pair<identify, encrypted identity> or null if the SIM is not available
* or config is invalid
*/
- public static Pair<String, String> getSimIdentity(TelephonyManager tm,
- TelephonyUtil telephonyUtil,
- WifiConfiguration config, CarrierNetworkConfig carrierNetworkConfig) {
- if (tm == null) {
- Log.e(TAG, "No valid TelephonyManager");
- return null;
- }
- TelephonyManager defaultDataTm = tm.createForSubscriptionId(
- SubscriptionManager.getDefaultDataSubscriptionId());
- if (carrierNetworkConfig == null) {
- Log.e(TAG, "No valid CarrierNetworkConfig");
+ public Pair<String, String> getSimIdentity(WifiConfiguration config) {
+ int subId = getBestMatchSubscriptionId(config);
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
return null;
}
- String imsi = defaultDataTm.getSubscriberId();
+
+ TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(subId);
+ String imsi = specifiedTm.getSubscriberId();
String mccMnc = "";
- if (defaultDataTm.getSimState() == TelephonyManager.SIM_STATE_READY) {
- mccMnc = defaultDataTm.getSimOperator();
+ if (specifiedTm.getSimState() == TelephonyManager.SIM_STATE_READY) {
+ mccMnc = specifiedTm.getSimOperator();
}
String identity = buildIdentity(getSimMethodForConfig(config), imsi, mccMnc, false);
@@ -116,7 +167,7 @@ public class TelephonyUtil {
ImsiEncryptionInfo imsiEncryptionInfo;
try {
- imsiEncryptionInfo = defaultDataTm.getCarrierInfoForImsiEncryption(
+ imsiEncryptionInfo = specifiedTm.getCarrierInfoForImsiEncryption(
TelephonyManager.KEY_TYPE_WLAN);
} catch (RuntimeException e) {
Log.e(TAG, "Failed to get imsi encryption info: " + e.getMessage());
@@ -127,7 +178,7 @@ public class TelephonyUtil {
return Pair.create(identity, "");
}
- String encryptedIdentity = buildEncryptedIdentity(telephonyUtil, identity,
+ String encryptedIdentity = buildEncryptedIdentity(identity,
imsiEncryptionInfo);
// In case of failure for encryption, abort current EAP authentication.
@@ -141,20 +192,17 @@ public class TelephonyUtil {
/**
* Gets Anonymous identity for current active SIM.
*
- * @param tm TelephonyManager instance
+ * @param config the instance of WifiConfiguration.
* @return anonymous identity@realm which is based on current MCC/MNC, {@code null} if SIM is
* not ready or absent.
*/
- public static String getAnonymousIdentityWith3GppRealm(@Nonnull TelephonyManager tm) {
- if (tm == null) {
+ public String getAnonymousIdentityWith3GppRealm(@NonNull WifiConfiguration config) {
+ int subId = getBestMatchSubscriptionId(config);
+ TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(subId);
+ if (specifiedTm.getSimState() != TelephonyManager.SIM_STATE_READY) {
return null;
}
- TelephonyManager defaultDataTm = tm.createForSubscriptionId(
- SubscriptionManager.getDefaultDataSubscriptionId());
- if (defaultDataTm.getSimState() != TelephonyManager.SIM_STATE_READY) {
- return null;
- }
- String mccMnc = defaultDataTm.getSimOperator();
+ String mccMnc = specifiedTm.getSimOperator();
if (mccMnc == null || mccMnc.isEmpty()) {
return null;
}
@@ -176,11 +224,12 @@ public class TelephonyUtil {
* a Base64 encoded string.
*
* @param key The public key to use for encryption
+ * @param data The data need to be encrypted
* @param encodingFlag base64 encoding flag
* @return Base64 encoded string, or null if encryption failed
*/
@VisibleForTesting
- public String encryptDataUsingPublicKey(PublicKey key, byte[] data, int encodingFlag) {
+ public static String encryptDataUsingPublicKey(PublicKey key, byte[] data, int encodingFlag) {
try {
Cipher cipher = Cipher.getInstance(IMSI_CIPHER_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, key);
@@ -202,13 +251,12 @@ public class TelephonyUtil {
* "1" - EAP-SIM Identity
* "6" - EAP-AKA' Identity
* Encrypted identity format: prefix|IMSI@<NAIRealm>
- * @param telephonyUtil TelephonyUtil instance
* @param identity permanent identity with format based on section 4.1.1.6 of RFC 4187
* and 4.2.1.6 of RFC 4186.
* @param imsiEncryptionInfo The IMSI encryption info retrieved from the SIM
* @return "\0" + encryptedIdentity + "{, Key Identifier AVP}"
*/
- private static String buildEncryptedIdentity(TelephonyUtil telephonyUtil, String identity,
+ private static String buildEncryptedIdentity(String identity,
ImsiEncryptionInfo imsiEncryptionInfo) {
if (imsiEncryptionInfo == null) {
Log.e(TAG, "imsiEncryptionInfo is not valid");
@@ -220,7 +268,7 @@ public class TelephonyUtil {
}
// Build and return the encrypted identity.
- String encryptedIdentity = telephonyUtil.encryptDataUsingPublicKey(
+ String encryptedIdentity = encryptDataUsingPublicKey(
imsiEncryptionInfo.getPublicKey(), identity.getBytes(), Base64.NO_WRAP);
if (encryptedIdentity == null) {
Log.e(TAG, "Failed to encrypt IMSI");
@@ -324,16 +372,6 @@ public class TelephonyUtil {
}
/**
- * Checks if the network is a SIM config.
- *
- * @param config Config corresponding to the network.
- * @return true if it is a SIM config, false otherwise.
- */
- public static boolean isSimConfig(WifiConfiguration config) {
- return getSimMethodForConfig(config) != WifiEnterpriseConfig.Eap.NONE;
- }
-
- /**
* Returns true if {@code identity} contains an anonymous@realm identity, false otherwise.
*/
public static boolean isAnonymousAtRealmIdentity(String identity) {
@@ -448,12 +486,12 @@ public class TelephonyUtil {
* [Length][RES][Length][CK][Length][IK] and more
*
* @param requestData RAND data from server.
- * @param tm the instance of TelephonyManager.
+ * @param config The instance of WifiConfiguration.
* @return the response data processed by SIM. If all request data is malformed, then returns
* empty string. If request data is invalid, then returns null.
*/
- public static String getGsmSimAuthResponse(String[] requestData, TelephonyManager tm) {
- return getGsmAuthResponseWithLength(requestData, tm, TelephonyManager.APPTYPE_USIM);
+ public String getGsmSimAuthResponse(String[] requestData, WifiConfiguration config) {
+ return getGsmAuthResponseWithLength(requestData, config, TelephonyManager.APPTYPE_USIM);
}
/**
@@ -465,22 +503,22 @@ public class TelephonyUtil {
* [Length][SRES][Length][Cipher Key Kc]
*
* @param requestData RAND data from server.
- * @param tm the instance of TelephonyManager.
+ * @param config The instance of WifiConfiguration.
* @return the response data processed by SIM. If all request data is malformed, then returns
* empty string. If request data is invalid, then returns null.
*/
- public static String getGsmSimpleSimAuthResponse(String[] requestData, TelephonyManager tm) {
- return getGsmAuthResponseWithLength(requestData, tm, TelephonyManager.APPTYPE_SIM);
+ public String getGsmSimpleSimAuthResponse(String[] requestData,
+ WifiConfiguration config) {
+ return getGsmAuthResponseWithLength(requestData, config, TelephonyManager.APPTYPE_SIM);
}
- private static String getGsmAuthResponseWithLength(String[] requestData, TelephonyManager tm,
- int appType) {
- if (tm == null) {
- Log.e(TAG, "No valid TelephonyManager");
+ private String getGsmAuthResponseWithLength(String[] requestData,
+ WifiConfiguration config, int appType) {
+ int subId = getBestMatchSubscriptionId(config);
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
return null;
}
- TelephonyManager defaultDataTm = tm.createForSubscriptionId(
- SubscriptionManager.getDefaultDataSubscriptionId());
+
StringBuilder sb = new StringBuilder();
for (String challenge : requestData) {
if (challenge == null || challenge.isEmpty()) {
@@ -497,8 +535,8 @@ public class TelephonyUtil {
}
String base64Challenge = Base64.encodeToString(rand, Base64.NO_WRAP);
-
- String tmResponse = defaultDataTm.getIccAuthentication(
+ TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(subId);
+ String tmResponse = specifiedTm.getIccAuthentication(
appType, TelephonyManager.AUTHTYPE_EAP_SIM, base64Challenge);
Log.v(TAG, "Raw Response - " + tmResponse);
@@ -542,18 +580,18 @@ public class TelephonyUtil {
* [SRES][Cipher Key Kc]
*
* @param requestData RAND data from server.
- * @param tm the instance of TelephonyManager.
+ * @param config the instance of WifiConfiguration.
* @return the response data processed by SIM. If all request data is malformed, then returns
* empty string. If request data is invalid, then returns null.
*/
- public static String getGsmSimpleSimNoLengthAuthResponse(String[] requestData,
- TelephonyManager tm) {
- if (tm == null) {
- Log.e(TAG, "No valid TelephonyManager");
+ public String getGsmSimpleSimNoLengthAuthResponse(String[] requestData,
+ @NonNull WifiConfiguration config) {
+
+ int subId = getBestMatchSubscriptionId(config);
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
return null;
}
- TelephonyManager defaultDataTm = tm.createForSubscriptionId(
- SubscriptionManager.getDefaultDataSubscriptionId());
+
StringBuilder sb = new StringBuilder();
for (String challenge : requestData) {
if (challenge == null || challenge.isEmpty()) {
@@ -570,8 +608,8 @@ public class TelephonyUtil {
}
String base64Challenge = Base64.encodeToString(rand, Base64.NO_WRAP);
-
- String tmResponse = defaultDataTm.getIccAuthentication(TelephonyManager.APPTYPE_SIM,
+ TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(subId);
+ String tmResponse = specifiedTm.getIccAuthentication(TelephonyManager.APPTYPE_SIM,
TelephonyManager.AUTHTYPE_EAP_SIM, base64Challenge);
Log.v(TAG, "Raw Response - " + tmResponse);
@@ -628,8 +666,15 @@ public class TelephonyUtil {
public String response;
}
- public static SimAuthResponseData get3GAuthResponse(SimAuthRequestData requestData,
- TelephonyManager tm) {
+ /**
+ * Get the response data for 3G authentication.
+ *
+ * @param requestData authentication request data from server.
+ * @param config the instance of WifiConfiguration.
+ * @return the response data processed by SIM. If request data is invalid, then returns null.
+ */
+ public SimAuthResponseData get3GAuthResponse(SimAuthRequestData requestData,
+ WifiConfiguration config) {
StringBuilder sb = new StringBuilder();
byte[] rand = null;
byte[] authn = null;
@@ -649,15 +694,15 @@ public class TelephonyUtil {
String tmResponse = "";
if (rand != null && authn != null) {
String base64Challenge = Base64.encodeToString(concatHex(rand, authn), Base64.NO_WRAP);
- if (tm != null) {
- tmResponse = tm
- .createForSubscriptionId(SubscriptionManager.getDefaultDataSubscriptionId())
- .getIccAuthentication(TelephonyManager.APPTYPE_USIM,
- TelephonyManager.AUTHTYPE_EAP_AKA, base64Challenge);
- Log.v(TAG, "Raw Response - " + tmResponse);
- } else {
- Log.e(TAG, "No valid TelephonyManager");
+ int subId = getBestMatchSubscriptionId(config);
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+ return null;
}
+ tmResponse = mTelephonyManager
+ .createForSubscriptionId(subId)
+ .getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_AKA, base64Challenge);
+ Log.v(TAG, "Raw Response - " + tmResponse);
}
boolean goodReponse = false;
@@ -735,26 +780,27 @@ public class TelephonyUtil {
/**
* Decorates a pseudonym with the NAI realm, in case it wasn't provided by the server
*
- * @param tm TelephonyManager instance
+ * @param config The instance of WifiConfiguration
* @param pseudonym The pseudonym (temporary identity) provided by the server
* @return pseudonym@realm which is based on current MCC/MNC, {@code null} if SIM is
* not ready or absent.
*/
- public static String decoratePseudonymWith3GppRealm(@NonNull TelephonyManager tm,
+ public String decoratePseudonymWith3GppRealm(@NonNull WifiConfiguration config,
String pseudonym) {
- if (tm == null || TextUtils.isEmpty(pseudonym)) {
+ if (TextUtils.isEmpty(pseudonym)) {
return null;
}
if (pseudonym.contains("@")) {
// Pseudonym is already decorated
return pseudonym;
}
- TelephonyManager defaultDataTm = tm.createForSubscriptionId(
- SubscriptionManager.getDefaultDataSubscriptionId());
- if (defaultDataTm.getSimState() != TelephonyManager.SIM_STATE_READY) {
+ int subId = getBestMatchSubscriptionId(config);
+
+ TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(subId);
+ if (specifiedTm.getSimState() != TelephonyManager.SIM_STATE_READY) {
return null;
}
- String mccMnc = defaultDataTm.getSimOperator();
+ String mccMnc = specifiedTm.getSimOperator();
if (mccMnc == null || mccMnc.isEmpty()) {
return null;
}
@@ -770,4 +816,17 @@ public class TelephonyUtil {
String realm = String.format(THREE_GPP_NAI_REALM_FORMAT, mnc, mcc);
return String.format("%s@%s", pseudonym, realm);
}
+
+ /**
+ * Reset the downloaded IMSI encryption key.
+ * @param config Instance of WifiConfiguration
+ */
+ public void resetCarrierKeysForImsiEncryption(@NonNull WifiConfiguration config) {
+ int subId = getBestMatchSubscriptionId(config);
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+ return;
+ }
+ TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(subId);
+ specifiedTm.resetCarrierKeysForImsiEncryption();
+ }
}