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