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