1/* 2 * Copyright (C) 2009 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 17package com.android.settings.wifi; 18 19import com.android.settings.R; 20import android.net.wifi.ScanResult; 21import org.apache.http.HttpResponse; 22import org.apache.http.client.HttpClient; 23import org.apache.http.client.methods.HttpGet; 24import org.apache.http.impl.client.DefaultHttpClient; 25import java.util.List; 26import android.app.Activity; 27import android.content.BroadcastReceiver; 28import android.content.Context; 29import android.content.Intent; 30import android.content.IntentFilter; 31import android.net.NetworkInfo; 32import android.net.wifi.SupplicantState; 33import android.net.wifi.WifiInfo; 34import android.net.wifi.WifiManager; 35import android.os.Bundle; 36import android.os.Handler; 37import android.text.TextUtils; 38import android.util.Log; 39import android.view.View; 40import android.view.View.OnClickListener; 41import android.widget.Button; 42import android.widget.TextView; 43import java.io.IOException; 44import java.net.UnknownHostException; 45 46 47/** 48 * Show the current status details of Wifi related fields 49 */ 50public class WifiStatusTest extends Activity { 51 52 private static final String TAG = "WifiStatusTest"; 53 54 private Button updateButton; 55 private TextView mWifiState; 56 private TextView mNetworkState; 57 private TextView mSupplicantState; 58 private TextView mRSSI; 59 private TextView mBSSID; 60 private TextView mSSID; 61 private TextView mHiddenSSID; 62 private TextView mIPAddr; 63 private TextView mMACAddr; 64 private TextView mNetworkId; 65 private TextView mLinkSpeed; 66 private TextView mScanList; 67 68 69 private TextView mPingIpAddr; 70 private TextView mPingHostname; 71 private TextView mHttpClientTest; 72 private Button pingTestButton; 73 74 private String mPingIpAddrResult; 75 private String mPingHostnameResult; 76 private String mHttpClientTestResult; 77 78 79 private WifiManager mWifiManager; 80 private IntentFilter mWifiStateFilter; 81 82 83 //============================ 84 // Activity lifecycle 85 //============================ 86 87 private final BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() { 88 @Override 89 public void onReceive(Context context, Intent intent) { 90 if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 91 handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 92 WifiManager.WIFI_STATE_UNKNOWN)); 93 } else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 94 handleNetworkStateChanged( 95 (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO)); 96 } else if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 97 handleScanResultsAvailable(); 98 } else if (intent.getAction().equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) { 99 /* TODO: handle supplicant connection change later */ 100 } else if (intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { 101 handleSupplicantStateChanged( 102 (SupplicantState) intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE), 103 intent.hasExtra(WifiManager.EXTRA_SUPPLICANT_ERROR), 104 intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 0)); 105 } else if (intent.getAction().equals(WifiManager.RSSI_CHANGED_ACTION)) { 106 handleSignalChanged(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, 0)); 107 } else if (intent.getAction().equals(WifiManager.NETWORK_IDS_CHANGED_ACTION)) { 108 /* TODO: handle network id change info later */ 109 } else { 110 Log.e(TAG, "Received an unknown Wifi Intent"); 111 } 112 } 113 }; 114 115 @Override 116 protected void onCreate(Bundle savedInstanceState) { 117 super.onCreate(savedInstanceState); 118 119 mWifiManager = (WifiManager) getSystemService(WIFI_SERVICE); 120 121 mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); 122 mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 123 mWifiStateFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 124 mWifiStateFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); 125 mWifiStateFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); 126 mWifiStateFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 127 128 registerReceiver(mWifiStateReceiver, mWifiStateFilter); 129 130 setContentView(R.layout.wifi_status_test); 131 132 updateButton = (Button) findViewById(R.id.update); 133 updateButton.setOnClickListener(updateButtonHandler); 134 135 mWifiState = (TextView) findViewById(R.id.wifi_state); 136 mNetworkState = (TextView) findViewById(R.id.network_state); 137 mSupplicantState = (TextView) findViewById(R.id.supplicant_state); 138 mRSSI = (TextView) findViewById(R.id.rssi); 139 mBSSID = (TextView) findViewById(R.id.bssid); 140 mSSID = (TextView) findViewById(R.id.ssid); 141 mHiddenSSID = (TextView) findViewById(R.id.hidden_ssid); 142 mIPAddr = (TextView) findViewById(R.id.ipaddr); 143 mMACAddr = (TextView) findViewById(R.id.macaddr); 144 mNetworkId = (TextView) findViewById(R.id.networkid); 145 mLinkSpeed = (TextView) findViewById(R.id.link_speed); 146 mScanList = (TextView) findViewById(R.id.scan_list); 147 148 149 mPingIpAddr = (TextView) findViewById(R.id.pingIpAddr); 150 mPingHostname = (TextView) findViewById(R.id.pingHostname); 151 mHttpClientTest = (TextView) findViewById(R.id.httpClientTest); 152 153 pingTestButton = (Button) findViewById(R.id.ping_test); 154 pingTestButton.setOnClickListener(mPingButtonHandler); 155 } 156 157 @Override 158 protected void onResume() { 159 super.onResume(); 160 registerReceiver(mWifiStateReceiver, mWifiStateFilter); 161 } 162 163 @Override 164 protected void onPause() { 165 super.onPause(); 166 unregisterReceiver(mWifiStateReceiver); 167 } 168 169 OnClickListener mPingButtonHandler = new OnClickListener() { 170 public void onClick(View v) { 171 updatePingState(); 172 } 173 }; 174 175 OnClickListener updateButtonHandler = new OnClickListener() { 176 public void onClick(View v) { 177 final WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); 178 179 setWifiStateText(mWifiManager.getWifiState()); 180 mBSSID.setText(wifiInfo.getBSSID()); 181 mHiddenSSID.setText(String.valueOf(wifiInfo.getHiddenSSID())); 182 int ipAddr = wifiInfo.getIpAddress(); 183 StringBuffer ipBuf = new StringBuffer(); 184 ipBuf.append(ipAddr & 0xff).append('.'). 185 append((ipAddr >>>= 8) & 0xff).append('.'). 186 append((ipAddr >>>= 8) & 0xff).append('.'). 187 append((ipAddr >>>= 8) & 0xff); 188 189 mIPAddr.setText(ipBuf); 190 mLinkSpeed.setText(String.valueOf(wifiInfo.getLinkSpeed())+" Mbps"); 191 mMACAddr.setText(wifiInfo.getMacAddress()); 192 mNetworkId.setText(String.valueOf(wifiInfo.getNetworkId())); 193 mRSSI.setText(String.valueOf(wifiInfo.getRssi())); 194 mSSID.setText(wifiInfo.getSSID()); 195 196 SupplicantState supplicantState = wifiInfo.getSupplicantState(); 197 setSupplicantStateText(supplicantState); 198 } 199 }; 200 201 private void setSupplicantStateText(SupplicantState supplicantState) { 202 if(SupplicantState.FOUR_WAY_HANDSHAKE.equals(supplicantState)) { 203 mSupplicantState.setText("FOUR WAY HANDSHAKE"); 204 } else if(SupplicantState.ASSOCIATED.equals(supplicantState)) { 205 mSupplicantState.setText("ASSOCIATED"); 206 } else if(SupplicantState.ASSOCIATING.equals(supplicantState)) { 207 mSupplicantState.setText("ASSOCIATING"); 208 } else if(SupplicantState.COMPLETED.equals(supplicantState)) { 209 mSupplicantState.setText("COMPLETED"); 210 } else if(SupplicantState.DISCONNECTED.equals(supplicantState)) { 211 mSupplicantState.setText("DISCONNECTED"); 212 } else if(SupplicantState.DORMANT.equals(supplicantState)) { 213 mSupplicantState.setText("DORMANT"); 214 } else if(SupplicantState.GROUP_HANDSHAKE.equals(supplicantState)) { 215 mSupplicantState.setText("GROUP HANDSHAKE"); 216 } else if(SupplicantState.INACTIVE.equals(supplicantState)) { 217 mSupplicantState.setText("INACTIVE"); 218 } else if(SupplicantState.INVALID.equals(supplicantState)) { 219 mSupplicantState.setText("INVALID"); 220 } else if(SupplicantState.SCANNING.equals(supplicantState)) { 221 mSupplicantState.setText("SCANNING"); 222 } else if(SupplicantState.UNINITIALIZED.equals(supplicantState)) { 223 mSupplicantState.setText("UNINITIALIZED"); 224 } else { 225 mSupplicantState.setText("BAD"); 226 Log.e(TAG, "supplicant state is bad"); 227 } 228 } 229 230 private void setWifiStateText(int wifiState) { 231 String wifiStateString; 232 switch(wifiState) { 233 case WifiManager.WIFI_STATE_DISABLING: 234 wifiStateString = getString(R.string.wifi_state_disabling); 235 break; 236 case WifiManager.WIFI_STATE_DISABLED: 237 wifiStateString = getString(R.string.wifi_state_disabled); 238 break; 239 case WifiManager.WIFI_STATE_ENABLING: 240 wifiStateString = getString(R.string.wifi_state_enabling); 241 break; 242 case WifiManager.WIFI_STATE_ENABLED: 243 wifiStateString = getString(R.string.wifi_state_enabled); 244 break; 245 case WifiManager.WIFI_STATE_UNKNOWN: 246 wifiStateString = getString(R.string.wifi_state_unknown); 247 break; 248 default: 249 wifiStateString = "BAD"; 250 Log.e(TAG, "wifi state is bad"); 251 break; 252 } 253 254 mWifiState.setText(wifiStateString); 255 } 256 257 private void handleSignalChanged(int rssi) { 258 mRSSI.setText(String.valueOf(rssi)); 259 } 260 261 private void handleWifiStateChanged(int wifiState) { 262 setWifiStateText(wifiState); 263 } 264 265 private void handleScanResultsAvailable() { 266 List<ScanResult> list = mWifiManager.getScanResults(); 267 268 StringBuffer scanList = new StringBuffer(); 269 if (list != null) { 270 for (int i = list.size() - 1; i >= 0; i--) { 271 final ScanResult scanResult = list.get(i); 272 273 if (scanResult == null) { 274 continue; 275 } 276 277 if (TextUtils.isEmpty(scanResult.SSID)) { 278 continue; 279 } 280 281 scanList.append(scanResult.SSID+" "); 282 } 283 } 284 mScanList.setText(scanList); 285 } 286 287 private void handleSupplicantStateChanged(SupplicantState state, boolean hasError, int error) { 288 if (hasError) { 289 mSupplicantState.setText("ERROR AUTHENTICATING"); 290 } else { 291 setSupplicantStateText(state); 292 } 293 } 294 295 private void handleNetworkStateChanged(NetworkInfo networkInfo) { 296 if (mWifiManager.isWifiEnabled()) { 297 String summary = Summary.get(this, mWifiManager.getConnectionInfo().getSSID(), 298 networkInfo.getDetailedState()); 299 mNetworkState.setText(summary); 300 } 301 } 302 303 private final void updatePingState() { 304 final Handler handler = new Handler(); 305 // Set all to unknown since the threads will take a few secs to update. 306 mPingIpAddrResult = getResources().getString(R.string.radioInfo_unknown); 307 mPingHostnameResult = getResources().getString(R.string.radioInfo_unknown); 308 mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown); 309 310 mPingIpAddr.setText(mPingIpAddrResult); 311 mPingHostname.setText(mPingHostnameResult); 312 mHttpClientTest.setText(mHttpClientTestResult); 313 314 final Runnable updatePingResults = new Runnable() { 315 public void run() { 316 mPingIpAddr.setText(mPingIpAddrResult); 317 mPingHostname.setText(mPingHostnameResult); 318 mHttpClientTest.setText(mHttpClientTestResult); 319 } 320 }; 321 Thread ipAddrThread = new Thread() { 322 @Override 323 public void run() { 324 pingIpAddr(); 325 handler.post(updatePingResults); 326 } 327 }; 328 ipAddrThread.start(); 329 330 Thread hostnameThread = new Thread() { 331 @Override 332 public void run() { 333 pingHostname(); 334 handler.post(updatePingResults); 335 } 336 }; 337 hostnameThread.start(); 338 339 Thread httpClientThread = new Thread() { 340 @Override 341 public void run() { 342 httpClientTest(); 343 handler.post(updatePingResults); 344 } 345 }; 346 httpClientThread.start(); 347 } 348 349 /** 350 * The ping functions have been borrowed from Radio diagnostic app to 351 * enable quick access on the wifi status screen 352 */ 353 private final void pingIpAddr() { 354 try { 355 // TODO: Hardcoded for now, make it UI configurable 356 String ipAddress = "74.125.47.104"; 357 Process p = Runtime.getRuntime().exec("ping -c 1 -w 100 " + ipAddress); 358 int status = p.waitFor(); 359 if (status == 0) { 360 mPingIpAddrResult = "Pass"; 361 } else { 362 mPingIpAddrResult = "Fail: IP addr not reachable"; 363 } 364 } catch (IOException e) { 365 mPingIpAddrResult = "Fail: IOException"; 366 } catch (InterruptedException e) { 367 mPingIpAddrResult = "Fail: InterruptedException"; 368 } 369 } 370 371 private final void pingHostname() { 372 try { 373 // TODO: Hardcoded for now, make it UI configurable 374 Process p = Runtime.getRuntime().exec("ping -c 1 -w 100 www.google.com"); 375 int status = p.waitFor(); 376 if (status == 0) { 377 mPingHostnameResult = "Pass"; 378 } else { 379 mPingHostnameResult = "Fail: Host unreachable"; 380 } 381 } catch (UnknownHostException e) { 382 mPingHostnameResult = "Fail: Unknown Host"; 383 } catch (IOException e) { 384 mPingHostnameResult= "Fail: IOException"; 385 } catch (InterruptedException e) { 386 mPingHostnameResult = "Fail: InterruptedException"; 387 } 388 } 389 390 private void httpClientTest() { 391 HttpClient client = new DefaultHttpClient(); 392 try { 393 // TODO: Hardcoded for now, make it UI configurable 394 HttpGet request = new HttpGet("http://www.google.com"); 395 HttpResponse response = client.execute(request); 396 if (response.getStatusLine().getStatusCode() == 200) { 397 mHttpClientTestResult = "Pass"; 398 } else { 399 mHttpClientTestResult = "Fail: Code: " + String.valueOf(response); 400 } 401 request.abort(); 402 } catch (IOException e) { 403 mHttpClientTestResult = "Fail: IOException"; 404 } 405 } 406 407} 408