1 package com.android.server.wifi; 2 3 import android.content.pm.UserInfo; 4 import android.net.wifi.WifiConfiguration; 5 import android.os.UserHandle; 6 import android.os.UserManager; 7 8 import java.util.ArrayList; 9 import java.util.Collection; 10 import java.util.HashMap; 11 import java.util.HashSet; 12 import java.util.Iterator; 13 import java.util.List; 14 import java.util.Map; 15 import java.util.Set; 16 17 public class ConfigurationMap { 18 private final Map<Integer, WifiConfiguration> mPerID = new HashMap<>(); 19 private final Map<Integer, WifiConfiguration> mPerConfigKey = new HashMap<>(); 20 21 private final Map<Integer, WifiConfiguration> mPerIDForCurrentUser = new HashMap<>(); 22 private final Map<String, WifiConfiguration> mPerFQDNForCurrentUser = new HashMap<>(); 23 /** 24 * List of all hidden networks in the current user's configuration. 25 * Use this list as a param for directed scanning . 26 */ 27 private final Set<Integer> mHiddenNetworkIdsForCurrentUser = new HashSet<>(); 28 29 private final UserManager mUserManager; 30 31 private int mCurrentUserId = UserHandle.USER_SYSTEM; 32 ConfigurationMap(UserManager userManager)33 ConfigurationMap(UserManager userManager) { 34 mUserManager = userManager; 35 } 36 37 // RW methods: put(WifiConfiguration config)38 public WifiConfiguration put(WifiConfiguration config) { 39 final WifiConfiguration current = mPerID.put(config.networkId, config); 40 mPerConfigKey.put(config.configKey().hashCode(), config); // This is ridiculous... 41 if (WifiConfigurationUtil.isVisibleToAnyProfile(config, 42 mUserManager.getProfiles(mCurrentUserId))) { 43 mPerIDForCurrentUser.put(config.networkId, config); 44 if (config.FQDN != null && config.FQDN.length() > 0) { 45 mPerFQDNForCurrentUser.put(config.FQDN, config); 46 } 47 if (config.hiddenSSID) { 48 mHiddenNetworkIdsForCurrentUser.add(config.networkId); 49 } 50 } 51 return current; 52 } 53 remove(int netID)54 public WifiConfiguration remove(int netID) { 55 WifiConfiguration config = mPerID.remove(netID); 56 if (config == null) { 57 return null; 58 } 59 mPerConfigKey.remove(config.configKey().hashCode()); 60 61 mPerIDForCurrentUser.remove(netID); 62 Iterator<Map.Entry<String, WifiConfiguration>> entries = 63 mPerFQDNForCurrentUser.entrySet().iterator(); 64 while (entries.hasNext()) { 65 if (entries.next().getValue().networkId == netID) { 66 entries.remove(); 67 break; 68 } 69 } 70 mHiddenNetworkIdsForCurrentUser.remove(netID); 71 return config; 72 } 73 clear()74 public void clear() { 75 mPerID.clear(); 76 mPerConfigKey.clear(); 77 mPerIDForCurrentUser.clear(); 78 mPerFQDNForCurrentUser.clear(); 79 mHiddenNetworkIdsForCurrentUser.clear(); 80 } 81 82 /** 83 * Handles the switch to a different foreground user: 84 * - Hides private network configurations belonging to the previous foreground user 85 * - Reveals private network configurations belonging to the new foreground user 86 * 87 * @param userId the id of the new foreground user 88 * @return a list of {@link WifiConfiguration}s that became hidden because of the user switch 89 */ handleUserSwitch(int userId)90 public List<WifiConfiguration> handleUserSwitch(int userId) { 91 mPerIDForCurrentUser.clear(); 92 mPerFQDNForCurrentUser.clear(); 93 mHiddenNetworkIdsForCurrentUser.clear(); 94 95 final List<UserInfo> previousUserProfiles = mUserManager.getProfiles(mCurrentUserId); 96 mCurrentUserId = userId; 97 final List<UserInfo> currentUserProfiles = mUserManager.getProfiles(mCurrentUserId); 98 99 final List<WifiConfiguration> hiddenConfigurations = new ArrayList<>(); 100 for (Map.Entry<Integer, WifiConfiguration> entry : mPerID.entrySet()) { 101 final WifiConfiguration config = entry.getValue(); 102 if (WifiConfigurationUtil.isVisibleToAnyProfile(config, currentUserProfiles)) { 103 mPerIDForCurrentUser.put(entry.getKey(), config); 104 if (config.FQDN != null && config.FQDN.length() > 0) { 105 mPerFQDNForCurrentUser.put(config.FQDN, config); 106 } 107 if (config.hiddenSSID) { 108 mHiddenNetworkIdsForCurrentUser.add(config.networkId); 109 } 110 } else if (WifiConfigurationUtil.isVisibleToAnyProfile(config, previousUserProfiles)) { 111 hiddenConfigurations.add(config); 112 } 113 } 114 115 return hiddenConfigurations; 116 } 117 118 // RO methods: getForAllUsers(int netid)119 public WifiConfiguration getForAllUsers(int netid) { 120 return mPerID.get(netid); 121 } 122 getForCurrentUser(int netid)123 public WifiConfiguration getForCurrentUser(int netid) { 124 return mPerIDForCurrentUser.get(netid); 125 } 126 sizeForAllUsers()127 public int sizeForAllUsers() { 128 return mPerID.size(); 129 } 130 sizeForCurrentUser()131 public int sizeForCurrentUser() { 132 return mPerIDForCurrentUser.size(); 133 } 134 getByFQDNForCurrentUser(String fqdn)135 public WifiConfiguration getByFQDNForCurrentUser(String fqdn) { 136 return mPerFQDNForCurrentUser.get(fqdn); 137 } 138 getByConfigKeyForCurrentUser(String key)139 public WifiConfiguration getByConfigKeyForCurrentUser(String key) { 140 if (key == null) { 141 return null; 142 } 143 for (WifiConfiguration config : mPerIDForCurrentUser.values()) { 144 if (config.configKey().equals(key)) { 145 return config; 146 } 147 } 148 return null; 149 } 150 getByConfigKeyIDForAllUsers(int id)151 public WifiConfiguration getByConfigKeyIDForAllUsers(int id) { 152 return mPerConfigKey.get(id); 153 } 154 getEnabledNetworksForCurrentUser()155 public Collection<WifiConfiguration> getEnabledNetworksForCurrentUser() { 156 List<WifiConfiguration> list = new ArrayList<>(); 157 for (WifiConfiguration config : mPerIDForCurrentUser.values()) { 158 if (config.status != WifiConfiguration.Status.DISABLED) { 159 list.add(config); 160 } 161 } 162 return list; 163 } 164 getEphemeralForCurrentUser(String ssid)165 public WifiConfiguration getEphemeralForCurrentUser(String ssid) { 166 for (WifiConfiguration config : mPerIDForCurrentUser.values()) { 167 if (ssid.equals(config.SSID) && config.ephemeral) { 168 return config; 169 } 170 } 171 return null; 172 } 173 valuesForAllUsers()174 public Collection<WifiConfiguration> valuesForAllUsers() { 175 return mPerID.values(); 176 } 177 valuesForCurrentUser()178 public Collection<WifiConfiguration> valuesForCurrentUser() { 179 return mPerIDForCurrentUser.values(); 180 } 181 getHiddenNetworkIdsForCurrentUser()182 public Set<Integer> getHiddenNetworkIdsForCurrentUser() { 183 return mHiddenNetworkIdsForCurrentUser; 184 } 185 } 186