summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorAmin Shaikh <ashaikh@google.com>2017-04-25 20:14:46 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-04-25 20:14:46 +0000
commit6390486a62185ef03df9d73db33faa11b0d64908 (patch)
treeef75c2adb9e2bdacb7c3e72bfba66083f922dc5a /service
parent1cd9e7bd982aa73b3434f1421a1c154b5384d832 (diff)
parent570478da56dd5181da0394e40cc94c9a3a610f5a (diff)
Merge changes from topic 'experio-scoring' into oc-dev am: a208bbfb1b
am: 570478da56 Change-Id: If4b1c1affa798cb3a298e1b8469904157b9f5821
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/RecommendedNetworkEvaluator.java328
-rw-r--r--service/java/com/android/server/wifi/ScoredNetworkEvaluator.java322
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java8
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java20
4 files changed, 339 insertions, 339 deletions
diff --git a/service/java/com/android/server/wifi/RecommendedNetworkEvaluator.java b/service/java/com/android/server/wifi/RecommendedNetworkEvaluator.java
deleted file mode 100644
index 80d1501a2..000000000
--- a/service/java/com/android/server/wifi/RecommendedNetworkEvaluator.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2016 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.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.net.INetworkScoreCache;
-import android.net.NetworkKey;
-import android.net.NetworkScoreManager;
-import android.net.RecommendationRequest;
-import android.net.RecommendationResult;
-import android.net.ScoredNetwork;
-import android.net.WifiKey;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.LocalLog;
-import android.util.LruCache;
-import android.util.Pair;
-import android.util.Slog;
-
-import com.android.server.wifi.util.ScanResultUtil;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * {@link WifiNetworkSelector.NetworkEvaluator} implementation that uses
- * {@link NetworkScoreManager#requestRecommendation(RecommendationRequest)}.
- */
-public class RecommendedNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluator {
- private static final String TAG = "RecNetEvaluator";
- private final NetworkScoreManager mNetworkScoreManager;
- private final WifiConfigManager mWifiConfigManager;
- private final LocalLog mLocalLog;
- private final ContentObserver mContentObserver;
- private final RequestedScoreCache mRequestedScoreCache;
- private boolean mNetworkRecommendationsEnabled;
-
- RecommendedNetworkEvaluator(final Context context, ContentResolver contentResolver,
- Looper looper, final FrameworkFacade frameworkFacade,
- NetworkScoreManager networkScoreManager, WifiConfigManager wifiConfigManager,
- LocalLog localLog) {
- mRequestedScoreCache = new RequestedScoreCache(frameworkFacade.getLongSetting(
- context, Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS,
- TimeUnit.DAYS.toMillis(1)));
- mNetworkScoreManager = networkScoreManager;
- mWifiConfigManager = wifiConfigManager;
- mLocalLog = localLog;
- mContentObserver = new ContentObserver(new Handler(looper)) {
- @Override
- public void onChange(boolean selfChange) {
- mNetworkRecommendationsEnabled = frameworkFacade.getIntegerSetting(context,
- Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0) == 1;
- }
- };
- frameworkFacade.registerContentObserver(context,
- Settings.Global.getUriFor(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED),
- false /* notifyForDescendents */, mContentObserver);
- mContentObserver.onChange(false /* unused */);
- mNetworkScoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mRequestedScoreCache,
- NetworkScoreManager.CACHE_FILTER_NONE);
- mLocalLog.log("RecommendedNetworkEvaluator constructed. mNetworkRecommendationsEnabled: "
- + mNetworkRecommendationsEnabled);
- }
-
- @Override
- public void update(List<ScanDetail> scanDetails) {
- if (mNetworkRecommendationsEnabled) {
- updateNetworkScoreCache(scanDetails);
- }
- clearNotRecommendedFlag();
- }
-
- private void updateNetworkScoreCache(List<ScanDetail> scanDetails) {
- ArrayList<NetworkKey> unscoredNetworks = new ArrayList<NetworkKey>();
-
- for (int i = 0; i < scanDetails.size(); i++) {
- ScanResult scanResult = scanDetails.get(i).getScanResult();
- try {
- WifiKey wifiKey = new WifiKey(
- ScanResultUtil.createQuotedSSID(scanResult.SSID), scanResult.BSSID);
- // Have we requested a score for this network? If not, request a score.
- if (mRequestedScoreCache.shouldRequestScore(wifiKey)) {
- unscoredNetworks.add(new NetworkKey(wifiKey));
- }
- } catch (IllegalArgumentException e) {
- mLocalLog.log("Invalid SSID=" + scanResult.SSID + " BSSID=" + scanResult.BSSID
- + " for network score. Skip.");
- }
- }
-
- // Kick the score manager if there are any unscored network.
- if (!unscoredNetworks.isEmpty()) {
- NetworkKey[] unscoredNetworkKeys =
- unscoredNetworks.toArray(new NetworkKey[unscoredNetworks.size()]);
- mNetworkScoreManager.requestScores(unscoredNetworkKeys);
- }
- }
-
- private void clearNotRecommendedFlag() {
- List<WifiConfiguration> savedNetworks = mWifiConfigManager.getSavedNetworks();
- for (int i = 0; i < savedNetworks.size(); i++) {
- mWifiConfigManager.updateNetworkNotRecommended(
- savedNetworks.get(i).networkId, false /* notRecommended*/);
- }
- }
-
- @Override
- public WifiConfiguration evaluateNetworks(List<ScanDetail> scanDetails,
- WifiConfiguration currentNetwork, String currentBssid, boolean connected,
- boolean untrustedNetworkAllowed,
- List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks) {
- if (!mNetworkRecommendationsEnabled) {
- mLocalLog.log("Skipping evaluateNetworks; Network recommendations disabled.");
- return null;
- }
- Set<WifiConfiguration> availableConfiguredNetworks = new ArraySet<>();
- List<ScanResult> scanResults = new ArrayList<>();
- for (int i = 0; i < scanDetails.size(); i++) {
- ScanDetail scanDetail = scanDetails.get(i);
- ScanResult scanResult = scanDetail.getScanResult();
- if (scanResult == null) continue;
- if (mWifiConfigManager.wasEphemeralNetworkDeleted(
- ScanResultUtil.createQuotedSSID(scanResult.SSID))) {
- continue;
- }
-
- final WifiConfiguration configuredNetwork =
- mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail);
-
- scanResult.untrusted = configuredNetwork == null || configuredNetwork.ephemeral;
-
- if (!untrustedNetworkAllowed && scanResult.untrusted) {
- continue;
- }
-
- if (configuredNetwork != null) {
- if (!configuredNetwork.getNetworkSelectionStatus().isNetworkEnabled()) {
- continue;
- }
- availableConfiguredNetworks.add(configuredNetwork);
- }
- scanResults.add(scanResult);
- // Track potential connectable networks for the watchdog.
- if (connectableNetworks != null) {
- connectableNetworks.add(Pair.create(scanDetail, configuredNetwork));
- }
- }
-
- if (scanResults.isEmpty()) {
- return null;
- }
-
- ScanResult[] scanResultArray = scanResults.toArray(new ScanResult[scanResults.size()]);
- WifiConfiguration[] availableConfigsArray = availableConfiguredNetworks
- .toArray(new WifiConfiguration[availableConfiguredNetworks.size()]);
- int lastSelectedNetworkId = mWifiConfigManager.getLastSelectedNetwork();
- long lastSelectedNetworkTimestamp = mWifiConfigManager.getLastSelectedTimeStamp();
- RecommendationRequest request = new RecommendationRequest.Builder()
- .setScanResults(scanResultArray)
- .setConnectedWifiConfig(currentNetwork)
- .setConnectableConfigs(availableConfigsArray)
- .setLastSelectedNetwork(lastSelectedNetworkId, lastSelectedNetworkTimestamp)
- // TODO: pass in currently recommended network
- .build();
- RecommendationResult result = mNetworkScoreManager.requestRecommendation(request);
- if (result == null) {
- // Recommendation provider could not be reached.
- return null;
- }
-
- if (result.getWifiConfiguration() == null) {
- // Recommendation provider recommended not connecting to any network.
- for (int i = 0; i < availableConfigsArray.length; i++) {
- if (availableConfigsArray[i].getNetworkSelectionStatus().isNetworkEnabled()) {
- mWifiConfigManager.updateNetworkNotRecommended(
- availableConfigsArray[i].networkId, true /* notRecommended*/);
- }
- }
- return null;
- }
-
- WifiConfiguration recommendedConfig = result.getWifiConfiguration();
- ScanDetail matchingScanDetail = findMatchingScanDetail(scanDetails, recommendedConfig);
- if (matchingScanDetail == null) {
- Slog.e(TAG, "Could not match WifiConfiguration to a ScanDetail.");
- return null;
- }
- ScanResult matchingScanResult = matchingScanDetail.getScanResult();
-
- // Look for a matching saved config. This can be null for ephemeral networks.
- final WifiConfiguration existingConfig =
- mWifiConfigManager.getSavedNetworkForScanDetailAndCache(matchingScanDetail);
-
- final int networkId;
- if (existingConfig == null) { // attempt to add a new ephemeral network.
- networkId = addEphemeralNetwork(recommendedConfig, matchingScanResult);
- if (networkId == WifiConfiguration.INVALID_NETWORK_ID) {
- return null;
- }
- } else { // Use the existing config
- networkId = existingConfig.networkId;
- }
- mWifiConfigManager.setNetworkCandidateScanResult(networkId,
- matchingScanResult, 0 /* score */);
- return mWifiConfigManager.getConfiguredNetwork(networkId);
- }
-
- private static ScanDetail findMatchingScanDetail(List<ScanDetail> scanDetails,
- WifiConfiguration wifiConfiguration) {
- String ssid = WifiInfo.removeDoubleQuotes(wifiConfiguration.SSID);
- String bssid = wifiConfiguration.BSSID;
- boolean ignoreBssid = TextUtils.isEmpty(bssid) || "any".equals(bssid);
- for (int i = 0; i < scanDetails.size(); i++) {
- final ScanDetail scanDetail = scanDetails.get(i);
- if (ssid.equals(scanDetail.getSSID())
- && (ignoreBssid || bssid.equals(scanDetail.getBSSIDString()))) {
- return scanDetail;
- }
- }
-
- return null;
- }
-
- private int addEphemeralNetwork(WifiConfiguration wifiConfiguration, ScanResult scanResult) {
- if (wifiConfiguration.allowedKeyManagement.isEmpty()) {
- ScanResultUtil.setAllowedKeyManagementFromScanResult(scanResult,
- wifiConfiguration);
- }
- wifiConfiguration.ephemeral = true;
- wifiConfiguration.BSSID = null;
- NetworkUpdateResult networkUpdateResult = mWifiConfigManager
- .addOrUpdateNetwork(wifiConfiguration, Process.WIFI_UID);
- if (networkUpdateResult.isSuccess()) {
- return networkUpdateResult.getNetworkId();
- }
- mLocalLog.log("Failed to add ephemeral network for networkId: "
- + WifiNetworkSelector.toScanId(scanResult));
- return WifiConfiguration.INVALID_NETWORK_ID;
- }
-
- @Override
- public String getName() {
- return TAG;
- }
-
- /** Cache for scores that have already been requested. */
- static class RequestedScoreCache extends INetworkScoreCache.Stub {
- /** Number entries to be stored in the {@link LruCache} of requested {@link WifiKey}s. */
- private static final int MAX_CACHE_SIZE = 1000;
-
- private final long mCacheExpiryMillis;
- @GuardedBy("mCache")
- private final LruCache<WifiKey, Object> mCache = new LruCache<>(MAX_CACHE_SIZE);
- @GuardedBy("mCache")
- private long mCacheCreationTime;
-
- RequestedScoreCache(long cacheExpiryMillis) {
- mCacheExpiryMillis = cacheExpiryMillis;
- }
-
- /** Returns whether a score should be requested for a given {@code wifiKey}. */
- public boolean shouldRequestScore(WifiKey wifiKey) {
- long nowMillis = SystemClock.elapsedRealtime();
- long oldestUsableCacheTimeMillis = nowMillis - mCacheExpiryMillis;
- synchronized (mCache) {
- if (mCacheCreationTime < oldestUsableCacheTimeMillis) {
- mCache.evictAll();
- mCacheCreationTime = nowMillis;
- }
- boolean shouldRequest = mCache.get(wifiKey) == null;
- mCache.put(wifiKey, this); // Update access time for wifiKey.
- return shouldRequest;
- }
- }
-
- @Override
- public void updateScores(List<ScoredNetwork> networks) throws RemoteException {}
-
- @Override
- public void clearScores() throws RemoteException {
- synchronized (mCache) {
- mCache.evictAll();
- mCacheCreationTime = 0;
- }
- }
-
- @Override
- protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- writer.println("RequestedScoreCache:");
- writer.println("mCacheExpiryMillis: " + mCacheExpiryMillis);
- synchronized (mCache) {
- writer.println("mCacheCreationTime: " + mCacheCreationTime);
- writer.println("mCache size: " + mCache.size());
- }
- }
- }
-}
diff --git a/service/java/com/android/server/wifi/ScoredNetworkEvaluator.java b/service/java/com/android/server/wifi/ScoredNetworkEvaluator.java
new file mode 100644
index 000000000..483da9936
--- /dev/null
+++ b/service/java/com/android/server/wifi/ScoredNetworkEvaluator.java
@@ -0,0 +1,322 @@
+/*
+ * 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.Nullable;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.NetworkKey;
+import android.net.NetworkScoreManager;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiNetworkScoreCache;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Process;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.server.wifi.util.ScanResultUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * {@link WifiNetworkSelector.NetworkEvaluator} implementation that uses scores obtained by
+ * {@link NetworkScoreManager#requestScores(NetworkKey[])} to make network connection decisions.
+ */
+public class ScoredNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluator {
+ private static final String TAG = "ScoredNetworkEvaluator";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private final NetworkScoreManager mNetworkScoreManager;
+ private final WifiConfigManager mWifiConfigManager;
+ private final LocalLog mLocalLog;
+ private final ContentObserver mContentObserver;
+ private boolean mNetworkRecommendationsEnabled;
+ private WifiNetworkScoreCache mScoreCache;
+
+ ScoredNetworkEvaluator(final Context context, Looper looper,
+ final FrameworkFacade frameworkFacade, NetworkScoreManager networkScoreManager,
+ WifiConfigManager wifiConfigManager, LocalLog localLog,
+ WifiNetworkScoreCache wifiNetworkScoreCache) {
+ mScoreCache = wifiNetworkScoreCache;
+ mNetworkScoreManager = networkScoreManager;
+ mWifiConfigManager = wifiConfigManager;
+ mLocalLog = localLog;
+ mContentObserver = new ContentObserver(new Handler(looper)) {
+ @Override
+ public void onChange(boolean selfChange) {
+ mNetworkRecommendationsEnabled = frameworkFacade.getIntegerSetting(context,
+ Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0) == 1;
+ }
+ };
+ frameworkFacade.registerContentObserver(context,
+ Settings.Global.getUriFor(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED),
+ false /* notifyForDescendents */, mContentObserver);
+ mContentObserver.onChange(false /* unused */);
+ mLocalLog.log("ScoredNetworkEvaluator constructed. mNetworkRecommendationsEnabled: "
+ + mNetworkRecommendationsEnabled);
+ }
+
+ @Override
+ public void update(List<ScanDetail> scanDetails) {
+ if (mNetworkRecommendationsEnabled) {
+ updateNetworkScoreCache(scanDetails);
+ }
+ }
+
+ private void updateNetworkScoreCache(List<ScanDetail> scanDetails) {
+ ArrayList<NetworkKey> unscoredNetworks = new ArrayList<NetworkKey>();
+ for (int i = 0; i < scanDetails.size(); i++) {
+ ScanResult scanResult = scanDetails.get(i).getScanResult();
+ NetworkKey networkKey = NetworkKey.createFromScanResult(scanResult);
+ if (networkKey != null) {
+ // Is there a ScoredNetwork for this ScanResult? If not, request a score.
+ if (mScoreCache.getScoredNetwork(networkKey) == null) {
+ unscoredNetworks.add(networkKey);
+ }
+ }
+ }
+
+ // Kick the score manager if there are any unscored network.
+ if (!unscoredNetworks.isEmpty()) {
+ NetworkKey[] unscoredNetworkKeys =
+ unscoredNetworks.toArray(new NetworkKey[unscoredNetworks.size()]);
+ mNetworkScoreManager.requestScores(unscoredNetworkKeys);
+ }
+ }
+
+ @Override
+ public WifiConfiguration evaluateNetworks(List<ScanDetail> scanDetails,
+ WifiConfiguration currentNetwork, String currentBssid, boolean connected,
+ boolean untrustedNetworkAllowed,
+ List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks) {
+ if (!mNetworkRecommendationsEnabled) {
+ mLocalLog.log("Skipping evaluateNetworks; Network recommendations disabled.");
+ return null;
+ }
+
+ final ScoreTracker scoreTracker = new ScoreTracker();
+ for (int i = 0; i < scanDetails.size(); i++) {
+ ScanDetail scanDetail = scanDetails.get(i);
+ ScanResult scanResult = scanDetail.getScanResult();
+ if (scanResult == null) continue;
+ if (mWifiConfigManager.wasEphemeralNetworkDeleted(
+ ScanResultUtil.createQuotedSSID(scanResult.SSID))) {
+ debugLog("Ignoring disabled ephemeral SSID: " + scanResult.SSID);
+ continue;
+ }
+ final WifiConfiguration configuredNetwork =
+ mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail);
+ boolean untrustedScanResult = configuredNetwork == null || configuredNetwork.ephemeral;
+
+ if (!untrustedNetworkAllowed && untrustedScanResult) {
+ continue;
+ }
+
+ // Track scan results for open wifi networks
+ if (configuredNetwork == null) {
+ if (ScanResultUtil.isScanResultForOpenNetwork(scanResult)) {
+ scoreTracker.trackUntrustedCandidate(scanResult);
+ }
+ continue;
+ }
+
+ // Ignore non-ephemeral and non-externally scored networks
+ if (!configuredNetwork.ephemeral && !configuredNetwork.useExternalScores) {
+ continue;
+ }
+
+ // Ignore externally scored or ephemeral networks that have been disabled for selection
+ if (!configuredNetwork.getNetworkSelectionStatus().isNetworkEnabled()) {
+ debugLog("Ignoring disabled SSID: " + configuredNetwork.SSID);
+ continue;
+ }
+
+ // TODO(b/37485956): consider applying a boost for networks with only the same SSID
+ boolean isCurrentNetwork = currentNetwork != null
+ && currentNetwork.networkId == configuredNetwork.networkId
+ && TextUtils.equals(currentBssid, scanResult.BSSID);
+ if (configuredNetwork.ephemeral) {
+ scoreTracker.trackUntrustedCandidate(
+ scanResult, configuredNetwork, isCurrentNetwork);
+ } else {
+ scoreTracker.trackExternallyScoredCandidate(
+ scanResult, configuredNetwork, isCurrentNetwork);
+ }
+ if (connectableNetworks != null) {
+ connectableNetworks.add(Pair.create(scanDetail, configuredNetwork));
+ }
+ }
+
+ return scoreTracker.getCandidateConfiguration();
+ }
+
+ /** Used to track the network with the highest score. */
+ class ScoreTracker {
+ private static final int EXTERNAL_SCORED_NONE = 0;
+ private static final int EXTERNAL_SCORED_SAVED_NETWORK = 1;
+ private static final int EXTERNAL_SCORED_UNTRUSTED_NETWORK = 2;
+
+ private int mBestCandidateType = EXTERNAL_SCORED_NONE;
+ private int mHighScore = WifiNetworkScoreCache.INVALID_NETWORK_SCORE;
+ private WifiConfiguration mEphemeralConfig;
+ private WifiConfiguration mSavedConfig;
+ private ScanResult mScanResultCandidate;
+
+ /**
+ * Returns the available external network score or null if no score is available.
+ *
+ * @param scanResult The scan result of the network to score.
+ * @param isCurrentNetwork Flag which indicates whether this is the current network.
+ * @return A valid external score if one is available or NULL.
+ */
+ @Nullable
+ private Integer getNetworkScore(ScanResult scanResult, boolean isCurrentNetwork) {
+ if (mScoreCache.isScoredNetwork(scanResult)) {
+ int score = mScoreCache.getNetworkScore(scanResult, isCurrentNetwork);
+ if (DEBUG) {
+ mLocalLog.log(WifiNetworkSelector.toScanId(scanResult) + " has score: "
+ + score + " isCurrentNetwork network: " + isCurrentNetwork);
+ }
+ return score;
+ }
+ return null;
+ }
+
+ /** Track an untrusted {@link ScanResult}. */
+ void trackUntrustedCandidate(ScanResult scanResult) {
+ Integer score = getNetworkScore(scanResult, false /* isCurrentNetwork */);
+ if (score != null && score > mHighScore) {
+ mHighScore = score;
+ mScanResultCandidate = scanResult;
+ mBestCandidateType = EXTERNAL_SCORED_UNTRUSTED_NETWORK;
+ debugLog(WifiNetworkSelector.toScanId(scanResult)
+ + " becomes the new untrusted candidate.");
+ }
+ }
+
+ /**
+ * Track an untrusted {@link ScanResult} that already has a corresponding
+ * ephemeral {@link WifiConfiguration}.
+ */
+ void trackUntrustedCandidate(
+ ScanResult scanResult, WifiConfiguration config, boolean isCurrentNetwork) {
+ Integer score = getNetworkScore(scanResult, isCurrentNetwork);
+ if (score != null && score > mHighScore) {
+ mHighScore = score;
+ mScanResultCandidate = scanResult;
+ mBestCandidateType = EXTERNAL_SCORED_UNTRUSTED_NETWORK;
+ mEphemeralConfig = config;
+ mWifiConfigManager.setNetworkCandidateScanResult(config.networkId, scanResult, 0);
+ debugLog(WifiNetworkSelector.toScanId(scanResult)
+ + " becomes the new untrusted candidate.");
+ }
+ }
+
+ /** Tracks a saved network that has been marked with useExternalScores */
+ void trackExternallyScoredCandidate(
+ ScanResult scanResult, WifiConfiguration config, boolean isCurrentNetwork) {
+ // Always take the highest score. If there's a tie and an untrusted network is currently
+ // the best then pick the saved network.
+ Integer score = getNetworkScore(scanResult, isCurrentNetwork);
+ if (score != null
+ && (score > mHighScore
+ || (mBestCandidateType == EXTERNAL_SCORED_UNTRUSTED_NETWORK
+ && score == mHighScore))) {
+ mHighScore = score;
+ mSavedConfig = config;
+ mScanResultCandidate = scanResult;
+ mBestCandidateType = EXTERNAL_SCORED_SAVED_NETWORK;
+ mWifiConfigManager.setNetworkCandidateScanResult(config.networkId, scanResult, 0);
+ debugLog(WifiNetworkSelector.toScanId(scanResult)
+ + " becomes the new externally scored saved network candidate.");
+ }
+ }
+
+ /** Returns the best candidate network tracked by this {@link ScoreTracker}. */
+ @Nullable
+ WifiConfiguration getCandidateConfiguration() {
+ int candidateNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+ switch (mBestCandidateType) {
+ case ScoreTracker.EXTERNAL_SCORED_UNTRUSTED_NETWORK:
+ if (mEphemeralConfig != null) {
+ candidateNetworkId = mEphemeralConfig.networkId;
+ mLocalLog.log(String.format("existing ephemeral candidate %s network ID:%d"
+ + ", meteredHint=%b",
+ WifiNetworkSelector.toScanId(mScanResultCandidate),
+ candidateNetworkId,
+ mEphemeralConfig.meteredHint));
+ break;
+ }
+
+ mEphemeralConfig =
+ ScanResultUtil.createNetworkFromScanResult(mScanResultCandidate);
+ // Mark this config as ephemeral so it isn't persisted.
+ mEphemeralConfig.ephemeral = true;
+ mEphemeralConfig.meteredHint = mScoreCache.getMeteredHint(mScanResultCandidate);
+ NetworkUpdateResult result =
+ mWifiConfigManager.addOrUpdateNetwork(mEphemeralConfig,
+ Process.WIFI_UID);
+ if (!result.isSuccess()) {
+ mLocalLog.log("Failed to add ephemeral network");
+ break;
+ }
+ if (!mWifiConfigManager.updateNetworkSelectionStatus(result.getNetworkId(),
+ WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE)) {
+ mLocalLog.log("Failed to make ephemeral network selectable");
+ break;
+ }
+ candidateNetworkId = result.getNetworkId();
+ mWifiConfigManager.setNetworkCandidateScanResult(candidateNetworkId,
+ mScanResultCandidate, 0);
+ mLocalLog.log(String.format("new ephemeral candidate %s network ID:%d, "
+ + "meteredHint=%b",
+ WifiNetworkSelector.toScanId(mScanResultCandidate),
+ candidateNetworkId,
+ mEphemeralConfig.meteredHint));
+ break;
+ case ScoreTracker.EXTERNAL_SCORED_SAVED_NETWORK:
+ candidateNetworkId = mSavedConfig.networkId;
+ mLocalLog.log(String.format("new saved network candidate %s network ID:%d",
+ WifiNetworkSelector.toScanId(mScanResultCandidate),
+ candidateNetworkId));
+ break;
+ case ScoreTracker.EXTERNAL_SCORED_NONE:
+ default:
+ mLocalLog.log("ScoredNetworkEvaluator did not see any good candidates.");
+ break;
+ }
+ return mWifiConfigManager.getConfiguredNetwork(candidateNetworkId);
+ }
+ }
+
+ private void debugLog(String msg) {
+ if (DEBUG) {
+ mLocalLog.log(msg);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return TAG;
+ }
+}
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index bd00b3f5b..010c6b294 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -124,7 +124,7 @@ public class WifiConnectivityManager {
// Saved network evaluator priority
private static final int SAVED_NETWORK_EVALUATOR_PRIORITY = 1;
private static final int PASSPOINT_NETWORK_EVALUATOR_PRIORITY = 2;
- private static final int RECOMMENDED_NETWORK_EVALUATOR_PRIORITY = 3;
+ private static final int SCORED_NETWORK_EVALUATOR_PRIORITY = 3;
// Log tag for this class
private static final String TAG = "WifiConnectivityManager";
@@ -512,7 +512,7 @@ public class WifiConnectivityManager {
Looper looper, Clock clock, LocalLog localLog, boolean enable,
FrameworkFacade frameworkFacade,
SavedNetworkEvaluator savedNetworkEvaluator,
- RecommendedNetworkEvaluator recommendedNetworkEvaluator,
+ ScoredNetworkEvaluator scoredNetworkEvaluator,
PasspointNetworkEvaluator passpointNetworkEvaluator) {
mStateMachine = stateMachine;
mScanner = scanner;
@@ -569,8 +569,8 @@ public class WifiConnectivityManager {
mNetworkSelector.registerNetworkEvaluator(passpointNetworkEvaluator,
PASSPOINT_NETWORK_EVALUATOR_PRIORITY);
}
- mNetworkSelector.registerNetworkEvaluator(recommendedNetworkEvaluator,
- RECOMMENDED_NETWORK_EVALUATOR_PRIORITY);
+ mNetworkSelector.registerNetworkEvaluator(scoredNetworkEvaluator,
+ SCORED_NETWORK_EVALUATOR_PRIORITY);
// Register for all single scan results
mScanner.registerScanListener(mAllSingleScanListener);
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 799f9d5a0..99cf7a9ad 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -18,12 +18,14 @@ package com.android.server.wifi;
import android.app.ActivityManager;
import android.content.Context;
+import android.net.NetworkKey;
import android.net.NetworkScoreManager;
import android.net.wifi.IApInterface;
import android.net.wifi.IWifiScanner;
import android.net.wifi.IWificond;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiNetworkScoreCache;
import android.net.wifi.WifiScanner;
import android.os.BatteryStats;
import android.os.HandlerThread;
@@ -106,7 +108,8 @@ public class WifiInjector {
private final WifiNetworkSelector mWifiNetworkSelector;
private final SavedNetworkEvaluator mSavedNetworkEvaluator;
private final PasspointNetworkEvaluator mPasspointNetworkEvaluator;
- private final RecommendedNetworkEvaluator mRecommendedNetworkEvaluator;
+ private final ScoredNetworkEvaluator mScoredNetworkEvaluator;
+ private final WifiNetworkScoreCache mWifiNetworkScoreCache;
private final NetworkScoreManager mNetworkScoreManager;
private WifiScanner mWifiScanner;
private final WifiPermissionsWrapper mWifiPermissionsWrapper;
@@ -140,6 +143,9 @@ public class WifiInjector {
mSettingsStore = new WifiSettingsStore(mContext);
mWifiPermissionsWrapper = new WifiPermissionsWrapper(mContext);
mNetworkScoreManager = mContext.getSystemService(NetworkScoreManager.class);
+ mWifiNetworkScoreCache = new WifiNetworkScoreCache(mContext);
+ mNetworkScoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
+ mWifiNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_NONE);
mWifiPermissionsUtil = new WifiPermissionsUtil(mWifiPermissionsWrapper, mContext,
mSettingsStore, UserManager.get(mContext), mNetworkScoreManager, this);
mBatteryStats = IBatteryStats.Stub.asInterface(mFrameworkFacade.getService(
@@ -198,11 +204,11 @@ public class WifiInjector {
mConnectivityLocalLog = new LocalLog(ActivityManager.isLowRamDeviceStatic() ? 256 : 512);
mWifiNetworkSelector = new WifiNetworkSelector(mContext, mWifiConfigManager, mClock,
mConnectivityLocalLog);
- mSavedNetworkEvaluator = new SavedNetworkEvaluator(mContext, mWifiConfigManager, mClock,
- mConnectivityLocalLog, mWifiConnectivityHelper);
- mRecommendedNetworkEvaluator = new RecommendedNetworkEvaluator(context,
- context.getContentResolver(), wifiStateMachineLooper, mFrameworkFacade,
- mNetworkScoreManager, mWifiConfigManager, mConnectivityLocalLog);
+ mSavedNetworkEvaluator = new SavedNetworkEvaluator(mContext,
+ mWifiConfigManager, mClock, mConnectivityLocalLog, mWifiConnectivityHelper);
+ mScoredNetworkEvaluator = new ScoredNetworkEvaluator(context, wifiStateMachineLooper,
+ mFrameworkFacade, mNetworkScoreManager, mWifiConfigManager, mConnectivityLocalLog,
+ mWifiNetworkScoreCache);
mSimAccessor = new SIMAccessor(mContext);
mPasspointManager = new PasspointManager(mContext, mWifiNative, mWifiKeyStore, mClock,
mSimAccessor, new PasspointObjectFactory(), mWifiConfigManager, mWifiConfigStore);
@@ -413,7 +419,7 @@ public class WifiInjector {
mWifiConfigManager, wifiInfo, mWifiNetworkSelector, mWifiConnectivityHelper,
mWifiLastResortWatchdog, mWifiMetrics, mWifiStateMachineHandlerThread.getLooper(),
mClock, mConnectivityLocalLog, hasConnectionRequests, mFrameworkFacade,
- mSavedNetworkEvaluator, mRecommendedNetworkEvaluator, mPasspointNetworkEvaluator);
+ mSavedNetworkEvaluator, mScoredNetworkEvaluator, mPasspointNetworkEvaluator);
}
public WifiPermissionsUtil getWifiPermissionsUtil() {