summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorSteven Liu <steveliu@google.com>2019-11-08 14:21:36 -0800
committerSteven Liu <steveliu@google.com>2019-12-10 16:55:51 -0800
commitcb852a0301332aded8f5d83cebf63a249c947611 (patch)
treecc82013f5c0d6fae7f4fe8fba9fb7b1f9307172e /service
parente5a1fe842ebc903c5135bbdf55c2bc8d407a13be (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')
-rw-r--r--service/java/com/android/server/wifi/CarrierNetworkConfig.java296
-rw-r--r--service/java/com/android/server/wifi/CarrierNetworkNominator.java169
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java4
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java3
-rw-r--r--service/java/com/android/server/wifi/WifiConfigurationUtil.java3
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java5
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java19
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java15
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java41
-rw-r--r--service/java/com/android/server/wifi/util/TelephonyUtil.java179
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);
+ }
}