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