1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.pmc;
18 
19 import android.app.Activity;
20 import android.app.AlarmManager;
21 import android.app.PendingIntent;
22 import android.content.BroadcastReceiver;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.IntentFilter;
26 import android.net.ConnectivityManager;
27 import android.net.wifi.WifiScanner;
28 import android.net.wifi.WifiScanner.ChannelSpec;
29 import android.net.wifi.WifiScanner.ScanSettings;
30 import android.os.Bundle;
31 import android.os.PowerManager;
32 import android.util.Log;
33 import android.view.Menu;
34 import android.view.MenuItem;
35 import android.view.View;
36 import android.widget.Button;
37 import android.widget.RadioGroup;
38 import android.widget.TextView;
39 import android.widget.Toast;
40 
41 /**
42  * Main class for PMC.
43  */
44 public class PMCMainActivity extends Activity {
45 
46     public static final String TAG = "PMC";
47     public static final String SETTING_SERVER_IP_KEY = "ServerIP";
48     public static final String SETTING_SERVER_PORT_KEY = "ServerPort";
49     public static final String SETTING_INTERVAL_KEY = "Interval";
50     public static final String SETTING_IPERF_BANDWIDTH_KEY = "IperfBandwidth";
51     public static final String SETTING_IPERF_LOGFILE_KEY = "IperfLogfile";
52     private static final String sConnScanAction = "ConnectionScan";
53     private static final String sGScanAction = "GScan";
54     private static final String sDownloadAction = "DownloadData";
55     private static final String SETPARAMS_INTENT_STRING = "com.android.pmc.action.SETPARAMS";
56     private static final String AUTOPOWER_INTENT_STRING = "com.android.pmc.action.AUTOPOWER";
57 
58     TextView mTextView;
59     Intent mSettingIntent;
60     private PendingIntent mPIGScan;
61     private PendingIntent mPIDownload;
62     private PendingIntent mPIConnScan;
63     private String mServerIP = "10.10.10.1";
64     private String mServerPort = "8080";
65     private int mIntervalMillis = 60 * 1000;
66     private String mIperfBandwidth = "1M";
67     private String mIperfLogFile = "/sdcard/iperf.txt";
68     private WifiConnScanReceiver mConnSR = null;
69     private WifiGScanReceiver mGScanR = null;
70     private WifiDownloadReceiver mDR = null;
71     private IperfClient mIperfClient = null;
72     private boolean mTethered = false;
73     private RadioGroup mRadioGroup;
74     private Button mBtnStart;
75     private Button mBtnStop;
76     private PMCReceiver mPMCReceiver;
77     private BleScanReceiver mBleScanReceiver;
78     private GattPMCReceiver mGattPMCReceiver;
79     private A2dpReceiver mA2dpReceiver;
80     private AlarmManager mAlarmManager;
81     private PowerManager.WakeLock mWakeLock;
82     private ConnectivityManager mConnManager;
83     private int mProvisionCheckSleep = 1250;
84 
85     class OnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback {
86         @Override
onTetheringStarted()87         public void onTetheringStarted() {
88             mTethered = true;
89         }
90     }
91 
92     @Override
onCreate(Bundle savedInstanceState)93     protected void onCreate(Bundle savedInstanceState) {
94         super.onCreate(savedInstanceState);
95         //Initiate wifi service manger
96         mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
97         mConnManager = (ConnectivityManager)
98                 this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
99         mPIGScan = PendingIntent.getBroadcast(this, 0, new Intent(sGScanAction), 0);
100         mPIDownload = PendingIntent.getBroadcast(this, 0, new Intent(sDownloadAction), 0);
101         mPIConnScan = PendingIntent.getBroadcast(this, 0, new Intent(sConnScanAction), 0);
102         mPMCReceiver = new PMCReceiver();
103         mBleScanReceiver = new BleScanReceiver(this, mAlarmManager);
104         mGattPMCReceiver = new GattPMCReceiver(this, mAlarmManager);
105         mA2dpReceiver = new A2dpReceiver(this, mAlarmManager);
106         setContentView(R.layout.activity_linear);
107         mTextView = (TextView) findViewById(R.id.text_content);
108         mRadioGroup = (RadioGroup) findViewById(R.id.rb_dataselect);
109         mBtnStart = (Button) findViewById(R.id.btnstart);
110         mBtnStop = (Button) findViewById(R.id.btnstop);
111         addListenerOnButton();
112         registerReceiver(mPMCReceiver, new IntentFilter(AUTOPOWER_INTENT_STRING));
113         registerReceiver(mPMCReceiver, new IntentFilter(SETPARAMS_INTENT_STRING));
114         registerReceiver(mBleScanReceiver, new IntentFilter(BleScanReceiver.BLE_SCAN_INTENT));
115         registerReceiver(mGattPMCReceiver, new IntentFilter(GattPMCReceiver.GATTPMC_INTENT));
116         registerReceiver(mA2dpReceiver, new IntentFilter(A2dpReceiver.A2DP_INTENT));
117     }
118 
119     @Override
onDestroy()120     protected void onDestroy() {
121         super.onDestroy();
122         unregisterReceiver(mPMCReceiver);
123     }
124 
125     /**
126      * Add Listener On Button
127      */
addListenerOnButton()128     public void addListenerOnButton() {
129         mBtnStart.setOnClickListener(new View.OnClickListener() {
130             @Override
131             public void onClick(View v) {
132                 // get selected radio button from radioGroup
133                 int selectedId = mRadioGroup.getCheckedRadioButtonId();
134                 switch (selectedId) {
135                     case R.id.rb_hundredkb:
136                         startDownloadFile("100kb.txt");
137                         break;
138                     case R.id.rb_kb:
139                         startDownloadFile("1kb.txt");
140                         break;
141                     case R.id.rb_tenkb:
142                         startDownloadFile("10kb.txt");
143                         break;
144                     case R.id.rb_mb:
145                         startDownloadFile("1mb.txt");
146                         break;
147                     case R.id.rb_connscan:
148                         startConnectivityScan();
149                         break;
150                     case R.id.rb_gscan2g:
151                         Integer[] channelList = {2412, 2437, 2462};
152                         startGscan(WifiScanner.WIFI_BAND_UNSPECIFIED, channelList);
153                         break;
154                     case R.id.rb_gscan_without_dfs:
155                         startGscan(WifiScanner.WIFI_BAND_BOTH, null);
156                         break;
157                     case R.id.rb_iperf_client:
158                         startIperfClient();
159                         break;
160                     case R.id.rb_usb_tethering:
161                         startUSBTethering();
162                         break;
163                     default:
164                         return;
165                 }
166             }
167         });
168 
169         mBtnStop.setOnClickListener(new View.OnClickListener() {
170             @Override
171             public void onClick(View v) {
172                 stopConnectivityScan();
173                 stopDownloadFile();
174                 stopGScan();
175                 stopIperfClient();
176                 stopUSBTethering();
177                 mBtnStart.setEnabled(true);
178             }
179         });
180     }
181 
182     /**
183      * Updates progress on the UI.
184      * @param status
185      */
updateProgressStatus(String status)186     public void updateProgressStatus(String status) {
187         mTextView.setText(status);
188     }
189 
startDownloadFile(String filename)190     private void startDownloadFile(String filename) {
191         // Stop any ongoing download sessions before starting a new instance.
192         stopDownloadFile();
193         Log.d(TAG, "serverIP ::" + mServerIP + " Port ::" + mServerPort
194                 + ". Interval: " + mIntervalMillis);
195         if (mServerIP.length() == 0 || mServerPort.length() == 0) {
196             String msg = "Provide server IP and Port information in Setting";
197             Toast errorMsg = Toast.makeText(getBaseContext(), msg, Toast.LENGTH_LONG);
198             errorMsg.show();
199             startSettingActivity();
200         } else {
201             mDR = new WifiDownloadReceiver(PMCMainActivity.this,
202                     "http://" + mServerIP + ":" + mServerPort + "/" + filename, mIntervalMillis,
203                     mAlarmManager, mPIDownload);
204             registerReceiver(mDR, new IntentFilter(sDownloadAction));
205             Log.d(TAG, "Setting download data alarm. Interval: " + mIntervalMillis);
206             mDR.scheduleDownload();
207             mBtnStart.setEnabled(false);
208             mRadioGroup.setFocusable(false);
209             mTextView.setText("Started downloadng " + filename);
210         }
211     }
212 
stopDownloadFile()213     private void stopDownloadFile() {
214         if (mDR != null) {
215             unregisterReceiver(mDR);
216             mDR.cancelDownload();
217             mDR = null;
218             mBtnStart.setEnabled(true);
219             mRadioGroup.setFocusable(true);
220             mTextView.setText("Stopped download");
221         }
222     }
223 
startConnectivityScan()224     private void startConnectivityScan() {
225         // Stop any ongoing scans before starting a new instance.
226         stopConnectivityScan();
227         mConnSR = new WifiConnScanReceiver(this, mIntervalMillis, mAlarmManager, mPIConnScan);
228         registerReceiver(mConnSR, new IntentFilter(sConnScanAction));
229         Log.d(TAG, "Setting connectivity scan alarm. Interval: " + mIntervalMillis);
230         mConnSR.scheduleConnScan();
231         mBtnStart.setEnabled(false);
232         mRadioGroup.setFocusable(false);
233         mTextView.setText("Started connectivity scan");
234     }
235 
stopConnectivityScan()236     private void stopConnectivityScan() {
237         if (mConnSR != null) {
238             unregisterReceiver(mConnSR);
239             mConnSR.cancelConnScan();
240             mConnSR = null;
241             mBtnStart.setEnabled(true);
242             mRadioGroup.setFocusable(true);
243             mTextView.setText("Stopped connectivity scan");
244         }
245     }
246 
startGscan(int band, Integer[] channelList)247     private void startGscan(int band, Integer[] channelList) {
248         // Stop any ongoing scans before starting a new instance.
249         stopGScan();
250         ScanSettings scanSettings = new ScanSettings();
251         String message;
252         if (band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
253             ChannelSpec[] channels = new ChannelSpec[channelList.length];
254             for (int i = 0; i < channelList.length; i++) {
255                 channels[i] = new ChannelSpec(channelList[i]);
256             }
257             scanSettings.channels = channels;
258             message = "Started GScan for social channels";
259         } else {
260             scanSettings.band = band;
261             message = "Started Gscan for both band without DFS channel";
262         }
263         mGScanR = new WifiGScanReceiver(
264                 this, scanSettings, mIntervalMillis, mAlarmManager, mPIGScan);
265         registerReceiver(mGScanR, new IntentFilter(sGScanAction));
266         Log.d(TAG, "Setting Gscan alarm. Interval: " + mIntervalMillis);
267         mGScanR.scheduleGscan();
268         mBtnStart.setEnabled(false);
269         mRadioGroup.setFocusable(false);
270         mTextView.setText(message);
271     }
272 
stopGScan()273     private void stopGScan() {
274         if (mGScanR != null) {
275             unregisterReceiver(mGScanR);
276             mGScanR.cancelGScan();
277             mGScanR = null;
278             mBtnStart.setEnabled(true);
279             mRadioGroup.setFocusable(true);
280             mTextView.setText("Stopped Gscan");
281         }
282     }
283 
startIperfClient()284     private void startIperfClient() {
285         // Stop any ongoing iperf sessions before starting a new instance.
286         stopIperfClient();
287         mIperfClient =
288                 new IperfClient(this, mServerIP, mServerPort, mIperfBandwidth, mIperfLogFile);
289         mIperfClient.startClient();
290         mBtnStart.setEnabled(false);
291         mRadioGroup.setFocusable(false);
292         mTextView.setText("Started iperf client");
293     }
294 
stopIperfClient()295     private void stopIperfClient() {
296         if (mIperfClient != null) {
297             mIperfClient.stopClient();
298             mIperfClient = null;
299             mBtnStart.setEnabled(true);
300             mRadioGroup.setFocusable(true);
301             mTextView.setText("Stopped iperf client");
302         }
303     }
304 
startUSBTethering()305     private void startUSBTethering() {
306         OnStartTetheringCallback tetherCallback = new OnStartTetheringCallback();
307         mConnManager.startTethering(ConnectivityManager.TETHERING_USB, true, tetherCallback);
308         // sleep until provisioning check for tethering is done
309         try {
310             Thread.sleep(mProvisionCheckSleep);
311         } catch (InterruptedException e) {
312             Log.d(TAG, "Sleep exception after enabling USB tethering");
313         }
314         if (mTethered) {
315             mBtnStart.setEnabled(false);
316             mRadioGroup.setFocusable(false);
317             mTextView.setText("Started usb tethering");
318         }
319     }
320 
stopUSBTethering()321     private void stopUSBTethering() {
322         if (mTethered) {
323             mConnManager.stopTethering(ConnectivityManager.TETHERING_USB);
324             mTethered = false;
325             mBtnStart.setEnabled(true);
326             mRadioGroup.setFocusable(true);
327             mTextView.setText("Stopped usb tethering");
328         }
329     }
330 
turnScreenOn(Context context)331     private void turnScreenOn(Context context) {
332         if (mWakeLock == null) {
333             PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
334             mWakeLock = pm.newWakeLock(
335                     PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);
336         }
337         if (mWakeLock != null && !mWakeLock.isHeld()) {
338             Log.i(TAG, "Turning screen on");
339             mWakeLock.acquire();
340         }
341     }
342 
turnScreenOff()343     private void turnScreenOff() {
344         if (mWakeLock != null && mWakeLock.isHeld()) {
345             Log.i(TAG, "Turning screen off");
346             mWakeLock.release();
347         }
348     }
349 
startSettingActivity()350     private void startSettingActivity() {
351         mSettingIntent = new Intent(PMCMainActivity.this, SettingActivity.class);
352         mSettingIntent.putExtra(SETTING_SERVER_IP_KEY, mServerIP);
353         mSettingIntent.putExtra(SETTING_SERVER_PORT_KEY, mServerPort);
354         mSettingIntent.putExtra(SETTING_INTERVAL_KEY, String.valueOf(mIntervalMillis / 1000));
355         mSettingIntent.putExtra(SETTING_IPERF_BANDWIDTH_KEY, mIperfBandwidth);
356         mSettingIntent.putExtra(SETTING_IPERF_LOGFILE_KEY, mIperfLogFile);
357         this.startActivityForResult(mSettingIntent, 0);
358     }
359 
setIntervalFromUser(String newValueInSeconds)360     private void setIntervalFromUser(String newValueInSeconds) {
361         if (newValueInSeconds.length() != 0 && Integer.parseInt(newValueInSeconds) >= 0) {
362             mIntervalMillis = Integer.parseInt(newValueInSeconds) * 1000;
363         }
364     }
365 
366     @Override
onCreateOptionsMenu(Menu menu)367     public boolean onCreateOptionsMenu(Menu menu) {
368         // Inflate the menu; this adds items to the action bar if it is present.
369         getMenuInflater().inflate(R.menu.main, menu);
370         return true;
371     }
372 
373     @Override
onOptionsItemSelected(MenuItem item)374     public boolean onOptionsItemSelected(MenuItem item) {
375         switch (item.getItemId()) {
376             case R.id.action_setting:
377                 startSettingActivity();
378                 return true;
379             default:
380                 return super.onOptionsItemSelected(item);
381         }
382     }
383 
384     @Override
onActivityResult(int requestCode, int resultCode, Intent data)385     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
386         super.onActivityResult(requestCode, resultCode, data);
387         //Retrieve data in the intent
388         if (resultCode == 0) {
389             mServerIP = data.getStringExtra(SETTING_SERVER_IP_KEY);
390             mServerPort = data.getStringExtra(SETTING_SERVER_PORT_KEY);
391             setIntervalFromUser(data.getStringExtra(SETTING_INTERVAL_KEY));
392             mIperfBandwidth = data.getStringExtra(SETTING_IPERF_BANDWIDTH_KEY);
393             mIperfLogFile = data.getStringExtra(SETTING_IPERF_LOGFILE_KEY);
394         }
395     }
396 
397     class PMCReceiver extends BroadcastReceiver {
398         @Override
onReceive(Context context, Intent intent)399         public void onReceive(Context context, Intent intent) {
400             if (intent.getAction().equals(AUTOPOWER_INTENT_STRING)) {
401                 Bundle extras = intent.getExtras();
402                 String key = "PowerAction";
403                 if (extras != null) {
404                     if (extras.containsKey(key)) {
405                         String actionstring = extras.getString(key);
406                         Log.d(TAG, "PowerAction = " + actionstring);
407                         if (actionstring.equalsIgnoreCase("StartConnectivityScan")) {
408                             startConnectivityScan();
409                         } else if (actionstring.equalsIgnoreCase("StopConnectivityScan")) {
410                             stopConnectivityScan();
411                         } else if (actionstring.equalsIgnoreCase("Download1KB")) {
412                             startDownloadFile("1kb.txt");
413                         } else if (actionstring.equalsIgnoreCase("Download10KB")) {
414                             startDownloadFile("10kb.txt");
415                         } else if (actionstring.equalsIgnoreCase("Download100KB")) {
416                             startDownloadFile("100kb.txt");
417                         } else if (actionstring.equalsIgnoreCase("Download1MB")) {
418                             startDownloadFile("1mb.txt");
419                         } else if (actionstring.equalsIgnoreCase("StopDownload")) {
420                             stopDownloadFile();
421                         } else if (actionstring.equalsIgnoreCase("StartGScanChannel")) {
422                             Integer[] channelList = {2412, 2437, 2462};
423                             startGscan(WifiScanner.WIFI_BAND_UNSPECIFIED, channelList);
424                         } else if (actionstring.equalsIgnoreCase("StartGScanBand")) {
425                             startGscan(WifiScanner.WIFI_BAND_BOTH, null);
426                         } else if (actionstring.equalsIgnoreCase("StopGScan")) {
427                             stopGScan();
428                         } else if (actionstring.equalsIgnoreCase("GetDownloadRate")) {
429                             if (mDR != null) {
430                                 String dataRateString = "Data Rate: "
431                                         + Integer.toString(mDR.getDownloadRate()) + " bytes/sec";
432                                 this.setResultData(dataRateString);
433                             } else {
434                                 this.setResultData("No download running");
435                             }
436                         } else if (actionstring.equalsIgnoreCase("StartIperfClient")) {
437                             startIperfClient();
438                         } else if (actionstring.equalsIgnoreCase("StopIperfClient")) {
439                             stopIperfClient();
440                         } else if (actionstring.equalsIgnoreCase("StartUSBTethering")) {
441                             startUSBTethering();
442                         } else if (actionstring.equalsIgnoreCase("StopUSBTethering")) {
443                             stopUSBTethering();
444                         } else if (actionstring.equalsIgnoreCase("TurnScreenOn")) {
445                             turnScreenOn(context);
446                         } else if (actionstring.equalsIgnoreCase("TurnScreenOff")) {
447                             turnScreenOff();
448                         }
449                         intent.removeExtra(key);
450                     }
451                 }
452             } else if (intent.getAction().equals(SETPARAMS_INTENT_STRING)) {
453                 Bundle extras = intent.getExtras();
454                 if (extras != null) {
455                     if (extras.containsKey(SETTING_INTERVAL_KEY)) {
456                         setIntervalFromUser(extras.getString(SETTING_INTERVAL_KEY));
457                     }
458                     if (extras.containsKey(SETTING_SERVER_IP_KEY)) {
459                         mServerIP = extras.getString(SETTING_SERVER_IP_KEY);
460                     }
461                     if (extras.containsKey(SETTING_SERVER_PORT_KEY)) {
462                         mServerPort = extras.getString(SETTING_SERVER_PORT_KEY);
463                     }
464                     if (extras.containsKey(SETTING_IPERF_BANDWIDTH_KEY)) {
465                         mIperfBandwidth = extras.getString(SETTING_IPERF_BANDWIDTH_KEY);
466                     }
467                     if (extras.containsKey(SETTING_IPERF_LOGFILE_KEY)) {
468                         mIperfLogFile = extras.getString(SETTING_IPERF_LOGFILE_KEY);
469                     }
470                 }
471             }
472         }
473     }
474 }
475