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