diff options
author | Nate Jiang <qiangjiang@google.com> | 2019-10-17 21:28:09 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-10-17 21:28:09 +0000 |
commit | 95ec2663cd0b59d5db0948b1218142d0770e0c44 (patch) | |
tree | 420c8facfe55974d789e61cea612396a2e936938 /service | |
parent | cfa6d1c8b2bc7b68a01625782fb090bbb0104a06 (diff) | |
parent | 4921f24cce83719fd9f5d9bdec913545a57ad7fd (diff) |
Merge "merge passpoint into network suggestion"
Diffstat (limited to 'service')
8 files changed, 263 insertions, 117 deletions
diff --git a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java index 9627a9daa..5babd3830 100644 --- a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java +++ b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java @@ -19,6 +19,7 @@ package com.android.server.wifi; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiNetworkSuggestion; +import android.net.wifi.hotspot2.PasspointConfiguration; import android.os.Process; import android.util.Log; import android.util.Pair; @@ -26,6 +27,7 @@ import android.util.Pair; import com.android.internal.util.XmlUtils; import com.android.server.wifi.WifiNetworkSuggestionsManager.ExtendedWifiNetworkSuggestion; import com.android.server.wifi.WifiNetworkSuggestionsManager.PerAppInfo; +import com.android.server.wifi.hotspot2.PasspointXmlUtils; import com.android.server.wifi.util.XmlUtil; import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil; @@ -61,6 +63,8 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData { private static final String XML_TAG_SUGGESTOR_PACKAGE_NAME = "SuggestorPackageName"; private static final String XML_TAG_SUGGESTOR_HAS_USER_APPROVED = "SuggestorHasUserApproved"; private static final String XML_TAG_SUGGESTOR_MAX_SIZE = "SuggestorMaxSize"; + private static final String XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION = + "PasspointConfiguration"; /** * Interface define the data source for the network suggestions store data. @@ -199,6 +203,12 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData { out, suggestion.wifiConfiguration.enterpriseConfig); XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION); } + if (suggestion.passpointConfiguration != null) { + XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION); + PasspointXmlUtils.serializePasspointConfiguration(out, + suggestion.passpointConfiguration); + XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION); + } // Serialize other fields XmlUtil.writeNextValue(out, XML_TAG_IS_APP_INTERACTION_REQUIRED, @@ -283,6 +293,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData { throws XmlPullParserException, IOException { Pair<String, WifiConfiguration> parsedConfig = null; WifiEnterpriseConfig enterpriseConfig = null; + PasspointConfiguration passpointConfiguration = null; boolean isAppInteractionRequired = false; boolean isUserInteractionRequired = false; int suggestorUid = Process.INVALID_UID; @@ -334,6 +345,14 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData { enterpriseConfig = XmlUtil.WifiEnterpriseConfigXmlUtil.parseFromXml( in, outerTagDepth + 1); break; + case XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION: + if (passpointConfiguration != null) { + throw new XmlPullParserException("Detected duplicate tag for: " + + XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION); + } + passpointConfiguration = PasspointXmlUtils + .deserializePasspointConfiguration(in, outerTagDepth + 1); + break; default: throw new XmlPullParserException("Unknown tag under " + XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION + ": " + in.getName()); @@ -354,8 +373,8 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData { wifiConfiguration.enterpriseConfig = enterpriseConfig; } return new WifiNetworkSuggestion( - wifiConfiguration, isAppInteractionRequired, isUserInteractionRequired, - suggestorUid, suggestorPackageName); + wifiConfiguration, passpointConfiguration, isAppInteractionRequired, + isUserInteractionRequired, suggestorUid, suggestorPackageName); } } diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java index b970330b7..2a264b37d 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java +++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java @@ -235,6 +235,9 @@ public class WifiNetworkSuggestionsManager { */ private Set<ExtendedWifiNetworkSuggestion> mActiveNetworkSuggestionsMatchingConnection; + private final Map<String, Set<ExtendedWifiNetworkSuggestion>> + mPasspointInfo = new HashMap<>(); + /** * Intent filter for processing notification actions. */ @@ -307,7 +310,6 @@ public class WifiNetworkSuggestionsManager { } @Override - public void fromDeserialized(Map<String, PerAppInfo> networkSuggestionsMap) { mActiveNetworkSuggestionsPerApp.putAll(networkSuggestionsMap); // Build the scan cache. @@ -320,7 +322,13 @@ public class WifiNetworkSuggestionsManager { startTrackingAppOpsChange(packageName, extNetworkSuggestions.iterator().next().wns.suggestorUid); } - addToScanResultMatchInfoMap(extNetworkSuggestions); + for (ExtendedWifiNetworkSuggestion ewns : extNetworkSuggestions) { + if (ewns.wns.wifiConfiguration.FQDN != null) { + addToPasspointInfoMap(ewns); + } else { + addToScanResultMatchInfoMap(ewns); + } + } } } @@ -329,6 +337,7 @@ public class WifiNetworkSuggestionsManager { mActiveNetworkSuggestionsPerApp.clear(); mActiveScanResultMatchInfoWithBssid.clear(); mActiveScanResultMatchInfoWithNoBssid.clear(); + mPasspointInfo.clear(); } @Override @@ -426,79 +435,102 @@ public class WifiNetworkSuggestionsManager { } private void addToScanResultMatchInfoMap( - @NonNull Collection<ExtendedWifiNetworkSuggestion> extNetworkSuggestions) { - for (ExtendedWifiNetworkSuggestion extNetworkSuggestion : extNetworkSuggestions) { - ScanResultMatchInfo scanResultMatchInfo = - ScanResultMatchInfo.fromWifiConfiguration( - extNetworkSuggestion.wns.wifiConfiguration); - Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestionsForScanResultMatchInfo; - if (!TextUtils.isEmpty(extNetworkSuggestion.wns.wifiConfiguration.BSSID)) { - Pair<ScanResultMatchInfo, MacAddress> lookupPair = - Pair.create(scanResultMatchInfo, - MacAddress.fromString( - extNetworkSuggestion.wns.wifiConfiguration.BSSID)); - extNetworkSuggestionsForScanResultMatchInfo = - mActiveScanResultMatchInfoWithBssid.get(lookupPair); - if (extNetworkSuggestionsForScanResultMatchInfo == null) { - extNetworkSuggestionsForScanResultMatchInfo = new HashSet<>(); - mActiveScanResultMatchInfoWithBssid.put( - lookupPair, extNetworkSuggestionsForScanResultMatchInfo); - } - } else { - extNetworkSuggestionsForScanResultMatchInfo = - mActiveScanResultMatchInfoWithNoBssid.get(scanResultMatchInfo); - if (extNetworkSuggestionsForScanResultMatchInfo == null) { - extNetworkSuggestionsForScanResultMatchInfo = new HashSet<>(); - mActiveScanResultMatchInfoWithNoBssid.put( - scanResultMatchInfo, extNetworkSuggestionsForScanResultMatchInfo); - } + @NonNull ExtendedWifiNetworkSuggestion extNetworkSuggestion) { + ScanResultMatchInfo scanResultMatchInfo = + ScanResultMatchInfo.fromWifiConfiguration( + extNetworkSuggestion.wns.wifiConfiguration); + Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestionsForScanResultMatchInfo; + if (!TextUtils.isEmpty(extNetworkSuggestion.wns.wifiConfiguration.BSSID)) { + Pair<ScanResultMatchInfo, MacAddress> lookupPair = + Pair.create(scanResultMatchInfo, + MacAddress.fromString( + extNetworkSuggestion.wns.wifiConfiguration.BSSID)); + extNetworkSuggestionsForScanResultMatchInfo = + mActiveScanResultMatchInfoWithBssid.get(lookupPair); + if (extNetworkSuggestionsForScanResultMatchInfo == null) { + extNetworkSuggestionsForScanResultMatchInfo = new HashSet<>(); + mActiveScanResultMatchInfoWithBssid.put( + lookupPair, extNetworkSuggestionsForScanResultMatchInfo); + } + } else { + extNetworkSuggestionsForScanResultMatchInfo = + mActiveScanResultMatchInfoWithNoBssid.get(scanResultMatchInfo); + if (extNetworkSuggestionsForScanResultMatchInfo == null) { + extNetworkSuggestionsForScanResultMatchInfo = new HashSet<>(); + mActiveScanResultMatchInfoWithNoBssid.put( + scanResultMatchInfo, extNetworkSuggestionsForScanResultMatchInfo); } - extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion); - extNetworkSuggestionsForScanResultMatchInfo.add(extNetworkSuggestion); } + extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion); + extNetworkSuggestionsForScanResultMatchInfo.add(extNetworkSuggestion); } private void removeFromScanResultMatchInfoMap( - @NonNull Collection<ExtendedWifiNetworkSuggestion> extNetworkSuggestions) { - for (ExtendedWifiNetworkSuggestion extNetworkSuggestion : extNetworkSuggestions) { - ScanResultMatchInfo scanResultMatchInfo = - ScanResultMatchInfo.fromWifiConfiguration( - extNetworkSuggestion.wns.wifiConfiguration); - Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestionsForScanResultMatchInfo; - if (!TextUtils.isEmpty(extNetworkSuggestion.wns.wifiConfiguration.BSSID)) { - Pair<ScanResultMatchInfo, MacAddress> lookupPair = - Pair.create(scanResultMatchInfo, - MacAddress.fromString( - extNetworkSuggestion.wns.wifiConfiguration.BSSID)); - extNetworkSuggestionsForScanResultMatchInfo = - mActiveScanResultMatchInfoWithBssid.get(lookupPair); - // This should never happen because we should have done necessary error checks in - // the parent method. - if (extNetworkSuggestionsForScanResultMatchInfo == null) { - Log.wtf(TAG, "No scan result match info found."); - } - extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion); - // Remove the set from map if empty. - if (extNetworkSuggestionsForScanResultMatchInfo.isEmpty()) { - mActiveScanResultMatchInfoWithBssid.remove(lookupPair); - } - } else { - extNetworkSuggestionsForScanResultMatchInfo = - mActiveScanResultMatchInfoWithNoBssid.get(scanResultMatchInfo); - // This should never happen because we should have done necessary error checks in - // the parent method. - if (extNetworkSuggestionsForScanResultMatchInfo == null) { - Log.wtf(TAG, "No scan result match info found."); - } - extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion); - // Remove the set from map if empty. - if (extNetworkSuggestionsForScanResultMatchInfo.isEmpty()) { - mActiveScanResultMatchInfoWithNoBssid.remove(scanResultMatchInfo); - } + @NonNull ExtendedWifiNetworkSuggestion extNetworkSuggestion) { + ScanResultMatchInfo scanResultMatchInfo = + ScanResultMatchInfo.fromWifiConfiguration( + extNetworkSuggestion.wns.wifiConfiguration); + Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestionsForScanResultMatchInfo; + if (!TextUtils.isEmpty(extNetworkSuggestion.wns.wifiConfiguration.BSSID)) { + Pair<ScanResultMatchInfo, MacAddress> lookupPair = + Pair.create(scanResultMatchInfo, + MacAddress.fromString( + extNetworkSuggestion.wns.wifiConfiguration.BSSID)); + extNetworkSuggestionsForScanResultMatchInfo = + mActiveScanResultMatchInfoWithBssid.get(lookupPair); + // This should never happen because we should have done necessary error checks in + // the parent method. + if (extNetworkSuggestionsForScanResultMatchInfo == null) { + Log.wtf(TAG, "No scan result match info found."); + return; + } + extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion); + // Remove the set from map if empty. + if (extNetworkSuggestionsForScanResultMatchInfo.isEmpty()) { + mActiveScanResultMatchInfoWithBssid.remove(lookupPair); + } + } else { + extNetworkSuggestionsForScanResultMatchInfo = + mActiveScanResultMatchInfoWithNoBssid.get(scanResultMatchInfo); + // This should never happen because we should have done necessary error checks in + // the parent method. + if (extNetworkSuggestionsForScanResultMatchInfo == null) { + Log.wtf(TAG, "No scan result match info found."); + return; } + extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion); + // Remove the set from map if empty. + if (extNetworkSuggestionsForScanResultMatchInfo.isEmpty()) { + mActiveScanResultMatchInfoWithNoBssid.remove(scanResultMatchInfo); + } + } + } + + private void addToPasspointInfoMap(ExtendedWifiNetworkSuggestion ewns) { + Set<ExtendedWifiNetworkSuggestion> extendedWifiNetworkSuggestions = + mPasspointInfo.get(ewns.wns.wifiConfiguration.FQDN); + if (extendedWifiNetworkSuggestions == null) { + extendedWifiNetworkSuggestions = new HashSet<>(); + } + extendedWifiNetworkSuggestions.add(ewns); + mPasspointInfo.put(ewns.wns.wifiConfiguration.FQDN, extendedWifiNetworkSuggestions); + } + + private void removeFromPassPointInfoMap(ExtendedWifiNetworkSuggestion ewns) { + Set<ExtendedWifiNetworkSuggestion> extendedWifiNetworkSuggestions = + mPasspointInfo.get(ewns.wns.wifiConfiguration.FQDN); + if (extendedWifiNetworkSuggestions == null + || !extendedWifiNetworkSuggestions.contains(ewns)) { + Log.wtf(TAG, "No Passpoint info found."); + return; + } + extendedWifiNetworkSuggestions.remove(ewns); + if (extendedWifiNetworkSuggestions.isEmpty()) { + mPasspointInfo.remove(ewns.wns.wifiConfiguration.FQDN); } } + // Issues a disconnect if the only serving network suggestion is removed. private void removeFromConfigManagerIfServingNetworkSuggestionRemoved( Collection<ExtendedWifiNetworkSuggestion> extNetworkSuggestionsRemoved) { @@ -598,11 +630,24 @@ public class WifiNetworkSuggestionsManager { // Start tracking app-op changes from the app if they have active suggestions. startTrackingAppOpsChange(packageName, uid); } - perAppInfo.extNetworkSuggestions.removeAll(extNetworkSuggestions); - perAppInfo.extNetworkSuggestions.addAll(extNetworkSuggestions); + for (ExtendedWifiNetworkSuggestion ewns: extNetworkSuggestions) { + if (ewns.wns.passpointConfiguration == null) { + addToScanResultMatchInfoMap(ewns); + } else { + // Install Passpoint config, if failure, ignore that suggestion + if (!mWifiInjector.getPasspointManager().addOrUpdateProvider( + ewns.wns.passpointConfiguration, uid, + packageName, true)) { + Log.e(TAG, "Passpoint profile install failure."); + continue; + } + addToPasspointInfoMap(ewns); + } + perAppInfo.extNetworkSuggestions.remove(ewns); + perAppInfo.extNetworkSuggestions.add(ewns); + } // Update the max size for this app. perAppInfo.maxSize = Math.max(perAppInfo.extNetworkSuggestions.size(), perAppInfo.maxSize); - addToScanResultMatchInfoMap(extNetworkSuggestions); saveToStore(); mWifiMetrics.incrementNetworkSuggestionApiNumModification(); mWifiMetrics.noteNetworkSuggestionApiListSizeHistogram(getAllMaxSizes()); @@ -642,10 +687,21 @@ public class WifiNetworkSuggestionsManager { // Stop tracking app-op changes from the app if they don't have active suggestions. stopTrackingAppOpsChange(packageName); } + // Clear the cache. + for (ExtendedWifiNetworkSuggestion ewns : extNetworkSuggestions) { + if (ewns.wns.wifiConfiguration.FQDN != null) { + // Clear the Passpoint config. + mWifiInjector.getPasspointManager().removeProvider( + ewns.wns.suggestorUid, + false, + ewns.wns.wifiConfiguration.FQDN); + removeFromPassPointInfoMap(ewns); + } else { + removeFromScanResultMatchInfoMap(ewns); + } + } // Disconnect suggested network if connected removeFromConfigManagerIfServingNetworkSuggestionRemoved(extNetworkSuggestions); - // Clear the scan cache. - removeFromScanResultMatchInfoMap(extNetworkSuggestions); } /** @@ -827,15 +883,26 @@ public class WifiNetworkSuggestionsManager { mUserApprovalNotificationPackageName = packageName; } - private boolean sendUserApprovalNotificationIfNotApproved( - @NonNull PerAppInfo perAppInfo, - @NonNull WifiNetworkSuggestion matchingSuggestion) { - if (perAppInfo.hasUserApproved) { + /** + * Send user approval notification if the app is not approved + * @param packageName app package name + * @param uid app UID + * @return true if app is not approved and send notification. + */ + public boolean sendUserApprovalNotificationIfNotApproved( + @NonNull String packageName, @NonNull int uid) { + if (!mActiveNetworkSuggestionsPerApp.containsKey(packageName)) { + Log.wtf(TAG, "AppInfo is missing for " + packageName); + return false; + } + if (mActiveNetworkSuggestionsPerApp.get(packageName).hasUserApproved) { return false; // already approved. } - Log.i(TAG, "Sending user approval notification for " + perAppInfo.packageName); - sendUserApprovalNotification(perAppInfo.packageName, matchingSuggestion.suggestorUid); + Log.i(TAG, "Sending user approval notification for " + packageName); + if (!mUserApprovalNotificationActive) { + sendUserApprovalNotification(packageName, uid); + } return true; } @@ -862,6 +929,14 @@ public class WifiNetworkSuggestionsManager { return extNetworkSuggestions; } + private @Nullable Set<ExtendedWifiNetworkSuggestion> getNetworkSuggestionsForFqdnMatch( + @Nullable String fqdn) { + if (TextUtils.isEmpty(fqdn)) { + return null; + } + return mPasspointInfo.get(fqdn); + } + /** * Returns a set of all network suggestions matching the provided scan detail. */ @@ -896,7 +971,8 @@ public class WifiNetworkSuggestionsManager { && approvedExtNetworkSuggestions.size() != extNetworkSuggestions.size()) { for (ExtendedWifiNetworkSuggestion extNetworkSuggestion : extNetworkSuggestions) { if (sendUserApprovalNotificationIfNotApproved( - extNetworkSuggestion.perAppInfo, extNetworkSuggestion.wns)) { + extNetworkSuggestion.perAppInfo.packageName, + extNetworkSuggestion.wns.suggestorUid)) { break; } } @@ -915,18 +991,22 @@ public class WifiNetworkSuggestionsManager { /** * Returns a set of all network suggestions matching the provided the WifiConfiguration. */ - private @Nullable Set<ExtendedWifiNetworkSuggestion> getNetworkSuggestionsForWifiConfiguration( + public @Nullable Set<ExtendedWifiNetworkSuggestion> getNetworkSuggestionsForWifiConfiguration( @NonNull WifiConfiguration wifiConfiguration, @Nullable String bssid) { Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestions = null; - try { - ScanResultMatchInfo scanResultMatchInfo = - ScanResultMatchInfo.fromWifiConfiguration(wifiConfiguration); - extNetworkSuggestions = getNetworkSuggestionsForScanResultMatchInfo( - scanResultMatchInfo, bssid == null ? null : MacAddress.fromString(bssid)); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Failed to lookup network from scan result match info map", e); + if (wifiConfiguration.isPasspoint()) { + extNetworkSuggestions = getNetworkSuggestionsForFqdnMatch(wifiConfiguration.FQDN); + } else { + try { + ScanResultMatchInfo scanResultMatchInfo = + ScanResultMatchInfo.fromWifiConfiguration(wifiConfiguration); + extNetworkSuggestions = getNetworkSuggestionsForScanResultMatchInfo( + scanResultMatchInfo, bssid == null ? null : MacAddress.fromString(bssid)); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Failed to lookup network from scan result match info map", e); + } } - if (extNetworkSuggestions == null) { + if (extNetworkSuggestions == null || extNetworkSuggestions.isEmpty()) { return null; } Set<ExtendedWifiNetworkSuggestion> approvedExtNetworkSuggestions = @@ -940,7 +1020,7 @@ public class WifiNetworkSuggestionsManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "getNetworkSuggestionsFoWifiConfiguration Found " + approvedExtNetworkSuggestions + " for " + wifiConfiguration.SSID - + "[" + wifiConfiguration.allowedKeyManagement + "]"); + + wifiConfiguration.FQDN + "[" + wifiConfiguration.allowedKeyManagement + "]"); } return approvedExtNetworkSuggestions; } @@ -1007,7 +1087,8 @@ public class WifiNetworkSuggestionsManager { private void handleConnectionSuccess( @NonNull WifiConfiguration connectedNetwork, @NonNull String connectedBssid) { Set<ExtendedWifiNetworkSuggestion> matchingExtNetworkSuggestions = - getNetworkSuggestionsForWifiConfiguration(connectedNetwork, connectedBssid); + getNetworkSuggestionsForWifiConfiguration(connectedNetwork, connectedBssid); + if (mVerboseLoggingEnabled) { Log.v(TAG, "Network suggestions matching the connection " + matchingExtNetworkSuggestions); diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index d19159e7f..442e94c3d 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -2103,7 +2103,7 @@ public class WifiServiceImpl extends BaseWifiService { int callingUid = Binder.getCallingUid(); mLog.info("addorUpdatePasspointConfiguration uid=%").c(callingUid).flush(); return mWifiThreadRunner.call( - () -> mPasspointManager.addOrUpdateProvider(config, callingUid, packageName), + () -> mPasspointManager.addOrUpdateProvider(config, callingUid, packageName, false), false); } @@ -2148,7 +2148,7 @@ public class WifiServiceImpl extends BaseWifiService { final boolean privilegedFinal = privileged; return mWifiThreadRunner.call( () -> mPasspointManager.getProviderConfigs(uid, privilegedFinal), - Collections.emptyList()); + Collections.emptyList()); } /** diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java b/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java index 0114cfb21..f2d7388a0 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java @@ -71,6 +71,7 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData { "RemediationCaCertificateAlias"; private static final String XML_TAG_HAS_EVER_CONNECTED = "HasEverConnected"; + private static final String XML_TAG_IS_FROM_SUGGESTION = "IsFromSuggestion"; private final WifiKeyStore mKeyStore; private final SIMAccessor mSimAccessor; @@ -200,6 +201,7 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData { XmlUtil.writeNextValue(out, XML_TAG_CLIENT_PRIVATE_KEY_ALIAS, provider.getClientPrivateKeyAlias()); XmlUtil.writeNextValue(out, XML_TAG_HAS_EVER_CONNECTED, provider.getHasEverConnected()); + XmlUtil.writeNextValue(out, XML_TAG_IS_FROM_SUGGESTION, provider.isFromSuggestion()); if (provider.getConfig() != null) { XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION); PasspointXmlUtils.serializePasspointConfiguration(out, provider.getConfig()); @@ -272,6 +274,7 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData { String remediationCaCertificateAlias = null; String packageName = null; boolean hasEverConnected = false; + boolean isFromSuggestion = false; boolean shared = false; PasspointConfiguration config = null; while (XmlUtils.nextElementWithin(in, outerTagDepth)) { @@ -309,6 +312,9 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData { case XML_TAG_HAS_EVER_CONNECTED: hasEverConnected = (boolean) value; break; + case XML_TAG_IS_FROM_SUGGESTION: + isFromSuggestion = (boolean) value; + break; } } else { if (!TextUtils.equals(in.getName(), @@ -338,8 +344,8 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData { throw new XmlPullParserException("Missing Passpoint configuration"); } return new PasspointProvider(config, mKeyStore, mSimAccessor, providerId, creatorUid, - packageName, caCertificateAliases, clientCertificateAlias, clientPrivateKeyAlias, - remediationCaCertificateAlias, hasEverConnected, shared); + packageName, isFromSuggestion, caCertificateAliases, clientCertificateAlias, + clientPrivateKeyAlias, remediationCaCertificateAlias, hasEverConnected, shared); } } diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index 3deac1290..0c795dcb3 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -392,7 +392,8 @@ public class PasspointManager { * @param packageName Package name of the app adding/Updating {@code config} * @return true if provider is added, false otherwise */ - public boolean addOrUpdateProvider(PasspointConfiguration config, int uid, String packageName) { + public boolean addOrUpdateProvider(PasspointConfiguration config, int uid, + String packageName, boolean isFromSuggestion) { mWifiMetrics.incrementNumPasspointProviderInstallation(); if (config == null) { Log.e(TAG, "Configuration not provided"); @@ -421,8 +422,8 @@ public class PasspointManager { } // Create a provider and install the necessary certificates and keys. - PasspointProvider newProvider = mObjectFactory.makePasspointProvider( - config, mKeyStore, mSimAccessor, mProviderIndex++, uid, packageName); + PasspointProvider newProvider = mObjectFactory.makePasspointProvider(config, mKeyStore, + mSimAccessor, mProviderIndex++, uid, packageName, isFromSuggestion); if (!newProvider.installCertsAndKeys()) { Log.e(TAG, "Failed to install certificates and keys to keystore"); @@ -431,15 +432,26 @@ public class PasspointManager { // Remove existing provider with the same FQDN. if (mProviders.containsKey(config.getHomeSp().getFqdn())) { + PasspointProvider old = mProviders.get(config.getHomeSp().getFqdn()); + // If new profile is from suggestion and from a different App, ignore new profile, + // return true. + // If from same app, update it. + if (isFromSuggestion && !old.getPackageName().equals(packageName)) { + newProvider.uninstallCertsAndKeys(); + return false; + } Log.d(TAG, "Replacing configuration for " + config.getHomeSp().getFqdn()); - mProviders.get(config.getHomeSp().getFqdn()).uninstallCertsAndKeys(); + old.uninstallCertsAndKeys(); mProviders.remove(config.getHomeSp().getFqdn()); + // New profile changes the credential, remove the related WifiConfig. + if (!old.equals(newProvider)) { + mWifiConfigManager.removePasspointConfiguredNetwork( + newProvider.getWifiConfig().configKey()); + } } mProviders.put(config.getHomeSp().getFqdn(), newProvider); - mWifiConfigManager.removePasspointConfiguredNetwork( - newProvider.getWifiConfig().configKey()); mWifiConfigManager.saveToStore(true /* forceWrite */); - if (newProvider.getPackageName() != null) { + if (!isFromSuggestion && newProvider.getPackageName() != null) { startTrackingAppOpsChange(newProvider.getPackageName(), uid); } Log.d(TAG, "Added/updated Passpoint configuration: " + config.getHomeSp().getFqdn() @@ -650,7 +662,7 @@ public class PasspointManager { // Create a provider and install the necessary certificates and keys. PasspointProvider newProvider = mObjectFactory.makePasspointProvider( - config, mKeyStore, mSimAccessor, mProviderIndex++, Process.WIFI_UID, null); + config, mKeyStore, mSimAccessor, mProviderIndex++, Process.WIFI_UID, null, false); newProvider.setEphemeral(true); Log.d(TAG, "installed PasspointConfiguration for carrier : " + config.getHomeSp().getFriendlyName()); @@ -713,18 +725,21 @@ public class PasspointManager { /** * Return the installed Passpoint provider configurations. - * * An empty list will be returned when no provider is installed. * * @param callingUid Calling UID. * @param privileged Whether the caller is a privileged entity * @return A list of {@link PasspointConfiguration} */ - public List<PasspointConfiguration> getProviderConfigs(int callingUid, boolean privileged) { + public List<PasspointConfiguration> getProviderConfigs(int callingUid, + boolean privileged) { List<PasspointConfiguration> configs = new ArrayList<>(); for (Map.Entry<String, PasspointProvider> entry : mProviders.entrySet()) { PasspointProvider provider = entry.getValue(); if (privileged || callingUid == provider.getCreatorUid()) { + if (provider.isEphemeral() || provider.isFromSuggestion()) { + continue; + } configs.add(provider.getConfig()); } } @@ -814,6 +829,15 @@ public class PasspointManager { roamingConsortium); if (matchStatus == PasspointMatch.HomeProvider || matchStatus == PasspointMatch.RoamingProvider) { + // If provider is from network suggestion, check user approval. + // Send user approval notification if need. + // If not approved, will be ignored in this matching. + if (provider.isFromSuggestion() + && mWifiInjector.getWifiNetworkSuggestionsManager() + .sendUserApprovalNotificationIfNotApproved( + provider.getPackageName(), provider.getCreatorUid())) { + continue; + } allMatches.add(Pair.create(provider, matchStatus)); } } @@ -1026,13 +1050,12 @@ public class PasspointManager { public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders( List<OsuProvider> osuProviders) { Map<OsuProvider, PasspointConfiguration> matchingPasspointConfigs = new HashMap<>(); - List<PasspointConfiguration> passpointConfigurations = - getProviderConfigs(Process.WIFI_UID /* ignored */, true); for (OsuProvider osuProvider : osuProviders) { Map<String, String> friendlyNamesForOsuProvider = osuProvider.getFriendlyNameList(); if (friendlyNamesForOsuProvider == null) continue; - for (PasspointConfiguration passpointConfiguration : passpointConfigurations) { + for (PasspointProvider provider : mProviders.values()) { + PasspointConfiguration passpointConfiguration = provider.getConfig(); Map<String, String> serviceFriendlyNamesForPpsMo = passpointConfiguration.getServiceFriendlyNames(); if (serviceFriendlyNamesForPpsMo == null) continue; @@ -1167,7 +1190,7 @@ public class PasspointManager { // Note that for legacy configuration, the alias for client private key is the same as the // alias for the client certificate. PasspointProvider provider = new PasspointProvider(passpointConfig, mKeyStore, - mSimAccessor, mProviderIndex++, wifiConfig.creatorUid, null, + mSimAccessor, mProviderIndex++, wifiConfig.creatorUid, null, false, Arrays.asList(enterpriseConfig.getCaCertificateAlias()), enterpriseConfig.getClientCertificateAlias(), enterpriseConfig.getClientCertificateAlias(), null, false, false); diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java index 6c8c281f3..2d98a9d71 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java @@ -244,8 +244,13 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva } // Add the newly created WifiConfiguration to WifiConfigManager. - NetworkUpdateResult result = - mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID); + NetworkUpdateResult result; + if (config.fromWifiNetworkSuggestion) { + result = mWifiConfigManager.addOrUpdateNetwork( + config, config.creatorUid, config.creatorName); + } else { + result = mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID); + } if (!result.isSuccess()) { localLog("Failed to add passpoint network"); return null; diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java b/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java index c083b86cc..94be270e2 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java @@ -59,9 +59,9 @@ public class PasspointObjectFactory{ */ public PasspointProvider makePasspointProvider(PasspointConfiguration config, WifiKeyStore keyStore, SIMAccessor simAccessor, long providerId, int creatorUid, - String packageName) { + String packageName, boolean isFromSuggestion) { return new PasspointProvider(config, keyStore, simAccessor, providerId, creatorUid, - packageName); + packageName, isFromSuggestion); } /** diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java index 753b9a53e..70ea738ac 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java @@ -98,6 +98,8 @@ public class PasspointProvider { private boolean mHasEverConnected; private boolean mIsShared; + private boolean mIsFromSuggestion; + /** * This is a flag to indicate if the Provider is created temporarily. @@ -106,14 +108,15 @@ public class PasspointProvider { private boolean mIsEphemeral = false; public PasspointProvider(PasspointConfiguration config, WifiKeyStore keyStore, - SIMAccessor simAccessor, long providerId, int creatorUid, String packageName) { - this(config, keyStore, simAccessor, providerId, creatorUid, packageName, null, null, null, - null, false, false); + SIMAccessor simAccessor, long providerId, int creatorUid, String packageName, + boolean isFromSuggestion) { + this(config, keyStore, simAccessor, providerId, creatorUid, packageName, isFromSuggestion, + null, null, null, null, false, false); } public PasspointProvider(PasspointConfiguration config, WifiKeyStore keyStore, SIMAccessor simAccessor, long providerId, int creatorUid, String packageName, - List<String> caCertificateAliases, + boolean isFromSuggestion, List<String> caCertificateAliases, String clientCertificateAlias, String clientPrivateKeyAlias, String remediationCaCertificateAlias, boolean hasEverConnected, boolean isShared) { @@ -129,6 +132,7 @@ public class PasspointProvider { mRemediationCaCertificateAlias = remediationCaCertificateAlias; mHasEverConnected = hasEverConnected; mIsShared = isShared; + mIsFromSuggestion = isFromSuggestion; // Setup EAP method and authentication parameter based on the credential. if (mConfig.getCredential().getUserCredential() != null) { @@ -205,6 +209,10 @@ public class PasspointProvider { return mImsiParameter; } + public boolean isFromSuggestion() { + return mIsFromSuggestion; + } + /** * Install certificates and key based on current configuration. * Note: the certificates and keys in the configuration will get cleared once @@ -426,6 +434,10 @@ public class PasspointProvider { wifiConfig.enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS); } wifiConfig.shared = mIsShared; + wifiConfig.fromWifiNetworkSuggestion = mIsFromSuggestion; + wifiConfig.ephemeral = mIsFromSuggestion; + wifiConfig.creatorName = mPackageName; + wifiConfig.creatorUid = mCreatorUid; return wifiConfig; } |