148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh/* 248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * Copyright (C) 2010 The Android Open Source Project 348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * 448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * you may not use this file except in compliance with the License. 648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * You may obtain a copy of the License at 748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * 848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * http://www.apache.org/licenses/LICENSE-2.0 948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * 1048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software 1148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS, 1248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * See the License for the specific language governing permissions and 1448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh * limitations under the License. 1548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh */ 1648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 1748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehpackage com.android.settings.wifi; 1848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 19ac57f3e1eb56998550534c1b32d99cb7b5cc2b7bRussell Brennerimport com.android.settings.R; 20ac57f3e1eb56998550534c1b32d99cb7b5cc2b7bRussell Brenner 2148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehimport android.content.Context; 2248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehimport android.net.NetworkInfo.DetailedState; 23d36699282cbd0a6897f425106081d3f2c0db55d4Daisuke Miyakawaimport android.net.wifi.ScanResult; 2448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehimport android.net.wifi.WifiConfiguration; 2548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehimport android.net.wifi.WifiConfiguration.KeyMgmt; 2648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehimport android.net.wifi.WifiInfo; 2748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehimport android.net.wifi.WifiManager; 283d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasaniimport android.os.Bundle; 2948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehimport android.preference.Preference; 308b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levyimport android.util.Log; 3148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehimport android.view.View; 3248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehimport android.widget.ImageView; 3348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 3448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yehclass AccessPoint extends Preference { 358b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy static final String TAG = "Settings.AccessPoint"; 363d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani 373d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani private static final String KEY_DETAILEDSTATE = "key_detailedstate"; 383d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani private static final String KEY_WIFIINFO = "key_wifiinfo"; 393d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani private static final String KEY_SCANRESULT = "key_scanresult"; 403d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani private static final String KEY_CONFIG = "key_config"; 413d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani 428b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy private static final int[] STATE_SECURED = { 438b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy R.attr.state_encrypted 448b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy }; 4548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh private static final int[] STATE_NONE = {}; 4648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 478b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy /** These values are matched in string arrays -- changes must be kept in sync */ 4848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh static final int SECURITY_NONE = 0; 4948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh static final int SECURITY_WEP = 1; 5048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh static final int SECURITY_PSK = 2; 5148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh static final int SECURITY_EAP = 3; 5248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 538b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy enum PskType { 548b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy UNKNOWN, 558b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy WPA, 568b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy WPA2, 578b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy WPA_WPA2 588b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } 598b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy 603d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani String ssid; 613d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani String bssid; 623d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani int security; 633d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani int networkId; 64b3024fa6a0359f18b93fd8aaf197fce59f806edeIrfan Sheriff boolean wpsAvailable = false; 6548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 668b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy PskType pskType = PskType.UNKNOWN; 678b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy 6848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh private WifiConfiguration mConfig; 698b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy /* package */ScanResult mScanResult; 703d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani 7148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh private int mRssi; 7248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh private WifiInfo mInfo; 7348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh private DetailedState mState; 7448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 7565cff177222560f43b7da367c45ec425e86e9eecIrfan Sheriff static int getSecurity(WifiConfiguration config) { 7648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { 7748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return SECURITY_PSK; 7848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 7948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) || 8048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 8148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return SECURITY_EAP; 8248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 8348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return (config.wepKeys[0] != null) ? SECURITY_WEP : SECURITY_NONE; 8448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 8548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 8648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh private static int getSecurity(ScanResult result) { 8748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh if (result.capabilities.contains("WEP")) { 8848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return SECURITY_WEP; 8948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } else if (result.capabilities.contains("PSK")) { 9048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return SECURITY_PSK; 9148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } else if (result.capabilities.contains("EAP")) { 9248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return SECURITY_EAP; 9348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 9448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return SECURITY_NONE; 9548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 9648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 978b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy public String getSecurityString(boolean concise) { 988b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy Context context = getContext(); 998b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy switch(security) { 1008b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case SECURITY_EAP: 1018b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return concise ? context.getString(R.string.wifi_security_short_eap) : 1028b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy context.getString(R.string.wifi_security_eap); 1038b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case SECURITY_PSK: 1048b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy switch (pskType) { 1058b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case WPA: 1068b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return concise ? context.getString(R.string.wifi_security_short_wpa) : 1078b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy context.getString(R.string.wifi_security_wpa); 1088b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case WPA2: 1098b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return concise ? context.getString(R.string.wifi_security_short_wpa2) : 1108b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy context.getString(R.string.wifi_security_wpa2); 1118b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case WPA_WPA2: 1128b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return concise ? context.getString(R.string.wifi_security_short_wpa_wpa2) : 1138b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy context.getString(R.string.wifi_security_wpa_wpa2); 1148b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case UNKNOWN: 1158b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy default: 1168b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return concise ? context.getString(R.string.wifi_security_short_psk_generic) 1178b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy : context.getString(R.string.wifi_security_psk_generic); 1188b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } 1198b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case SECURITY_WEP: 1208b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return concise ? context.getString(R.string.wifi_security_short_wep) : 1218b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy context.getString(R.string.wifi_security_wep); 1228b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case SECURITY_NONE: 1238b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy default: 1248b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return concise ? "" : context.getString(R.string.wifi_security_none); 1258b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } 1268b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } 1278b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy 1288b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy private static PskType getPskType(ScanResult result) { 1298b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy boolean wpa = result.capabilities.contains("WPA-PSK"); 1308b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy boolean wpa2 = result.capabilities.contains("WPA2-PSK"); 1318b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy if (wpa2 && wpa) { 1328b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return PskType.WPA_WPA2; 1338b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } else if (wpa2) { 1348b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return PskType.WPA2; 1358b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } else if (wpa) { 1368b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return PskType.WPA; 1378b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } else { 1388b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy Log.w(TAG, "Received abnormal flag string: " + result.capabilities); 1398b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy return PskType.UNKNOWN; 1408b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } 1418b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } 1428b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy 14348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh AccessPoint(Context context, WifiConfiguration config) { 14448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh super(context); 14548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh setWidgetLayoutResource(R.layout.preference_widget_wifi_signal); 1463d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani loadConfig(config); 147e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy refresh(); 1483d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani } 1493d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani 1503d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani AccessPoint(Context context, ScanResult result) { 1513d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani super(context); 1523d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani setWidgetLayoutResource(R.layout.preference_widget_wifi_signal); 1533d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani loadResult(result); 154e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy refresh(); 1553d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani } 1563d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani 1573d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani AccessPoint(Context context, Bundle savedState) { 1583d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani super(context); 1593d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani setWidgetLayoutResource(R.layout.preference_widget_wifi_signal); 1603d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani 1613d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani mConfig = savedState.getParcelable(KEY_CONFIG); 1623d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani if (mConfig != null) { 1633d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani loadConfig(mConfig); 1643d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani } 1653d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani mScanResult = (ScanResult) savedState.getParcelable(KEY_SCANRESULT); 1663d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani if (mScanResult != null) { 1673d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani loadResult(mScanResult); 1683d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani } 1693d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani mInfo = (WifiInfo) savedState.getParcelable(KEY_WIFIINFO); 1703d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani if (savedState.containsKey(KEY_DETAILEDSTATE)) { 1713d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani mState = DetailedState.valueOf(savedState.getString(KEY_DETAILEDSTATE)); 1723d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani } 1733d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani update(mInfo, mState); 1743d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani } 1753d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani 1763d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani public void saveWifiState(Bundle savedState) { 1773d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani savedState.putParcelable(KEY_CONFIG, mConfig); 1783d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani savedState.putParcelable(KEY_SCANRESULT, mScanResult); 1793d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani savedState.putParcelable(KEY_WIFIINFO, mInfo); 1803d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani if (mState != null) { 1813d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani savedState.putString(KEY_DETAILEDSTATE, mState.toString()); 1823d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani } 1833d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani } 1843d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani 1853d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani private void loadConfig(WifiConfiguration config) { 1868c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang ssid = (config.SSID == null ? "" : removeDoubleQuotes(config.SSID)); 187b3024fa6a0359f18b93fd8aaf197fce59f806edeIrfan Sheriff bssid = config.BSSID; 18848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh security = getSecurity(config); 18948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh networkId = config.networkId; 19048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh mRssi = Integer.MAX_VALUE; 1913d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani mConfig = config; 19248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 19348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 1943d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani private void loadResult(ScanResult result) { 19548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh ssid = result.SSID; 196b3024fa6a0359f18b93fd8aaf197fce59f806edeIrfan Sheriff bssid = result.BSSID; 19748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh security = getSecurity(result); 1983d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani wpsAvailable = security != SECURITY_EAP && result.capabilities.contains("WPS"); 1998b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy if (security == SECURITY_PSK) 2008b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy pskType = getPskType(result); 20148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh networkId = -1; 20248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh mRssi = result.level; 2033d13110d40b972a44c80558e0179323f9b330b2fAmith Yamasani mScanResult = result; 20448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 20548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 20648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh @Override 20748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh protected void onBindView(View view) { 208e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy super.onBindView(view); 209e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy ImageView signal = (ImageView) view.findViewById(R.id.signal); 21048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh if (mRssi == Integer.MAX_VALUE) { 211e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy signal.setImageDrawable(null); 21248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } else { 213e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy signal.setImageLevel(getLevel()); 214ac57f3e1eb56998550534c1b32d99cb7b5cc2b7bRussell Brenner signal.setImageDrawable(getContext().getTheme().obtainStyledAttributes( 215ac57f3e1eb56998550534c1b32d99cb7b5cc2b7bRussell Brenner new int[] {R.attr.wifi_signal}).getDrawable(0)); 216e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy signal.setImageState((security != SECURITY_NONE) ? 21748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh STATE_SECURED : STATE_NONE, true); 21848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 21948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 22048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 22152727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff @Override 22252727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff public int compareTo(Preference preference) { 22352727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff if (!(preference instanceof AccessPoint)) { 22452727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff return 1; 22552727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff } 22652727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff AccessPoint other = (AccessPoint) preference; 22752727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff // Active one goes first. 228ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff if (mInfo != null && other.mInfo == null) return -1; 229ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff if (mInfo == null && other.mInfo != null) return 1; 230ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff 23152727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff // Reachable one goes before unreachable one. 232ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff if (mRssi != Integer.MAX_VALUE && other.mRssi == Integer.MAX_VALUE) return -1; 233ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff if (mRssi == Integer.MAX_VALUE && other.mRssi != Integer.MAX_VALUE) return 1; 234ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff 23552727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff // Configured one goes before unconfigured one. 236ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff if (networkId != WifiConfiguration.INVALID_NETWORK_ID 237ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff && other.networkId == WifiConfiguration.INVALID_NETWORK_ID) return -1; 238ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff if (networkId == WifiConfiguration.INVALID_NETWORK_ID 239ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff && other.networkId != WifiConfiguration.INVALID_NETWORK_ID) return 1; 240ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff 24152727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff // Sort by signal strength. 24252727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff int difference = WifiManager.compareSignalLevel(other.mRssi, mRssi); 24352727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff if (difference != 0) { 24452727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff return difference; 24552727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff } 24652727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff // Sort by ssid. 24752727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff return ssid.compareToIgnoreCase(other.ssid); 24852727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff } 24952727dd1fbca7612c2179b50689cd77f8f939b1aIrfan Sheriff 250ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff @Override 251ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff public boolean equals(Object other) { 252ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff if (!(other instanceof AccessPoint)) return false; 253ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff return (this.compareTo((AccessPoint) other) == 0); 254ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff } 255ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff 256ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff @Override 257ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff public int hashCode() { 258ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff int result = 0; 259ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff if (mInfo != null) result += 13 * mInfo.hashCode(); 260ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff result += 19 * mRssi; 261ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff result += 23 * networkId; 262ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff result += 29 * ssid.hashCode(); 263ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff return result; 264ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff } 265ebc57e3ae68524c5612be7d9a5564b87203c432aIrfan Sheriff 26648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh boolean update(ScanResult result) { 26748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh if (ssid.equals(result.SSID) && security == getSecurity(result)) { 26848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh if (WifiManager.compareSignalLevel(result.level, mRssi) > 0) { 269e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy int oldLevel = getLevel(); 27048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh mRssi = result.level; 271e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy if (getLevel() != oldLevel) { 272e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy notifyChanged(); 273e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy } 27448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 2758b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy // This flag only comes from scans, is not easily saved in config 276e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy if (security == SECURITY_PSK) { 2778b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy pskType = getPskType(result); 278e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy } 279e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy refresh(); 28048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return true; 28148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 28248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return false; 28348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 28448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 28548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh void update(WifiInfo info, DetailedState state) { 28648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh boolean reorder = false; 287e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy if (info != null && networkId != WifiConfiguration.INVALID_NETWORK_ID 288e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy && networkId == info.getNetworkId()) { 28948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh reorder = (mInfo == null); 29048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh mRssi = info.getRssi(); 29148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh mInfo = info; 29248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh mState = state; 29348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh refresh(); 29448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } else if (mInfo != null) { 29548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh reorder = true; 29648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh mInfo = null; 29748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh mState = null; 29848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh refresh(); 29948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 30048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh if (reorder) { 30148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh notifyHierarchyChanged(); 30248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 30348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 30448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 30548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh int getLevel() { 30648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh if (mRssi == Integer.MAX_VALUE) { 30748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return -1; 30848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 30948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return WifiManager.calculateSignalLevel(mRssi, 4); 31048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 31148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 31248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh WifiConfiguration getConfig() { 31348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return mConfig; 31448090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 31548090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 31648090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh WifiInfo getInfo() { 31748090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return mInfo; 31848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 31948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 32048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh DetailedState getState() { 32148090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh return mState; 32248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 32348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 3248c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang static String removeDoubleQuotes(String string) { 3258c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang int length = string.length(); 3268c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang if ((length > 1) && (string.charAt(0) == '"') 3278c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang && (string.charAt(length - 1) == '"')) { 3288c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang return string.substring(1, length - 1); 3298c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang } 3308c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang return string; 3318c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang } 3328c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang 3338c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang static String convertToQuotedString(String string) { 3348c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang return "\"" + string + "\""; 3358c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang } 3368c81257f70fabeaa505e292bd0c2226dd5eefc4cChung-yih Wang 337e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy /** Updates the title and summary; may indirectly call notifyChanged() */ 33848090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh private void refresh() { 339e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy setTitle(ssid); 34048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 341e2c6e7520b5002573bf76bcdee909281514eabb0Isaac Levy Context context = getContext(); 3420085de7999bea8140c82c72efc0e56b9af0529a1Jaewan Kim if (mConfig != null && mConfig.status == WifiConfiguration.Status.DISABLED) { 3438b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy switch (mConfig.disableReason) { 3448b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case WifiConfiguration.DISABLED_AUTH_FAILURE: 3458b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy setSummary(context.getString(R.string.wifi_disabled_password_failure)); 3468b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy break; 3478b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case WifiConfiguration.DISABLED_DHCP_FAILURE: 3488b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case WifiConfiguration.DISABLED_DNS_FAILURE: 3498b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy setSummary(context.getString(R.string.wifi_disabled_network_failure)); 3508b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy break; 3518b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy case WifiConfiguration.DISABLED_UNKNOWN_REASON: 3528b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy setSummary(context.getString(R.string.wifi_disabled_generic)); 3538b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } 3540085de7999bea8140c82c72efc0e56b9af0529a1Jaewan Kim } else if (mRssi == Integer.MAX_VALUE) { // Wifi out of range 3550085de7999bea8140c82c72efc0e56b9af0529a1Jaewan Kim setSummary(context.getString(R.string.wifi_not_in_range)); 3560085de7999bea8140c82c72efc0e56b9af0529a1Jaewan Kim } else if (mState != null) { // This is the active connection 3570085de7999bea8140c82c72efc0e56b9af0529a1Jaewan Kim setSummary(Summary.get(context, mState)); 3588b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } else { // In range, not disabled. 3598b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy StringBuilder summary = new StringBuilder(); 3608b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy if (mConfig != null) { // Is saved network 3618b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy summary.append(context.getString(R.string.wifi_remembered)); 36248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 36348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh 3648b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy if (security != SECURITY_NONE) { 3658b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy String securityStrFormat; 3668b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy if (summary.length() == 0) { 3678b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy securityStrFormat = context.getString(R.string.wifi_secured_first_item); 368e45e13f47ad5e09aa8291d81a03a136618b383c0Irfan Sheriff } else { 3698b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy securityStrFormat = context.getString(R.string.wifi_secured_second_item); 370e45e13f47ad5e09aa8291d81a03a136618b383c0Irfan Sheriff } 3718b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy summary.append(String.format(securityStrFormat, getSecurityString(true))); 3728b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy } 3738b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy 3748b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy if (mConfig == null && wpsAvailable) { // Only list WPS available for unsaved networks 3758b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy if (summary.length() == 0) { 3768b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy summary.append(context.getString(R.string.wifi_wps_available_first_item)); 377b3024fa6a0359f18b93fd8aaf197fce59f806edeIrfan Sheriff } else { 3788b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy summary.append(context.getString(R.string.wifi_wps_available_second_item)); 379b3024fa6a0359f18b93fd8aaf197fce59f806edeIrfan Sheriff } 38048090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 3818b2bf2e53814a20f09f658554cde61657df8ac99Isaac Levy setSummary(summary.toString()); 38248090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 38348090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh } 38422d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy 38522d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy /** 38622d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy * Generate and save a default wifiConfiguration with common values. 38722d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy * Can only be called for unsecured networks. 38822d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy * @hide 38922d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy */ 39022d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy protected void generateOpenNetworkConfig() { 39122d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy if (security != SECURITY_NONE) 39222d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy throw new IllegalStateException(); 39322d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy if (mConfig != null) 39422d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy return; 39522d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy mConfig = new WifiConfiguration(); 39622d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy mConfig.SSID = AccessPoint.convertToQuotedString(ssid); 39722d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy mConfig.allowedKeyManagement.set(KeyMgmt.NONE); 39822d441acdba0fb7b99f5958ddd0198f4c371b2a7Isaac Levy } 39948090d4066fdf3084a4fb31277e785149c1bce37Chia-chi Yeh} 400