diff options
Diffstat (limited to 'service')
4 files changed, 108 insertions, 0 deletions
diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java index a971dcd56..9a84cee44 100644 --- a/service/java/com/android/server/wifi/WifiAutoJoinController.java +++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java @@ -1489,6 +1489,11 @@ public class WifiAutoJoinController { !isOpenNetwork(result)) { continue; } + if (mWifiConfigStore.mDeletedEphemeralSSIDs.contains + ("\"" + result.SSID + "\"")) { + // SSID had been Forgotten by user, then don't score it + continue; + } if ((nowMs - result.seen) < mScanResultAutoJoinAge) { // Increment usage count for the network mWifiConnectionStatistics.incrementOrAddUntrusted(result.SSID, 0, 1); diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index c7b8ab301..1aa830d4e 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -158,6 +158,15 @@ public class WifiConfigStore extends IpConfigStore { */ private Set<Long> mDeletedSSIDs = new HashSet<Long>(); + /** + * Framework keeps a list of ephemeral SSIDs that where deleted by user, + * so as, framework knows not to autojoin again those SSIDs based on scorer input. + * The list is never cleared up. + * + * The SSIDs are encoded in a String as per definition of WifiConfiguration.SSID field. + */ + public Set<String> mDeletedEphemeralSSIDs = new HashSet<String>(); + /* Tracks the highest priority of configured networks */ private int mLastPriority = -1; @@ -209,6 +218,7 @@ public class WifiConfigStore extends IpConfigStore { private static final String EPHEMERAL_KEY = "EPHEMERAL: "; private static final String NUM_ASSOCIATION_KEY = "NUM_ASSOCIATION: "; private static final String DELETED_CRC32_KEY = "DELETED_CRC32: "; + private static final String DELETED_EPHEMERAL_KEY = "DELETED_EPHEMERAL: "; private static final String JOIN_ATTEMPT_BOOST_KEY = "JOIN_ATTEMPT_BOOST: "; private static final String THRESHOLD_INITIAL_AUTO_JOIN_ATTEMPT_RSSI_MIN_5G_KEY @@ -830,6 +840,15 @@ public class WifiConfigStore extends IpConfigStore { + " Uid=" + Integer.toString(config.creatorUid) + "/" + Integer.toString(config.lastUpdateUid)); } + + if (mDeletedEphemeralSSIDs.remove(config.SSID)) { + if (VDBG) { + loge("WifiConfigStore: removed from ephemeral blacklist: " + config.SSID); + } + // NOTE: This will be flushed to disk as part of the addOrUpdateNetworkNative call + // below, since we're creating/modifying a config. + } + boolean newNetwork = (config.networkId == INVALID_NETWORK_ID); NetworkUpdateResult result = addOrUpdateNetworkNative(config, uid); int netId = result.getNetworkId(); @@ -947,6 +966,42 @@ public class WifiConfigStore extends IpConfigStore { } } + + /** + * Disable an ephemeral SSID for the purpose of auto-joining thru scored. + * This SSID will never be scored anymore. + * The only way to "un-disable it" is if the user create a network for that SSID and then + * forget it. + * + * @param SSID caller must ensure that the SSID passed thru this API match + * the WifiConfiguration.SSID rules, and thus be surrounded by quotes. + * @return the {@link WifiConfiguration} corresponding to this SSID, if any, so that we can + * disconnect if this is the current network. + */ + WifiConfiguration disableEphemeralNetwork(String SSID) { + if (SSID == null) { + return null; + } + + WifiConfiguration foundConfig = null; + + mDeletedEphemeralSSIDs.add(SSID); + loge("Forget ephemeral SSID " + SSID + " num=" + mDeletedEphemeralSSIDs.size()); + + for (WifiConfiguration config : mConfiguredNetworks.values()) { + if (SSID.equals(config.SSID) && config.ephemeral) { + loge("Found ephemeral config in disableEphemeralNetwork: " + config.networkId); + foundConfig = config; + } + } + + // Force a write, because the mDeletedEphemeralSSIDs list has changed even though the + // configurations may not have. + writeKnownNetworkHistory(true); + + return foundConfig; + } + /** * Forget the specified network and save config * @@ -1719,6 +1774,13 @@ public class WifiConfigStore extends IpConfigStore { out.writeUTF(SEPARATOR_KEY); } } + if (mDeletedEphemeralSSIDs != null && mDeletedEphemeralSSIDs.size() > 0) { + for (String ssid : mDeletedEphemeralSSIDs) { + out.writeUTF(DELETED_EPHEMERAL_KEY); + out.writeUTF(ssid); + out.writeUTF(SEPARATOR_KEY); + } + } } }); } @@ -2049,6 +2111,13 @@ public class WifiConfigStore extends IpConfigStore { Long c = Long.parseLong(crc); mDeletedSSIDs.add(c); } + if (key.startsWith(DELETED_EPHEMERAL_KEY)) { + String s = key.replace(DELETED_EPHEMERAL_KEY, ""); + if (!TextUtils.isEmpty(s)) { + s = s.replace(SEPARATOR_KEY, ""); + mDeletedEphemeralSSIDs.add(s); + } + } } } } diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index bcaab925a..11d0259e1 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -1302,6 +1302,14 @@ public final class WifiServiceImpl extends IWifiManager.Stub { return new Messenger(mClientHandler); } + /** + * Disable an ephemeral network, i.e. network that is created thru a WiFi Scorer + */ + public void disableEphemeralNetwork(String SSID) { + enforceAccessPermission(); + enforceChangePermission(); + mWifiStateMachine.disableEphemeralNetwork(SSID); + } /** * Get the IP and proxy configuration file diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 09920f5d1..220ca74cc 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -578,6 +578,9 @@ public class WifiStateMachine extends StateMachine { /* Disconnecting state watchdog */ static final int CMD_DISCONNECTING_WATCHDOG_TIMER = BASE + 96; + /* Disable an ephemeral network */ + static final int CMD_DISABLE_EPHEMERAL_NETWORK = BASE + 98; + /* P2p commands */ /* We are ok with no response here since we wont do much with it anyway */ public static final int CMD_ENABLE_P2P = BASE + 131; @@ -2019,6 +2022,12 @@ public class WifiStateMachine extends StateMachine { } } + public void disableEphemeralNetwork(String SSID) { + if (SSID != null) { + sendMessage(CMD_DISABLE_EPHEMERAL_NETWORK, SSID); + } + } + /** * Get unsynchronized pointer to scan result list * Can be called only from AutoJoinController which runs in the WifiStateMachine context @@ -4713,6 +4722,7 @@ public class WifiStateMachine extends StateMachine { case CMD_UNWANTED_NETWORK: case CMD_DISCONNECTING_WATCHDOG_TIMER: case CMD_ROAM_WATCHDOG_TIMER: + case CMD_DISABLE_EPHEMERAL_NETWORK: messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; break; case DhcpStateMachine.CMD_ON_QUIT: @@ -5691,6 +5701,9 @@ public class WifiStateMachine extends StateMachine { case CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER: s = "CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER"; break; + case CMD_DISABLE_EPHEMERAL_NETWORK: + s = "CMD_DISABLE_EPHEMERAL_NETWORK"; + break; case CMD_START_DRIVER: s = "CMD_START_DRIVER"; break; @@ -6025,6 +6038,10 @@ public class WifiStateMachine extends StateMachine { WifiConfiguration config = mWifiConfigStore.getWifiConfiguration(mLastNetworkId); if (config != null) { config.lastDisconnected = System.currentTimeMillis(); + if (config.ephemeral) { + // Remove ephemeral WifiConfigurations from file + mWifiConfigStore.forgetNetwork(mLastNetworkId); + } } } } @@ -6240,6 +6257,15 @@ public class WifiStateMachine extends StateMachine { WifiManager.ERROR); } break; + case CMD_DISABLE_EPHEMERAL_NETWORK: + config = mWifiConfigStore.disableEphemeralNetwork((String)message.obj); + if (config != null) { + if (config.networkId == mLastNetworkId) { + // Disconnect and let autojoin reselect a new network + sendMessage(CMD_DISCONNECT); + } + } + break; case CMD_BLACKLIST_NETWORK: mWifiNative.addToBlacklist((String) message.obj); break; |