1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi; 18 19 import android.net.wifi.ScanResult; 20 import android.net.wifi.WifiConfiguration; 21 import android.os.UserHandle; 22 import android.text.TextUtils; 23 24 import androidx.annotation.NonNull; 25 26 import com.android.server.wifi.util.WifiPermissionsUtil; 27 28 import java.io.FileDescriptor; 29 import java.io.PrintWriter; 30 import java.util.Collection; 31 import java.util.HashMap; 32 import java.util.Iterator; 33 import java.util.Map; 34 35 public class ConfigurationMap { 36 private final Map<Integer, WifiConfiguration> mPerID = new HashMap<>(); 37 38 private final Map<Integer, WifiConfiguration> mPerIDForCurrentUser = new HashMap<>(); 39 private final Map<ScanResultMatchInfo, WifiConfiguration> 40 mScanResultMatchInfoMapForCurrentUser = new HashMap<>(); 41 42 @NonNull private final WifiPermissionsUtil mWifiPermissionsUtil; 43 44 private int mCurrentUserId = UserHandle.SYSTEM.getIdentifier(); 45 ConfigurationMap(@onNull WifiPermissionsUtil wifiPermissionsUtil)46 ConfigurationMap(@NonNull WifiPermissionsUtil wifiPermissionsUtil) { 47 mWifiPermissionsUtil = wifiPermissionsUtil; 48 } 49 50 /** Dump internal state for debugging. */ dump(FileDescriptor fd, PrintWriter pw, String[] args)51 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 52 pw.println("mPerId=" + mPerID); 53 pw.println("mPerIDForCurrentUser=" + mPerIDForCurrentUser); 54 pw.println("mScanResultMatchInfoMapForCurrentUser=" 55 + mScanResultMatchInfoMapForCurrentUser); 56 pw.println("mCurrentUserId=" + mCurrentUserId); 57 } 58 59 // RW methods: put(WifiConfiguration config)60 public WifiConfiguration put(WifiConfiguration config) { 61 final WifiConfiguration current = mPerID.put(config.networkId, config); 62 if (config.shared || mWifiPermissionsUtil 63 .doesUidBelongToCurrentUserOrDeviceOwner(config.creatorUid)) { 64 mPerIDForCurrentUser.put(config.networkId, config); 65 // TODO (b/142035508): Add a more generic fix. This cache should only hold saved 66 // networks. 67 if (!config.fromWifiNetworkSpecifier && !config.fromWifiNetworkSuggestion 68 && !config.isPasspoint()) { 69 mScanResultMatchInfoMapForCurrentUser.put( 70 ScanResultMatchInfo.fromWifiConfiguration(config), config); 71 } 72 } 73 return current; 74 } 75 remove(int netID)76 public WifiConfiguration remove(int netID) { 77 WifiConfiguration config = mPerID.remove(netID); 78 if (config == null) { 79 return null; 80 } 81 82 mPerIDForCurrentUser.remove(netID); 83 84 Iterator<Map.Entry<ScanResultMatchInfo, WifiConfiguration>> scanResultMatchInfoEntries = 85 mScanResultMatchInfoMapForCurrentUser.entrySet().iterator(); 86 while (scanResultMatchInfoEntries.hasNext()) { 87 if (scanResultMatchInfoEntries.next().getValue().networkId == netID) { 88 scanResultMatchInfoEntries.remove(); 89 break; 90 } 91 } 92 return config; 93 } 94 clear()95 public void clear() { 96 mPerID.clear(); 97 mPerIDForCurrentUser.clear(); 98 mScanResultMatchInfoMapForCurrentUser.clear(); 99 } 100 101 /** 102 * Sets the new foreground user ID. 103 * 104 * @param userId the id of the new foreground user 105 */ setNewUser(int userId)106 public void setNewUser(int userId) { 107 mCurrentUserId = userId; 108 } 109 110 // RO methods: getForAllUsers(int netid)111 public WifiConfiguration getForAllUsers(int netid) { 112 return mPerID.get(netid); 113 } 114 getForCurrentUser(int netid)115 public WifiConfiguration getForCurrentUser(int netid) { 116 return mPerIDForCurrentUser.get(netid); 117 } 118 sizeForAllUsers()119 public int sizeForAllUsers() { 120 return mPerID.size(); 121 } 122 sizeForCurrentUser()123 public int sizeForCurrentUser() { 124 return mPerIDForCurrentUser.size(); 125 } 126 getByConfigKeyForCurrentUser(String key)127 public WifiConfiguration getByConfigKeyForCurrentUser(String key) { 128 if (key == null) { 129 return null; 130 } 131 for (WifiConfiguration config : mPerIDForCurrentUser.values()) { 132 if (TextUtils.equals(config.getProfileKey(), key)) { 133 return config; 134 } 135 } 136 return null; 137 } 138 139 /** 140 * Retrieves the |WifiConfiguration| object matching the provided |scanResult| from the internal 141 * map. 142 * Essentially checks if network config and scan result have the same SSID and encryption type. 143 */ getByScanResultForCurrentUser(ScanResult scanResult)144 public WifiConfiguration getByScanResultForCurrentUser(ScanResult scanResult) { 145 return mScanResultMatchInfoMapForCurrentUser.get( 146 ScanResultMatchInfo.fromScanResult(scanResult)); 147 } 148 valuesForAllUsers()149 public Collection<WifiConfiguration> valuesForAllUsers() { 150 return mPerID.values(); 151 } 152 valuesForCurrentUser()153 public Collection<WifiConfiguration> valuesForCurrentUser() { 154 return mPerIDForCurrentUser.values(); 155 } 156 } 157