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