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                 Context.RECEIVER_EXPORTED_UNAUDITED);
114         registerReceiver(mPMCReceiver, new IntentFilter(SETPARAMS_INTENT_STRING),
115                 Context.RECEIVER_EXPORTED_UNAUDITED);
116         registerReceiver(mBleScanReceiver, new IntentFilter(BleScanReceiver.BLE_SCAN_INTENT),
117                 Context.RECEIVER_EXPORTED_UNAUDITED);
118         registerReceiver(mGattPMCReceiver, new IntentFilter(GattPMCReceiver.GATTPMC_INTENT),
119                 Context.RECEIVER_EXPORTED_UNAUDITED);
120         registerReceiver(mA2dpReceiver, new IntentFilter(A2dpReceiver.A2DP_INTENT),
121                 Context.RECEIVER_EXPORTED_UNAUDITED);
122     }
123 
124     @Override
onDestroy()125     protected void onDestroy() {
126         super.onDestroy();
127         unregisterReceiver(mPMCReceiver);
128     }
129 
130     /**
131      * Add Listener On Button
132      */
addListenerOnButton()133     public void addListenerOnButton() {
134         mBtnStart.setOnClickListener(new View.OnClickListener() {
135             @Override
136             public void onClick(View v) {
137                 // get selected radio button from radioGroup
138                 int selectedId = mRadioGroup.getCheckedRadioButtonId();
139                 switch (selectedId) {
140                     case R.id.rb_hundredkb:
141                         startDownloadFile("100kb.txt");
142                         break;
143                     case R.id.rb_kb:
144                         startDownloadFile("1kb.txt");
145                         break;
146                     case R.id.rb_tenkb:
147                         startDownloadFile("10kb.txt");
148                         break;
149                     case R.id.rb_mb:
150                         startDownloadFile("1mb.txt");
151                         break;
152                     case R.id.rb_connscan:
153                         startConnectivityScan();
154                         break;
155                     case R.id.rb_gscan2g:
156                         Integer[] channelList = {2412, 2437, 2462};
157                         startGscan(WifiScanner.WIFI_BAND_UNSPECIFIED, channelList);
158                         break;
159                     case R.id.rb_gscan_without_dfs:
160                         startGscan(WifiScanner.WIFI_BAND_BOTH, null);
161                         break;
162                     case R.id.rb_iperf_client:
163                         startIperfClient();
164                         break;
165                     case R.id.rb_usb_tethering:
166                         startUSBTethering();
167                         break;
168                     default:
169                         return;
170                 }
171             }
172         });
173 
174         mBtnStop.setOnClickListener(new View.OnClickListener() {
175             @Override
176             public void onClick(View v) {
177                 stopConnectivityScan();
178                 stopDownloadFile();
179                 stopGScan();
180                 stopIperfClient();
181                 stopUSBTethering();
182                 mBtnStart.setEnabled(true);
183             }
184         });
185     }
186 
187     /**
188      * Updates progress on the UI.
189      * @param status
190      */
updateProgressStatus(String status)191     public void updateProgressStatus(String status) {
192         mTextView.setText(status);
193     }
194 
startDownloadFile(String filename)195     private void startDownloadFile(String filename) {
196         // Stop any ongoing download sessions before starting a new instance.
197         stopDownloadFile();
198         Log.d(TAG, "serverIP ::" + mServerIP + " Port ::" + mServerPort
199                 + ". Interval: " + mIntervalMillis);
200         if (mServerIP.length() == 0 || mServerPort.length() == 0) {
201             String msg = "Provide server IP and Port information in Setting";
202             Toast errorMsg = Toast.makeText(getBaseContext(), msg, Toast.LENGTH_LONG);
203             errorMsg.show();
204             startSettingActivity();
205         } else {
206             mDR = new WifiDownloadReceiver(PMCMainActivity.this,
207                     "http://" + mServerIP + ":" + mServerPort + "/" + filename, mIntervalMillis,
208                     mAlarmManager, mPIDownload);
209             registerReceiver(mDR, new IntentFilter(sDownloadAction),
210                     Context.RECEIVER_EXPORTED_UNAUDITED);
211             Log.d(TAG, "Setting download data alarm. Interval: " + mIntervalMillis);
212             mDR.scheduleDownload();
213             mBtnStart.setEnabled(false);
214             mRadioGroup.setFocusable(false);
215             mTextView.setText("Started downloadng " + filename);
216         }
217     }
218 
stopDownloadFile()219     private void stopDownloadFile() {
220         if (mDR != null) {
221             unregisterReceiver(mDR);
222             mDR.cancelDownload();
223             mDR = null;
224             mBtnStart.setEnabled(true);
225             mRadioGroup.setFocusable(true);
226             mTextView.setText("Stopped download");
227         }
228     }
229 
startConnectivityScan()230     private void startConnectivityScan() {
231         // Stop any ongoing scans before starting a new instance.
232         stopConnectivityScan();
233         mConnSR = new WifiConnScanReceiver(this, mIntervalMillis, mAlarmManager, mPIConnScan);
234         registerReceiver(mConnSR, new IntentFilter(sConnScanAction),
235                 Context.RECEIVER_EXPORTED_UNAUDITED);
236         Log.d(TAG, "Setting connectivity scan alarm. Interval: " + mIntervalMillis);
237         mConnSR.scheduleConnScan();
238         mBtnStart.setEnabled(false);
239         mRadioGroup.setFocusable(false);
240         mTextView.setText("Started connectivity scan");
241     }
242 
stopConnectivityScan()243     private void stopConnectivityScan() {
244         if (mConnSR != null) {
245             unregisterReceiver(mConnSR);
246             mConnSR.cancelConnScan();
247             mConnSR = null;
248             mBtnStart.setEnabled(true);
249             mRadioGroup.setFocusable(true);
250             mTextView.setText("Stopped connectivity scan");
251         }
252     }
253 
startGscan(int band, Integer[] channelList)254     private void startGscan(int band, Integer[] channelList) {
255         // Stop any ongoing scans before starting a new instance.
256         stopGScan();
257         ScanSettings scanSettings = new ScanSettings();
258         String message;
259         if (band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
260             ChannelSpec[] channels = new ChannelSpec[channelList.length];
261             for (int i = 0; i < channelList.length; i++) {
262                 channels[i] = new ChannelSpec(channelList[i]);
263             }
264             scanSettings.channels = channels;
265             message = "Started GScan for social channels";
266         } else {
267             scanSettings.band = band;
268             message = "Started Gscan for both band without DFS channel";
269         }
270         mGScanR = new WifiGScanReceiver(
271                 this, scanSettings, mIntervalMillis, mAlarmManager, mPIGScan);
272         registerReceiver(mGScanR, new IntentFilter(sGScanAction),
273                 Context.RECEIVER_EXPORTED_UNAUDITED);
274         Log.d(TAG, "Setting Gscan alarm. Interval: " + mIntervalMillis);
275         mGScanR.scheduleGscan();
276         mBtnStart.setEnabled(false);
277         mRadioGroup.setFocusable(false);
278         mTextView.setText(message);
279     }
280 
stopGScan()281     private void stopGScan() {
282         if (mGScanR != null) {
283             unregisterReceiver(mGScanR);
284             mGScanR.cancelGScan();
285             mGScanR = null;
286             mBtnStart.setEnabled(true);
287             mRadioGroup.setFocusable(true);
288             mTextView.setText("Stopped Gscan");
289         }
290     }
291 
startIperfClient()292     private void startIperfClient() {
293         // Stop any ongoing iperf sessions before starting a new instance.
294         stopIperfClient();
295         mIperfClient =
296                 new IperfClient(this, mServerIP, mServerPort, mIperfBandwidth, mIperfLogFile);
297         mIperfClient.startClient();
298         mBtnStart.setEnabled(false);
299         mRadioGroup.setFocusable(false);
300         mTextView.setText("Started iperf client");
301     }
302 
stopIperfClient()303     private void stopIperfClient() {
304         if (mIperfClient != null) {
305             mIperfClient.stopClient();
306             mIperfClient = null;
307             mBtnStart.setEnabled(true);
308             mRadioGroup.setFocusable(true);
309             mTextView.setText("Stopped iperf client");
310         }
311     }
312 
startUSBTethering()313     private void startUSBTethering() {
314         OnStartTetheringCallback tetherCallback = new OnStartTetheringCallback();
315         mConnManager.startTethering(ConnectivityManager.TETHERING_USB, true, tetherCallback);
316         // sleep until provisioning check for tethering is done
317         try {
318             Thread.sleep(mProvisionCheckSleep);
319         } catch (InterruptedException e) {
320             Log.d(TAG, "Sleep exception after enabling USB tethering");
321         }
322         if (mTethered) {
323             mBtnStart.setEnabled(false);
324             mRadioGroup.setFocusable(false);
325             mTextView.setText("Started usb tethering");
326         }
327     }
328 
stopUSBTethering()329     private void stopUSBTethering() {
330         if (mTethered) {
331             mConnManager.stopTethering(ConnectivityManager.TETHERING_USB);
332             mTethered = false;
333             mBtnStart.setEnabled(true);
334             mRadioGroup.setFocusable(true);
335             mTextView.setText("Stopped usb tethering");
336         }
337     }
338 
turnScreenOn(Context context)339     private void turnScreenOn(Context context) {
340         if (mWakeLock == null) {
341             PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
342             mWakeLock = pm.newWakeLock(
343                     PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);
344         }
345         if (mWakeLock != null && !mWakeLock.isHeld()) {
346             Log.i(TAG, "Turning screen on");
347             mWakeLock.acquire();
348         }
349     }
350 
turnScreenOff()351     private void turnScreenOff() {
352         if (mWakeLock != null && mWakeLock.isHeld()) {
353             Log.i(TAG, "Turning screen off");
354             mWakeLock.release();
355         }
356     }
357 
startSettingActivity()358     private void startSettingActivity() {
359         mSettingIntent = new Intent(PMCMainActivity.this, SettingActivity.class);
360         mSettingIntent.putExtra(SETTING_SERVER_IP_KEY, mServerIP);
361         mSettingIntent.putExtra(SETTING_SERVER_PORT_KEY, mServerPort);
362         mSettingIntent.putExtra(SETTING_INTERVAL_KEY, String.valueOf(mIntervalMillis / 1000));
363         mSettingIntent.putExtra(SETTING_IPERF_BANDWIDTH_KEY, mIperfBandwidth);
364         mSettingIntent.putExtra(SETTING_IPERF_LOGFILE_KEY, mIperfLogFile);
365         this.startActivityForResult(mSettingIntent, 0);
366     }
367 
setIntervalFromUser(String newValueInSeconds)368     private void setIntervalFromUser(String newValueInSeconds) {
369         if (newValueInSeconds.length() != 0 && Integer.parseInt(newValueInSeconds) >= 0) {
370             mIntervalMillis = Integer.parseInt(newValueInSeconds) * 1000;
371         }
372     }
373 
374     @Override
onCreateOptionsMenu(Menu menu)375     public boolean onCreateOptionsMenu(Menu menu) {
376         // Inflate the menu; this adds items to the action bar if it is present.
377         getMenuInflater().inflate(R.menu.main, menu);
378         return true;
379     }
380 
381     @Override
onOptionsItemSelected(MenuItem item)382     public boolean onOptionsItemSelected(MenuItem item) {
383         switch (item.getItemId()) {
384             case R.id.action_setting:
385                 startSettingActivity();
386                 return true;
387             default:
388                 return super.onOptionsItemSelected(item);
389         }
390     }
391 
392     @Override
onActivityResult(int requestCode, int resultCode, Intent data)393     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
394         super.onActivityResult(requestCode, resultCode, data);
395         //Retrieve data in the intent
396         if (resultCode == 0) {
397             mServerIP = data.getStringExtra(SETTING_SERVER_IP_KEY);
398             mServerPort = data.getStringExtra(SETTING_SERVER_PORT_KEY);
399             setIntervalFromUser(data.getStringExtra(SETTING_INTERVAL_KEY));
400             mIperfBandwidth = data.getStringExtra(SETTING_IPERF_BANDWIDTH_KEY);
401             mIperfLogFile = data.getStringExtra(SETTING_IPERF_LOGFILE_KEY);
402         }
403     }
404 
405     class PMCReceiver extends BroadcastReceiver {
406         @Override
onReceive(Context context, Intent intent)407         public void onReceive(Context context, Intent intent) {
408             if (intent.getAction().equals(AUTOPOWER_INTENT_STRING)) {
409                 Bundle extras = intent.getExtras();
410                 String key = "PowerAction";
411                 if (extras != null) {
412                     if (extras.containsKey(key)) {
413                         String actionstring = extras.getString(key);
414                         Log.d(TAG, "PowerAction = " + actionstring);
415                         if (actionstring.equalsIgnoreCase("StartConnectivityScan")) {
416                             startConnectivityScan();
417                         } else if (actionstring.equalsIgnoreCase("StopConnectivityScan")) {
418                             stopConnectivityScan();
419                         } else if (actionstring.equalsIgnoreCase("Download1KB")) {
420                             startDownloadFile("1kb.txt");
421                         } else if (actionstring.equalsIgnoreCase("Download10KB")) {
422                             startDownloadFile("10kb.txt");
423                         } else if (actionstring.equalsIgnoreCase("Download100KB")) {
424                             startDownloadFile("100kb.txt");
425                         } else if (actionstring.equalsIgnoreCase("Download1MB")) {
426                             startDownloadFile("1mb.txt");
427                         } else if (actionstring.equalsIgnoreCase("StopDownload")) {
428                             stopDownloadFile();
429                         } else if (actionstring.equalsIgnoreCase("StartGScanChannel")) {
430                             Integer[] channelList = {2412, 2437, 2462};
431                             startGscan(WifiScanner.WIFI_BAND_UNSPECIFIED, channelList);
432                         } else if (actionstring.equalsIgnoreCase("StartGScanBand")) {
433                             startGscan(WifiScanner.WIFI_BAND_BOTH, null);
434                         } else if (actionstring.equalsIgnoreCase("StopGScan")) {
435                             stopGScan();
436                         } else if (actionstring.equalsIgnoreCase("GetDownloadRate")) {
437                             if (mDR != null) {
438                                 String dataRateString = "Data Rate: "
439                                         + Integer.toString(mDR.getDownloadRate()) + " bytes/sec";
440                                 this.setResultData(dataRateString);
441                             } else {
442                                 this.setResultData("No download running");
443                             }
444                         } else if (actionstring.equalsIgnoreCase("StartIperfClient")) {
445                             startIperfClient();
446                         } else if (actionstring.equalsIgnoreCase("StopIperfClient")) {
447                             stopIperfClient();
448                         } else if (actionstring.equalsIgnoreCase("StartUSBTethering")) {
449                             startUSBTethering();
450                         } else if (actionstring.equalsIgnoreCase("StopUSBTethering")) {
451                             stopUSBTethering();
452                         } else if (actionstring.equalsIgnoreCase("TurnScreenOn")) {
453                             turnScreenOn(context);
454                         } else if (actionstring.equalsIgnoreCase("TurnScreenOff")) {
455                             turnScreenOff();
456                         }
457                         intent.removeExtra(key);
458                     }
459                 }
460             } else if (intent.getAction().equals(SETPARAMS_INTENT_STRING)) {
461                 Bundle extras = intent.getExtras();
462                 if (extras != null) {
463                     if (extras.containsKey(SETTING_INTERVAL_KEY)) {
464                         setIntervalFromUser(extras.getString(SETTING_INTERVAL_KEY));
465                     }
466                     if (extras.containsKey(SETTING_SERVER_IP_KEY)) {
467                         mServerIP = extras.getString(SETTING_SERVER_IP_KEY);
468                     }
469                     if (extras.containsKey(SETTING_SERVER_PORT_KEY)) {
470                         mServerPort = extras.getString(SETTING_SERVER_PORT_KEY);
471                     }
472                     if (extras.containsKey(SETTING_IPERF_BANDWIDTH_KEY)) {
473                         mIperfBandwidth = extras.getString(SETTING_IPERF_BANDWIDTH_KEY);
474                     }
475                     if (extras.containsKey(SETTING_IPERF_LOGFILE_KEY)) {
476                         mIperfLogFile = extras.getString(SETTING_IPERF_LOGFILE_KEY);
477                     }
478                 }
479             }
480         }
481     }
482 }
483