Home | History | Annotate | Download | only in wifi
      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