1 /** 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 package com.android.development; 19 20 import android.app.Activity; 21 import android.app.AlarmManager; 22 import android.app.PendingIntent; 23 import android.content.BroadcastReceiver; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.IntentFilter; 27 import android.content.SharedPreferences; 28 import android.content.pm.PackageManager.NameNotFoundException; 29 import android.net.ConnectivityManager; 30 import android.net.ConnectivityManager.NetworkCallback; 31 import android.net.LinkAddress; 32 import android.net.LinkProperties; 33 import android.net.Network; 34 import android.net.NetworkCapabilities; 35 import android.net.NetworkRequest; 36 import android.net.NetworkUtils; 37 import android.net.RouteInfo; 38 import android.net.wifi.ScanResult; 39 import android.net.wifi.WifiActivityEnergyInfo; 40 import android.net.wifi.WifiManager; 41 import android.os.RemoteException; 42 import android.os.Handler; 43 import android.os.Message; 44 import android.os.IBinder; 45 import android.os.INetworkManagementService; 46 import android.os.Parcel; 47 import android.os.PowerManager; 48 import android.os.PowerManager.WakeLock; 49 import android.os.ServiceManager; 50 import android.os.ServiceManagerNative; 51 import android.os.SystemClock; 52 import android.provider.Settings; 53 import android.os.Bundle; 54 import android.text.TextUtils; 55 import android.util.Log; 56 import android.view.IWindowManager; 57 import android.view.View; 58 import android.widget.ArrayAdapter; 59 import android.widget.Button; 60 import android.widget.CheckBox; 61 import android.widget.CompoundButton; 62 import android.widget.EditText; 63 import android.widget.Spinner; 64 import android.widget.TextView; 65 import android.widget.Toast; 66 import android.widget.AdapterView.OnItemSelectedListener; 67 68 import com.android.internal.telephony.Phone; 69 import libcore.io.IoUtils; 70 71 import java.io.BufferedReader; 72 import java.io.FileInputStream; 73 import java.io.FileOutputStream; 74 import java.io.InputStreamReader; 75 import java.io.IOException; 76 import java.io.OutputStreamWriter; 77 import java.io.PrintWriter; 78 import java.net.HttpURLConnection; 79 import java.net.InetAddress; 80 import java.net.Proxy; 81 import java.net.Socket; 82 import java.net.URL; 83 import java.util.ArrayList; 84 import java.util.Enumeration; 85 import java.util.List; 86 import java.util.Random; 87 88 import static android.net.NetworkCapabilities.*; 89 90 public class Connectivity extends Activity { 91 private static final String TAG = "DevToolsConnectivity"; 92 private static final String GET_SCAN_RES = "Get Results"; 93 private static final String START_SCAN = "Start Scan"; 94 private static final String PROGRESS_SCAN = "In Progress"; 95 96 private static final long SCAN_CYCLES = 15; 97 98 private static final int EVENT_TOGGLE_WIFI = 1; 99 private static final int EVENT_TOGGLE_SCREEN = 2; 100 101 private EditText mDCOnDurationEdit; 102 private EditText mDCOffDurationEdit; 103 private TextView mDCCycleCountView; 104 private long mDCOnDuration = 120000; 105 private long mDCOffDuration = 120000; 106 private int mDCCycleCount = 0; 107 108 private EditText mSCOnDurationEdit; 109 private EditText mSCOffDurationEdit; 110 private TextView mSCCycleCountView; 111 private long mSCOnDuration = 120000; 112 private long mSCOffDuration = 12000; 113 private int mSCCycleCount = 0; 114 115 private boolean mDelayedCycleStarted = false; 116 117 private Button mScanButton; 118 private TextView mScanResults; 119 private EditText mScanCyclesEdit; 120 private CheckBox mScanDisconnect; 121 private long mScanCycles = SCAN_CYCLES; 122 private long mScanCur = -1; 123 private long mStartTime = -1; 124 private long mStopTime; 125 private long mTotalScanTime = 0; 126 private long mTotalScanCount = 0; 127 128 private TextView mLinkStatsResults; 129 private TextView mHttpRequestResults; 130 131 private String mTdlsAddr = null; 132 133 private WifiManager mWm; 134 private WifiManager.MulticastLock mWml; 135 private PowerManager mPm; 136 private ConnectivityManager mCm; 137 private INetworkManagementService mNetd; 138 139 private WifiScanReceiver mScanRecv; 140 IntentFilter mIntentFilter; 141 142 private WakeLock mWakeLock = null; 143 private WakeLock mScreenonWakeLock = null; 144 145 private boolean mScreenOffToggleRunning = false; 146 private boolean mScreenOff = false; 147 148 private static final String CONNECTIVITY_TEST_ALARM = 149 "com.android.development.CONNECTIVITY_TEST_ALARM"; 150 private static final String TEST_ALARM_EXTRA = "CONNECTIVITY_TEST_EXTRA"; 151 private static final String TEST_ALARM_ON_EXTRA = "CONNECTIVITY_TEST_ON_EXTRA"; 152 private static final String TEST_ALARM_OFF_EXTRA = "CONNECTIVITY_TEST_OFF_EXTRA"; 153 private static final String TEST_ALARM_CYCLE_EXTRA = "CONNECTIVITY_TEST_CYCLE_EXTRA"; 154 private static final String SCREEN_ON = "SCREEN_ON"; 155 private static final String SCREEN_OFF = "SCREEN_OFF"; 156 public BroadcastReceiver mReceiver = new BroadcastReceiver() { 157 public void onReceive(Context context, Intent intent) { 158 if (intent.getAction().equals(CONNECTIVITY_TEST_ALARM)) { 159 String extra = (String)intent.getExtra(TEST_ALARM_EXTRA); 160 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 161 Long on = new Long(120000); 162 Long off = new Long(120000); 163 int cycle = 0; 164 try { 165 on = Long.parseLong((String)intent.getExtra(TEST_ALARM_ON_EXTRA)); 166 off = Long.parseLong((String)intent.getExtra(TEST_ALARM_OFF_EXTRA)); 167 cycle = Integer.parseInt((String)intent.getExtra(TEST_ALARM_CYCLE_EXTRA)); 168 } catch (Exception e) {} 169 170 if (extra.equals(SCREEN_ON)) { 171 mScreenonWakeLock = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK | 172 PowerManager.ACQUIRE_CAUSES_WAKEUP, 173 "ConnectivityTest"); 174 mScreenonWakeLock.acquire(); 175 176 mSCCycleCount = cycle+1; 177 mSCOnDuration = on; 178 mSCOffDuration = off; 179 mSCCycleCountView.setText(Integer.toString(mSCCycleCount)); 180 181 scheduleAlarm(mSCOnDuration, SCREEN_OFF); 182 } else if (extra.equals(SCREEN_OFF)) { 183 184 mSCCycleCount = cycle; 185 mSCOnDuration = on; 186 mSCOffDuration = off; 187 188 mScreenonWakeLock.release(); 189 mScreenonWakeLock = null; 190 scheduleAlarm(mSCOffDuration, SCREEN_ON); 191 pm.goToSleep(SystemClock.uptimeMillis()); 192 } 193 } 194 } 195 }; 196 197 public Handler mHandler2 = new Handler() { 198 public void handleMessage(Message msg) { 199 switch(msg.what) { 200 case EVENT_TOGGLE_WIFI: 201 Log.e(TAG, "EVENT_TOGGLE_WIFI"); 202 if (mDelayedCycleStarted && mWm != null) { 203 long delay; 204 switch (mWm.getWifiState()) { 205 case WifiManager.WIFI_STATE_ENABLED: 206 case WifiManager.WIFI_STATE_ENABLING: 207 mWm.setWifiEnabled(false); 208 delay = mDCOffDuration; 209 break; 210 default: 211 mWm.setWifiEnabled(true); 212 delay = mDCOnDuration; 213 mDCCycleCount++; 214 mDCCycleCountView.setText(Integer.toString(mDCCycleCount)); 215 } 216 sendMessageDelayed(obtainMessage(EVENT_TOGGLE_WIFI), 217 delay); 218 } 219 break; 220 } 221 } 222 }; 223 224 /** 225 * Wifi Scan Listener 226 */ 227 private class WifiScanReceiver extends BroadcastReceiver { 228 @Override 229 public void onReceive(Context context, Intent intent) { 230 String action = intent.getAction(); 231 232 if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 233 mStopTime = SystemClock.elapsedRealtime(); 234 if (mStartTime != -1) { 235 mTotalScanTime += (mStopTime - mStartTime); 236 mStartTime = -1; 237 } 238 Log.d(TAG, "Scan: READY " + mScanCur); 239 mScanResults.setVisibility(View.INVISIBLE); 240 241 List<ScanResult> wifiScanResults = mWm.getScanResults(); 242 if (wifiScanResults != null) { 243 mTotalScanCount += wifiScanResults.size(); 244 mScanResults.setText("Current scan = " + Long.toString(wifiScanResults.size())); 245 mScanResults.setVisibility(View.VISIBLE); 246 Log.d(TAG, "Scan: Results = " + wifiScanResults.size()); 247 } 248 249 mScanCur--; 250 mScanCyclesEdit.setText(Long.toString(mScanCur)); 251 if (mScanCur == 0) { 252 unregisterReceiver(mScanRecv); 253 mScanButton.setText(GET_SCAN_RES); 254 mScanResults.setVisibility(View.INVISIBLE); 255 } else { 256 Log.d(TAG, "Scan: START " + mScanCur); 257 mStartTime = SystemClock.elapsedRealtime(); 258 mWm.startScan(); 259 } 260 } 261 } 262 } 263 264 private static class DevToolsNetworkCallback extends NetworkCallback { 265 private static final String TAG = "DevToolsNetworkCallback"; 266 267 public void onPreCheck(Network network) { 268 Log.d(TAG, "onPreCheck: " + network.netId); 269 } 270 271 public void onAvailable(Network network) { 272 Log.d(TAG, "onAvailable: " + network.netId); 273 } 274 275 public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) { 276 Log.d(TAG, "onCapabilitiesChanged: " + network.netId + " " + nc.toString()); 277 } 278 279 public void onLinkPropertiesChanged(Network network, LinkProperties lp) { 280 Log.d(TAG, "onLinkPropertiesChanged: " + network.netId + " " + lp.toString()); 281 } 282 283 public void onLosing(Network network, int maxMsToLive) { 284 Log.d(TAG, "onLosing: " + network.netId + " " + maxMsToLive); 285 } 286 287 public void onLost(Network network) { 288 Log.d(TAG, "onLost: " + network.netId); 289 } 290 } 291 private DevToolsNetworkCallback mCallback; 292 293 private class RequestableNetwork { 294 private final NetworkRequest mRequest; 295 private final int mRequestButton, mReleaseButton, mProgressBar; 296 private NetworkCallback mCallback; 297 private Network mNetwork; 298 299 public RequestableNetwork(NetworkRequest request, int requestButton, int releaseButton, 300 int progressBar) { 301 mRequest = request; 302 mRequestButton = requestButton; 303 mReleaseButton = releaseButton; 304 mProgressBar = progressBar; 305 } 306 307 public RequestableNetwork(int capability, int requestButton, int releaseButton, 308 int progressBar) { 309 this(new NetworkRequest.Builder() 310 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) 311 .addCapability(capability) 312 .build(), 313 requestButton, releaseButton, progressBar); 314 } 315 316 public void addOnClickListener() { 317 findViewById(mRequestButton).setOnClickListener( 318 new View.OnClickListener() { public void onClick(View v) { request(); }}); 319 findViewById(mReleaseButton).setOnClickListener( 320 new View.OnClickListener() { public void onClick(View v) { release(); }}); 321 } 322 323 public void setRequested(boolean requested) { 324 findViewById(mRequestButton).setEnabled(!requested); 325 findViewById(mReleaseButton).setEnabled(requested); 326 findViewById(mProgressBar).setVisibility( 327 requested ? View.VISIBLE : View.GONE); 328 } 329 330 public void request() { 331 if (mCallback == null) { 332 mCallback = new NetworkCallback() { 333 @Override 334 public void onAvailable(Network network) { 335 mNetwork = network; 336 onHttpRequestResults(null); 337 runOnUiThread(() -> findViewById(mProgressBar).setVisibility(View.GONE)); 338 } 339 @Override 340 public void onLost(Network network) { 341 mNetwork = null; 342 onHttpRequestResults(null); 343 } 344 }; 345 mCm.requestNetwork(mRequest, mCallback); 346 setRequested(true); 347 } 348 } 349 350 public void release() { 351 if (mCallback != null) { 352 mNetwork = null; 353 onHttpRequestResults(null); 354 mCm.unregisterNetworkCallback(mCallback); 355 mCallback = null; 356 setRequested(false); 357 } 358 } 359 360 public Network getNetwork() { 361 return mNetwork; 362 } 363 } 364 365 private final ArrayList<RequestableNetwork> mRequestableNetworks = new ArrayList<>(); 366 private final RequestableNetwork mBoundTestNetwork; 367 private boolean mRequestRunning; 368 369 private void addRequestableNetwork(RequestableNetwork network) { 370 mRequestableNetworks.add(network); 371 } 372 373 private void addRequestableNetwork(int capability, int requestButton, int releaseButton, 374 int progressBar) { 375 mRequestableNetworks.add(new RequestableNetwork(capability, requestButton, releaseButton, 376 progressBar)); 377 } 378 379 public Connectivity() { 380 super(); 381 addRequestableNetwork(NET_CAPABILITY_MMS, R.id.request_mms, R.id.release_mms, 382 R.id.mms_progress); 383 addRequestableNetwork(NET_CAPABILITY_SUPL, R.id.request_supl, R.id.release_supl, 384 R.id.supl_progress); 385 addRequestableNetwork(NET_CAPABILITY_INTERNET, R.id.request_cell, R.id.release_cell, 386 R.id.cell_progress); 387 388 // Make bound requests use cell data. 389 mBoundTestNetwork = mRequestableNetworks.get(mRequestableNetworks.size() - 1); 390 391 NetworkRequest wifiRequest = new NetworkRequest.Builder() 392 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) 393 .build(); 394 addRequestableNetwork(new RequestableNetwork(wifiRequest, 395 R.id.request_wifi, R.id.release_wifi, R.id.wifi_progress)); 396 } 397 398 final NetworkRequest mEmptyRequest = new NetworkRequest.Builder().clearCapabilities().build(); 399 400 @Override 401 public void onCreate(Bundle icicle) { 402 super.onCreate(icicle); 403 404 setContentView(R.layout.connectivity); 405 406 mWm = (WifiManager)getSystemService(Context.WIFI_SERVICE); 407 mWml = mWm.createMulticastLock(TAG); 408 mWml.setReferenceCounted(false); 409 mPm = (PowerManager)getSystemService(Context.POWER_SERVICE); 410 mCm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 411 IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 412 mNetd = INetworkManagementService.Stub.asInterface(b); 413 414 findViewById(R.id.enableWifi).setOnClickListener(mClickListener); 415 findViewById(R.id.disableWifi).setOnClickListener(mClickListener); 416 findViewById(R.id.acquireWifiMulticastLock).setOnClickListener(mClickListener); 417 findViewById(R.id.releaseWifiMulticastLock).setOnClickListener(mClickListener); 418 findViewById(R.id.releaseWifiMulticastLock).setEnabled(false); 419 420 findViewById(R.id.startDelayedCycle).setOnClickListener(mClickListener); 421 findViewById(R.id.stopDelayedCycle).setOnClickListener(mClickListener); 422 mDCOnDurationEdit = (EditText)findViewById(R.id.dc_wifi_on_duration); 423 mDCOnDurationEdit.setText(Long.toString(mDCOnDuration)); 424 mDCOffDurationEdit = (EditText)findViewById(R.id.dc_wifi_off_duration); 425 mDCOffDurationEdit.setText(Long.toString(mDCOffDuration)); 426 mDCCycleCountView = (TextView)findViewById(R.id.dc_wifi_cycles_done); 427 mDCCycleCountView.setText(Integer.toString(mDCCycleCount)); 428 429 findViewById(R.id.startScreenCycle).setOnClickListener(mClickListener); 430 findViewById(R.id.stopScreenCycle).setOnClickListener(mClickListener); 431 mSCOnDurationEdit = (EditText)findViewById(R.id.sc_wifi_on_duration); 432 mSCOnDurationEdit.setText(Long.toString(mSCOnDuration)); 433 mSCOffDurationEdit = (EditText)findViewById(R.id.sc_wifi_off_duration); 434 mSCOffDurationEdit.setText(Long.toString(mSCOffDuration)); 435 mSCCycleCountView = (TextView)findViewById(R.id.sc_wifi_cycles_done); 436 mSCCycleCountView.setText(Integer.toString(mSCCycleCount)); 437 438 mScanButton = (Button)findViewById(R.id.startScan); 439 mScanButton.setOnClickListener(mClickListener); 440 mScanCyclesEdit = (EditText)findViewById(R.id.sc_scan_cycles); 441 mScanCyclesEdit.setText(Long.toString(mScanCycles)); 442 mScanDisconnect = (CheckBox)findViewById(R.id.scanDisconnect); 443 mScanDisconnect.setChecked(true); 444 mScanResults = (TextView)findViewById(R.id.sc_scan_results); 445 mScanResults.setVisibility(View.INVISIBLE); 446 447 mScanRecv = new WifiScanReceiver(); 448 mIntentFilter = new IntentFilter(); 449 mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 450 451 findViewById(R.id.startTdls).setOnClickListener(mClickListener); 452 findViewById(R.id.stopTdls).setOnClickListener(mClickListener); 453 454 findViewById(R.id.report_all_bad).setOnClickListener(mClickListener); 455 456 findViewById(R.id.default_request).setOnClickListener(mClickListener); 457 findViewById(R.id.bound_http_request).setOnClickListener(mClickListener); 458 findViewById(R.id.bound_socket_request).setOnClickListener(mClickListener); 459 460 findViewById(R.id.link_stats).setOnClickListener(mClickListener); 461 462 for (RequestableNetwork network : mRequestableNetworks) { 463 network.setRequested(false); 464 network.addOnClickListener(); 465 } 466 onHttpRequestResults(null); 467 468 registerReceiver(mReceiver, new IntentFilter(CONNECTIVITY_TEST_ALARM)); 469 470 mLinkStatsResults = (TextView)findViewById(R.id.stats); 471 mLinkStatsResults.setVisibility(View.VISIBLE); 472 473 mHttpRequestResults = (TextView)findViewById(R.id.http_response); 474 mHttpRequestResults.setVisibility(View.VISIBLE); 475 476 mCallback = new DevToolsNetworkCallback(); 477 mCm.registerNetworkCallback(mEmptyRequest, mCallback); 478 } 479 480 @Override 481 public void onDestroy() { 482 super.onDestroy(); 483 for (RequestableNetwork network : mRequestableNetworks) { 484 network.release(); 485 } 486 mCm.unregisterNetworkCallback(mCallback); 487 mCallback = null; 488 unregisterReceiver(mReceiver); 489 mWml.release(); 490 } 491 492 @Override 493 public void onResume() { 494 super.onResume(); 495 findViewById(R.id.connectivity_layout).requestFocus(); 496 } 497 498 private View.OnClickListener mClickListener = new View.OnClickListener() { 499 public void onClick(View v) { 500 switch (v.getId()) { 501 case R.id.enableWifi: 502 mWm.setWifiEnabled(true); 503 break; 504 case R.id.disableWifi: 505 mWm.setWifiEnabled(false); 506 break; 507 case R.id.acquireWifiMulticastLock: 508 case R.id.releaseWifiMulticastLock: 509 onWifiMulticastLock(v.getId() == R.id.acquireWifiMulticastLock); 510 break; 511 case R.id.startDelayedCycle: 512 onStartDelayedCycle(); 513 break; 514 case R.id.stopDelayedCycle: 515 onStopDelayedCycle(); 516 break; 517 case R.id.startScreenCycle: 518 onStartScreenCycle(); 519 break; 520 case R.id.stopScreenCycle: 521 onStopScreenCycle(); 522 break; 523 case R.id.startScan: 524 onStartScanCycle(); 525 break; 526 case R.id.startTdls: 527 onStartTdls(); 528 break; 529 case R.id.stopTdls: 530 onStopTdls(); 531 break; 532 case R.id.default_request: 533 onHttpRequest(DEFAULT); 534 break; 535 case R.id.bound_http_request: 536 onHttpRequest(HTTPS); 537 break; 538 case R.id.bound_socket_request: 539 onHttpRequest(SOCKET); 540 break; 541 case R.id.report_all_bad: 542 onReportAllBad(); 543 break; 544 case R.id.link_stats: 545 onLinkStats(); 546 break; 547 } 548 } 549 }; 550 551 552 private void onStartDelayedCycle() { 553 if (!mDelayedCycleStarted) { 554 mDelayedCycleStarted = true; 555 try { 556 mDCOnDuration = Long.parseLong(mDCOnDurationEdit.getText().toString()); 557 mDCOffDuration = Long.parseLong(mDCOffDurationEdit.getText().toString()); 558 } catch (Exception e) { }; 559 mDCCycleCount = 0; 560 561 mWakeLock = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ConnectivityTest"); 562 mWakeLock.acquire(); 563 mHandler2.sendMessage(mHandler2.obtainMessage(EVENT_TOGGLE_WIFI)); 564 } 565 } 566 567 private void onStopDelayedCycle() { 568 if (mDelayedCycleStarted) { 569 mDelayedCycleStarted = false; 570 mWakeLock.release(); 571 mWakeLock = null; 572 if(mHandler2.hasMessages(EVENT_TOGGLE_WIFI)) { 573 mHandler2.removeMessages(EVENT_TOGGLE_WIFI); 574 } 575 } 576 } 577 578 private void onStartScreenCycle() { 579 try { 580 mSCOnDuration = Long.parseLong(mSCOnDurationEdit.getText().toString()); 581 mSCOffDuration = Long.parseLong(mSCOffDurationEdit.getText().toString()); 582 } catch (Exception e) { }; 583 mSCCycleCount = 0; 584 585 mScreenonWakeLock = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK, 586 "ConnectivityTest"); 587 mScreenonWakeLock.acquire(); 588 589 scheduleAlarm(10, SCREEN_OFF); 590 } 591 592 private void scheduleAlarm(long delayMs, String eventType) { 593 AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE); 594 Intent i = new Intent(CONNECTIVITY_TEST_ALARM); 595 596 i.putExtra(TEST_ALARM_EXTRA, eventType); 597 i.putExtra(TEST_ALARM_ON_EXTRA, Long.toString(mSCOnDuration)); 598 i.putExtra(TEST_ALARM_OFF_EXTRA, Long.toString(mSCOffDuration)); 599 i.putExtra(TEST_ALARM_CYCLE_EXTRA, Integer.toString(mSCCycleCount)); 600 601 PendingIntent p = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT); 602 603 am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delayMs, p); 604 } 605 606 private void onStopScreenCycle() { 607 } 608 609 private void onReportAllBad() { 610 Network[] networks = mCm.getAllNetworks(); 611 for (Network network : networks) { 612 mCm.reportBadNetwork(network); 613 } 614 } 615 616 private void onStartScanCycle() { 617 if (mScanCur == -1) { 618 try { 619 mScanCur = Long.parseLong(mScanCyclesEdit.getText().toString()); 620 mScanCycles = mScanCur; 621 } catch (Exception e) { }; 622 if (mScanCur <= 0) { 623 mScanCur = -1; 624 mScanCycles = SCAN_CYCLES; 625 return; 626 } 627 } 628 if (mScanCur > 0) { 629 registerReceiver(mScanRecv, mIntentFilter); 630 mScanButton.setText(PROGRESS_SCAN); 631 mScanResults.setVisibility(View.INVISIBLE); 632 if (mScanDisconnect.isChecked()) 633 mWm.disconnect(); 634 mTotalScanTime = 0; 635 mTotalScanCount = 0; 636 Log.d(TAG, "Scan: START " + mScanCur); 637 mStartTime = SystemClock.elapsedRealtime(); 638 mWm.startScan(); 639 } else { 640 // Show results 641 mScanResults.setText("Average Scan Time = " + 642 Long.toString(mTotalScanTime / mScanCycles) + " ms ; Average Scan Amount = " + 643 Long.toString(mTotalScanCount / mScanCycles)); 644 mScanResults.setVisibility(View.VISIBLE); 645 mScanButton.setText(START_SCAN); 646 mScanCur = -1; 647 mScanCyclesEdit.setText(Long.toString(mScanCycles)); 648 if (mScanDisconnect.isChecked()) 649 mWm.reassociate(); 650 } 651 } 652 653 private void onStartTdls() { 654 mTdlsAddr = ((EditText)findViewById(R.id.sc_ip_mac)).getText().toString(); 655 Log.d(TAG, "TDLS: START " + mTdlsAddr); 656 InetAddress inetAddress = null; 657 try { 658 inetAddress = InetAddress.getByName(mTdlsAddr); 659 mWm.setTdlsEnabled(inetAddress, true); 660 } catch (Exception e) { 661 mWm.setTdlsEnabledWithMacAddress(mTdlsAddr, true); 662 } 663 } 664 665 private void onStopTdls() { 666 if (mTdlsAddr == null) return; 667 Log.d(TAG, "TDLS: STOP " + mTdlsAddr); 668 InetAddress inetAddress = null; 669 try { 670 inetAddress = InetAddress.getByName(mTdlsAddr); 671 mWm.setTdlsEnabled(inetAddress, false); 672 } catch (Exception e) { 673 mWm.setTdlsEnabledWithMacAddress(mTdlsAddr, false); 674 } 675 } 676 677 private void onLinkStats() { 678 Log.e(TAG, "LINK STATS: "); 679 try { 680 WifiActivityEnergyInfo info = 681 mWm.getControllerActivityEnergyInfo(0); 682 if (info != null) { 683 mLinkStatsResults.setText(" power " + info.toString()); 684 } else { 685 mLinkStatsResults.setText(" null! "); 686 } 687 } catch (Exception e) { 688 mLinkStatsResults.setText(" failed! " + e.toString()); 689 } 690 } 691 692 693 private final static int DEFAULT = 0; 694 private final static int SOCKET = 1; 695 private final static int HTTPS = 2; 696 697 private void onHttpRequestResults(final String results) { 698 runOnUiThread(new Runnable() { 699 @Override 700 public void run() { 701 boolean enabled = !mRequestRunning; 702 findViewById(R.id.default_request).setEnabled(enabled); 703 704 enabled = !mRequestRunning && mBoundTestNetwork.getNetwork() != null; 705 findViewById(R.id.bound_http_request).setEnabled(enabled); 706 findViewById(R.id.bound_socket_request).setEnabled(enabled); 707 708 if (!TextUtils.isEmpty(results) || !mRequestRunning) { 709 ((TextView) findViewById(R.id.http_response)).setText(results); 710 } 711 } 712 }); 713 } 714 715 private String doSocketRequest(Network network, String host, String path) throws IOException { 716 Socket sock = network.getSocketFactory().createSocket(host, 80); 717 try { 718 sock.setSoTimeout(5000); 719 OutputStreamWriter writer = new OutputStreamWriter(sock.getOutputStream()); 720 String request = String.format( 721 "GET %s HTTP/1.1\nHost: %s\nConnection: close\n\n", path, host); 722 writer.write(request); 723 writer.flush(); 724 BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream())); 725 String line = reader.readLine(); 726 727 if (line == null || !line.startsWith("HTTP/1.1 200")) { 728 // Error. 729 return "Error: " + line; 730 } 731 732 do { 733 // Consume headers. 734 line = reader.readLine(); 735 } while (!TextUtils.isEmpty(line)); 736 737 // Return first line of body. 738 return reader.readLine(); 739 } finally { 740 if (sock != null) { 741 IoUtils.closeQuietly(sock); 742 } 743 } 744 } 745 746 private void onHttpRequest(final int type) { 747 mRequestRunning = true; 748 onHttpRequestResults(null); 749 750 Thread requestThread = new Thread() { 751 public void run() { 752 final String path = "/ip.js?fmt=text"; 753 final String randomHost = 754 "h" + Integer.toString(new Random().nextInt()) + ".ds.ipv6test.google.com"; 755 final String fixedHost = "google-ipv6test.appspot.com"; 756 757 Network network = mBoundTestNetwork.getNetwork(); 758 HttpURLConnection conn = null; 759 InputStreamReader in = null; 760 761 try { 762 final URL httpsUrl = new URL("https", fixedHost, path); 763 BufferedReader reader; 764 765 switch (type) { 766 case DEFAULT: 767 conn = (HttpURLConnection) httpsUrl.openConnection(Proxy.NO_PROXY); 768 in = new InputStreamReader(conn.getInputStream()); 769 reader = new BufferedReader(in); 770 onHttpRequestResults(reader.readLine()); 771 break; 772 case SOCKET: 773 String response = doSocketRequest(network, randomHost, path); 774 onHttpRequestResults(response); 775 break; 776 case HTTPS: 777 conn = (HttpURLConnection) network.openConnection(httpsUrl, 778 Proxy.NO_PROXY); 779 in = new InputStreamReader(conn.getInputStream()); 780 reader = new BufferedReader(in); 781 onHttpRequestResults(reader.readLine()); 782 break; 783 default: 784 throw new IllegalArgumentException("Cannot happen"); 785 } 786 } catch(IOException e) { 787 onHttpRequestResults("Error! "); 788 } finally { 789 mRequestRunning = false; 790 if (in != null) IoUtils.closeQuietly(in); 791 if (conn != null) conn.disconnect(); 792 } 793 } 794 }; 795 requestThread.start(); 796 } 797 798 private void onWifiMulticastLock(boolean enable) { 799 Log.d(TAG, (enable ? "Acquiring" : "Releasing") + " wifi multicast lock"); 800 if (enable) { 801 mWml.acquire(); 802 } else { 803 mWml.release(); 804 } 805 findViewById(R.id.acquireWifiMulticastLock).setEnabled(!enable); 806 findViewById(R.id.releaseWifiMulticastLock).setEnabled(enable); 807 } 808 } 809