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