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