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