diff options
author | Steven Liu <steveliu@google.com> | 2019-11-08 14:21:36 -0800 |
---|---|---|
committer | Steven Liu <steveliu@google.com> | 2019-12-10 16:55:51 -0800 |
commit | cb852a0301332aded8f5d83cebf63a249c947611 (patch) | |
tree | cc82013f5c0d6fae7f4fe8fba9fb7b1f9307172e /service | |
parent | e5a1fe842ebc903c5135bbdf55c2bc8d407a13be (diff) |
Migration of carrier network config to Carrier WiFi app
Bug: 130875004
Test: unit test - atest com.android.server.wifi, manual test
Change-Id: Ifeac605372eab18cac16465442d62676e0c064eb
Diffstat (limited to 'service')
10 files changed, 183 insertions, 551 deletions
diff --git a/service/java/com/android/server/wifi/CarrierNetworkConfig.java b/service/java/com/android/server/wifi/CarrierNetworkConfig.java deleted file mode 100644 index 174b5d723..000000000 --- a/service/java/com/android/server/wifi/CarrierNetworkConfig.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wifi; - -import android.annotation.NonNull; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.database.ContentObserver; -import android.net.Uri; -import android.net.wifi.EAPConstants; -import android.net.wifi.WifiEnterpriseConfig; -import android.os.Handler; -import android.os.PersistableBundle; -import android.telephony.CarrierConfigManager; -import android.telephony.ImsiEncryptionInfo; -import android.telephony.SubscriptionInfo; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; -import android.util.Base64; -import android.util.Log; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Class for maintaining/caching carrier Wi-Fi network configurations. - */ -public class CarrierNetworkConfig { - private static final String TAG = "CarrierNetworkConfig"; - - private static final String NETWORK_CONFIG_SEPARATOR = ","; - private static final int ENCODED_SSID_INDEX = 0; - private static final int EAP_TYPE_INDEX = 1; - private static final int CONFIG_ELEMENT_SIZE = 2; - - private static final Uri CONTENT_URI = Uri.parse("content://carrier_information/carrier"); - - private boolean mDbg = false; - - private final Map<String, NetworkInfo> mCarrierNetworkMap; - private boolean mIsCarrierImsiEncryptionInfoAvailable = false; - private ImsiEncryptionInfo mLastImsiEncryptionInfo = null; // used for dumpsys only - - /** - * Enable/disable verbose logging. - */ - public void enableVerboseLogging(int verbose) { - mDbg = verbose > 0; - } - - public CarrierNetworkConfig(@NonNull Context context, @NonNull Handler handler, - @NonNull FrameworkFacade framework) { - mCarrierNetworkMap = new HashMap<>(); - updateNetworkConfig(context); - - // Monitor for carrier config changes. - IntentFilter filter = new IntentFilter(); - filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); - context.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - updateNetworkConfig(context); - } - }, filter); - - try { - framework.registerContentObserver(context, CONTENT_URI, false, - new ContentObserver(handler) { - @Override - public void onChange(boolean selfChange) { - updateNetworkConfig(context); - } - }); - } catch (SecurityException e) { - Log.e(TAG, "Failed to register content observer", e); - } - } - - /** - * @return true if the given SSID is associated with a carrier network - */ - public boolean isCarrierNetwork(String ssid) { - return mCarrierNetworkMap.containsKey(ssid); - } - - /** - * @return the EAP type associated with a carrier AP, or -1 if the specified AP - * is not associated with a carrier network - */ - public int getNetworkEapType(String ssid) { - NetworkInfo info = mCarrierNetworkMap.get(ssid); - return info == null ? -1 : info.mEapType; - } - - /** - * @return the name of carrier associated with a carrier AP, or null if the specified AP - * is not associated with a carrier network. - */ - public String getCarrierName(String ssid) { - NetworkInfo info = mCarrierNetworkMap.get(ssid); - return info == null ? null : info.mCarrierName; - } - - /** - * @return True if carrier IMSI encryption info is available, False otherwise. - */ - public boolean isCarrierEncryptionInfoAvailable() { - return mIsCarrierImsiEncryptionInfoAvailable; - } - - /** - * Verify whether carrier IMSI encryption info is available. - * - * @param context Current application context - * - * @return True if carrier IMSI encryption info is available, False otherwise. - */ - private boolean verifyCarrierImsiEncryptionInfoIsAvailable(Context context) { - // TODO(b/132188983): Inject this using WifiInjector - TelephonyManager telephonyManager = - (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - if (telephonyManager == null) { - return false; - } - try { - mLastImsiEncryptionInfo = telephonyManager - .createForSubscriptionId(SubscriptionManager.getDefaultDataSubscriptionId()) - .getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_WLAN); - if (mLastImsiEncryptionInfo == null) { - return false; - } - } catch (RuntimeException e) { - Log.e(TAG, "Failed to get imsi encryption info: " + e.getMessage()); - return false; - } - - return true; - } - - /** - * Utility class for storing carrier network information. - */ - private static class NetworkInfo { - final int mEapType; - final String mCarrierName; - - NetworkInfo(int eapType, String carrierName) { - mEapType = eapType; - mCarrierName = carrierName; - } - - @Override - public String toString() { - return new StringBuffer("NetworkInfo: eap=").append(mEapType).append( - ", carrier=").append(mCarrierName).toString(); - } - } - - /** - * Update the carrier network map based on the current carrier configuration of the active - * subscriptions. - * - * @param context Current application context - */ - private void updateNetworkConfig(Context context) { - mIsCarrierImsiEncryptionInfoAvailable = verifyCarrierImsiEncryptionInfoIsAvailable(context); - - // Reset network map. - mCarrierNetworkMap.clear(); - - CarrierConfigManager carrierConfigManager = - (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); - if (carrierConfigManager == null) { - return; - } - - SubscriptionManager subscriptionManager = (SubscriptionManager) context.getSystemService( - Context.TELEPHONY_SUBSCRIPTION_SERVICE); - if (subscriptionManager == null) { - return; - } - List<SubscriptionInfo> subInfoList = subscriptionManager.getActiveSubscriptionInfoList(); - if (subInfoList == null) { - return; - } - - // Process the carrier config for each active subscription. - for (SubscriptionInfo subInfo : subInfoList) { - CharSequence displayNameCs = subInfo.getDisplayName(); - String displayNameStr = displayNameCs == null ? "" : displayNameCs.toString(); - PersistableBundle bundle = carrierConfigManager.getConfigForSubId( - subInfo.getSubscriptionId()); - processNetworkConfig(bundle, displayNameStr); - } - } - - /** - * Process the carrier network config, the network config string is formatted as follow: - * - * "[Base64 Encoded SSID],[EAP Type]" - * Where EAP Type is the standard EAP method number, refer to - * http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml for more info. - - * @param carrierConfig The bundle containing the carrier configuration - * @param carrierName The display name of the associated carrier - */ - private void processNetworkConfig(PersistableBundle carrierConfig, String carrierName) { - if (carrierConfig == null) { - return; - } - String[] networkConfigs = carrierConfig.getStringArray( - CarrierConfigManager.KEY_CARRIER_WIFI_STRING_ARRAY); - if (mDbg) { - Log.v(TAG, "processNetworkConfig: networkConfigs=" - + Arrays.deepToString(networkConfigs)); - } - if (networkConfigs == null) { - return; - } - - for (String networkConfig : networkConfigs) { - String[] configArr = networkConfig.split(NETWORK_CONFIG_SEPARATOR); - if (configArr.length != CONFIG_ELEMENT_SIZE) { - Log.e(TAG, "Ignore invalid config: " + networkConfig); - continue; - } - try { - - String ssid = new String(Base64.decode( - configArr[ENCODED_SSID_INDEX], Base64.NO_WRAP)); - int eapType = parseEapType(Integer.parseInt(configArr[EAP_TYPE_INDEX])); - - // Verify EAP type, must be a SIM based EAP type. - if (eapType == -1) { - Log.e(TAG, "Invalid EAP type: " + configArr[EAP_TYPE_INDEX]); - continue; - } - mCarrierNetworkMap.put(ssid, new NetworkInfo(eapType, carrierName)); - } catch (NumberFormatException e) { - Log.e(TAG, "Failed to parse EAP type: '" + configArr[EAP_TYPE_INDEX] + "' " - + e.getMessage()); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Failed to decode SSID: '" + configArr[ENCODED_SSID_INDEX] + "' " - + e.getMessage()); - } - } - } - - /** - * Convert a standard SIM-based EAP type (SIM, AKA, AKA') to the internal EAP type as defined in - * {@link WifiEnterpriseConfig.Eap}. -1 will be returned if the given EAP type is not - * SIM-based. - * - * @return SIM-based EAP type as defined in {@link WifiEnterpriseConfig.Eap}, or -1 if not - * SIM-based EAP type - */ - private static int parseEapType(int eapType) { - if (eapType == EAPConstants.EAP_SIM) { - return WifiEnterpriseConfig.Eap.SIM; - } else if (eapType == EAPConstants.EAP_AKA) { - return WifiEnterpriseConfig.Eap.AKA; - } else if (eapType == EAPConstants.EAP_AKA_PRIME) { - return WifiEnterpriseConfig.Eap.AKA_PRIME; - } - return -1; - } - - /** Dump state. */ - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println(TAG + ": "); - pw.println("mCarrierNetworkMap=" + mCarrierNetworkMap); - pw.println("mIsCarrierImsiEncryptionInfoAvailable=" - + mIsCarrierImsiEncryptionInfoAvailable); - pw.println("mLastImsiEncryptionInfo=" + mLastImsiEncryptionInfo); - } -} diff --git a/service/java/com/android/server/wifi/CarrierNetworkNominator.java b/service/java/com/android/server/wifi/CarrierNetworkNominator.java deleted file mode 100644 index c1a3e02a3..000000000 --- a/service/java/com/android/server/wifi/CarrierNetworkNominator.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wifi; - -import android.net.wifi.ScanResult; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiEnterpriseConfig; -import android.os.Process; -import android.telephony.TelephonyManager; -import android.util.LocalLog; - -import com.android.server.wifi.WifiNetworkSelector.NetworkNominator; -import com.android.server.wifi.util.ScanResultUtil; -import com.android.server.wifi.util.TelephonyUtil; - -import java.util.List; - -import javax.annotation.concurrent.NotThreadSafe; - -/** - * Nominator to select a Carrier Wi-Fi network which can be connected to. The Nominator performs - * two functions: - * - * 1. Filtering: figure out which of the networks is a Carrier Wi-Fi network (using the - * {@link CarrierNetworkConfig} APIs). - * 2. Nominating: Connectable networks: all networks which match #1 will be fed to this API - * - * Note: This class is not thread safe and meant to be used only from {@link WifiNetworkSelector}. - */ -@NotThreadSafe -public class CarrierNetworkNominator implements NetworkNominator { - private static final String TAG = "CarrierNetworkNominator"; - - private final WifiConfigManager mWifiConfigManager; - private final CarrierNetworkConfig mCarrierNetworkConfig; - private final LocalLog mLocalLog; - private final WifiInjector mWifiInjector; - private TelephonyManager mTelephonyManager; - - public CarrierNetworkNominator(WifiConfigManager wifiConfigManager, - CarrierNetworkConfig carrierNetworkConfig, LocalLog localLog, - WifiInjector wifiInjector) { - mWifiConfigManager = wifiConfigManager; - mCarrierNetworkConfig = carrierNetworkConfig; - mLocalLog = localLog; - mWifiInjector = wifiInjector; - } - - private TelephonyManager getTelephonyManager() { - if (mTelephonyManager == null) { - mTelephonyManager = mWifiInjector.makeTelephonyManager(); - } - return mTelephonyManager; - } - - @Override - public @NominatorId int getId() { - return NOMINATOR_ID_CARRIER; - } - - @Override - public String getName() { - return TAG; - } - - @Override - public void update(List<ScanDetail> scanDetails) { - // nothing to be done - } - - @Override - public void nominateNetworks(List<ScanDetail> scanDetails, - WifiConfiguration currentNetwork, String currentBssid, boolean connected, - boolean untrustedNetworkAllowed, OnConnectableListener onConnectableListener) { - if (!mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()) { - return; - } - - for (ScanDetail scanDetail : scanDetails) { - ScanResult scanResult = scanDetail.getScanResult(); - - if (!ScanResultUtil.isScanResultForEapNetwork(scanResult) - || !mCarrierNetworkConfig.isCarrierNetwork(scanResult.SSID)) { - continue; - } - int eapType = mCarrierNetworkConfig.getNetworkEapType(scanResult.SSID); - if (!TelephonyUtil.isSimEapMethod(eapType)) { - mLocalLog.log(TAG + ": eapType is not a carrier eap method: " + eapType); - continue; - } - // If the user previously forgot this network, don't select it. - if (mWifiConfigManager.wasEphemeralNetworkDeleted( - ScanResultUtil.createQuotedSSID(scanResult.SSID))) { - mLocalLog.log(TAG + ": Ignoring disabled ephemeral SSID: " - + WifiNetworkSelector.toScanId(scanResult)); - continue; - } - - WifiConfiguration config = ScanResultUtil.createNetworkFromScanResult(scanResult); - config.ephemeral = true; - if (config.enterpriseConfig == null) { - config.enterpriseConfig = new WifiEnterpriseConfig(); - } - config.enterpriseConfig.setEapMethod(eapType); - - // Check if we already have a network with the same credentials in WifiConfigManager - // database. If yes, we should check if the network is currently blacklisted. - WifiConfiguration existingNetwork = - mWifiConfigManager.getConfiguredNetwork(config.getKey()); - if (existingNetwork != null - && !existingNetwork.getNetworkSelectionStatus().isNetworkEnabled() - && !mWifiConfigManager.tryEnableNetwork(existingNetwork.networkId)) { - mLocalLog.log(TAG + ": Ignoring blacklisted network: " - + WifiNetworkSelector.toNetworkString(existingNetwork)); - continue; - } - - // Add the newly created WifiConfiguration to WifiConfigManager. - NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork(config, - Process.WIFI_UID); - if (!result.isSuccess()) { - mLocalLog.log(TAG + ": Failed to add carrier network: " + config); - continue; - } - if (!mWifiConfigManager.enableNetwork( - result.getNetworkId(), false, Process.WIFI_UID, null)) { - mLocalLog.log(TAG + ": Failed to enable carrier network: " + config); - continue; - } - if (!mWifiConfigManager.setNetworkCandidateScanResult(result.getNetworkId(), scanResult, - 0)) { - mLocalLog.log( - TAG + ": Failed to set network candidate for carrier network: " + config); - - continue; - } - - config = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId()); - - WifiConfiguration.NetworkSelectionStatus nss = null; - if (config != null) { - nss = config.getNetworkSelectionStatus(); - } - if (nss == null) { - mLocalLog.log(TAG + ": null network selection status for: " + config); - continue; - } - if (nss.getCandidate() != null && nss.getCandidate().level < scanResult.level) { - mWifiConfigManager.updateScanDetailForNetwork(result.getNetworkId(), scanDetail); - } - - onConnectableListener.onConnectable(scanDetail, config); - } - } -} diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 46d36758f..3642d4437 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -3740,8 +3740,8 @@ public class ClientModeImpl extends StateMachine { if (config.enterpriseConfig != null && config.enterpriseConfig.requireSimCredential() - && mWifiInjector.getCarrierNetworkConfig() - .isCarrierEncryptionInfoAvailable() + && mTelephonyUtil.isImsiEncryptionInfoAvailable( + mTelephonyUtil.getBestMatchSubscriptionId(config)) && TextUtils.isEmpty(config.enterpriseConfig.getAnonymousIdentity())) { String anonAtRealm = mTelephonyUtil .getAnonymousIdentityWith3GppRealm(config); diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index c00c33019..707701fb4 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -952,7 +952,7 @@ public class WifiConfigManager { // Since it is "owned" by us, so always allow us to modify them. if (config.enterpriseConfig != null && uid == Process.WIFI_UID - && TelephonyUtil.isSimEapMethod(config.enterpriseConfig.getEapMethod())) { + && config.enterpriseConfig.requireSimCredential()) { return true; } @@ -3445,6 +3445,7 @@ public class WifiConfigManager { pw.println("WifiConfigManager - PNO scan recency sorting enabled = " + mPnoRecencySortingEnabled); mWifiConfigStore.dump(fd, pw, args); + mTelephonyUtil.dump(fd, pw, args); } /** diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java index 09674ecef..36ddc8443 100644 --- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java +++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java @@ -34,7 +34,6 @@ import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.server.wifi.util.NativeUtil; -import com.android.server.wifi.util.TelephonyUtil; import java.nio.charset.StandardCharsets; import java.security.cert.X509Certificate; @@ -219,7 +218,7 @@ public class WifiConfigurationUtil { newEnterpriseConfig.getIdentity())) { return true; } - if (!TelephonyUtil.isSimEapMethod(existingEnterpriseConfig.getEapMethod()) + if (!existingEnterpriseConfig.requireSimCredential() && !TextUtils.equals(existingEnterpriseConfig.getAnonymousIdentity(), newEnterpriseConfig.getAnonymousIdentity())) { return true; diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 55342ccd1..c9fa60d71 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -128,7 +128,6 @@ public class WifiConnectivityManager { private final WifiNetworkSelector mNetworkSelector; private final WifiLastResortWatchdog mWifiLastResortWatchdog; private final OpenNetworkNotifier mOpenNetworkNotifier; - private final CarrierNetworkConfig mCarrierNetworkConfig; private final WifiMetrics mWifiMetrics; private final AlarmManager mAlarmManager; private final Handler mEventHandler; @@ -552,7 +551,7 @@ public class WifiConnectivityManager { WifiInjector injector, WifiConfigManager configManager, WifiInfo wifiInfo, WifiNetworkSelector networkSelector, WifiConnectivityHelper connectivityHelper, WifiLastResortWatchdog wifiLastResortWatchdog, OpenNetworkNotifier openNetworkNotifier, - CarrierNetworkConfig carrierNetworkConfig, WifiMetrics wifiMetrics, Handler handler, + WifiMetrics wifiMetrics, Handler handler, Clock clock, LocalLog localLog) { mContext = context; mStateMachine = stateMachine; @@ -564,7 +563,6 @@ public class WifiConnectivityManager { mLocalLog = localLog; mWifiLastResortWatchdog = wifiLastResortWatchdog; mOpenNetworkNotifier = openNetworkNotifier; - mCarrierNetworkConfig = carrierNetworkConfig; mWifiMetrics = wifiMetrics; mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); mEventHandler = handler; @@ -1392,7 +1390,6 @@ public class WifiConnectivityManager { mLocalLog.dump(fd, pw, args); pw.println("WifiConnectivityManager - Log End ----"); mOpenNetworkNotifier.dump(fd, pw, args); - mCarrierNetworkConfig.dump(fd, pw, args); mBssidBlocklistMonitor.dump(fd, pw, args); } } diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index bde949f4f..530ed1de6 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -106,7 +106,6 @@ public class WifiInjector { private final ActiveModeWarden mActiveModeWarden; private final WifiSettingsStore mSettingsStore; private OpenNetworkNotifier mOpenNetworkNotifier; - private final CarrierNetworkConfig mCarrierNetworkConfig; private final WifiLockManager mLockManager; private final WificondControl mWificondControl; private final Clock mClock = new Clock(); @@ -128,7 +127,6 @@ public class WifiInjector { private final NetworkSuggestionNominator mNetworkSuggestionNominator; private final PasspointNetworkNominator mPasspointNetworkNominator; private final ScoredNetworkNominator mScoredNetworkNominator; - private final CarrierNetworkNominator mCarrierNetworkNominator; private final WifiNetworkScoreCache mWifiNetworkScoreCache; private final NetworkScoreManager mNetworkScoreManager; private WifiScanner mWifiScanner; @@ -210,7 +208,6 @@ public class WifiInjector { mPasspointProvisionerHandlerThread = new HandlerThread("PasspointProvisionerHandlerThread"); mPasspointProvisionerHandlerThread.start(); - mCarrierNetworkConfig = new CarrierNetworkConfig(mContext, wifiHandler, mFrameworkFacade); WifiAwareMetrics awareMetrics = new WifiAwareMetrics(mClock); RttMetrics rttMetrics = new RttMetrics(mClock); mWifiP2pMetrics = new WifiP2pMetrics(mClock); @@ -232,7 +229,7 @@ public class WifiInjector { mWifiNative = new WifiNative( mWifiVendorHal, mSupplicantStaIfaceHal, mHostapdHal, mWificondControl, mWifiMonitor, mPropertyService, mWifiMetrics, - mCarrierNetworkConfig, wifiHandler, new Random(), this); + wifiHandler, new Random(), this); mWifiP2pMonitor = new WifiP2pMonitor(this); mSupplicantP2pIfaceHal = new SupplicantP2pIfaceHal(mWifiP2pMonitor); mWifiP2pNative = new WifiP2pNative( @@ -257,7 +254,8 @@ public class WifiInjector { WifiConfigStore.createSharedFiles(mFrameworkFacade.isNiapModeOn(mContext))); SubscriptionManager subscriptionManager = mContext.getSystemService(SubscriptionManager.class); - mTelephonyUtil = new TelephonyUtil(makeTelephonyManager(), subscriptionManager); + mTelephonyUtil = new TelephonyUtil(makeTelephonyManager(), subscriptionManager, + mFrameworkFacade, mContext, wifiHandler); // Config Manager mWifiConfigManager = new WifiConfigManager(mContext, mClock, mUserManager, mTelephonyUtil, @@ -301,8 +299,6 @@ public class WifiInjector { mFrameworkFacade, mNetworkScoreManager, mContext.getPackageManager(), mWifiConfigManager, mConnectivityLocalLog, mWifiNetworkScoreCache, mWifiPermissionsUtil); - mCarrierNetworkNominator = new CarrierNetworkNominator(mWifiConfigManager, - mCarrierNetworkConfig, mConnectivityLocalLog, this); mPasspointManager = new PasspointManager(mContext, this, wifiHandler, mWifiNative, mWifiKeyStore, mClock, new PasspointObjectFactory(), mWifiConfigManager, mWifiConfigStore, mWifiMetrics, mTelephonyUtil); @@ -358,7 +354,6 @@ public class WifiInjector { mWifiNetworkSelector.registerNetworkNominator(mSavedNetworkNominator); mWifiNetworkSelector.registerNetworkNominator(mNetworkSuggestionNominator); mWifiNetworkSelector.registerNetworkNominator(mPasspointNetworkNominator); - mWifiNetworkSelector.registerNetworkNominator(mCarrierNetworkNominator); mWifiNetworkSelector.registerNetworkNominator(mScoredNetworkNominator); mClientModeImpl.start(); @@ -388,10 +383,10 @@ public class WifiInjector { mHalDeviceManager.enableVerboseLogging(verbose); mScanRequestProxy.enableVerboseLogging(verbose); mWakeupController.enableVerboseLogging(verbose); - mCarrierNetworkConfig.enableVerboseLogging(verbose); mWifiNetworkSuggestionsManager.enableVerboseLogging(verbose); LogcatLog.enableVerboseLogging(verbose); mDppManager.enableVerboseLogging(verbose); + mTelephonyUtil.enableVerboseLogging(verbose); } public UserManager getUserManager() { @@ -502,10 +497,6 @@ public class WifiInjector { return mPasspointManager; } - public CarrierNetworkConfig getCarrierNetworkConfig() { - return mCarrierNetworkConfig; - } - public WakeupController getWakeupController() { return mWakeupController; } @@ -615,7 +606,7 @@ public class WifiInjector { mWifiConfigManager, clientModeImpl.getWifiInfo(), mWifiNetworkSelector, mWifiConnectivityHelper, mWifiLastResortWatchdog, mOpenNetworkNotifier, - mCarrierNetworkConfig, mWifiMetrics, new Handler(mWifiHandlerThread.getLooper()), + mWifiMetrics, new Handler(mWifiHandlerThread.getLooper()), mClock, mConnectivityLocalLog); } diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index 5005c1c6c..6ff7c0b42 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -42,7 +42,6 @@ import com.android.server.wifi.util.InformationElementUtil; import com.android.server.wifi.util.NativeUtil; import com.android.server.wifi.util.NetdWrapper; import com.android.server.wifi.util.NetdWrapper.NetdEventObserver; -import com.android.server.wifi.util.ScanResultUtil; import com.android.server.wifi.wificond.NativeScanResult; import com.android.server.wifi.wificond.RadioChainInfo; @@ -87,7 +86,6 @@ public class WifiNative { private final WifiMonitor mWifiMonitor; private final PropertyService mPropertyService; private final WifiMetrics mWifiMetrics; - private final CarrierNetworkConfig mCarrierNetworkConfig; private final Handler mHandler; private final Random mRandom; private final WifiInjector mWifiInjector; @@ -98,7 +96,7 @@ public class WifiNative { SupplicantStaIfaceHal staIfaceHal, HostapdHal hostapdHal, WificondControl condControl, WifiMonitor wifiMonitor, PropertyService propertyService, WifiMetrics wifiMetrics, - CarrierNetworkConfig carrierNetworkConfig, Handler handler, Random random, + Handler handler, Random random, WifiInjector wifiInjector) { mWifiVendorHal = vendorHal; mSupplicantStaIfaceHal = staIfaceHal; @@ -107,7 +105,6 @@ public class WifiNative { mWifiMonitor = wifiMonitor; mPropertyService = propertyService; mWifiMetrics = wifiMetrics; - mCarrierNetworkConfig = carrierNetworkConfig; mHandler = handler; mRandom = random; mWifiInjector = wifiInjector; @@ -1473,16 +1470,6 @@ public class WifiNative { ScanResult scanResult = scanDetail.getScanResult(); scanResult.setWifiStandard(networkDetail.getWifiMode()); - // Update carrier network info if this AP's SSID is associated with a carrier Wi-Fi - // network and it uses EAP. - if (ScanResultUtil.isScanResultForEapNetwork(scanDetail.getScanResult()) - && mCarrierNetworkConfig.isCarrierNetwork(wifiSsid.toString())) { - scanResult.isCarrierAp = true; - scanResult.carrierApEapType = - mCarrierNetworkConfig.getNetworkEapType(wifiSsid.toString()); - scanResult.carrierName = - mCarrierNetworkConfig.getCarrierName(wifiSsid.toString()); - } // Fill up the radio chain info. if (result.radioChainInfos != null) { scanResult.radioChainInfos = diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java index 70c30dd58..c4b6c9122 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java +++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java @@ -1034,27 +1034,28 @@ public class WifiNetworkSuggestionsManager { if (extNetworkSuggestions == null) { return null; } - Set<ExtendedWifiNetworkSuggestion> approvedExtNetworkSuggestions = - extNetworkSuggestions - .stream() - .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; - } + Set<ExtendedWifiNetworkSuggestion> approvedExtNetworkSuggestions = extNetworkSuggestions + .stream() + .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) + || (mTelephonyUtil.requiresImsiEncryption(subId) + && !mTelephonyUtil.isImsiEncryptionInfoAvailable(subId))) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "No SIM is matched or IMSI encryption " + + "info is required, ignore the config."); } - return true; - }) - .collect(Collectors.toSet()); + 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, // we end up picking the first one. The others will be reconsidered in the next iteration. diff --git a/service/java/com/android/server/wifi/util/TelephonyUtil.java b/service/java/com/android/server/wifi/util/TelephonyUtil.java index 9e9c6c9c8..3f4f22466 100644 --- a/service/java/com/android/server/wifi/util/TelephonyUtil.java +++ b/service/java/com/android/server/wifi/util/TelephonyUtil.java @@ -17,10 +17,18 @@ package com.android.server.wifi.util; import android.annotation.NonNull; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.database.ContentObserver; +import android.net.Uri; 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.os.Handler; +import android.telephony.CarrierConfigManager; import android.telephony.ImsiEncryptionInfo; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -29,11 +37,15 @@ import android.text.TextUtils; import android.util.Base64; import android.util.Log; import android.util.Pair; +import android.util.SparseBooleanArray; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.wifi.FrameworkFacade; import com.android.server.wifi.IMSIParameter; import com.android.server.wifi.WifiNative; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; @@ -82,9 +94,15 @@ public class TelephonyUtil { private static final int START_KC_POS = START_SRES_POS + SRES_LEN; private static final int KC_LEN = 8; + private static final Uri CONTENT_URI = Uri.parse("content://carrier_information/carrier"); + private final TelephonyManager mTelephonyManager; private final SubscriptionManager mSubscriptionManager; + private boolean mVerboseLogEnabled = false; + private SparseBooleanArray mImsiEncryptionRequired = new SparseBooleanArray(); + private SparseBooleanArray mImsiEncryptionInfoAvailable = new SparseBooleanArray(); + /** * Gets the instance of TelephonyUtil. * @param telephonyManager Instance of {@link TelephonyManager} @@ -92,9 +110,101 @@ public class TelephonyUtil { * @return The instance of TelephonyUtil */ public TelephonyUtil(@NonNull TelephonyManager telephonyManager, - @NonNull SubscriptionManager subscriptionManager) { + @NonNull SubscriptionManager subscriptionManager, + @NonNull FrameworkFacade frameworkFacade, + @NonNull Context context, + @NonNull Handler handler) { mTelephonyManager = telephonyManager; mSubscriptionManager = subscriptionManager; + + updateImsiEncryptionInfo(context); + + // Monitor for carrier config changes. + IntentFilter filter = new IntentFilter(); + filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); + context.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED + .equals(intent.getAction())) { + updateImsiEncryptionInfo(context); + } + } + }, filter); + + frameworkFacade.registerContentObserver(context, CONTENT_URI, false, + new ContentObserver(handler) { + @Override + public void onChange(boolean selfChange) { + updateImsiEncryptionInfo(context); + } + }); + } + + /** + * Enable/disable verbose logging. + */ + public void enableVerboseLogging(int verbose) { + mVerboseLogEnabled = verbose > 0; + } + + /** + * Updates the IMSI encryption information. + */ + private void updateImsiEncryptionInfo(Context context) { + CarrierConfigManager carrierConfigManager = + (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); + if (carrierConfigManager == null) { + return; + } + + mImsiEncryptionRequired.clear(); + mImsiEncryptionInfoAvailable.clear(); + List<SubscriptionInfo> activeSubInfos = + mSubscriptionManager.getActiveSubscriptionInfoList(); + if (activeSubInfos == null) { + return; + } + for (SubscriptionInfo subInfo : activeSubInfos) { + int subId = subInfo.getSubscriptionId(); + if ((carrierConfigManager.getConfigForSubId(subId) + .getInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT) + & TelephonyManager.KEY_TYPE_WLAN) != 0) { + vlogd("IMSI encryption is required for " + subId); + mImsiEncryptionRequired.put(subId, true); + } + + try { + if (mImsiEncryptionRequired.get(subId) + && mTelephonyManager.createForSubscriptionId(subId) + .getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_WLAN) != null) { + vlogd("IMSI encryption info is available for " + subId); + mImsiEncryptionInfoAvailable.put(subId, true); + } + } catch (IllegalArgumentException e) { + vlogd("IMSI encryption info is not available."); + } + } + } + + /** + * Check if the IMSI encryption is required for the SIM card. + * + * @param subId The subscription ID of SIM card. + * @return true if the IMSI encryption is required, otherwise false. + */ + public boolean requiresImsiEncryption(int subId) { + return mImsiEncryptionRequired.get(subId); + } + + /** + * Check if the IMSI encryption is downloaded(available) for the SIM card. + * + * @param subId The subscription ID of SIM card. + * @return true if the IMSI encryption is available, otherwise false. + */ + public boolean isImsiEncryptionInfoAvailable(int subId) { + return mImsiEncryptionInfoAvailable.get(subId); } /** @@ -127,7 +237,7 @@ public class TelephonyUtil { } } } - Log.d(TAG, "matching subId is " + matchSubId); + vlogd("matching subId is " + matchSubId); return matchSubId; } @@ -143,10 +253,10 @@ public class TelephonyUtil { } int dataSubId = SubscriptionManager.getDefaultDataSubscriptionId(); if (isSimPresent(dataSubId)) { - Log.d(TAG, "carrierId is not assigned, using the default data sub."); + vlogd("carrierId is not assigned, using the default data sub."); return dataSubId; } - Log.d(TAG, "data sim is not present."); + vlogd("data sim is not present."); return SubscriptionManager.INVALID_SUBSCRIPTION_ID; } @@ -375,7 +485,8 @@ public class TelephonyUtil { * @return the outer EAP method associated with this SIM configuration. */ private static int getSimMethodForConfig(WifiConfiguration config) { - if (config == null || config.enterpriseConfig == null) { + if (config == null || config.enterpriseConfig == null + || !config.enterpriseConfig.requireSimCredential()) { return WifiEnterpriseConfig.Eap.NONE; } int eapMethod = config.enterpriseConfig.getEapMethod(); @@ -394,7 +505,7 @@ public class TelephonyUtil { } } - return isSimEapMethod(eapMethod) ? eapMethod : WifiEnterpriseConfig.Eap.NONE; + return eapMethod; } /** @@ -405,18 +516,6 @@ public class TelephonyUtil { return identity.startsWith(TelephonyUtil.ANONYMOUS_IDENTITY + "@"); } - /** - * Checks if the EAP outer method is SIM related. - * - * @param eapMethod WifiEnterpriseConfig Eap method. - * @return true if this EAP outer method is SIM-related, false otherwise. - */ - public static boolean isSimEapMethod(int eapMethod) { - return eapMethod == WifiEnterpriseConfig.Eap.SIM - || eapMethod == WifiEnterpriseConfig.Eap.AKA - || eapMethod == WifiEnterpriseConfig.Eap.AKA_PRIME; - } - // TODO replace some of this code with Byte.parseByte private static int parseHex(char ch) { if ('0' <= ch && ch <= '9') { @@ -869,7 +968,7 @@ public class TelephonyUtil { // 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"); + vlogd("IMSI is not available or not full"); return false; } List<SubscriptionInfo> infos = mSubscriptionManager.getActiveSubscriptionInfoList(); @@ -899,10 +998,13 @@ public class TelephonyUtil { public @Nullable String getMatchingImsi(int carrierId) { int subId = getMatchingSubId(carrierId); if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + if (requiresImsiEncryption(subId) && !isImsiEncryptionInfoAvailable(subId)) { + vlogd("required IMSI encryption information is not available."); + return null; + } return mTelephonyManager.createForSubscriptionId(subId).getSubscriberId(); } - - Log.d(TAG, "no active SIM card to match the carrier ID."); + vlogd("no active SIM card to match the carrier ID."); return null; } @@ -935,8 +1037,12 @@ public class TelephonyUtil { // 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()); + int subId = subInfo.getSubscriptionId(); + if (requiresImsiEncryption(subId) && !isImsiEncryptionInfoAvailable(subId)) { + vlogd("required IMSI encryption information is not available."); + continue; + } + TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(subId); String operatorNumeric = specifiedTm.getSimOperator(); if (operatorNumeric != null && imsiParameter.matchesMccMnc(operatorNumeric)) { String curImsi = specifiedTm.getSubscriberId(); @@ -944,29 +1050,44 @@ public class TelephonyUtil { continue; } matchedPair = new Pair<>(curImsi, subInfo.getCarrierId()); - if (subInfo.getSubscriptionId() == dataSubId) { + if (subId == dataSubId) { matchedDataPair = matchedPair; - if (getCarrierType(subInfo.getSubscriptionId()) == CARRIER_MNO_TYPE) { - Log.d(TAG, "MNO data is matched via IMSI."); + if (getCarrierType(subId) == CARRIER_MNO_TYPE) { + vlogd("MNO data is matched via IMSI."); return matchedDataPair; } } - if (getCarrierType(subInfo.getSubscriptionId()) == CARRIER_MNO_TYPE) { + if (getCarrierType(subId) == CARRIER_MNO_TYPE) { matchedMnoPair = matchedPair; } } } if (matchedMnoPair != null) { - Log.d(TAG, "MNO sub is matched via IMSI."); + vlogd("MNO sub is matched via IMSI."); return matchedMnoPair; } if (matchedDataPair != null) { - Log.d(TAG, "MVNO data sub is matched via IMSI."); + vlogd("MVNO data sub is matched via IMSI."); return matchedDataPair; } return matchedPair; } + + private void vlogd(String msg) { + if (!mVerboseLogEnabled) { + return; + } + + Log.d(TAG, msg); + } + + /** Dump state. */ + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.println(TAG + ": "); + pw.println("mImsiEncryptionRequired=" + mImsiEncryptionRequired); + pw.println("mImsiEncryptionInfoAvailable=" + mImsiEncryptionInfoAvailable); + } } |