summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate(Qiang) Jiang <qiangjiang@google.com>2019-12-06 13:25:11 -0800
committerNate(Qiang) Jiang <qiangjiang@google.com>2020-01-09 12:43:58 -0800
commit916257387266b8c5002ebf68e699c9e0d794bfe9 (patch)
tree1d9d10a9d1ba9f8aa13e9983ea3e3882991271f6
parent7a96efbad8d681f7c0d9411e5bd7946fc3fd0072 (diff)
[NetworkSuggestion]carrier privileged exemption
Give user approval exemption for carrier privileged apps. Only allow apps have carrier privileged or hold NETWORK_CARRIER_PROVISIONING permission to suggest SIM-based network. Bug: 142063113 Bug: 142001564 Test: atest com.android.server.wifi Change-Id: Ic8398996ee81ae68d84d2292cb2b51b53ded7af6
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java1
-rw-r--r--service/java/com/android/server/wifi/NetworkSuggestionNominator.java2
-rw-r--r--service/java/com/android/server/wifi/NetworkSuggestionStoreData.java9
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java203
-rw-r--r--service/java/com/android/server/wifi/util/TelephonyUtil.java33
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java19
-rw-r--r--tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java2
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java184
-rw-r--r--tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java50
9 files changed, 434 insertions, 69 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 7da4b6fd1..3d6d1b09b 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -3966,6 +3966,7 @@ public class ClientModeImpl extends StateMachine {
if (!simPresent) {
mWifiConfigManager.resetSimNetworks();
}
+ mWifiNetworkSuggestionsManager.resetCarrierPrivilegedApps();
break;
case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
// If BT was connected and then turned off, there is no CONNECTION_STATE_CHANGE
diff --git a/service/java/com/android/server/wifi/NetworkSuggestionNominator.java b/service/java/com/android/server/wifi/NetworkSuggestionNominator.java
index 144703f67..40325989e 100644
--- a/service/java/com/android/server/wifi/NetworkSuggestionNominator.java
+++ b/service/java/com/android/server/wifi/NetworkSuggestionNominator.java
@@ -98,7 +98,7 @@ public class NetworkSuggestionNominator implements WifiNetworkSelector.NetworkNo
for (Pair<ScanDetail, WifiConfiguration> candidate : candidates) {
Set<ExtendedWifiNetworkSuggestion> matchingPasspointExtSuggestions =
mWifiNetworkSuggestionsManager
- .getNetworkSuggestionsForFqfn(candidate.second.FQDN);
+ .getNetworkSuggestionsForFqdn(candidate.second.FQDN);
if (matchingPasspointExtSuggestions == null
|| matchingPasspointExtSuggestions.isEmpty()) {
continue;
diff --git a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
index ba91579b9..2a4ae353e 100644
--- a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
@@ -24,6 +24,7 @@ import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.os.Process;
+import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.Pair;
@@ -68,6 +69,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
private static final String XML_TAG_SUGGESTOR_PACKAGE_NAME = "SuggestorPackageName";
private static final String XML_TAG_SUGGESTOR_FEATURE_ID = "SuggestorFeatureId";
private static final String XML_TAG_SUGGESTOR_HAS_USER_APPROVED = "SuggestorHasUserApproved";
+ private static final String XML_TAG_SUGGESTOR_CARRIER_ID = "SuggestorCarrierId";
private static final String XML_TAG_SUGGESTOR_MAX_SIZE = "SuggestorMaxSize";
private static final String XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION =
"PasspointConfiguration";
@@ -166,6 +168,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
boolean hasUserApproved = entry.getValue().hasUserApproved;
int maxSize = entry.getValue().maxSize;
int uid = entry.getValue().uid;
+ int carrierId = entry.getValue().carrierId;
Set<ExtendedWifiNetworkSuggestion> networkSuggestions =
entry.getValue().extNetworkSuggestions;
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION_PER_APP);
@@ -174,6 +177,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_HAS_USER_APPROVED, hasUserApproved);
XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_MAX_SIZE, maxSize);
XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_UID, uid);
+ XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_CARRIER_ID, carrierId);
serializeExtNetworkSuggestions(out, networkSuggestions, encryptionUtil);
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION_PER_APP);
}
@@ -260,6 +264,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
boolean hasUserApproved = false;
int maxSize = -1;
int uid = Process.INVALID_UID;
+ int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
// Loop through and parse out all the elements from the stream within this section.
while (XmlUtils.nextElementWithin(in, outerTagDepth + 1)) {
if (in.getAttributeValue(null, "name") != null) {
@@ -282,6 +287,9 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
case XML_TAG_SUGGESTOR_UID:
uid = (int) value;
break;
+ case XML_TAG_SUGGESTOR_CARRIER_ID:
+ carrierId = (int) value;
+ break;
default:
Log.w(TAG, "Ignoring unknown value name found: " + valueName[0]);
break;
@@ -302,6 +310,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
perAppInfo = new PerAppInfo(uid, packageName, featureId);
perAppInfo.hasUserApproved = hasUserApproved;
perAppInfo.maxSize = maxSize;
+ perAppInfo.carrierId = carrierId;
}
switch (tagName) {
case XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION:
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index 41a67f2d6..082ed0883 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -41,11 +41,13 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
+import android.net.wifi.hotspot2.PasspointConfiguration;
import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -143,6 +145,10 @@ public class WifiNetworkSuggestionsManager {
* Whether we have shown the user a notification for this app.
*/
public boolean hasUserApproved = false;
+ /**
+ * Carrier Id of SIM which give app carrier privileges.
+ */
+ public int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
/** Stores the max size of the {@link #extNetworkSuggestions} list ever for this app */
public int maxSize = 0;
@@ -649,8 +655,11 @@ public class WifiNetworkSuggestionsManager {
return WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
}
if (!validateNetworkSuggestions(networkSuggestions, uid, packageName)) {
+ Log.e(TAG, "bad wifi suggestion from app: " + packageName);
return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED;
}
+
+ int carrierId = mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(packageName);
PerAppInfo perAppInfo = mActiveNetworkSuggestionsPerApp.get(packageName);
if (perAppInfo == null) {
perAppInfo = new PerAppInfo(uid, packageName, featureId);
@@ -658,6 +667,9 @@ public class WifiNetworkSuggestionsManager {
if (mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(uid)) {
Log.i(TAG, "Setting the carrier provisioning app approved");
perAppInfo.hasUserApproved = true;
+ } else if (carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
+ Log.i(TAG, "Setting the carrier privileged app approved");
+ perAppInfo.carrierId = carrierId;
} else {
sendUserApprovalNotification(packageName, uid);
}
@@ -689,8 +701,14 @@ public class WifiNetworkSuggestionsManager {
}
for (ExtendedWifiNetworkSuggestion ewns: extNetworkSuggestions) {
if (ewns.wns.passpointConfiguration == null) {
+ if (carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
+ ewns.wns.wifiConfiguration.carrierId = carrierId;
+ }
addToScanResultMatchInfoMap(ewns);
} else {
+ if (carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
+ ewns.wns.passpointConfiguration.setCarrierId(carrierId);
+ }
// Install Passpoint config, if failure, ignore that suggestion
if (!mWifiInjector.getPasspointManager().addOrUpdateProvider(
ewns.wns.passpointConfiguration, uid,
@@ -711,17 +729,35 @@ public class WifiNetworkSuggestionsManager {
return WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
}
- private boolean validateNetworkSuggestions(
- List<WifiNetworkSuggestion> networkSuggestions, int uid, String packageName) {
- if (mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(uid)) {
+ private boolean validateNetworkSuggestions(List<WifiNetworkSuggestion> networkSuggestions,
+ int uid, String packageName) {
+ if (mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(uid)
+ || mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(packageName)
+ != TelephonyManager.UNKNOWN_CARRIER_ID) {
return true;
}
+ // If an app doesn't have carrier privileges or carrier provisioning permission, suggests
+ // SIM-based network and sets CarrierId are illegal.
for (WifiNetworkSuggestion suggestion : networkSuggestions) {
- WifiConfiguration config = suggestion.wifiConfiguration;
- if (config != null
- && config.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
- Log.e(TAG, "bad wifi suggestion from app: " + packageName);
- return false;
+ if (suggestion.passpointConfiguration == null) {
+ WifiConfiguration config = suggestion.wifiConfiguration;
+ if (config != null
+ && config.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
+ return false;
+ }
+ if (config != null && config.enterpriseConfig != null
+ && config.enterpriseConfig.isAuthenticationSimBased()) {
+ return false;
+ }
+ } else {
+ PasspointConfiguration config = suggestion.passpointConfiguration;
+ if (config.getCarrierId() != TelephonyManager.UNKNOWN_CARRIER_ID) {
+ return false;
+ }
+ if (config.getCredential() != null
+ && config.getCredential().getSimCredential() != null) {
+ return false;
+ }
}
}
@@ -968,7 +1004,7 @@ public class WifiNetworkSuggestionsManager {
* @param uid app UID
* @return true if app is not approved and send notification.
*/
- public boolean sendUserApprovalNotificationIfNotApproved(
+ private boolean sendUserApprovalNotificationIfNotApproved(
@NonNull String packageName, @NonNull int uid) {
if (!mActiveNetworkSuggestionsPerApp.containsKey(packageName)) {
Log.wtf(TAG, "AppInfo is missing for " + packageName);
@@ -978,10 +1014,11 @@ public class WifiNetworkSuggestionsManager {
return false; // already approved.
}
- Log.i(TAG, "Sending user approval notification for " + packageName);
- if (!mUserApprovalNotificationActive) {
- sendUserApprovalNotification(packageName, uid);
+ if (mUserApprovalNotificationActive) {
+ return false; // has active notification.
}
+ Log.i(TAG, "Sending user approval notification for " + packageName);
+ sendUserApprovalNotification(packageName, uid);
return true;
}
@@ -1019,30 +1056,19 @@ public class WifiNetworkSuggestionsManager {
/**
* Returns a set of all network suggestions matching the provided FQDN.
*/
- public @Nullable Set<ExtendedWifiNetworkSuggestion> getNetworkSuggestionsForFqfn(String fqdn) {
+ public @Nullable Set<ExtendedWifiNetworkSuggestion> getNetworkSuggestionsForFqdn(String fqdn) {
Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestions =
getNetworkSuggestionsForFqdnMatch(fqdn);
if (extNetworkSuggestions == null) {
return null;
}
- Set<ExtendedWifiNetworkSuggestion> approvedExtNetworkSuggestions =
- extNetworkSuggestions
- .stream()
- .filter(n -> n.perAppInfo.hasUserApproved)
- .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.
- if (!mUserApprovalNotificationActive
- && approvedExtNetworkSuggestions.size() != extNetworkSuggestions.size()) {
- for (ExtendedWifiNetworkSuggestion extNetworkSuggestion : extNetworkSuggestions) {
- if (sendUserApprovalNotificationIfNotApproved(
- extNetworkSuggestion.perAppInfo.packageName,
- extNetworkSuggestion.perAppInfo.uid)) {
- break;
- }
+ Set<ExtendedWifiNetworkSuggestion> approvedExtNetworkSuggestions = new HashSet<>();
+ for (ExtendedWifiNetworkSuggestion ewns : extNetworkSuggestions) {
+ if (isNetworkSuggestionUserApprovedAndAvailableToConnect(ewns)) {
+ approvedExtNetworkSuggestions.add(ewns);
}
}
+
if (approvedExtNetworkSuggestions.isEmpty()) {
return null;
}
@@ -1075,41 +1101,13 @@ 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.isAuthenticationSimBased()) {
- 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 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.
- if (!mUserApprovalNotificationActive
- && approvedExtNetworkSuggestions.size() != extNetworkSuggestions.size()) {
- for (ExtendedWifiNetworkSuggestion extNetworkSuggestion : extNetworkSuggestions) {
- if (sendUserApprovalNotificationIfNotApproved(
- extNetworkSuggestion.perAppInfo.packageName,
- extNetworkSuggestion.perAppInfo.uid)) {
- break;
- }
+ Set<ExtendedWifiNetworkSuggestion> approvedExtNetworkSuggestions = new HashSet<>();
+ for (ExtendedWifiNetworkSuggestion ewns : extNetworkSuggestions) {
+ if (isNetworkSuggestionUserApprovedAndAvailableToConnect(ewns)) {
+ approvedExtNetworkSuggestions.add(ewns);
}
}
+
if (approvedExtNetworkSuggestions.isEmpty()) {
return null;
}
@@ -1121,6 +1119,57 @@ public class WifiNetworkSuggestionsManager {
return approvedExtNetworkSuggestions;
}
+ private boolean isNetworkSuggestionUserApprovedAndAvailableToConnect(
+ ExtendedWifiNetworkSuggestion ewns) {
+ if (!ewns.perAppInfo.hasUserApproved
+ && ewns.perAppInfo.carrierId == TelephonyManager.UNKNOWN_CARRIER_ID) {
+ sendUserApprovalNotificationIfNotApproved(ewns.perAppInfo.packageName,
+ ewns.perAppInfo.uid);
+ return false;
+ }
+ WifiConfiguration config = ewns.wns.wifiConfiguration;
+ PasspointConfiguration passpointConfiguration = ewns.wns.passpointConfiguration;
+ int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ if (config == null) {
+ Log.e(TAG, "WifiConfiguration is missing for " + ewns);
+ return false;
+ }
+ if (passpointConfiguration != null) {
+ // If passpoint config is not SIM based return true.
+ if (passpointConfiguration.getCredential().getSimCredential() == null) {
+ return true;
+ }
+ subId = mTelephonyUtil.getMatchingSubId(passpointConfiguration.getCarrierId());
+ } else {
+ // If Wifi Config is not SIM based return true.
+ if (config.enterpriseConfig == null
+ || !config.enterpriseConfig.isAuthenticationSimBased()) {
+ return true;
+ }
+ subId = mTelephonyUtil.getBestMatchSubscriptionId(config);
+ }
+
+ if (!mTelephonyUtil.isSimPresent(subId)) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "SIM is not present for subId: " + subId);
+ }
+ return false;
+ }
+ if (mTelephonyUtil.requiresImsiEncryption(subId)
+ && !mTelephonyUtil.isImsiEncryptionInfoAvailable(subId)) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "IMSI encryption is required but info is missing for subId: "
+ + subId);
+ }
+ return false;
+ }
+ if (!mTelephonyUtil.requiresImsiEncryption(subId)) {
+ // TODO(142001564): sendImsiProtectionWarningNotification();
+ return false;
+ }
+ return true;
+ }
+
/**
* Returns a set of all network suggestions matching the provided the WifiConfiguration.
*/
@@ -1405,7 +1454,6 @@ public class WifiNetworkSuggestionsManager {
default:
return WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN;
}
-
}
/**
@@ -1447,6 +1495,33 @@ public class WifiNetworkSuggestionsManager {
}
/**
+ * When SIM state changes, check if carrier privileges changes for app.
+ * If app changes from privileged to not privileged, remove all suggestions and reset state.
+ * If app changes from not privileges to privileged, set target carrier id for all suggestions.
+ */
+ public void resetCarrierPrivilegedApps() {
+ Log.w(TAG, "SIM state is changed!");
+ for (PerAppInfo appInfo : mActiveNetworkSuggestionsPerApp.values()) {
+ int carrierId = mTelephonyUtil
+ .getCarrierIdForPackageWithCarrierPrivileges(appInfo.packageName);
+ if (carrierId == appInfo.carrierId) {
+ continue;
+ }
+ if (carrierId == TelephonyManager.UNKNOWN_CARRIER_ID) {
+ Log.v(TAG, "Carrier privilege revoked for " + appInfo.packageName);
+ removeInternal(Collections.EMPTY_LIST, appInfo.packageName, appInfo);
+ mActiveNetworkSuggestionsPerApp.remove(appInfo.packageName);
+ continue;
+ }
+ appInfo.carrierId = carrierId;
+ for (ExtendedWifiNetworkSuggestion ewns : appInfo.extNetworkSuggestions) {
+ ewns.wns.wifiConfiguration.carrierId = carrierId;
+ }
+ }
+ saveToStore();
+ }
+
+ /**
* Dump of {@link WifiNetworkSuggestionsManager}.
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -1457,6 +1532,8 @@ public class WifiNetworkSuggestionsManager {
pw.println("Package Name: " + networkSuggestionsEntry.getKey());
PerAppInfo appInfo = networkSuggestionsEntry.getValue();
pw.println("Has user approved: " + appInfo.hasUserApproved);
+ pw.println("Has carrier privileges: "
+ + (appInfo.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID));
for (ExtendedWifiNetworkSuggestion extNetworkSuggestion
: appInfo.extNetworkSuggestions) {
pw.println("Network: " + extNetworkSuggestion);
diff --git a/service/java/com/android/server/wifi/util/TelephonyUtil.java b/service/java/com/android/server/wifi/util/TelephonyUtil.java
index 22ce92571..30ccefecf 100644
--- a/service/java/com/android/server/wifi/util/TelephonyUtil.java
+++ b/service/java/com/android/server/wifi/util/TelephonyUtil.java
@@ -217,6 +217,7 @@ public class TelephonyUtil {
/**
* Gets the SubscriptionId of SIM card which is from the carrier specified in config.
+ *
* @param config the instance of {@link WifiConfiguration}
* @return the best match SubscriptionId
*/
@@ -228,7 +229,13 @@ public class TelephonyUtil {
}
}
- private int getMatchingSubId(int carrierId) {
+ /**
+ * Gets the SubscriptionId of SIM card for given carrier Id
+ *
+ * @param carrierId carrier id for target carrier
+ * @return the matched SubscriptionId
+ */
+ public int getMatchingSubId(int carrierId) {
List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
if (subInfoList == null || subInfoList.isEmpty()) {
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -1108,4 +1115,28 @@ public class TelephonyUtil {
pw.println("mImsiEncryptionRequired=" + mImsiEncryptionRequired);
pw.println("mImsiEncryptionInfoAvailable=" + mImsiEncryptionInfoAvailable);
}
+
+ /**
+ * Get the carrier ID {@link TelephonyManager#getSimCarrierId()} of the carrier which give
+ * target package carrier privileges.
+ *
+ * @param packageName target package to check if grant privileges by any carrier.
+ * @return Carrier ID who give privilege to this package. If package isn't granted privilege
+ * by any available carrier, will return UNKNOWN_CARRIER_ID.
+ */
+ public int getCarrierIdForPackageWithCarrierPrivileges(String packageName) {
+ List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
+ if (subInfoList == null || subInfoList.isEmpty()) {
+ return TelephonyManager.UNKNOWN_CARRIER_ID;
+ }
+ for (SubscriptionInfo info : subInfoList) {
+ TelephonyManager specifiedTm =
+ mTelephonyManager.createForSubscriptionId(info.getSubscriptionId());
+ if (specifiedTm.checkCarrierPrivilegesForPackage(packageName)
+ == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+ return info.getCarrierId();
+ }
+ }
+ return TelephonyManager.UNKNOWN_CARRIER_ID;
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index cf893f494..caf1d5d19 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -3734,7 +3734,8 @@ public class ClientModeImplTest extends WifiBaseTest {
}
/**
- * Verify removing sim will also remove an ephemeral Passpoint Provider.
+ * Verify removing sim will also remove an ephemeral Passpoint Provider. And reset carrier
+ * privileged suggestor apps.
*/
@Test
public void testResetSimNetworkWhenRemovingSim() throws Exception {
@@ -3746,6 +3747,22 @@ public class ClientModeImplTest extends WifiBaseTest {
mLooper.dispatchAll();
verify(mWifiConfigManager).resetSimNetworks();
+ verify(mWifiNetworkSuggestionsManager).resetCarrierPrivilegedApps();
+ }
+
+ /**
+ * Verify inserting sim will rest carrier privileged suggestor apps.
+ */
+ @Test
+ public void testResetCarrierPrivilegedAppsWhenInsertingSim() throws Exception {
+ // Switch to connect mode and verify wifi is reported as enabled
+ startSupplicantAndDispatchMessages();
+
+ // Indicate that sim is removed.
+ mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS, true);
+ mLooper.dispatchAll();
+
+ verify(mWifiNetworkSuggestionsManager).resetCarrierPrivilegedApps();
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java b/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java
index 7eaad99ca..0d2f239c6 100644
--- a/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java
@@ -651,7 +651,7 @@ public class NetworkSuggestionNominatorTest extends WifiBaseTest {
when(mPasspointNetworkNominateHelper
.getPasspointNetworkCandidates(Arrays.asList(scanDetails), true))
.thenReturn(passpointCandidates);
- when(mWifiNetworkSuggestionsManager.getNetworkSuggestionsForFqfn(TEST_FQDN))
+ when(mWifiNetworkSuggestionsManager.getNetworkSuggestionsForFqdn(TEST_FQDN))
.thenReturn(matchedExtSuggestions);
List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
mNetworkSuggestionNominator.nominateNetworks(
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
index 528c1dde5..e318524cd 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -51,11 +51,13 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle;
import android.os.test.TestLooper;
+import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
@@ -174,6 +176,8 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
when(mPackageManager.getApplicationInfoAsUser(eq(TEST_PACKAGE_2), eq(0), any()))
.thenReturn(appInfO2);
when(mPackageManager.getApplicationLabel(appInfO2)).thenReturn(TEST_APP_NAME_2);
+ when(mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(any())).thenReturn(
+ TelephonyManager.UNKNOWN_CARRIER_ID);
mWifiNetworkSuggestionsManager =
new WifiNetworkSuggestionsManager(mContext, new Handler(mLooper.getLooper()),
@@ -2494,6 +2498,8 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
HomeSp homeSp = new HomeSp();
homeSp.setFqdn(TEST_FQDN);
passpointConfiguration.setHomeSp(homeSp);
+ Credential credential = new Credential();
+ passpointConfiguration.setCredential(credential);
WifiConfiguration dummyConfiguration = new WifiConfiguration();
dummyConfiguration.FQDN = TEST_FQDN;
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(dummyConfiguration,
@@ -2506,7 +2512,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
TEST_PACKAGE_1, TEST_FEATURE), WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
Set<ExtendedWifiNetworkSuggestion> ewns =
- mWifiNetworkSuggestionsManager.getNetworkSuggestionsForFqfn(TEST_FQDN);
+ mWifiNetworkSuggestionsManager.getNetworkSuggestionsForFqdn(TEST_FQDN);
assertEquals(1, ewns.size());
assertEquals(networkSuggestion, ewns.iterator().next().wns);
}
@@ -2531,7 +2537,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
assertEquals(mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1,
TEST_PACKAGE_1, TEST_FEATURE), WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
Set<ExtendedWifiNetworkSuggestion> ewns =
- mWifiNetworkSuggestionsManager.getNetworkSuggestionsForFqfn(TEST_FQDN);
+ mWifiNetworkSuggestionsManager.getNetworkSuggestionsForFqdn(TEST_FQDN);
assertNull(ewns);
}
@@ -2542,4 +2548,178 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
.collect(Collectors.toSet());
assertEquals(expectedSuggestions, actualSuggestions);
}
+
+ /**
+ * Verify error code returns when add SIM-based network from app has no carrier privileges.
+ */
+ @Test
+ public void testAddSimCredentialNetworkWithoutCarrierPrivileges() {
+ WifiConfiguration config =
+ WifiConfigurationTestUtil.createEapNetwork(WifiEnterpriseConfig.Eap.SIM,
+ WifiEnterpriseConfig.Phase2.NONE);
+ WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
+ config, null, true, false, true);
+ List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
+ networkSuggestionList.add(networkSuggestion);
+ when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1))
+ .thenReturn(false);
+ when(mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE_1))
+ .thenReturn(TelephonyManager.UNKNOWN_CARRIER_ID);
+ int status = mWifiNetworkSuggestionsManager
+ .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED, status);
+ verify(mNotificationManger, never()).notify(anyInt(), any());
+ assertEquals(0, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1).size());
+ }
+
+ /**
+ * Verify success when add SIM-based network from app has carrier privileges.
+ */
+ @Test
+ public void testAddSimCredentialNetworkWithCarrierPrivileges() {
+ WifiConfiguration config =
+ WifiConfigurationTestUtil.createEapNetwork(WifiEnterpriseConfig.Eap.SIM,
+ WifiEnterpriseConfig.Phase2.NONE);
+ WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
+ config, null, true, false, true);
+ List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
+ networkSuggestionList.add(networkSuggestion);
+ when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1))
+ .thenReturn(false);
+ when(mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE_1))
+ .thenReturn(VALID_CARRIER_ID);
+ int status = mWifiNetworkSuggestionsManager
+ .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, status);
+ verify(mNotificationManger, never()).notify(anyInt(), any());
+ assertEquals(1, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1).size());
+ }
+
+ /**
+ * Verify success when add SIM-based network from app has carrier provision permission.
+ */
+ @Test
+ public void testAddSimCredentialNetworkWithCarrierProvisionPermission() {
+ WifiConfiguration config =
+ WifiConfigurationTestUtil.createEapNetwork(WifiEnterpriseConfig.Eap.SIM,
+ WifiEnterpriseConfig.Phase2.NONE);
+ WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
+ config, null, true, false, true);
+ List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
+ networkSuggestionList.add(networkSuggestion);
+ when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1))
+ .thenReturn(true);
+ when(mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE_1))
+ .thenReturn(TelephonyManager.UNKNOWN_CARRIER_ID);
+ int status = mWifiNetworkSuggestionsManager
+ .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE);
+ assertEquals(status, WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
+ verify(mNotificationManger, never()).notify(anyInt(), any());
+ assertEquals(1, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1).size());
+ }
+
+ /**
+ * Verify matched SIM-based network will return when imsi protection is available.
+ */
+ @Test
+ public void testMatchSimBasedNetworkWithImsiProtection() {
+ WifiConfiguration config =
+ WifiConfigurationTestUtil.createEapNetwork(WifiEnterpriseConfig.Eap.SIM,
+ WifiEnterpriseConfig.Phase2.NONE);
+ WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
+ config, null, true, false, true);
+ List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
+ networkSuggestionList.add(networkSuggestion);
+ when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1))
+ .thenReturn(false);
+ when(mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE_1))
+ .thenReturn(VALID_CARRIER_ID);
+ when(mTelephonyUtil.getBestMatchSubscriptionId(config)).thenReturn(TEST_SUBID);
+ when(mTelephonyUtil.isSimPresent(TEST_SUBID)).thenReturn(true);
+ when(mTelephonyUtil.requiresImsiEncryption(TEST_SUBID)).thenReturn(true);
+ when(mTelephonyUtil.isImsiEncryptionInfoAvailable(TEST_SUBID)).thenReturn(true);
+ ScanDetail scanDetail = createScanDetailForNetwork(config);
+ int status = mWifiNetworkSuggestionsManager
+ .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, status);
+
+ Set<ExtendedWifiNetworkSuggestion> matchingExtNetworkSuggestions =
+ mWifiNetworkSuggestionsManager.getNetworkSuggestionsForScanDetail(scanDetail);
+ Set<WifiNetworkSuggestion> expectedMatchingNetworkSuggestions =
+ new HashSet<WifiNetworkSuggestion>() {{
+ add(networkSuggestion);
+ }};
+ verify(mNotificationManger, never()).notify(anyInt(), any());
+ assertSuggestionsEquals(expectedMatchingNetworkSuggestions, matchingExtNetworkSuggestions);
+ }
+
+ /**
+ * Verify matched SIM-based network won't return when imsi protection isn't available.
+ * Todo(142001564): verify user approval notification.
+ */
+ @Test
+ public void testMatchSimBasedNetworkWithoutImsiProtection() {
+ WifiConfiguration config =
+ WifiConfigurationTestUtil.createEapNetwork(WifiEnterpriseConfig.Eap.SIM,
+ WifiEnterpriseConfig.Phase2.NONE);
+ WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
+ config, null, true, false, true);
+ List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
+ networkSuggestionList.add(networkSuggestion);
+ when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1))
+ .thenReturn(false);
+ when(mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE_1))
+ .thenReturn(VALID_CARRIER_ID);
+ when(mTelephonyUtil.getBestMatchSubscriptionId(config)).thenReturn(TEST_SUBID);
+ when(mTelephonyUtil.isSimPresent(TEST_SUBID)).thenReturn(true);
+ when(mTelephonyUtil.requiresImsiEncryption(TEST_SUBID)).thenReturn(false);
+ when(mTelephonyUtil.isImsiEncryptionInfoAvailable(TEST_SUBID)).thenReturn(false);
+ ScanDetail scanDetail = createScanDetailForNetwork(config);
+ int status = mWifiNetworkSuggestionsManager
+ .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, status);
+
+ Set<ExtendedWifiNetworkSuggestion> matchingExtNetworkSuggestions =
+ mWifiNetworkSuggestionsManager.getNetworkSuggestionsForScanDetail(scanDetail);
+ //Todo(142001564): should send out user notification.
+ assertNull(matchingExtNetworkSuggestions);
+ }
+
+ /**
+ * Verify when SIM changes, the app loses carrier privilege. Suggestions from this app will be
+ * removed. If this app suggests again, it will be considered as normal suggestor.
+ */
+ @Test
+ public void testSimStateChangeWillResetCarrierPrivilegedApp() {
+ WifiConfiguration config =
+ WifiConfigurationTestUtil.createEapNetwork(WifiEnterpriseConfig.Eap.SIM,
+ WifiEnterpriseConfig.Phase2.NONE);
+ WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
+ config, null, true, false, true);
+ List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
+ networkSuggestionList.add(networkSuggestion);
+ when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1))
+ .thenReturn(false);
+ when(mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE_1))
+ .thenReturn(VALID_CARRIER_ID);
+ int status = mWifiNetworkSuggestionsManager
+ .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, status);
+ verify(mNotificationManger, never()).notify(anyInt(), any());
+ when(mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE_1))
+ .thenReturn(TelephonyManager.UNKNOWN_CARRIER_ID);
+ mWifiNetworkSuggestionsManager.resetCarrierPrivilegedApps();
+ assertEquals(0, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1).size());
+ verify(mWifiConfigManager, times(2)).saveToStore(true);
+ status = mWifiNetworkSuggestionsManager
+ .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED, status);
+ networkSuggestionList.clear();
+ networkSuggestionList.add(new WifiNetworkSuggestion(
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, true));
+ status = mWifiNetworkSuggestionsManager
+ .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, status);
+ verify(mNotificationManger).notify(anyInt(), any());
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
index 0ac7b6a2c..adb814e32 100644
--- a/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
@@ -93,6 +93,7 @@ public class TelephonyUtilTest extends WifiBaseTest {
private static final String DATA_OPERATOR_NUMERIC = "123456";
private static final String NON_DATA_OPERATOR_NUMERIC = "123456";
private static final String NO_MATCH_OPERATOR_NUMERIC = "654321";
+ private static final String TEST_PACKAGE = "com.test12345";
private static final String ANONYMOUS_IDENTITY = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org";
@Mock
@@ -1327,4 +1328,53 @@ public class TelephonyUtilTest extends WifiBaseTest {
assertTrue(mTelephonyUtil.isAnonymousAtRealmIdentity("6" + ANONYMOUS_IDENTITY));
assertFalse(mTelephonyUtil.isAnonymousAtRealmIdentity("AKA" + ANONYMOUS_IDENTITY));
}
+
+ /**
+ * Verify when no subscription available, get carrier id for target package will return
+ * UNKNOWN_CARRIER_ID.
+ */
+ @Test
+ public void getCarrierPrivilegeWithNoActiveSubscription() {
+ when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null);
+ assertEquals(TelephonyManager.UNKNOWN_CARRIER_ID,
+ mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE));
+
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Collections.emptyList());
+ assertEquals(TelephonyManager.UNKNOWN_CARRIER_ID,
+ mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE));
+ }
+
+ /**
+ * Verify when package has no carrier privileges, get carrier id for that package will return
+ * UNKNOWN_CARRIER_ID.
+ */
+ @Test
+ public void getCarrierPrivilegeWithPackageHasNoPrivilege() {
+ SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
+ when(subInfo.getSubscriptionId()).thenReturn(DATA_SUBID);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(subInfo));
+ when(mDataTelephonyManager.checkCarrierPrivilegesForPackage(TEST_PACKAGE))
+ .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+ assertEquals(TelephonyManager.UNKNOWN_CARRIER_ID,
+ mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE));
+ }
+
+ /**
+ * Verify when package get carrier privileges from carrier, get carrier id for that package will
+ * return the carrier id for that carrier.
+ */
+ @Test
+ public void getCarrierPrivilegeWithPackageHasPrivilege() {
+ SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
+ when(subInfo.getSubscriptionId()).thenReturn(DATA_SUBID);
+ when(subInfo.getCarrierId()).thenReturn(DATA_CARRIER_ID);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(subInfo));
+ when(mDataTelephonyManager.checkCarrierPrivilegesForPackage(TEST_PACKAGE))
+ .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+ assertEquals(DATA_CARRIER_ID,
+ mTelephonyUtil.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE));
+ }
}