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