1 /* 2 * Copyright (C) 2014 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.Manifest.permission; 20 import android.content.Context; 21 import android.net.INetworkScoreCache; 22 import android.net.NetworkKey; 23 import android.net.ScoredNetwork; 24 import android.net.wifi.ScanResult; 25 import android.net.wifi.WifiManager; 26 import android.util.Log; 27 28 import java.io.FileDescriptor; 29 import java.io.PrintWriter; 30 import java.util.HashMap; 31 import java.util.List; 32 import java.util.Map; 33 34 public class WifiNetworkScoreCache extends INetworkScoreCache.Stub 35 { 36 37 // A Network scorer returns a score in the range [-127, +127] 38 public static int INVALID_NETWORK_SCORE = 100000; 39 40 private static String TAG = "WifiNetworkScoreCache"; 41 private boolean DBG = true; 42 private final Context mContext; 43 44 // The key is of the form "<ssid>"<bssid> 45 // TODO: What about SSIDs that can't be encoded as UTF-8? 46 private final Map<String, ScoredNetwork> mNetworkCache; 47 48 public WifiNetworkScoreCache(Context context) { 49 mContext = context; 50 mNetworkCache = new HashMap<String, ScoredNetwork>(); 51 } 52 53 @Override public final void updateScores(List<android.net.ScoredNetwork> networks) { 54 if (networks == null) { 55 return; 56 } 57 Log.e(TAG, "updateScores list size=" + networks.size()); 58 59 synchronized(mNetworkCache) { 60 for (ScoredNetwork network : networks) { 61 String networkKey = buildNetworkKey(network); 62 if (networkKey == null) continue; 63 mNetworkCache.put(networkKey, network); 64 } 65 } 66 } 67 68 @Override public final void clearScores() { 69 synchronized (mNetworkCache) { 70 mNetworkCache.clear(); 71 } 72 } 73 74 public boolean isScoredNetwork(ScanResult result) { 75 String key = buildNetworkKey(result); 76 if (key == null) return false; 77 78 //find it 79 synchronized(mNetworkCache) { 80 ScoredNetwork network = mNetworkCache.get(key); 81 if (network != null) { 82 return true; 83 } 84 } 85 return false; 86 } 87 88 public int getNetworkScore(ScanResult result) { 89 90 int score = INVALID_NETWORK_SCORE; 91 92 String key = buildNetworkKey(result); 93 if (key == null) return score; 94 95 //find it 96 synchronized(mNetworkCache) { 97 ScoredNetwork network = mNetworkCache.get(key); 98 if (network != null && network.rssiCurve != null) { 99 score = network.rssiCurve.lookupScore(result.level); 100 if (DBG) { 101 Log.e(TAG, "getNetworkScore found scored network " + key 102 + " score " + Integer.toString(score) 103 + " RSSI " + result.level); 104 } 105 } 106 } 107 return score; 108 } 109 110 public int getNetworkScore(ScanResult result, int rssiBoost) { 111 112 int score = INVALID_NETWORK_SCORE; 113 114 String key = buildNetworkKey(result); 115 if (key == null) return score; 116 117 //find it 118 synchronized(mNetworkCache) { 119 ScoredNetwork network = mNetworkCache.get(key); 120 if (network != null && network.rssiCurve != null) { 121 score = network.rssiCurve.lookupScore(result.level + rssiBoost); 122 if (DBG) { 123 Log.e(TAG, "getNetworkScore found scored network " + key 124 + " score " + Integer.toString(score) 125 + " RSSI " + result.level 126 + " boost " + rssiBoost); 127 } 128 } 129 } 130 return score; 131 } 132 133 private String buildNetworkKey(ScoredNetwork network) { 134 if (network.networkKey == null) return null; 135 if (network.networkKey.wifiKey == null) return null; 136 if (network.networkKey.type == NetworkKey.TYPE_WIFI) { 137 String key = network.networkKey.wifiKey.ssid; 138 if (key == null) return null; 139 if (network.networkKey.wifiKey.bssid != null) { 140 key = key + network.networkKey.wifiKey.bssid; 141 } 142 return key; 143 } 144 return null; 145 } 146 147 private String buildNetworkKey(ScanResult result) { 148 if (result.SSID == null) { 149 return null; 150 } 151 StringBuilder key = new StringBuilder("\""); 152 key.append(result.SSID); 153 key.append("\""); 154 if (result.BSSID != null) { 155 key.append(result.BSSID); 156 } 157 return key.toString(); 158 } 159 160 @Override protected final void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 161 mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG); 162 writer.println("WifiNetworkScoreCache"); 163 writer.println(" All score curves:"); 164 for (Map.Entry<String, ScoredNetwork> entry : mNetworkCache.entrySet()) { 165 writer.println(" " + entry.getKey() + ": " + entry.getValue().rssiCurve); 166 } 167 writer.println(" Current network scores:"); 168 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 169 for (ScanResult scanResult : wifiManager.getScanResults()) { 170 writer.println(" " + buildNetworkKey(scanResult) + ": " + getNetworkScore(scanResult)); 171 } 172 } 173 174 } 175