diff options
author | Jim Tan <jimtan@google.com> | 2016-12-28 01:33:08 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-12-28 01:33:08 +0000 |
commit | 464d2ce0aefdc77b66cd3d9c08b3b075e4eda6f6 (patch) | |
tree | f912095db66bbad25db1a4c649236c7f5161d192 | |
parent | 1a23e824c91097c9825e9e5579b11a79a8ce9b00 (diff) | |
parent | 92c4901a9855b58f1ae6d927ecd59c90bd73ae2f (diff) | |
download | platform_packages_apps_Test_connectivity-464d2ce0aefdc77b66cd3d9c08b3b075e4eda6f6.tar.gz platform_packages_apps_Test_connectivity-464d2ce0aefdc77b66cd3d9c08b3b075e4eda6f6.tar.bz2 platform_packages_apps_Test_connectivity-464d2ce0aefdc77b66cd3d9c08b3b075e4eda6f6.zip |
Merge "Move PMC from Master to AOSP" am: 53c796ea45
am: 92c4901a98
Change-Id: I65ba3b40782b75f835cd527954f3257703286daa
-rw-r--r-- | PMC/Android.mk | 24 | ||||
-rw-r--r-- | PMC/AndroidManifest.xml | 46 | ||||
-rwxr-xr-x | PMC/build_pmc.sh | 113 | ||||
-rw-r--r-- | PMC/res/drawable-xhdpi/ic_launcher.png | bin | 0 -> 12516 bytes | |||
-rw-r--r-- | PMC/res/layout/activity_linear.xml | 96 | ||||
-rw-r--r-- | PMC/res/layout/activity_setting.xml | 110 | ||||
-rw-r--r-- | PMC/res/menu/main.xml | 10 | ||||
-rw-r--r-- | PMC/res/values/dimens.xml | 7 | ||||
-rw-r--r-- | PMC/res/values/strings.xml | 27 | ||||
-rw-r--r-- | PMC/res/values/styles.xml | 18 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/BleScanReceiver.java | 276 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/IperfClient.java | 113 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/PMCMainActivity.java | 400 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/SettingActivity.java | 47 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/WifiConnScanReceiver.java | 149 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/WifiDownloadReceiver.java | 185 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/WifiGScanReceiver.java | 175 |
17 files changed, 1796 insertions, 0 deletions
diff --git a/PMC/Android.mk b/PMC/Android.mk new file mode 100644 index 0000000..fcd25bd --- /dev/null +++ b/PMC/Android.mk @@ -0,0 +1,24 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_JAVA_LIBRARIES := bouncycastle conscrypt +LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 android-support-v13 jsr305 + +LOCAL_PACKAGE_NAME := PMC +LOCAL_CERTIFICATE := platform +LOCAL_DEX_PREOPT := false + +LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PRIVILEGED_MODULE := true +LOCAL_PROGUARD_ENABLED := disabled + +include $(BUILD_PACKAGE) + + +# only include rules to build other stuff for the original package, not the derived package. +#ifeq ($(strip $(LOCAL_PACKAGE_OVERRIDES)),) +# additionally, build unit tests in a separate .apk +include $(call all-makefiles-under,$(LOCAL_PATH)) +#endif diff --git a/PMC/AndroidManifest.xml b/PMC/AndroidManifest.xml new file mode 100644 index 0000000..127e11d --- /dev/null +++ b/PMC/AndroidManifest.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.pmc" + android:versionCode="3" + android:versionName="3.0" > + + <uses-sdk + android:minSdkVersion="19" + android:targetSdkVersion="21" /> + + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> + <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> + <uses-permission android:name="android.permission.LOCATION_HARDWARE" /> + <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.BLUETOOTH" /> + <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> + + <application + android:allowBackup="true" + android:icon="@drawable/ic_launcher" + android:label="@string/app_name" + android:theme="@style/AppTheme" > + <!-- Main activity --> + <activity + android:name="com.android.pmc.PMCMainActivity" + android:configChanges="keyboardHidden|orientation|screenSize" + android:label="@string/app_name" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <!-- Settings activity --> + <activity + android:name="com.android.pmc.SettingActivity" + android:configChanges="keyboardHidden|orientation|screenSize" + android:label="@string/settings" > + </activity> + </application> + +</manifest> diff --git a/PMC/build_pmc.sh b/PMC/build_pmc.sh new file mode 100755 index 0000000..4f57274 --- /dev/null +++ b/PMC/build_pmc.sh @@ -0,0 +1,113 @@ +#! /bin/bash +#This script does a clean build of PMC and install it to your device through adb +#Requires envsetup.sh in the branch + +#function to change jdk version +function setup_jdk() { + # Remove the current JDK from PATH + if [ -n "$JAVA_HOME" ] ; then + PATH=${PATH/$JAVA_HOME\/bin:/} + fi + export JAVA_HOME=$1 + export PATH=$JAVA_HOME/bin:$PATH +} + +#Color code for echo +r='\e[0;31m' +brn='\e[0;33m' +y='\e[1;33m' +g='\e[0;32m' +cy='\e[0;36m' +lb='\e[1;34m' +p='\e[0;35m' +lg='\e[0;37m' +NC='\e[0m' # No Color + +echo -e "Welcome to ${r}U${brn}N${y}I${g}C${lb}O${cy}R${p}N${NC} build system for ${g}PMC${NC}" + +IFS='_' read -a array <<< "$TARGET_PRODUCT" +export TP=${array[0]} +if [[ ${#array[@]} -eq 2 ]]; then + export TP=${array[1]} +fi + +APP_NAME=PMC +APP_PACKAGE_NAME=com.android.pmc + +BRANCH_ROOT=$PWD/../../../../.. +PMC_PROJ=$BRANCH_ROOT/vendor/google_testing/comms/Tools/PMC +SHARED_LIB_JAR_ROOT=$BRANCH_ROOT/out/target/common/obj/JAVA_LIBRARIES +APP_JAR_ROOT=$BRANCH_ROOT/out/target/common/obj/APPS +APK_ROOT=$BRANCH_ROOT/out/target/product/$TP/system/priv-app/PMC + +function pmc_build { + +echo -e "${y}Removing intermeidates of the app${NC}" +rm -r $APP_JAR_ROOT/"$APP_NAME"_intermediates +#Remove the apk file +rm $APK_ROOT/"$APP_NAME".apk + +#Build all the dependency libs +. $BRANCH_ROOT/build/envsetup.sh + +exec () { + ${@:1:($#-1)} + if [ $? -ne 0 ]; then + echo -e "${r}Encountered error when ${@:$#}${NC}" + echo -e "${lg}UNICORN ${r}DIED${NC}!" + exit 1 + fi +} + +echo -e "${lb}+++++++ Building $APP_NAME.apk +++++++${NC}" +cd $PMC_PROJ +exec mm -B "building $APP_NAME.apk" +echo + +} + +function pmc_flash { + +echo -e "${y}Switching to root${NC}" +adb root +adb wait-for-device remount + +echo -e "${y}Uninstalling old apk from device${NC}" +adb uninstall $APP_PACKAGE_NAME +adb shell rm -r /system/priv-app/$APP_NAME.apk + +echo -e "${lb}Installing apk to device${NC}" +cd $APK_ROOT +#exec adb install $APP_NAME.apk "installing apk to device" +#exec adb push $APP_NAME.apk /system/priv-app "installing apk to previliged dir" +exec adb install -r $APP_NAME.apk "installing apk to previliged dir" + +} + +DO_BUILD=1 +DO_FLASH=1 + +if [ $# -ne 0 ] ; then + DO_BUILD=0 + DO_FLASH=0 + while getopts "bf" ARG + do + case $ARG in + b) DO_BUILD=1 && echo "Build it we will.";; + f) DO_FLASH=1 && echo "Flash it we must.";; + ?) echo "Invalid Argument ${ARG}" && exit 1;; + esac + done +fi + +if [ ${DO_BUILD} -eq "1" ] ; then + pmc_build +fi + +if [ ${DO_FLASH} -eq "1" ] ; then + pmc_flash +fi + +echo "All clear!" +echo -e " ${r}U${brn}N${y}I${g}C${cy}O${lb}R${p}N ${r}P${brn}O${y}W${g}E${cy}R${lb}!${p}!${NC}" + diff --git a/PMC/res/drawable-xhdpi/ic_launcher.png b/PMC/res/drawable-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..d4fb7cd --- /dev/null +++ b/PMC/res/drawable-xhdpi/ic_launcher.png diff --git a/PMC/res/layout/activity_linear.xml b/PMC/res/layout/activity_linear.xml new file mode 100644 index 0000000..6461b4d --- /dev/null +++ b/PMC/res/layout/activity_linear.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" > + + <TextView + android:id="@+id/text_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:textSize="18sp" + android:text="@string/choose_pm_activity" /> + + <RadioGroup + android:id="@+id/rb_dataselect" + android:layout_below="@+id/text_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" > + + <RadioButton + android:id="@+id/rb_connscan" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/conn_scan" + android:checked="true" /> + + <RadioButton + android:id="@+id/rb_kb" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/kbfile"/> + + <RadioButton + android:id="@+id/rb_tenkb" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/tenkbfile" /> + + <RadioButton + android:id="@+id/rb_hundredkb" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/hundredkbfile" /> + + <RadioButton + android:id="@+id/rb_mb" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/mbfile" /> + + <RadioButton + android:id="@+id/rb_gscan2g" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/gscan_2g" /> + + <RadioButton + android:id="@+id/rb_gscan_without_dfs" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/gscan_without_dfs" /> + + <RadioButton + android:id="@+id/rb_iperf_client" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/iperf_client" /> + </RadioGroup> + + <Button + android:id="@+id/btnstart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignBaseline="@+id/btnstop" + android:layout_alignBottom="@+id/btnstop" + android:layout_alignStart="@+id/rb_dataselect" + android:text="@string/btn_start" /> + + <Button + android:id="@+id/btnstop" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@+id/rb_dataselect" + android:layout_toEndOf="@+id/text_content" + android:text="@string/btn_stop" /> + + <TextView + android:id="@+id/text_content" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignEnd="@+id/text_title" + android:layout_alignParentStart="true" + android:layout_below="@+id/btnstart" /> + +</RelativeLayout> diff --git a/PMC/res/layout/activity_setting.xml b/PMC/res/layout/activity_setting.xml new file mode 100644 index 0000000..b682a9b --- /dev/null +++ b/PMC/res/layout/activity_setting.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" > + + <TextView + android:id="@+id/server_ip" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:labelFor="@+id/server_iptext" + android:textSize="16sp" + android:text="@string/server_ip" /> + + <EditText + android:id="@+id/server_iptext" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@+id/server_ip" + android:layout_marginTop="16dp" + android:inputType="phone" + android:ems="10" /> + + <TextView + android:id="@+id/server_port" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@+id/server_iptext" + android:labelFor="@+id/server_porttext" + android:layout_marginTop="33dp" + android:textSize="16sp" + android:text="@string/server_port" /> + + <EditText + android:id="@+id/server_porttext" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@+id/server_port" + android:layout_marginTop="17dp" + android:inputType="number" + android:ems="10" /> + + <TextView + android:id="@+id/interval" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@+id/server_porttext" + android:labelFor="@+id/intervaltext" + android:layout_marginTop="33dp" + android:textSize="16sp" + android:text="@string/interval" /> + + <EditText + android:id="@+id/intervaltext" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@+id/interval" + android:layout_marginTop="17dp" + android:inputType="number" + android:ems="10" /> + + <TextView + android:id="@+id/iperf_bandwidth" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@+id/intervaltext" + android:labelFor="@+id/iperf_bandwidthtext" + android:layout_marginTop="33dp" + android:textSize="16sp" + android:text="@string/iperf_bandwidth" /> + + <EditText + android:id="@+id/iperf_bandwidthtext" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@+id/iperf_bandwidth" + android:layout_marginTop="17dp" + android:inputType="number" + android:ems="10" /> + + <TextView + android:id="@+id/iperf_logfile" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@+id/iperf_bandwidthtext" + android:labelFor="@+id/iperf_logfiletext" + android:layout_marginTop="33dp" + android:textSize="16sp" + android:text="@string/iperf_logfile" /> + + <EditText + android:id="@+id/iperf_logfiletext" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@+id/iperf_logfile" + android:layout_marginTop="17dp" + android:inputType="text" + android:ems="10" /> + +</RelativeLayout> diff --git a/PMC/res/menu/main.xml b/PMC/res/menu/main.xml new file mode 100644 index 0000000..0286b46 --- /dev/null +++ b/PMC/res/menu/main.xml @@ -0,0 +1,10 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + tools:context="com.example.dataflow.MainActivity" > + + <item + android:id="@+id/action_setting" + android:orderInCategory="100" + android:showAsAction="never" + android:title="@string/settings"/> +</menu> diff --git a/PMC/res/values/dimens.xml b/PMC/res/values/dimens.xml new file mode 100644 index 0000000..55c1e59 --- /dev/null +++ b/PMC/res/values/dimens.xml @@ -0,0 +1,7 @@ +<resources> + + <!-- Default screen margins, per the Android Design guidelines. --> + <dimen name="activity_horizontal_margin">16dp</dimen> + <dimen name="activity_vertical_margin">16dp</dimen> + +</resources> diff --git a/PMC/res/values/strings.xml b/PMC/res/values/strings.xml new file mode 100644 index 0000000..2d37c06 --- /dev/null +++ b/PMC/res/values/strings.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string name="app_name">PMC</string> + <string name="settings">Settings</string> + <string name="choose_pm_activity">Start Power Measuring Activity</string> + <string name="start_dataflow">Start background data!</string> + <string name="action_settings">Settings</string> + <string name="action_stop">Stop</string> + <string name="action_start">Start</string> + <string name="conn_scan">Connectivity Scan</string> + <string name="gscan_2g">GScan for Channel-1,6,11</string> + <string name="gscan_without_dfs">GScan without DFS Channel</string> + <string name="iperf_client">Iperf Client</string> + <string name="kbfile">Download 1KB file</string> + <string name="tenkbfile">Download 10KB file</string> + <string name="hundredkbfile">Download 100KB file</string> + <string name="mbfile">Download 1MB file</string> + <string name="btn_start">Start</string> + <string name="btn_stop">Stop</string> + <string name="server_ip">Server IP</string> + <string name="server_port">Server Port</string> + <string name="interval">Download/Scan Interval (seconds)</string> + <string name="iperf_bandwidth">Iperf Bandwidth</string> + <string name="iperf_logfile">Iperf Logfile</string> + +</resources> diff --git a/PMC/res/values/styles.xml b/PMC/res/values/styles.xml new file mode 100644 index 0000000..d53bc55 --- /dev/null +++ b/PMC/res/values/styles.xml @@ -0,0 +1,18 @@ +<resources> + + <!-- + Base application theme for API 14+. This theme completely replaces + AppBaseTheme from BOTH res/values/styles.xml and + res/values-v11/styles.xml on API 14+ devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar"> + <!-- API 14 theme customizations can go here. --> + </style> + + <!-- Application theme. --> + <style name="AppTheme" parent="AppBaseTheme"> + <!-- All customizations that are NOT specific to a particular API-level can go here. --> + </style> + + +</resources> diff --git a/PMC/src/com/android/pmc/BleScanReceiver.java b/PMC/src/com/android/pmc/BleScanReceiver.java new file mode 100644 index 0000000..91ab526 --- /dev/null +++ b/PMC/src/com/android/pmc/BleScanReceiver.java @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2016 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.pmc; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.le.BluetoothLeScanner; +import android.bluetooth.le.ScanCallback; +import android.bluetooth.le.ScanFilter; +import android.bluetooth.le.ScanResult; +import android.bluetooth.le.ScanSettings; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.SystemClock; +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; + +/** + * Bluetooth LE Receiver functions for power testing. + */ +public class BleScanReceiver extends BroadcastReceiver { + public static final String TAG = "BLEPOWER"; + public static final String BLE_SCAN_INTENT = "com.android.pmc.BLESCAN"; + public static final int START_SCAN = 1; + public static final int STOP_SCAN = 2; + public static final int INIT_ALARM_NO = 1; + private final Context mContext; + private final AlarmManager mAlarmManager; + private final BleScanListener mAlarmScanListener; + private BluetoothLeScanner mBleScanner; + private ScanSettings mScanSettings; + private List<ScanFilter> mScanFilterList; + + private ScanCallback mScanCallback = new ScanCallback() { + @Override + public void onScanResult(int callbackType, ScanResult result) { + Log.e(TAG, "Bluetooth scan result: " + result.toString()); + } + + @Override + public void onScanFailed(int errorCode) { + Log.e(TAG, "Scan Failed: " + errorCode); + } + }; + + /** + * Class to provide callback for AlarmManager to start BLE scan alarms + */ + public class BleScanListener extends BroadcastReceiver { + + public static final String BLESCAN = + "com.android.pmc.BLESCAN.ALARM"; + + private int mScanTime; + private int mNoScanTime; + private int mNumAlarms; + + /** + * Constructor + * + */ + public BleScanListener() { + BluetoothAdapter bleAdaptor = BluetoothAdapter.getDefaultAdapter(); + if (bleAdaptor == null) { + Log.e(TAG, "BleAdaptor is Null"); + return; + } else { + if (!bleAdaptor.isEnabled()) { + Log.e(TAG, "BleAdaptor is NOT enabled"); + return; + } + } + mBleScanner = bleAdaptor.getBluetoothLeScanner(); + mScanFilterList = new ArrayList<ScanFilter>(); + } + + /** + * Function to be called by BleScanReceiver to start + * Initial Bluetooth scan alarm + * + * @param scanMode - scan mode + * @param startTime - time when the first scan needs to be started + * @param scanTime - time for the scan is lasted + * @param noScanTime - time when the scan is stopped + * @param numAlarms - number of alarms to start and to stop scan + * + */ + public void firstAlarm(int scanMode, int startTime, int scanTime, + int noScanTime, int numAlarms) { + Log.d(TAG, "First Alarm for scan mode: " + scanMode); + mScanTime = scanTime; + mNoScanTime = noScanTime; + mNumAlarms = numAlarms; + mScanSettings = new ScanSettings.Builder().setScanMode( + scanMode).build(); + + Intent alarmIntent = new Intent(BleScanListener.BLESCAN); + alarmIntent.putExtra("com.android.pmc.BLESCAN.Action", START_SCAN); + alarmIntent.putExtra("com.android.pmc.BLESCAN.CurrentAlarm", INIT_ALARM_NO); + long triggerTime = SystemClock.elapsedRealtime() + + startTime * 1000; + mAlarmManager.setExactAndAllowWhileIdle( + AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime, + PendingIntent.getBroadcast(mContext, 0, + alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT)); + } + + /** + * Function to be called by onReceive() to start subsequent alarm + * + * @param intent - intent to get extra data + * @param timeInterval - time for alarm to trigger next alarm + * @param nextAction - next action for the alarm + * + */ + public void repeatAlarm(Intent intent, int timeInterval, + int nextAction) { + + int currentAlarm = intent.getIntExtra("com.android.pmc.BLESCAN.CurrentAlarm", 0); + Log.d(TAG, "repeatAlarm() currentAlarm: " + currentAlarm); + if (currentAlarm == 0) { + Log.d(TAG, "Received Alarm with no currentAlarm"); + return; + } + if (currentAlarm >= mNumAlarms) { + Log.d(TAG, "All alarms are done"); + return; + } + Log.d(TAG, "Next Action: " + nextAction); + Intent alarmIntent = new Intent(BleScanListener.BLESCAN); + alarmIntent.putExtra("com.android.pmc.BLESCAN.Action", nextAction); + alarmIntent.putExtra("com.android.pmc.BLESCAN.CurrentAlarm", ++currentAlarm); + long triggerTime = SystemClock.elapsedRealtime() + + timeInterval * 1000; + mAlarmManager.setExactAndAllowWhileIdle( + AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime, + PendingIntent.getBroadcast(mContext, 0, + alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT)); + } + + /** + * Callback will be called for AlarmManager to start Bluetooth LE scan + * + * @param context - system will provide a context to this function + * @param intent - system will provide an intent to this function + */ + @Override + public void onReceive(Context context, Intent intent) { + if (!intent.getAction().equals(BLESCAN)) { + return; + } + int action = intent.getIntExtra("com.android.pmc.BLESCAN.Action", 0); + Log.d(TAG, "onReceive() Action: " + action); + if (action == -1) { + Log.e(TAG, "Received Alarm with no Action"); + return; + } + if (action == START_SCAN) { + Log.v(TAG, "Before Start Scan"); + mBleScanner.startScan(mScanFilterList, mScanSettings, + mScanCallback); + repeatAlarm(intent, mScanTime, STOP_SCAN); + } else if (action == STOP_SCAN) { + Log.v(TAG, "Before Stop scan"); + mBleScanner.stopScan(mScanCallback); + repeatAlarm(intent, mNoScanTime, START_SCAN); + } else { + Log.e(TAG, "Unknown Action"); + } + } + } + + /** + * Constructor to be called by PMC + * + * @param context - PMC will provide a context + * @param alarmManager - PMC will provide alarmManager + */ + public BleScanReceiver(Context context, AlarmManager alarmManager) { + // prepare for setting alarm service + mContext = context; + mAlarmManager = alarmManager; + mAlarmScanListener = new BleScanListener(); + + // RegisterAlarmReceiver for BleStartScanListener and BleStopScanListener + mContext.registerReceiver(mAlarmScanListener, + new IntentFilter(BleScanListener.BLESCAN)); + + } + + /** + * Method to receive the broadcast from python client + * + * @param context - system will provide a context to this function + * @param intent - system will provide an intent to this function + */ + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(BLE_SCAN_INTENT)) { + Bundle extras = intent.getExtras(); + int scanMode = -1, startTime = 0, scanTime = 0, noScanTime = 0; + int repetitions = 1; + String str; + + if (extras == null) { + Log.e(TAG, "No parameters specified"); + return; + } + + if (!extras.containsKey("ScanMode")) { + Log.e(TAG, "No scan mode specified"); + return; + } + str = extras.getString("ScanMode"); + Log.d(TAG, "Scan Mode = " + str); + scanMode = Integer.valueOf(str); + + if (!extras.containsKey("StartTime")) { + Log.e(TAG, "No Start Time specified"); + return; + } + str = extras.getString("StartTime"); + Log.d(TAG, "Start Time = " + str); + startTime = Integer.valueOf(str); + + if (!extras.containsKey("ScanTime")) { + Log.e(TAG, "No Scan Time specified"); + return; + } + str = extras.getString("ScanTime"); + Log.d(TAG, "Scan Time = " + str); + scanTime = Integer.valueOf(str); + + if (extras.containsKey("Repetitions")) { + + str = extras.getString("Repetitions"); + Log.d(TAG, "Repetitions = " + str); + repetitions = Integer.valueOf(str); + + if (!extras.containsKey("NoScanTime")) { + Log.e(TAG, "No NoScan Time specified"); + return; + } + str = extras.getString("NoScanTime"); + Log.d(TAG, "NoScan Time = " + str); + noScanTime = Integer.valueOf(str); + } + if (scanTime == 0 || startTime == 0 || scanMode == -1) { + Log.d(TAG, "Invalid paramters"); + return; + } + mAlarmScanListener.firstAlarm(scanMode, startTime, + scanTime, noScanTime, repetitions * 2); + } + } +} diff --git a/PMC/src/com/android/pmc/IperfClient.java b/PMC/src/com/android/pmc/IperfClient.java new file mode 100644 index 0000000..a6dbf99 --- /dev/null +++ b/PMC/src/com/android/pmc/IperfClient.java @@ -0,0 +1,113 @@ +package com.android.pmc; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.WifiManager; +import android.os.AsyncTask; +import android.os.PowerManager; +import android.os.SystemClock; +import android.util.Log; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * Starts an iperf client with the provided params for data transmission tests. + * The client starts a UDP data transfer with the provided server with the max possible timeout.t a + */ +public class IperfClient { + + private static final String IPERF_COMMAND = "iperf3"; + private static final String IPERF_OPTION_SERVER_FLAG = "-c"; + private static final String IPERF_OPTION_PORT_FLAG = "-p"; + private static final String IPERF_OPTION_BANDWIDTH_FLAG = "-b"; + private static final String IPERF_OPTION_INTERVAL_FLAG = "-i"; + private static final String IPERF_OPTION_VERBOSE_FLAG = "-V"; + private static final String IPERF_OPTION_UDP_FLAG = "-u"; + private static final String IPERF_OPTION_JSON_OUTPUT_FLAG = "-J"; + private static final String IPERF_OPTION_TIMEOUT_FLAG = "-t"; + private static final String IPERF_OPTION_LOGFILE_FLAG = "--logfile"; + private static final String IPERF_OPTION_TMPDIR_FLAG = "--tmpdir"; + private static final int IPERF_OPTION_INTERVAL = 2; + // This is the max value supported by iperf3. + private static final int IPERF_OPTION_TIMEOUT = 86400; + + private final PMCMainActivity mPMCMainActivity; + private final ProcessBuilder mProcessBuilder; + private PowerManager.WakeLock mWakeLock; + private Process mProcess; + private File mLogFile; + + public IperfClient(PMCMainActivity activity, String serverAddress, + String serverPort, String bandWidthInMbps, String logFile) { + mPMCMainActivity = activity; + List<String> cmdList = new ArrayList<>(); + cmdList.add(IPERF_COMMAND); + cmdList.add(IPERF_OPTION_VERBOSE_FLAG); + cmdList.add(IPERF_OPTION_UDP_FLAG); + cmdList.add(IPERF_OPTION_JSON_OUTPUT_FLAG); + cmdList.add(IPERF_OPTION_INTERVAL_FLAG); + cmdList.add(Integer.toString(IPERF_OPTION_INTERVAL)); + cmdList.add(IPERF_OPTION_TIMEOUT_FLAG); + cmdList.add(Integer.toString(IPERF_OPTION_TIMEOUT)); + cmdList.add(IPERF_OPTION_TMPDIR_FLAG); + cmdList.add(activity.getCacheDir().getPath()); + if (serverAddress != null && serverAddress.length() > 0) { + cmdList.add(IPERF_OPTION_SERVER_FLAG); + cmdList.add(serverAddress); + } + if (serverPort != null && serverPort.length() > 0) { + cmdList.add(IPERF_OPTION_PORT_FLAG); + cmdList.add(serverPort); + } + if (bandWidthInMbps != null && bandWidthInMbps.length() > 0) { + cmdList.add(IPERF_OPTION_BANDWIDTH_FLAG); + cmdList.add(bandWidthInMbps); + } + if (logFile != null && logFile.length() > 0) { + mLogFile = new File(logFile); + } + mProcessBuilder = new ProcessBuilder(cmdList); + } + + /** + * Start the iperf client + */ + public void startClient() { + Log.i(PMCMainActivity.TAG, "Starting iperf client: " + mProcessBuilder.command()); + PowerManager pm = (PowerManager) mPMCMainActivity.getSystemService(Context.POWER_SERVICE); + mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WIFITEST"); + // Acquire the lock + mWakeLock.acquire(); + try { + mProcessBuilder.redirectOutput(mLogFile); + mProcessBuilder.redirectError(mLogFile); + mProcess = mProcessBuilder.start(); + } catch (Exception e) { + Log.e(PMCMainActivity.TAG, "Starting iperf client failed: " + e); + mPMCMainActivity.updateProgressStatus("Starting iperf client failed"); + } + } + + /** + * Stop the iperf client + */ + public void stopClient() { + if (mProcess != null) { + Log.i(PMCMainActivity.TAG, "Stopping iperf client: " + mProcessBuilder.command()); + try { + mProcess.destroy(); + mProcess.waitFor(); + } catch (Exception e) { + Log.e(PMCMainActivity.TAG, "Stopping iperf client failed: " + e); + } + mWakeLock.release(); + mProcess = null; + } + } +} diff --git a/PMC/src/com/android/pmc/PMCMainActivity.java b/PMC/src/com/android/pmc/PMCMainActivity.java new file mode 100644 index 0000000..71c7920 --- /dev/null +++ b/PMC/src/com/android/pmc/PMCMainActivity.java @@ -0,0 +1,400 @@ +package com.android.pmc; + +import android.app.Activity; +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.WifiScanner; +import android.net.wifi.WifiScanner.ChannelSpec; +import android.net.wifi.WifiScanner.ScanSettings; +import android.os.Bundle; +import android.os.PowerManager; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.RadioGroup; +import android.widget.TextView; +import android.widget.Toast; + +public class PMCMainActivity extends Activity { + + public static final String TAG = "PMC"; + public static final String SETTING_SERVER_IP_KEY = "ServerIP"; + public static final String SETTING_SERVER_PORT_KEY = "ServerPort"; + public static final String SETTING_INTERVAL_KEY = "Interval"; + public static final String SETTING_IPERF_BANDWIDTH_KEY = "IperfBandwidth"; + public static final String SETTING_IPERF_LOGFILE_KEY = "IperfLogfile"; + private static final String sConnScanAction = "ConnectionScan"; + private static final String sGScanAction = "GScan"; + private static final String sDownloadAction = "DownloadData"; + private static final String SETPARAMS_INTENT_STRING = "com.android.pmc.action.SETPARAMS"; + private static final String AUTOPOWER_INTENT_STRING = "com.android.pmc.action.AUTOPOWER"; + + TextView mTextView; + Intent mSettingIntent; + private PendingIntent mPIGScan; + private PendingIntent mPIDownload; + private PendingIntent mPIConnScan; + private String mServerIP = "10.10.10.1"; + private String mServerPort = "8080"; + private int mIntervalMillis = 60 * 1000; + private String mIperfBandwidth = "1M"; + private String mIperfLogFile = "/sdcard/iperf.txt"; + private WifiConnScanReceiver mConnSR = null; + private WifiGScanReceiver mGScanR = null; + private WifiDownloadReceiver mDR = null; + private IperfClient mIperfClient = null; + private RadioGroup mRadioGroup; + private Button mBtnStart; + private Button mBtnStop; + private PMCReceiver mPMCReceiver; + private BleScanReceiver mBleScanReceiver; + private AlarmManager mAlarmManager; + private PowerManager.WakeLock mWakeLock; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //Initiate wifi service manger + mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + mPIGScan = PendingIntent.getBroadcast(this, 0, new Intent(sGScanAction), 0); + mPIDownload = PendingIntent.getBroadcast(this, 0, new Intent(sDownloadAction), 0); + mPIConnScan = PendingIntent.getBroadcast(this, 0, new Intent(sConnScanAction), 0); + mPMCReceiver = new PMCReceiver(); + mBleScanReceiver = new BleScanReceiver(this, mAlarmManager); + setContentView(R.layout.activity_linear); + mTextView = (TextView) findViewById(R.id.text_content); + mRadioGroup = (RadioGroup) findViewById(R.id.rb_dataselect); + mBtnStart = (Button) findViewById(R.id.btnstart); + mBtnStop = (Button) findViewById(R.id.btnstop); + addListenerOnButton(); + registerReceiver(mPMCReceiver, new IntentFilter(AUTOPOWER_INTENT_STRING)); + registerReceiver(mPMCReceiver, new IntentFilter(SETPARAMS_INTENT_STRING)); + registerReceiver(mBleScanReceiver, new IntentFilter(BleScanReceiver.BLE_SCAN_INTENT)); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(mPMCReceiver); + } + + public void addListenerOnButton() { + mBtnStart.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // get selected radio button from radioGroup + int selectedId = mRadioGroup.getCheckedRadioButtonId(); + switch (selectedId) { + case R.id.rb_hundredkb: + startDownloadFile("100kb.txt"); + break; + case R.id.rb_kb: + startDownloadFile("1kb.txt"); + break; + case R.id.rb_tenkb: + startDownloadFile("10kb.txt"); + break; + case R.id.rb_mb: + startDownloadFile("1mb.txt"); + break; + case R.id.rb_connscan: + startConnectivityScan(); + break; + case R.id.rb_gscan2g: + Integer[] channelList = {2412, 2437, 2462}; + startGscan(WifiScanner.WIFI_BAND_UNSPECIFIED, channelList); + break; + case R.id.rb_gscan_without_dfs: + startGscan(WifiScanner.WIFI_BAND_BOTH, null); + break; + case R.id.rb_iperf_client: + startIperfClient(); + break; + default: + return; + } + } + }); + + mBtnStop.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + stopConnectivityScan(); + stopDownloadFile(); + stopGScan(); + stopIperfClient(); + mBtnStart.setEnabled(true); + } + }); + } + + /** + * Updates progress on the UI. + * @param status + */ + public void updateProgressStatus(String status) { + mTextView.setText(status); + } + + private void startDownloadFile(String filename) { + // Stop any ongoing download sessions before starting a new instance. + stopDownloadFile(); + Log.d(TAG, "serverIP ::" + mServerIP + " Port ::" + mServerPort + + ". Interval: " + mIntervalMillis); + if (mServerIP.length() == 0 || mServerPort.length() == 0) { + String msg = "Provide server IP and Port information in Setting"; + Toast errorMsg = Toast.makeText(getBaseContext(), msg, Toast.LENGTH_LONG); + errorMsg.show(); + startSettingActivity(); + } else { + mDR = new WifiDownloadReceiver(PMCMainActivity.this, + "http://" + mServerIP + ":" + mServerPort + "/" + filename, mIntervalMillis, + mAlarmManager, mPIDownload); + registerReceiver(mDR, new IntentFilter(sDownloadAction)); + Log.d(TAG, "Setting download data alarm. Interval: " + mIntervalMillis); + mDR.scheduleDownload(); + mBtnStart.setEnabled(false); + mRadioGroup.setFocusable(false); + mTextView.setText("Started downloadng " + filename); + } + } + + private void stopDownloadFile() { + if (mDR != null) { + unregisterReceiver(mDR); + mDR.cancelDownload(); + mDR = null; + mBtnStart.setEnabled(true); + mRadioGroup.setFocusable(true); + mTextView.setText("Stopped download"); + } + } + + private void startConnectivityScan() { + // Stop any ongoing scans before starting a new instance. + stopConnectivityScan(); + mConnSR = new WifiConnScanReceiver(this, mIntervalMillis, mAlarmManager, mPIConnScan); + registerReceiver(mConnSR, new IntentFilter(sConnScanAction)); + Log.d(TAG, "Setting connectivity scan alarm. Interval: " + mIntervalMillis); + mConnSR.scheduleConnScan(); + mBtnStart.setEnabled(false); + mRadioGroup.setFocusable(false); + mTextView.setText("Started connectivity scan"); + } + + private void stopConnectivityScan() { + if (mConnSR != null) { + unregisterReceiver(mConnSR); + mConnSR.cancelConnScan(); + mConnSR = null; + mBtnStart.setEnabled(true); + mRadioGroup.setFocusable(true); + mTextView.setText("Stopped connectivity scan"); + } + } + + private void startGscan(int band, Integer[] channelList) { + // Stop any ongoing scans before starting a new instance. + stopGScan(); + ScanSettings scanSettings = new ScanSettings(); + String message; + if (band == WifiScanner.WIFI_BAND_UNSPECIFIED) { + ChannelSpec[] channels = new ChannelSpec[channelList.length]; + for (int i = 0; i < channelList.length; i++) { + channels[i] = new ChannelSpec(channelList[i]); + } + scanSettings.channels = channels; + message = "Started GScan for social channels"; + } else { + scanSettings.band = band; + message = "Started Gscan for both band without DFS channel"; + } + mGScanR = new WifiGScanReceiver( + this, scanSettings, mIntervalMillis, mAlarmManager, mPIGScan); + registerReceiver(mGScanR, new IntentFilter(sGScanAction)); + Log.d(TAG, "Setting Gscan alarm. Interval: " + mIntervalMillis); + mGScanR.scheduleGscan(); + mBtnStart.setEnabled(false); + mRadioGroup.setFocusable(false); + mTextView.setText(message); + } + + private void stopGScan() { + if (mGScanR != null) { + unregisterReceiver(mGScanR); + mGScanR.cancelGScan(); + mGScanR = null; + mBtnStart.setEnabled(true); + mRadioGroup.setFocusable(true); + mTextView.setText("Stopped Gscan"); + } + } + + private void startIperfClient() { + // Stop any ongoing iperf sessions before starting a new instance. + stopIperfClient(); + mIperfClient = + new IperfClient(this, mServerIP, mServerPort, mIperfBandwidth, mIperfLogFile); + mIperfClient.startClient(); + mBtnStart.setEnabled(false); + mRadioGroup.setFocusable(false); + mTextView.setText("Started iperf client"); + } + + private void stopIperfClient() { + if (mIperfClient != null) { + mIperfClient.stopClient(); + mIperfClient = null; + mBtnStart.setEnabled(true); + mRadioGroup.setFocusable(true); + mTextView.setText("Stopped iperf client"); + } + } + + private void turnScreenOn(Context context) { + if (mWakeLock == null) { + PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); + mWakeLock = pm.newWakeLock( + PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG); + } + if (mWakeLock != null && !mWakeLock.isHeld()) { + Log.i(TAG, "Turning screen on"); + mWakeLock.acquire(); + } + } + + private void turnScreenOff() { + if (mWakeLock != null && mWakeLock.isHeld()) { + Log.i(TAG, "Turning screen off"); + mWakeLock.release(); + } + } + + private void startSettingActivity() { + mSettingIntent = new Intent(PMCMainActivity.this, SettingActivity.class); + mSettingIntent.putExtra(SETTING_SERVER_IP_KEY, mServerIP); + mSettingIntent.putExtra(SETTING_SERVER_PORT_KEY, mServerPort); + mSettingIntent.putExtra(SETTING_INTERVAL_KEY, String.valueOf(mIntervalMillis / 1000)); + mSettingIntent.putExtra(SETTING_IPERF_BANDWIDTH_KEY, mIperfBandwidth); + mSettingIntent.putExtra(SETTING_IPERF_LOGFILE_KEY, mIperfLogFile); + this.startActivityForResult(mSettingIntent, 0); + } + + private void setIntervalFromUser(String newValueInSeconds) { + if (newValueInSeconds.length() != 0 && Integer.parseInt(newValueInSeconds) >= 0) { + mIntervalMillis = Integer.parseInt(newValueInSeconds) * 1000; + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_setting: + startSettingActivity(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + //Retrieve data in the intent + if (resultCode == 0) { + mServerIP = data.getStringExtra(SETTING_SERVER_IP_KEY); + mServerPort = data.getStringExtra(SETTING_SERVER_PORT_KEY); + setIntervalFromUser(data.getStringExtra(SETTING_INTERVAL_KEY)); + mIperfBandwidth = data.getStringExtra(SETTING_IPERF_BANDWIDTH_KEY); + mIperfLogFile = data.getStringExtra(SETTING_IPERF_LOGFILE_KEY); + } + } + + class PMCReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(AUTOPOWER_INTENT_STRING)) { + Bundle extras = intent.getExtras(); + String key = "PowerAction"; + if (extras != null) { + if (extras.containsKey(key)) { + String actionstring = extras.getString(key); + Log.d(TAG, "PowerAction = " + actionstring); + if (actionstring.equalsIgnoreCase("StartConnectivityScan")) { + startConnectivityScan(); + } else if (actionstring.equalsIgnoreCase("StopConnectivityScan")) { + stopConnectivityScan(); + } else if (actionstring.equalsIgnoreCase("Download1KB")) { + startDownloadFile("1kb.txt"); + } else if (actionstring.equalsIgnoreCase("Download10KB")) { + startDownloadFile("10kb.txt"); + } else if (actionstring.equalsIgnoreCase("Download100KB")) { + startDownloadFile("100kb.txt"); + } else if (actionstring.equalsIgnoreCase("Download1MB")) { + startDownloadFile("1mb.txt"); + } else if (actionstring.equalsIgnoreCase("StopDownload")) { + stopDownloadFile(); + } else if (actionstring.equalsIgnoreCase("StartGScanChannel")) { + Integer[] channelList = {2412, 2437, 2462}; + startGscan(WifiScanner.WIFI_BAND_UNSPECIFIED, channelList); + } else if (actionstring.equalsIgnoreCase("StartGScanBand")) { + startGscan(WifiScanner.WIFI_BAND_BOTH, null); + } else if (actionstring.equalsIgnoreCase("StopGScan")) { + stopGScan(); + } else if (actionstring.equalsIgnoreCase("GetDownloadRate")) { + if (mDR != null) { + String dataRateString = "Data Rate: " + + Integer.toString(mDR.getDownloadRate()) + " bytes/sec"; + this.setResultData(dataRateString); + } else { + this.setResultData("No download running"); + } + } else if (actionstring.equalsIgnoreCase("StartIperfClient")) { + startIperfClient(); + } else if (actionstring.equalsIgnoreCase("StopIperfClient")) { + stopIperfClient(); + } else if (actionstring.equalsIgnoreCase("TurnScreenOn")) { + turnScreenOn(context); + } else if (actionstring.equalsIgnoreCase("TurnScreenOff")) { + turnScreenOff(); + } + intent.removeExtra(key); + } + } + } else if (intent.getAction().equals(SETPARAMS_INTENT_STRING)) { + Bundle extras = intent.getExtras(); + if (extras != null) { + if (extras.containsKey(SETTING_INTERVAL_KEY)) { + setIntervalFromUser(extras.getString(SETTING_INTERVAL_KEY)); + } + if (extras.containsKey(SETTING_SERVER_IP_KEY)) { + mServerIP = extras.getString(SETTING_SERVER_IP_KEY); + } + if (extras.containsKey(SETTING_SERVER_PORT_KEY)) { + mServerPort = extras.getString(SETTING_SERVER_PORT_KEY); + } + if (extras.containsKey(SETTING_IPERF_BANDWIDTH_KEY)) { + mIperfBandwidth = extras.getString(SETTING_IPERF_BANDWIDTH_KEY); + } + if (extras.containsKey(SETTING_IPERF_LOGFILE_KEY)) { + mIperfLogFile = extras.getString(SETTING_IPERF_LOGFILE_KEY); + } + } + } + } + } +} diff --git a/PMC/src/com/android/pmc/SettingActivity.java b/PMC/src/com/android/pmc/SettingActivity.java new file mode 100644 index 0000000..4b95577 --- /dev/null +++ b/PMC/src/com/android/pmc/SettingActivity.java @@ -0,0 +1,47 @@ +package com.android.pmc; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.widget.EditText; + +public class SettingActivity extends Activity { + + EditText mServerIP; + EditText mServerPort; + EditText mInterval; + EditText mIperfBandwidth; + EditText mIperfLogfile; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_setting); + mServerIP = (EditText) findViewById(R.id.server_iptext); + mServerPort = (EditText) findViewById(R.id.server_porttext); + mInterval = (EditText) findViewById(R.id.intervaltext); + mIperfBandwidth = (EditText) findViewById(R.id.iperf_bandwidthtext); + mIperfLogfile = (EditText) findViewById(R.id.iperf_logfiletext); + // Populate the fields with the current values passed from PMCMainActivity. + Intent intent = this.getIntent(); + mServerIP.setText(intent.getStringExtra(PMCMainActivity.SETTING_SERVER_IP_KEY)); + mServerPort.setText(intent.getStringExtra(PMCMainActivity.SETTING_SERVER_PORT_KEY)); + mInterval.setText(intent.getStringExtra(PMCMainActivity.SETTING_INTERVAL_KEY)); + mIperfBandwidth.setText(intent.getStringExtra(PMCMainActivity.SETTING_IPERF_BANDWIDTH_KEY)); + mIperfLogfile.setText(intent.getStringExtra(PMCMainActivity.SETTING_IPERF_LOGFILE_KEY)); + } + + @Override + public void onBackPressed() { + Intent intent = new Intent(); + intent.putExtra(PMCMainActivity.SETTING_SERVER_IP_KEY, mServerIP.getText().toString()); + intent.putExtra(PMCMainActivity.SETTING_SERVER_PORT_KEY, mServerPort.getText().toString()); + intent.putExtra(PMCMainActivity.SETTING_INTERVAL_KEY, mInterval.getText().toString()); + intent.putExtra(PMCMainActivity.SETTING_IPERF_BANDWIDTH_KEY, + mIperfBandwidth.getText().toString()); + intent.putExtra(PMCMainActivity.SETTING_IPERF_LOGFILE_KEY, + mIperfLogfile.getText().toString()); + setResult(0, intent); //The data you want to send back + finish(); + } +} diff --git a/PMC/src/com/android/pmc/WifiConnScanReceiver.java b/PMC/src/com/android/pmc/WifiConnScanReceiver.java new file mode 100644 index 0000000..15aeb11 --- /dev/null +++ b/PMC/src/com/android/pmc/WifiConnScanReceiver.java @@ -0,0 +1,149 @@ +package com.android.pmc; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.WifiManager; +import android.os.AsyncTask; +import android.os.PowerManager; +import android.os.SystemClock; +import android.util.Log; + +/** + * Call wifi scan whenever an alarm is received. + */ +public class WifiConnScanReceiver extends BroadcastReceiver { + int mScanCount = 0; + ConnectvityScanTask mConnScanTask; + PMCMainActivity mPMCMainActivity; + private WifiManager mWifiManager; + private Context mContext; + private PowerManager.WakeLock mWakeLock; + private int mAlarmInterval; + private AlarmManager mAlarmManager; + private PendingIntent mAlarmIntent; + + public WifiConnScanReceiver(PMCMainActivity activity, int interval, AlarmManager alarmManager, + PendingIntent alarmIntent) { + mPMCMainActivity = activity; + mScanCount = 0; + mAlarmInterval = interval; + mAlarmManager = alarmManager; + mAlarmIntent = alarmIntent; + } + + @Override + public void onReceive(Context context, Intent intent) { + if (mConnScanTask != null && mConnScanTask.getStatus() != AsyncTask.Status.FINISHED) { + Log.e(PMCMainActivity.TAG, "Previous connection scan still running."); + try { + mConnScanTask.get(); + } catch (Exception e) { + Log.e(PMCMainActivity.TAG, "Connection scan cancelled."); + } + } else { + mContext = context; + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WIFITEST"); + // Acquire the lock + mWakeLock.acquire(); + mWifiManager = (WifiManager) context.getApplicationContext() + .getSystemService(Context.WIFI_SERVICE); + Log.i(PMCMainActivity.TAG, "Starting Connectivity Scan Task"); + mConnScanTask = new ConnectvityScanTask(); + mConnScanTask.execute(); + } + scheduleConnScan(); + } + + /** + * Schedule the next connectivity scan. + */ + public void scheduleConnScan() { + Log.i(PMCMainActivity.TAG, "Scheduling the next conn scan after " + mAlarmInterval); + mAlarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + mAlarmInterval, mAlarmIntent); + } + + /** + * Cancel the connectivity scans. + */ + public void cancelConnScan() { + mAlarmManager.cancel(mAlarmIntent); + if (mConnScanTask != null) mConnScanTask.cancel(true); + } + + class ConnectvityScanTask extends AsyncTask<Integer, Integer, String> { + WifiScanReceiver mWifiScanReceiver; + Boolean mScanCompleted = false; + + ConnectvityScanTask() { + mWifiScanReceiver = new WifiScanReceiver(); + mContext.getApplicationContext().registerReceiver(mWifiScanReceiver, + new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); + } + + @Override + protected String doInBackground(Integer... stime) { + //android.os.Debug.waitForDebugger(); + int waitCount = 0; + try { + mScanCompleted = false; + mWifiManager.startScan(); + while (!mScanCompleted) { + if (waitCount >= 100) { + return "Timeout, scan results avaiable action didn't triggered"; + } else { + Thread.sleep(100); + waitCount += 1; + } + } + waitCount = 0; + mScanCount += 1; + Log.d(PMCMainActivity.TAG, "Number of scan completed " + mScanCount); + publishProgress(mScanCount); + } catch (Exception e) { + Log.e(PMCMainActivity.TAG, e.toString()); + return e.toString(); + } + return null; + } + + @Override + protected void onCancelled(String result) { + mContext.getApplicationContext().unregisterReceiver(mWifiScanReceiver); + mWakeLock.release(); + } + + @Override + protected void onProgressUpdate(Integer... values) { + Log.d(PMCMainActivity.TAG, "ConnectvityScanTask onProgressUpdate updating the UI"); + mPMCMainActivity.updateProgressStatus("Total Connectivity scan completed :: " + + Integer.toString(values[0].intValue())); + } + + @Override + protected void onPostExecute(String error) { + if (error != null) { + Log.e(PMCMainActivity.TAG, error); + mPMCMainActivity.updateProgressStatus(error); + } + mContext.getApplicationContext().unregisterReceiver(mWifiScanReceiver); + mWakeLock.release(); + } + + class WifiScanReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context c, Intent intent) { + String action = intent.getAction(); + if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { + Log.d(PMCMainActivity.TAG, "Wifi connection scan finished, results available."); + mScanCompleted = true; + } + } + } + } +} diff --git a/PMC/src/com/android/pmc/WifiDownloadReceiver.java b/PMC/src/com/android/pmc/WifiDownloadReceiver.java new file mode 100644 index 0000000..a8a7d9a --- /dev/null +++ b/PMC/src/com/android/pmc/WifiDownloadReceiver.java @@ -0,0 +1,185 @@ +package com.android.pmc; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; +import android.os.PowerManager; +import android.os.SystemClock; +import android.util.Log; + +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +/** + * Call wifi Download data whenever an alarm is received. + */ +public class WifiDownloadReceiver extends BroadcastReceiver { + private static final int DOWNLOAD_BUFFER_SIZE = 1024 * 4; + + DownloadTask mDownloadTask; + PMCMainActivity mPMCMainActivity; + int mFileCount; + int mBytesCount; + long mDownloadStartTime; + String mDownloadURL; + private Context mContext; + private PowerManager.WakeLock mWakeLock; + private int mAlarmInterval; + private AlarmManager mAlarmManager; + private PendingIntent mAlarmIntent; + + public WifiDownloadReceiver(PMCMainActivity activity, String url, int interval, + AlarmManager alarmManager, PendingIntent alarmIntent) { + mPMCMainActivity = activity; + mDownloadURL = url; + mFileCount = 0; + mBytesCount = 0; + mDownloadStartTime = -1; + mAlarmInterval = interval; + mAlarmManager = alarmManager; + mAlarmIntent = alarmIntent; + } + + @Override + public void onReceive(Context context, Intent intent) { + if (mDownloadTask != null && mDownloadTask.getStatus() != AsyncTask.Status.FINISHED) { + Log.e(PMCMainActivity.TAG, "Previous download still running."); + try { + mDownloadTask.get(); + } catch (Exception e) { + Log.e(PMCMainActivity.TAG, "Download cancelled."); + } + } else { + mContext = context; + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WIFITEST"); + // Acquire the lock + mWakeLock.acquire(); + Log.i(PMCMainActivity.TAG, "Starting Download Task"); + mDownloadTask = new DownloadTask(); + mDownloadTask.execute(mDownloadURL); + } + scheduleDownload(); + } + + /** + * Schedule the next download. + */ + public void scheduleDownload() { + if (mDownloadStartTime == -1) { + // Note down the start of all download activity + mDownloadStartTime = System.currentTimeMillis(); + } + Log.i(PMCMainActivity.TAG, "Scheduling the next download after " + mAlarmInterval); + mAlarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + mAlarmInterval, mAlarmIntent); + } + + /** + * Cancel the downloads. + */ + public void cancelDownload() { + mAlarmManager.cancel(mAlarmIntent); + if (mDownloadTask != null) mDownloadTask.cancel(true); + } + + /** + * Returns an approximate data rate at which we're downloading the files. + * @return + */ + public int getDownloadRate() { + long durationInMilliSeconds = (System.currentTimeMillis() - mDownloadStartTime); + int durationInSeconds = (int) (durationInMilliSeconds / 1000); + return (mBytesCount / durationInSeconds); + } + + class DownloadTask extends AsyncTask<String, Integer, String> { + @Override + protected String doInBackground(String... sUrl) { + //android.os.Debug.waitForDebugger(); + Log.d(PMCMainActivity.TAG, "Starting background task for downloading file"); + HttpURLConnection connection = null; + try { + URL url = new URL(sUrl[0]); + connection = (HttpURLConnection) url.openConnection(); + connection.connect(); + // expect HTTP 200 OK, so we don't mistakenly save error report + // instead of the file + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + return "Server returned HTTP " + connection.getResponseCode() + + " " + connection.getResponseMessage(); + } + // this will be useful to display download percentage + // might be -1: server did not report the length + int fileLength = connection.getContentLength(); + int bytesRead = downloadFile(connection); + if (fileLength != bytesRead) { + return "Expected file of size " + fileLength + " but only received " + + bytesRead; + } + Log.d(PMCMainActivity.TAG, "Downloaded file size " + fileLength); + mFileCount += 1; + mBytesCount += fileLength; + publishProgress(mFileCount, getDownloadRate()); + Thread.sleep(10000); + } catch (Exception e) { + Log.e(PMCMainActivity.TAG, e.toString()); + return e.toString(); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + return null; + } + + @Override + protected void onCancelled(String result) { + mWakeLock.release(); + } + + @Override + protected void onProgressUpdate(Integer... values) { + Log.d(PMCMainActivity.TAG, "DownloadTask onProgressUpdate updating the UI"); + mPMCMainActivity.updateProgressStatus("Total file downloaded :: " + + values[0].toString() + ", Data rate :: " + + values[1].toString() + " bytes/sec"); + } + + @Override + protected void onPostExecute(String error) { + if (error != null) { + Log.e(PMCMainActivity.TAG, error); + mPMCMainActivity.updateProgressStatus(error); + } + mWakeLock.release(); + } + + private int downloadFile(HttpURLConnection connection) { + if (connection == null) return -1; + int totalBytesRead = 0; + InputStream inputStream = null; + // Just read out the input file, not saving it anywhere in the device + try { + inputStream = connection.getInputStream(); + int bytesRead = -1; + byte[] buffer = new byte[DOWNLOAD_BUFFER_SIZE]; + while ((bytesRead = inputStream.read(buffer)) != -1) { + totalBytesRead += bytesRead; + } + } catch (Exception e) { + Log.e(PMCMainActivity.TAG, "Downloaded failed"); + } finally { + try { + if (inputStream != null) inputStream.close(); + } catch (Exception e) { + Log.e(PMCMainActivity.TAG, "Downloaded close failed"); + } + } + return totalBytesRead; + } + } +} diff --git a/PMC/src/com/android/pmc/WifiGScanReceiver.java b/PMC/src/com/android/pmc/WifiGScanReceiver.java new file mode 100644 index 0000000..e865364 --- /dev/null +++ b/PMC/src/com/android/pmc/WifiGScanReceiver.java @@ -0,0 +1,175 @@ +package com.android.pmc; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiScanner; +import android.net.wifi.WifiScanner.ScanData; +import android.net.wifi.WifiScanner.ScanSettings; +import android.os.AsyncTask; +import android.os.PowerManager; +import android.os.SystemClock; +import android.util.Log; + +/** + * Call wifi Gscan whenever an alarm is received. + */ +public class WifiGScanReceiver extends BroadcastReceiver { + int mScanCount = 0; + GScanTask mGScanTask; + PMCMainActivity mPMCMainActivity; + private WifiManager mWifiManager; + private Context mContext; + private PowerManager.WakeLock mWakeLock; + private WifiScanner mScan; + private ScanSettings mScanSettings; + private int mAlarmInterval; + private AlarmManager mAlarmManager; + private PendingIntent mAlarmIntent; + + + public WifiGScanReceiver(PMCMainActivity activity, ScanSettings settings, int interval, + AlarmManager alarmManager, PendingIntent alarmIntent) { + mPMCMainActivity = activity; + mScanSettings = settings; + mScanCount = 0; + mAlarmInterval = interval; + mAlarmManager = alarmManager; + mAlarmIntent = alarmIntent; + } + + @Override + public void onReceive(Context context, Intent intent) { + if (mGScanTask != null && mGScanTask.getStatus() != AsyncTask.Status.FINISHED) { + Log.e(PMCMainActivity.TAG, "Previous Gscan still running."); + try { + mGScanTask.get(); + } catch (Exception e) { + Log.e(PMCMainActivity.TAG, "Gscan cancelled."); + } + } else { + mContext = context; + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WIFITEST"); + // Acquire the lock + mWakeLock.acquire(); + mScan = (WifiScanner) context.getSystemService(Context.WIFI_SCANNING_SERVICE); + Log.i(PMCMainActivity.TAG, "Starting GScan Task"); + mGScanTask = new GScanTask(); + mGScanTask.execute(mScanSettings); + } + scheduleGscan(); + } + + /** + * Schedule the next Gscan. + */ + public void scheduleGscan() { + Log.i(PMCMainActivity.TAG, "Scheduling the next gscan after " + mAlarmInterval); + mAlarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + mAlarmInterval, mAlarmIntent); + } + + /** + * Cancel the Gscans. + */ + public void cancelGScan() { + mAlarmManager.cancel(mAlarmIntent); + if (mGScanTask != null) mGScanTask.cancel(true); + } + + class GScanTask extends AsyncTask<ScanSettings, Integer, String> { + WifiScanListener mWifiScanListener; + Boolean mScanCompleted = false; + + GScanTask() { + mWifiScanListener = new WifiScanListener(); + } + + @Override + protected String doInBackground(ScanSettings... settings) { + //android.os.Debug.waitForDebugger(); + Log.d(PMCMainActivity.TAG, "Starting background task for gscan with channel"); + int waitCount = 0; + try { + mScanCompleted = false; + mScan.startScan(settings[0], mWifiScanListener); + while (!mScanCompleted) { + if (waitCount >= 100) { + return "Timeout, scan results avaiable action didn't triggered"; + } else { + Thread.sleep(100); + waitCount += 1; + } + } + mScanCount += 1; + waitCount = 0; + Log.d(PMCMainActivity.TAG, "Number of scan completed " + mScanCount); + publishProgress(mScanCount); + } catch (Exception e) { + Log.e(PMCMainActivity.TAG, e.toString()); + return e.toString(); + } finally { + mScan.stopScan(mWifiScanListener); + } + return null; + } + + @Override + protected void onCancelled(String result) { + mWakeLock.release(); + } + + @Override + protected void onProgressUpdate(Integer... values) { + Log.d(PMCMainActivity.TAG, "GScanTask onProgressUpdate updating the UI"); + mPMCMainActivity.updateProgressStatus("Total Gscan completed :: " + + Integer.toString(values[0].intValue())); + } + + @Override + protected void onPostExecute(String error) { + if (error != null) { + Log.e(PMCMainActivity.TAG, error); + mPMCMainActivity.updateProgressStatus(error); + } + mWakeLock.release(); + } + + private class WifiScanListener implements WifiScanner.ScanListener { + WifiScanListener() { + + } + + @Override + public void onSuccess() { + Log.d(PMCMainActivity.TAG, "onSuccess called"); + } + + @Override + public void onFailure(int reason, String description) { + Log.d(PMCMainActivity.TAG, "onFailure called"); + } + + @Override + public void onPeriodChanged(int periodInMs) { + Log.d(PMCMainActivity.TAG, "onPeriodChanged called"); + } + + @Override + public void onFullResult(ScanResult fullScanResult) { + Log.d(PMCMainActivity.TAG, "onFullResult called"); + } + + @Override + public void onResults(ScanData[] results) { + Log.d(PMCMainActivity.TAG, "onResult WifiScanListener called"); + mScanCompleted = true; + } + } + } +} |