Home | History | Annotate | Download | only in wifi
      1 /*
      2  * Copyright (C) 2010 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.settings.wifi;
     18 
     19 import com.android.settings.R;
     20 
     21 import android.content.Context;
     22 import android.net.NetworkInfo.DetailedState;
     23 import android.net.wifi.WifiConfiguration;
     24 import android.net.wifi.WifiConfiguration.KeyMgmt;
     25 import android.net.wifi.WifiInfo;
     26 import android.net.wifi.WifiManager;
     27 import android.net.wifi.ScanResult;
     28 import android.preference.Preference;
     29 import android.text.TextUtils;
     30 import android.view.View;
     31 import android.widget.ImageView;
     32 
     33 class AccessPoint extends Preference {
     34     private static final int[] STATE_SECURED = {R.attr.state_encrypted};
     35     private static final int[] STATE_NONE = {};
     36 
     37     static final int SECURITY_NONE = 0;
     38     static final int SECURITY_WEP = 1;
     39     static final int SECURITY_PSK = 2;
     40     static final int SECURITY_EAP = 3;
     41 
     42     final String ssid;
     43     final int security;
     44     final int networkId;
     45 
     46     private WifiConfiguration mConfig;
     47     private int mRssi;
     48     private WifiInfo mInfo;
     49     private DetailedState mState;
     50     private ImageView mSignal;
     51 
     52     static int getSecurity(WifiConfiguration config) {
     53         if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
     54             return SECURITY_PSK;
     55         }
     56         if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
     57                 config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
     58             return SECURITY_EAP;
     59         }
     60         return (config.wepKeys[0] != null) ? SECURITY_WEP : SECURITY_NONE;
     61     }
     62 
     63     private static int getSecurity(ScanResult result) {
     64         if (result.capabilities.contains("WEP")) {
     65             return SECURITY_WEP;
     66         } else if (result.capabilities.contains("PSK")) {
     67             return SECURITY_PSK;
     68         } else if (result.capabilities.contains("EAP")) {
     69             return SECURITY_EAP;
     70         }
     71         return SECURITY_NONE;
     72     }
     73 
     74     AccessPoint(Context context, WifiConfiguration config) {
     75         super(context);
     76         setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);
     77         ssid = (config.SSID == null ? "" : removeDoubleQuotes(config.SSID));
     78         security = getSecurity(config);
     79         networkId = config.networkId;
     80         mConfig = config;
     81         mRssi = Integer.MAX_VALUE;
     82     }
     83 
     84     AccessPoint(Context context, ScanResult result) {
     85         super(context);
     86         setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);
     87         ssid = result.SSID;
     88         security = getSecurity(result);
     89         networkId = -1;
     90         mRssi = result.level;
     91     }
     92 
     93     @Override
     94     protected void onBindView(View view) {
     95         setTitle(ssid);
     96         mSignal = (ImageView) view.findViewById(R.id.signal);
     97         if (mRssi == Integer.MAX_VALUE) {
     98             mSignal.setImageDrawable(null);
     99         } else {
    100             mSignal.setImageResource(R.drawable.wifi_signal);
    101             mSignal.setImageState((security != SECURITY_NONE) ?
    102                     STATE_SECURED : STATE_NONE, true);
    103         }
    104         refresh();
    105         super.onBindView(view);
    106     }
    107 
    108     @Override
    109     public int compareTo(Preference preference) {
    110         if (!(preference instanceof AccessPoint)) {
    111             return 1;
    112         }
    113         AccessPoint other = (AccessPoint) preference;
    114         // Active one goes first.
    115         if (mInfo != other.mInfo) {
    116             return (mInfo != null) ? -1 : 1;
    117         }
    118         // Reachable one goes before unreachable one.
    119         if ((mRssi ^ other.mRssi) < 0) {
    120             return (mRssi != Integer.MAX_VALUE) ? -1 : 1;
    121         }
    122         // Configured one goes before unconfigured one.
    123         if ((networkId ^ other.networkId) < 0) {
    124             return (networkId != -1) ? -1 : 1;
    125         }
    126         // Sort by signal strength.
    127         int difference = WifiManager.compareSignalLevel(other.mRssi, mRssi);
    128         if (difference != 0) {
    129             return difference;
    130         }
    131         // Sort by ssid.
    132         return ssid.compareToIgnoreCase(other.ssid);
    133     }
    134 
    135     boolean update(ScanResult result) {
    136         // We do not call refresh() since this is called before onBindView().
    137         if (ssid.equals(result.SSID) && security == getSecurity(result)) {
    138             if (WifiManager.compareSignalLevel(result.level, mRssi) > 0) {
    139                 mRssi = result.level;
    140             }
    141             return true;
    142         }
    143         return false;
    144     }
    145 
    146     void update(WifiInfo info, DetailedState state) {
    147         boolean reorder = false;
    148         if (info != null && networkId != -1 && networkId == info.getNetworkId()) {
    149             reorder = (mInfo == null);
    150             mRssi = info.getRssi();
    151             mInfo = info;
    152             mState = state;
    153             refresh();
    154         } else if (mInfo != null) {
    155             reorder = true;
    156             mInfo = null;
    157             mState = null;
    158             refresh();
    159         }
    160         if (reorder) {
    161             notifyHierarchyChanged();
    162         }
    163     }
    164 
    165     int getLevel() {
    166         if (mRssi == Integer.MAX_VALUE) {
    167             return -1;
    168         }
    169         return WifiManager.calculateSignalLevel(mRssi, 4);
    170     }
    171 
    172     WifiConfiguration getConfig() {
    173         return mConfig;
    174     }
    175 
    176     WifiInfo getInfo() {
    177         return mInfo;
    178     }
    179 
    180     DetailedState getState() {
    181         return mState;
    182     }
    183 
    184     static String removeDoubleQuotes(String string) {
    185         int length = string.length();
    186         if ((length > 1) && (string.charAt(0) == '"')
    187                 && (string.charAt(length - 1) == '"')) {
    188             return string.substring(1, length - 1);
    189         }
    190         return string;
    191     }
    192 
    193     static String convertToQuotedString(String string) {
    194         return "\"" + string + "\"";
    195     }
    196 
    197     private void refresh() {
    198         if (mSignal == null) {
    199             return;
    200         }
    201         Context context = getContext();
    202         mSignal.setImageLevel(getLevel());
    203 
    204         if (mState != null) {
    205             setSummary(Summary.get(context, mState));
    206         } else {
    207             String status = null;
    208             if (mRssi == Integer.MAX_VALUE) {
    209                 status = context.getString(R.string.wifi_not_in_range);
    210             } else if (mConfig != null) {
    211                 status = context.getString((mConfig.status == WifiConfiguration.Status.DISABLED) ?
    212                         R.string.wifi_disabled : R.string.wifi_remembered);
    213             }
    214 
    215             if (security == SECURITY_NONE) {
    216                 setSummary(status);
    217             } else {
    218                 String format = context.getString((status == null) ?
    219                         R.string.wifi_secured : R.string.wifi_secured_with_status);
    220                 String[] type = context.getResources().getStringArray(R.array.wifi_security);
    221                 setSummary(String.format(format, type[security], status));
    222             }
    223         }
    224     }
    225 }
    226