summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/SavedNetworkNominator.java83
-rw-r--r--service/java/com/android/server/wifi/WifiCarrierInfoManager.java21
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java3
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SavedNetworkNominatorTest.java58
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java26
5 files changed, 162 insertions, 29 deletions
diff --git a/service/java/com/android/server/wifi/SavedNetworkNominator.java b/service/java/com/android/server/wifi/SavedNetworkNominator.java
index cbc2c323e..2d91881a0 100644
--- a/service/java/com/android/server/wifi/SavedNetworkNominator.java
+++ b/service/java/com/android/server/wifi/SavedNetworkNominator.java
@@ -19,10 +19,12 @@ package com.android.server.wifi;
import android.annotation.NonNull;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
+import android.telephony.TelephonyManager;
import android.util.LocalLog;
import android.util.Pair;
import com.android.server.wifi.hotspot2.PasspointNetworkNominateHelper;
+import com.android.server.wifi.util.WifiPermissionsUtil;
import java.util.List;
@@ -36,14 +38,17 @@ public class SavedNetworkNominator implements WifiNetworkSelector.NetworkNominat
private final LocalLog mLocalLog;
private final WifiCarrierInfoManager mWifiCarrierInfoManager;
private final PasspointNetworkNominateHelper mPasspointNetworkNominateHelper;
+ private final WifiPermissionsUtil mWifiPermissionsUtil;
SavedNetworkNominator(WifiConfigManager configManager,
- PasspointNetworkNominateHelper nominateHelper,
- LocalLog localLog, WifiCarrierInfoManager wifiCarrierInfoManager) {
+ PasspointNetworkNominateHelper nominateHelper, LocalLog localLog,
+ WifiCarrierInfoManager wifiCarrierInfoManager,
+ WifiPermissionsUtil wifiPermissionsUtil) {
mWifiConfigManager = configManager;
mPasspointNetworkNominateHelper = nominateHelper;
mLocalLog = localLog;
mWifiCarrierInfoManager = wifiCarrierInfoManager;
+ mWifiPermissionsUtil = wifiPermissionsUtil;
}
private void localLog(String log) {
@@ -127,7 +132,8 @@ public class SavedNetworkNominator implements WifiNetworkSelector.NetworkNominat
if (!status.isNetworkEnabled()) {
continue;
- } else if (network.BSSID != null && !network.BSSID.equals("any")
+ }
+ if (network.BSSID != null && !network.BSSID.equals("any")
&& !network.BSSID.equals(scanResult.BSSID)) {
// App has specified the only BSSID to connect for this
// configuration. So only the matching ScanResult can be a candidate.
@@ -135,20 +141,9 @@ public class SavedNetworkNominator implements WifiNetworkSelector.NetworkNominat
+ " has specified BSSID " + network.BSSID + ". Skip "
+ scanResult.BSSID);
continue;
- } else if (network.enterpriseConfig != null
- && network.enterpriseConfig.isAuthenticationSimBased()) {
- int subId = mWifiCarrierInfoManager.getBestMatchSubscriptionId(network);
- if (!mWifiCarrierInfoManager.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;
- }
- // Ignore metered network with non-data Sim, ignore.
- if (WifiConfiguration.isMetered(network, null)
- && mWifiCarrierInfoManager.isCarrierNetworkFromNonDefaultDataSim(network)) {
- continue;
- }
+ }
+ if (isNetworkSimBasedCredential(network) && !isSimBasedNetworkAbleToAutoJoin(network)) {
+ continue;
}
// If the network is marked to use external scores, or is an open network with
@@ -170,12 +165,60 @@ public class SavedNetworkNominator implements WifiNetworkSelector.NetworkNominat
mPasspointNetworkNominateHelper.getPasspointNetworkCandidates(scanDetails, false);
for (Pair<ScanDetail, WifiConfiguration> candidate : candidates) {
WifiConfiguration config = candidate.second;
- // Ignore metered network with non-data Sim, ignore.
- if (WifiConfiguration.isMetered(config, null)
- && mWifiCarrierInfoManager.isCarrierNetworkFromNonDefaultDataSim(config)) {
+ if (isNetworkSimBasedCredential(config) && !isSimBasedNetworkAbleToAutoJoin(config)) {
continue;
}
onConnectableListener.onConnectable(candidate.first, config);
}
}
+
+ private boolean isSimBasedNetworkAbleToAutoJoin(WifiConfiguration network) {
+ int carrierId = network.carrierId == TelephonyManager.UNKNOWN_CARRIER_ID
+ ? mWifiCarrierInfoManager.getDefaultDataSimCarrierId() : network.carrierId;
+ int subId = mWifiCarrierInfoManager.getMatchingSubId(carrierId);
+ // Ignore security type is EAP SIM/AKA/AKA' when SIM is not present.
+ if (!mWifiCarrierInfoManager.isSimPresent(subId)) {
+ localLog("No SIM card is good for Network "
+ + WifiNetworkSelector.toNetworkString(network));
+ return false;
+ }
+ // Ignore IMSI info not available or protection exemption pending network.
+ if (mWifiCarrierInfoManager.requiresImsiEncryption(subId)) {
+ if (!mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(subId)) {
+ localLog("Imsi protection required but not available for Network "
+ + WifiNetworkSelector.toNetworkString(network));
+ return false;
+ }
+ } else if (isImsiProtectionApprovalNeeded(network.creatorUid, carrierId)) {
+ localLog("Imsi protection exemption needed for Network "
+ + WifiNetworkSelector.toNetworkString(network));
+ return false;
+ }
+ // Ignore metered network with non-data Sim.
+ if (WifiConfiguration.isMetered(network, null)
+ && mWifiCarrierInfoManager.isCarrierNetworkFromNonDefaultDataSim(network)) {
+ localLog("No default SIM is used for metered Network: "
+ + WifiNetworkSelector.toNetworkString(network));
+ return false;
+ }
+ return true;
+ }
+
+ private boolean isNetworkSimBasedCredential(WifiConfiguration network) {
+ return network != null && network.enterpriseConfig != null
+ && network.enterpriseConfig.isAuthenticationSimBased();
+ }
+
+ private boolean isImsiProtectionApprovalNeeded(int creatorUid, int carrierId) {
+ // User saved network got exemption.
+ if (mWifiPermissionsUtil.checkNetworkSettingsPermission(creatorUid)
+ || mWifiPermissionsUtil.checkNetworkSetupWizardPermission(creatorUid)) {
+ return false;
+ }
+ if (mWifiCarrierInfoManager.hasUserApprovedImsiPrivacyExemptionForCarrier(carrierId)) {
+ return false;
+ }
+ mWifiCarrierInfoManager.sendImsiProtectionExemptionNotificationIfRequired(carrierId);
+ return true;
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
index 63786f920..a0dcfe9f5 100644
--- a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
+++ b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
@@ -146,8 +146,9 @@ public class WifiCarrierInfoManager {
mOnUserApproveCarrierListeners =
new ArrayList<>();
- private boolean mUserApprovalUiActive;
- private boolean mHasNewDataToSerialize;
+ private boolean mUserApprovalUiActive = false;
+ private boolean mHasNewDataToSerialize = false;
+ private boolean mUserDataLoaded = false;
/**
* Interface for other modules to listen to the user approve IMSI protection exemption.
@@ -175,11 +176,13 @@ public class WifiCarrierInfoManager {
@Override
public void fromDeserialized(Map<Integer, Boolean> imsiProtectionExemptionMap) {
+ mUserDataLoaded = true;
mImsiPrivacyProtectionExemptionMap.putAll(imsiProtectionExemptionMap);
}
@Override
public void reset() {
+ mUserDataLoaded = false;
mImsiPrivacyProtectionExemptionMap.clear();
}
@@ -268,7 +271,6 @@ public class WifiCarrierInfoManager {
mIntentFilter.addAction(NOTIFICATION_USER_DISMISSED_INTENT_ACTION);
mIntentFilter.addAction(NOTIFICATION_USER_ALLOWED_CARRIER_INTENT_ACTION);
mIntentFilter.addAction(NOTIFICATION_USER_DISALLOWED_CARRIER_INTENT_ACTION);
- mUserApprovalUiActive = false;
mContext.registerReceiver(mBroadcastReceiver, mIntentFilter, null, handler);
configStore.registerStoreData(wifiInjector.makeImsiProtectionExemptionStoreData(
@@ -1341,6 +1343,15 @@ public class WifiCarrierInfoManager {
}
/**
+ * Get the carrier Id of the default data sim.
+ */
+ public int getDefaultDataSimCarrierId() {
+ int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+ TelephonyManager specifiedTm = mTelephonyManager.createForSubscriptionId(subId);
+ return specifiedTm.getSimCarrierId();
+ }
+
+ /**
* Add a listener to monitor user approval IMSI protection exemption.
*/
public void addImsiExemptionUserApprovalListener(
@@ -1463,6 +1474,10 @@ public class WifiCarrierInfoManager {
*/
public void sendImsiProtectionExemptionNotificationIfRequired(int carrierId) {
int subId = getMatchingSubId(carrierId);
+ // If user data isn't loaded, don't send notification.
+ if (!mUserDataLoaded) {
+ return;
+ }
if (requiresImsiEncryption(subId)) {
return;
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 78bacc56d..23bb75ad0 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -309,7 +309,8 @@ public class WifiInjector {
new PasspointNetworkNominateHelper(mPasspointManager, mWifiConfigManager,
mConnectivityLocalLog);
mSavedNetworkNominator = new SavedNetworkNominator(
- mWifiConfigManager, nominateHelper, mConnectivityLocalLog, mWifiCarrierInfoManager);
+ mWifiConfigManager, nominateHelper, mConnectivityLocalLog, mWifiCarrierInfoManager,
+ mWifiPermissionsUtil);
mNetworkSuggestionNominator = new NetworkSuggestionNominator(mWifiNetworkSuggestionsManager,
mWifiConfigManager, nominateHelper, mConnectivityLocalLog, mWifiCarrierInfoManager);
mScoredNetworkNominator = new ScoredNetworkNominator(mContext, wifiHandler,
diff --git a/tests/wifitests/src/com/android/server/wifi/SavedNetworkNominatorTest.java b/tests/wifitests/src/com/android/server/wifi/SavedNetworkNominatorTest.java
index cdc6762ba..839b2e5fe 100644
--- a/tests/wifitests/src/com/android/server/wifi/SavedNetworkNominatorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SavedNetworkNominatorTest.java
@@ -29,6 +29,7 @@ import android.util.Pair;
import com.android.server.wifi.WifiNetworkSelector.NetworkNominator.OnConnectableListener;
import com.android.server.wifi.WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs;
import com.android.server.wifi.hotspot2.PasspointNetworkNominateHelper;
+import com.android.server.wifi.util.WifiPermissionsUtil;
import org.junit.After;
import org.junit.Before;
@@ -52,9 +53,14 @@ public class SavedNetworkNominatorTest extends WifiBaseTest {
MockitoAnnotations.initMocks(this);
mLocalLog = new LocalLog(512);
mSavedNetworkNominator = new SavedNetworkNominator(mWifiConfigManager,
- mPasspointNetworkNominateHelper, mLocalLog, mWifiCarrierInfoManager);
+ mPasspointNetworkNominateHelper, mLocalLog, mWifiCarrierInfoManager,
+ mWifiPermissionsUtil);
when(mWifiCarrierInfoManager.isSimPresent(anyInt())).thenReturn(true);
- when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any())).thenReturn(1);
+ when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any())).thenReturn(VALID_SUBID);
+ when(mWifiCarrierInfoManager.requiresImsiEncryption(VALID_SUBID)).thenReturn(true);
+ when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(anyInt())).thenReturn(true);
+ when(mWifiCarrierInfoManager.getMatchingSubId(TEST_CARRIER_ID)).thenReturn(VALID_SUBID);
+
}
/** Cleans up test. */
@@ -65,9 +71,11 @@ public class SavedNetworkNominatorTest extends WifiBaseTest {
private ArgumentCaptor<WifiConfiguration> mWifiConfigurationArgumentCaptor =
ArgumentCaptor.forClass(WifiConfiguration.class);
+ private static final int VALID_SUBID = 10;
private static final int INVALID_SUBID = 1;
private static final int TEST_CARRIER_ID = 100;
private static final int RSSI_LEVEL = -50;
+ private static final int TEST_UID = 1001;
private SavedNetworkNominator mSavedNetworkNominator;
@Mock private WifiConfigManager mWifiConfigManager;
@@ -75,6 +83,7 @@ public class SavedNetworkNominatorTest extends WifiBaseTest {
@Mock private OnConnectableListener mOnConnectableListener;
@Mock private WifiCarrierInfoManager mWifiCarrierInfoManager;
@Mock private PasspointNetworkNominateHelper mPasspointNetworkNominateHelper;
+ @Mock private WifiPermissionsUtil mWifiPermissionsUtil;
private LocalLog mLocalLog;
/**
@@ -121,8 +130,7 @@ public class SavedNetworkNominatorTest extends WifiBaseTest {
WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
savedConfigs[0].carrierId = TEST_CARRIER_ID;
// SIM is absent
- when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class)))
- .thenReturn(INVALID_SUBID);
+ when(mWifiCarrierInfoManager.getMatchingSubId(TEST_CARRIER_ID)).thenReturn(INVALID_SUBID);
when(mWifiCarrierInfoManager.isSimPresent(eq(INVALID_SUBID))).thenReturn(false);
mSavedNetworkNominator.nominateNetworks(scanDetails,
@@ -238,7 +246,7 @@ public class SavedNetworkNominatorTest extends WifiBaseTest {
* Verify if a network is metered and with non-data sim, will not nominate as a candidate.
*/
@Test
- public void ignoreNetworksIfMeteredAndFromNonDataSim() {
+ public void testIgnoreNetworksIfMeteredAndFromNonDataSim() {
String[] ssids = {"\"test1\""};
String[] bssids = {"6c:f3:7f:ae:8c:f3"};
int[] freqs = {2470};
@@ -249,6 +257,7 @@ public class SavedNetworkNominatorTest extends WifiBaseTest {
freqs, levels, mWifiConfigManager, mClock);
List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
+ savedConfigs[0].carrierId = TEST_CARRIER_ID;
when(mWifiCarrierInfoManager.isCarrierNetworkFromNonDefaultDataSim(savedConfigs[0]))
.thenReturn(false);
mSavedNetworkNominator.nominateNetworks(scanDetails,
@@ -259,4 +268,43 @@ public class SavedNetworkNominatorTest extends WifiBaseTest {
.thenReturn(true);
verify(mOnConnectableListener, never()).onConnectable(any(), any());
}
+
+ /**
+ * Verify a saved network is from app not user, if IMSI privacy protection is not required, will
+ * send notification for user to approve exemption, and not consider as a candidate.
+ */
+ @Test
+ public void testIgnoreNetworksFromAppIfNoImsiProtection() {
+ String[] ssids = {"\"test1\""};
+ String[] bssids = {"6c:f3:7f:ae:8c:f3"};
+ int[] freqs = {2470};
+ int[] levels = {RSSI_LEVEL};
+ when(mWifiCarrierInfoManager.isCarrierNetworkFromNonDefaultDataSim(any()))
+ .thenReturn(false);
+ ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
+ WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigForEapSimNetwork(ssids, bssids,
+ freqs, levels, mWifiConfigManager, mClock);
+ List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
+ WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
+ savedConfigs[0].carrierId = TEST_CARRIER_ID;
+ // Doesn't require Imsi protection and user didn't approved
+ when(mWifiCarrierInfoManager.requiresImsiEncryption(VALID_SUBID)).thenReturn(false);
+ when(mWifiCarrierInfoManager.hasUserApprovedImsiPrivacyExemptionForCarrier(TEST_CARRIER_ID))
+ .thenReturn(false);
+ mSavedNetworkNominator.nominateNetworks(scanDetails,
+ null, null, true, false, mOnConnectableListener);
+ verify(mOnConnectableListener, never()).onConnectable(any(), any());
+ verify(mWifiCarrierInfoManager)
+ .sendImsiProtectionExemptionNotificationIfRequired(TEST_CARRIER_ID);
+ // Simulate user approved
+ when(mWifiCarrierInfoManager.hasUserApprovedImsiPrivacyExemptionForCarrier(TEST_CARRIER_ID))
+ .thenReturn(true);
+ mSavedNetworkNominator.nominateNetworks(scanDetails,
+ null, null, true, false, mOnConnectableListener);
+ verify(mOnConnectableListener).onConnectable(any(), any());
+ // If from settings app, will bypass the IMSI check.
+ when(mWifiCarrierInfoManager.hasUserApprovedImsiPrivacyExemptionForCarrier(TEST_CARRIER_ID))
+ .thenReturn(false);
+ when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
index 1053d733f..28bffa149 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
@@ -75,6 +75,7 @@ import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import javax.crypto.BadPaddingException;
@@ -243,6 +244,7 @@ public class WifiCarrierInfoManagerTest extends WifiBaseTest {
eq(R.string.wifi_suggestion_action_disallow_imsi_privacy_exemption_confirmation)))
.thenReturn("blah");
mWifiCarrierInfoManager.addImsiExemptionUserApprovalListener(mListener);
+ mImsiDataSource.fromDeserialized(new HashMap<>());
}
@After
@@ -1698,6 +1700,30 @@ public class WifiCarrierInfoManagerTest extends WifiBaseTest {
verify(mListener, never()).onUserAllowed(DATA_CARRIER_ID);
}
+ @Test
+ public void testUserDataStoreIsNotLoadedNotificationWillNotBeSent() {
+ // reset data source to unloaded state.
+ mImsiDataSource.reset();
+ // Setup carrier without IMSI privacy protection
+ when(mCarrierConfigManager.getConfigForSubId(DATA_SUBID))
+ .thenReturn(generateTestCarrierConfig(false));
+ ArgumentCaptor<BroadcastReceiver> receiver =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mContext).registerReceiver(receiver.capture(), any(IntentFilter.class));
+
+ receiver.getValue().onReceive(mContext,
+ new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+ assertFalse(mWifiCarrierInfoManager.requiresImsiEncryption(DATA_SUBID));
+
+ mWifiCarrierInfoManager.sendImsiProtectionExemptionNotificationIfRequired(DATA_CARRIER_ID);
+ verifyNoMoreInteractions(mNotificationManger);
+
+ // Loaded user data store, notification should be sent
+ mImsiDataSource.fromDeserialized(new HashMap<>());
+ mWifiCarrierInfoManager.sendImsiProtectionExemptionNotificationIfRequired(DATA_CARRIER_ID);
+ validateImsiProtectionNotification(CARRIER_NAME);
+ }
+
private void validateImsiProtectionNotification(String carrierName) {
verify(mNotificationManger, atLeastOnce()).notify(
eq(SystemMessage.NOTE_NETWORK_SUGGESTION_AVAILABLE),