This is for the mobile offloading project.
This commit is contained in:
HappyZ 2016-02-23 01:27:01 -08:00
commit c245e45a2d
77 changed files with 6017 additions and 0 deletions

7
OffloadingDemo/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures

View File

@ -0,0 +1 @@
OffloadingDemo

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

View File

@ -0,0 +1,3 @@
<component name="CopyrightManager">
<settings default="" />
</component>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/mobile" />
<option value="$PROJECT_DIR$/wear" />
</set>
</option>
<option name="myModules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/mobile" />
<option value="$PROJECT_DIR$/wear" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/OffloadingDemo.iml" filepath="$PROJECT_DIR$/OffloadingDemo.iml" />
<module fileurl="file://$PROJECT_DIR$/mobile/mobile.iml" filepath="$PROJECT_DIR$/mobile/mobile.iml" />
<module fileurl="file://$PROJECT_DIR$/wear/wear.iml" filepath="$PROJECT_DIR$/wear/wear.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="OffloadingDemo" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,23 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@ -0,0 +1,18 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Tue Sep 15 23:28:19 PDT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip

164
OffloadingDemo/gradlew vendored Executable file
View File

@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
OffloadingDemo/gradlew.bat vendored Normal file
View File

@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

1
OffloadingDemo/mobile/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,28 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "edu.ucsb.cs.sandlab.offloadingdemo"
minSdkVersion 16
targetSdkVersion 23
versionCode 2
versionName "1.1"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
wearApp project(':wear')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.google.android.gms:play-services:7.8.0'
}

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":mobile" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="OffloadingDemo" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":mobile" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<afterSyncTasks>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/.DS_Store" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/debug" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/mediarouter-v7/22.2.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-ads/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-analytics/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-appindexing/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-appinvite/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-appstate/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-base/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-cast/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-drive/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-fitness/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-games/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-gcm/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-identity/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-location/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-maps/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-nearby/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-panorama/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-plus/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-safetynet/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-vision/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-wallet/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-wearable/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/mockable-android-23.jar" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/tmp" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="play-services-vision-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-identity-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-drive-7.8.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-23.0.1" level="project" />
<orderEntry type="library" exported="" name="play-services-location-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-nearby-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-ads-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-panorama-7.8.0" level="project" />
<orderEntry type="library" exported="" name="mediarouter-v7-22.2.0" level="project" />
<orderEntry type="library" exported="" name="play-services-safetynet-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-analytics-7.8.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="hamcrest-core-1.3" level="project" />
<orderEntry type="library" exported="" name="play-services-base-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-appinvite-7.8.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="junit-4.12" level="project" />
<orderEntry type="library" exported="" name="play-services-plus-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-7.8.0" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-23.0.1" level="project" />
<orderEntry type="library" exported="" name="play-services-appindexing-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-fitness-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-gcm-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-games-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-cast-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-wearable-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-wallet-7.8.0" level="project" />
<orderEntry type="library" exported="" name="play-services-appstate-7.8.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.0.1" level="project" />
<orderEntry type="library" exported="" name="play-services-maps-7.8.0" level="project" />
</component>
</module>

View File

@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/yanzi/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@ -0,0 +1,13 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.ucsb.cs.sandlab.offloadingdemo" >
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE"/>
<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.READ_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault.Light">
<activity android:name=".MainActivity"
android:configChanges="orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".SSLogger"
android:label="SSLogger"
android:exported="false"/>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,129 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
/**
* Created by yanzi on 7/10/15.
*/
public class Connectivity {
/**
* Get the network info
* @param context
* @return
*/
public static NetworkInfo getNetworkInfo(Context context){
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo();
}
/**
* Check if there is any connectivity
* @param context
* @return
*/
public static boolean isConnected(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected());
}
/**
* Check if there is any connectivity to a Wifi network
* @param context
* @return
*/
public static boolean isConnectedWifi(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
}
/**
* Check if there is any connectivity to a mobile network
* @param context
* @return
*/
public static boolean isConnectedMobile(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
}
/**
* Check if there is any connectivity to a mobile network
* @param context
* @return
*/
public static boolean isConnectedLTE(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getSubtype() == TelephonyManager.NETWORK_TYPE_LTE);
}
/**
* Check if there is fast connectivity
* @param context
* @return
*/
public static boolean isConnectedFast(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(),info.getSubtype()));
}
/**
* Check if the connection is fast
* @param type
* @param subType
* @return
*/
public static boolean isConnectionFast(int type, int subType){
if(type== ConnectivityManager.TYPE_WIFI){
return true;
}else if(type== ConnectivityManager.TYPE_MOBILE){
switch(subType){
case TelephonyManager.NETWORK_TYPE_1xRTT:
return false; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_CDMA:
return false; // ~ 14-64 kbps
case TelephonyManager.NETWORK_TYPE_EDGE:
return false; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_EVDO_0:
return true; // ~ 400-1000 kbps
case TelephonyManager.NETWORK_TYPE_EVDO_A:
return true; // ~ 600-1400 kbps
case TelephonyManager.NETWORK_TYPE_GPRS:
return false; // ~ 100 kbps
case TelephonyManager.NETWORK_TYPE_HSDPA:
return true; // ~ 2-14 Mbps
case TelephonyManager.NETWORK_TYPE_HSPA:
return true; // ~ 700-1700 kbps
case TelephonyManager.NETWORK_TYPE_HSUPA:
return true; // ~ 1-23 Mbps
case TelephonyManager.NETWORK_TYPE_UMTS:
return true; // ~ 400-7000 kbps
/*
* Above API level 7, make sure to set android:targetSdkVersion
* to appropriate level to use these
*/
// case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11
// return true; // ~ 1-2 Mbps
// case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
// return true; // ~ 5 Mbps
case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
return true; // ~ 10-20 Mbps
// case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
// return false; // ~25 kbps
case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
return true; // ~ 10+ Mbps
// Unknown
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
default:
return false;
}
}else{
return false;
}
}
}

View File

@ -0,0 +1,820 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.provider.Settings;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class MainActivity extends Activity {
// unchanged stuff
protected static final String sshlinklab = "ssh linklab@hotcrp.cs.ucsb.edu -i /data/.ssh/id_rsa -o StrictHostKeyChecking=no";
protected static final String sshlinklablocal = "ssh linklab@128.111.68.220 -i /data/.ssh/id_rsa -o StrictHostKeyChecking=no";
protected static final String udpserver_pathport = "~/mobileRDMABeach/UDPServer 32000 ";
protected static final String binaryFolderPath = "/data/local/tmp/";
protected static final String binary_tcpdump = "tcpdump";
protected static final int oneMB = 1048576;
private static final String TAG = "MainActivity";
private static final int mVersion = Build.VERSION.SDK_INT;
// the configs
protected static boolean isForcingCPU0 = false;
protected static boolean isVerbose = true;
protected static boolean isLocal = false;
protected static boolean isLoggingTCPDump = false;
protected static boolean isUsingTCPDump = true;
protected static boolean isLoggingPerProcPID = false;
protected static boolean isLoggingAppSelf = false;
protected static int time_wait_for = 100; // ms
protected static int wifiDriverPID = -1;
// maintained variables
private Button btn_startTransmit, btn_startReceive;
private Button btn_setByte2send, btn_setRepeatTimes, btn_setTCPDumpInterface,
btn_clearStatus, btn_setLogFreq, btn_setOthers;
private CharSequence[] existedItems;
private CharSequence[] existedItemsThrpt;
private WifiManager wm;
private Intent intentSSLogger;
protected static int coreNum = 1;
protected static int perProcPID = -1;
protected static int UDPfinishTime = 0;
protected static double reportedFinishTime = 0.0;
protected static int repeatCounts = 3;
protected static int bytes2send = 10*oneMB; // default 10MB
protected static int currentBandwidth = 20000000; // bytes per sec, default unlimited (not for loopback)
protected static TextView txt_results;
protected static Handler myHandler;
protected static String RXportNum = "4445";
protected static String outFolderPath;
protected static String btn_click_time;
protected static String tcpdumpInterface = "wlan0";
protected static String binary_TX_Normal = "normal";
protected static String binary_TX_NormalUDP = "normal_udp";
protected static String binary_TX_Sendfile = "sendfile";
protected static String binary_TX_Splice = "splice";
protected static String binary_TX_RawNormal = "bypassl3";
protected static final String binary_TX_RawSplice = "";
protected static String binary_RX_Normal = "normal_recv";
protected static String binary_RX_NormalUDP = "normal_udp_recv";
protected static final String binary_RX_Sendfile = "";
protected static String binary_RX_Splice = "splice_recv";
protected static String binary_RX_RawNormal = "bypassl3_recv";
protected static boolean isUsingWifi = true;
protected static boolean isRunning_TX_Normal = false;
protected static boolean isRunning_TX_NormalUDP = false;
protected static boolean isRunning_TX_Sendfile = false;
protected static boolean isRunning_TX_Splice = false;
protected static boolean isRunning_TX_RawNormal = false;
protected static boolean isRunning_TX_RawSplice = false;
protected static boolean isRunning_RX_Normal = false;
protected static boolean isRunning_RX_NormalUDP = false;
protected static boolean isRunning_RX_Sendfile = false;
protected static boolean isRunning_RX_Splice = false;
protected static boolean isRunning_RX_RawNormal = false;
/**
* Check whether a service is running
* @param serviceClass
* @return true/false
*/
protected boolean isServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
/**
* Check if service is still running in the background, if so tell me in logcat
*/
private void myServiceCheck() {
if (!isVerbose) return;
if (isServiceRunning(SSLogger.class)) {
Log.d(TAG, "SSLogger running..");
} else {
Log.d(TAG, "SSLogger stopped..");
}
}
private boolean checkBinaryFilesExist() {
String missingFiles = "";
if (!Utilities.fileExist(binaryFolderPath + binary_tcpdump))
missingFiles += binary_tcpdump;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Normal))
missingFiles += " " + binary_TX_Normal;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Normal + "_lo"))
missingFiles += " " + binary_TX_Normal + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_TX_NormalUDP))
missingFiles += " " + binary_TX_NormalUDP;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_NormalUDP + "_lo"))
missingFiles += " " + binary_TX_NormalUDP + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Sendfile))
missingFiles += " " + binary_TX_Sendfile;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Sendfile + "_lo"))
missingFiles += " " + binary_TX_Sendfile + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Splice))
missingFiles += " " + binary_TX_Splice;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_RawNormal))
missingFiles += " " + binary_TX_RawNormal;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_RawNormal + "_lo"))
missingFiles += " " + binary_TX_RawNormal + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_RX_Normal))
missingFiles += " " + binary_RX_Normal;
if (!Utilities.fileExist(binaryFolderPath + binary_RX_Normal + "_lo"))
missingFiles += " " + binary_RX_Normal + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_RX_NormalUDP))
missingFiles += " " + binary_RX_NormalUDP;
if (!Utilities.fileExist(binaryFolderPath + binary_RX_NormalUDP + "_lo"))
missingFiles += " " + binary_RX_NormalUDP + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_RX_Splice))
missingFiles += " " + binary_RX_Splice;
if (!Utilities.fileExist(binaryFolderPath + binary_RX_Splice + "_lo"))
missingFiles += " " + binary_RX_Splice + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_RX_RawNormal))
missingFiles += " " + binary_RX_RawNormal;
if (!Utilities.fileExist(binaryFolderPath + binary_RX_RawNormal + "_lo"))
missingFiles += " " + binary_RX_RawNormal + "_lo";
if (!missingFiles.equals("")) {
final String mFiles = missingFiles;
myHandler.post(new Runnable() {
@Override
public void run() {
txt_results.setText("Failed to find following files:\n" + mFiles);
btn_startTransmit.setEnabled(false);
btn_startReceive.setEnabled(false);
}
});
return false;
} else {
btn_startTransmit.setEnabled(true);
btn_startReceive.setEnabled(true);
}
return true;
}
/**
* start the record
* @param myflag
*/
protected void startRecording(boolean myflag) {
final boolean flagRecv = myflag;
final ArrayList<Integer> selectedItems = new ArrayList<>();
AlertDialog.Builder adb = new AlertDialog.Builder(MainActivity.this);
adb.setMultiChoiceItems(existedItems, null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (which == 5 || (flagRecv && which == 2) || (mVersion < 21 && which == 3)) {
Toast.makeText(MainActivity.this, "not working", Toast.LENGTH_SHORT).show();
return;
}
if (isChecked) {
selectedItems.add(which);
} else if (selectedItems.contains(which)) {
selectedItems.remove(Integer.valueOf(which));
}
}
});
adb.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
// Process su = null;
@Override
public void onClick(DialogInterface dialog, int which) {
if (selectedItems.size() < 1) {
Toast.makeText(MainActivity.this, "Nothing is selected", Toast.LENGTH_SHORT).show();
return;
}
final ArrayList<Integer> selectedItemsThrpt = new ArrayList<>();
AlertDialog.Builder adb = new AlertDialog.Builder(MainActivity.this);
adb.setMultiChoiceItems(existedItemsThrpt, null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (isChecked) {
selectedItemsThrpt.add(which);
} else if (selectedItemsThrpt.contains(which)) {
selectedItemsThrpt.remove(Integer.valueOf(which));
}
}
});
adb.setPositiveButton("Go!", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (selectedItemsThrpt.size() < 1) {
Toast.makeText(MainActivity.this, "Nothing is selected", Toast.LENGTH_SHORT).show();
return;
}
if (isVerbose) {
Log.d(TAG, "selected variations " + selectedItemsThrpt);
}
Utilities.estimateTime(repeatCounts, selectedItems.size(), bytes2send, selectedItemsThrpt);
new Thread(new Runnable() {
@Override
public void run() {
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "&&";
// change screen brightness to 0
Settings.System.putInt(MainActivity.this.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, 0);
final WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = 0.0f;// 100 / 100.0f;
myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Begin..\n");
getWindow().setAttributes(lp);
}
});
// prepare
try {
Runtime.getRuntime().exec("su -c killall -9 normal").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_udp").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_udp_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 sendfile").waitFor();
Runtime.getRuntime().exec("su -c killall -9 sendfile_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 splice").waitFor();
Runtime.getRuntime().exec("su -c killall -9 splice_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 bypassl3").waitFor();
Runtime.getRuntime().exec("su -c killall -9 bypassl3_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_recv").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_recv_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_udp_recv").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_udp_recv_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 splice_recv").waitFor();
Runtime.getRuntime().exec("su -c killall -9 splice_recv_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 bypassl3_recv").waitFor();
Runtime.getRuntime().exec("su -c killall -9 bypassl3_recv_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 tcpdump").waitFor();
Runtime.getRuntime().exec("su -c killall -9 TCPReceiver_mobile").waitFor();
Runtime.getRuntime().exec("su -c killall -9 TCPSender_mobile").waitFor();
Runtime.getRuntime().exec("su -c killall -9 UDPServer_mobile").waitFor();
if (isLocal) {
if (flagRecv)
Runtime.getRuntime().exec("su && /data/local/tmp/Run_for_Download.sh").waitFor();
else
Runtime.getRuntime().exec("su && /data/local/tmp/Run_for_Upload.sh").waitFor();
} else {
myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("In case you forget, remember to run " + ((flagRecv) ? "Run_for_Download.sh" : "Run_for_Upload.sh") + "\n");
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// start iteration
for (int k = 0; k < selectedItemsThrpt.size(); ++k) {
int myI = selectedItemsThrpt.get(k);
currentBandwidth = Utilities.findCorrespondingThrpt(myI);
RXportNum = Integer.toString(4445 - myI + 24);
if (isVerbose) {
Log.d(TAG, "bandwidth is set to " + currentBandwidth
+ "\nRXportNum is set to " + RXportNum);
}
// start
try {
commd[2] = "cd " + outFolderPath
+ " && ls | grep -v '.tar.gz' | busybox xargs rm -rf";
Runtime.getRuntime().exec(commd).waitFor();
commd[2] = "mkdir -p";
for (int i = 0; i < selectedItems.size(); ++i) {
commd[2] += " " + outFolderPath + "/" + existedItems[selectedItems.get(i)];
}
Runtime.getRuntime().exec(commd).waitFor();
Thread.sleep(1000);
// start repeating
int waitTimeSec = 0;
for (int i = 0; i < repeatCounts; ++i) {
for (int j = 0; j < selectedItems.size(); ++j) {
if (flagRecv && (selectedItems.get(j) == 1 || selectedItems.get(j) == 4)) {
if (isLocal) {
waitTimeSec = (Math.max(bytes2send / currentBandwidth + 20, 20));
Runtime.getRuntime().exec("su -c /data/local/tmp/UDPServer_mobile 32000 "
+ currentBandwidth + " " + waitTimeSec + " &").waitFor();
} else {
waitTimeSec = (Math.max(bytes2send / currentBandwidth + 20, 60));
Process proc = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(proc.getOutputStream());
if (isUsingWifi) {
os.writeBytes(sshlinklablocal + "\n");
os.flush();
Thread.sleep(5001);
} else {
os.writeBytes(sshlinklab + "\n");
os.flush();
Thread.sleep(10001);
}
os.writeBytes(udpserver_pathport + currentBandwidth + " " + waitTimeSec + " &\n");
os.flush();
Thread.sleep(1001);
os.writeBytes("exit\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
Thread.sleep(501);
os.close();
proc.destroy();
Thread.sleep(805);
}
}
Thread.sleep(1000);
btn_click_time = Long.toString(System.currentTimeMillis());
startService(intentSSLogger);
Thread.sleep(1000);
myServiceCheck();
if (flagRecv) { // Starting Receiving
switch (selectedItems.get(j)) {
case 0: // normal
new Thread(new Thread_RX_CNormal()).start();
Thread.sleep(1005);
while (isRunning_RX_Normal) {
Thread.sleep(1005);
}
break;
case 1: // normal udp
new Thread(new Thread_RX_CNormalUDP()).start();
Thread.sleep(1005);
while (isRunning_RX_NormalUDP) {
Thread.sleep(1005);
}
break;
case 2: // sendfile unimplemented
break;
case 3: // splice
new Thread(new Thread_RX_CSplice()).start();
Thread.sleep(1005);
while (isRunning_RX_Splice) {
Thread.sleep(1005);
}
break;
case 4: // rawsocket
new Thread(new Thread_RX_CRawNormal()).start();
Thread.sleep(1005);
while (isRunning_RX_RawNormal) {
Thread.sleep(1005);
}
break;
default: // do nothing
break;
}
} else { // Starting Transmitting
switch (selectedItems.get(j)) {
case 0: // normal
new Thread(new Thread_TX_CNormal()).start();
Thread.sleep(1005);
while (isRunning_TX_Normal) {
Thread.sleep(1005);
}
break;
case 1: // normal udp
new Thread(new Thread_TX_CNormalUDP()).start();
Thread.sleep(1005);
while (isRunning_TX_NormalUDP) {
Thread.sleep(1005);
}
break;
case 2: // sendfile
new Thread(new Thread_TX_CSendfile()).start();
Thread.sleep(1005);
while (isRunning_TX_Sendfile) {
Thread.sleep(1005);
}
break;
case 3: // splice
new Thread(new Thread_TX_CSplice()).start();
Thread.sleep(1005);
while (isRunning_TX_Splice) {
Thread.sleep(1005);
}
break;
case 4: // rawsocket
new Thread(new Thread_TX_CRawNormal()).start();
Thread.sleep(1005);
while (isRunning_TX_RawNormal) {
Thread.sleep(1005);
}
break;
case 5: // rawsocket splice unimplemented
break;
default: // do nothing
break;
}
}
stopService(intentSSLogger);
myServiceCheck();
Thread.sleep(1000);
Runtime.getRuntime().gc();
System.gc();
if (flagRecv && (selectedItems.get(j) == 1 || selectedItems.get(j) == 4)) {
Thread.sleep(Math.abs(waitTimeSec*1000 - UDPfinishTime));
}
commd[2] = "cd " + outFolderPath + " && mv *" + btn_click_time
+ "* " + existedItems[selectedItems.get(j)] + "/";
Runtime.getRuntime().exec(commd).waitFor();
Log.d(TAG, "Finished " + (currentBandwidth / 1000000.0) + "MBps, "
+ i + "th repeat on " + existedItems[selectedItems.get(j)]
+ ", t="+reportedFinishTime+"ms");
Thread.sleep(5000);
}
}
// parse and zip it
for (int i = 0; i < selectedItems.size(); ++i) {
if (Utilities.parseCPUforFolder((String) existedItems[selectedItems.get(i)])) {
String tarName = ((flagRecv) ? "download_" : "upload_")
+ existedItems[selectedItems.get(i)] + "_"
+ (bytes2send / 1024) + "KB_" + repeatCounts + "repeats_thrpt_"
+ (currentBandwidth / 1000000.0) + "MBps_"
+ new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())
+ ".tar.gz";
commd[2] = "cd " + outFolderPath + "/"
+ existedItems[selectedItems.get(i)]
+ " && busybox tar -czf ../" + tarName + " *";
Runtime.getRuntime().exec(commd).waitFor();
} else {
final CharSequence failedFolderName = existedItems[selectedItems.get(i)];
myHandler.post(new Runnable() {
@Override
public void run() {
txt_results.append("Failed for folder "
+ failedFolderName + "\n");
}
});
}
}
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// change screen brightness back
Settings.System.putInt(MainActivity.this.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, 200);
lp.screenBrightness = 80;// 80 / 100.0f;
myHandler.post(new Runnable() {
@Override
public void run() {
txt_results.append("All Done\n");
getWindow().setAttributes(lp);
}
});
}
}).start();
}
});
adb.setNegativeButton("Cancel", null);
adb.create().show();
}
});
adb.setNegativeButton("Cancel", null);
adb.create().show();
}
/**
* Intialize parameters etc.
*/
protected void initialization() {
// must have root privilege in order to run
try {
Runtime.getRuntime().exec("su");
} catch (Throwable e) {
Toast.makeText(this, R.string.warn_root, Toast.LENGTH_LONG).show();
}
// handler that updates the ui at main thread
// it's used in sslogger thus will be modded in receiver activity also
// do not modify this
myHandler = new Handler();
existedItems = new CharSequence[] {
"Socket_Normal", "Socket_NormalUDP", "Socket_Sendfile",
"Socket_Splice", "RawSocket_Normal"
};
existedItemsThrpt = new CharSequence[]{
"50KB", "100KB", "250KB", "0.5MB", "0.75MB", "1MB", "1.5MB", "2MB", // 0-7
"2.5MB", "3MB", "3.5MB", "4MB", "4.5MB", "5MB", "5.5MB", "6MB", // 8-15
"6.5MB", "7MB", "7.5MB", "8MB", "8.5MB", "9MB", "9.5MB", "10MB", // 16-23
"Unlimited", // 24
"15MB", "20MB", "25MB", "30MB", "35MB", "40MB", "45MB", "50MB", // 25-32
"55MB", "60MB", "65MB", "70MB", "75MB", "80MB", "85MB", "90MB", // 33-40
"95MB", "100MB", // 41-42
"11MB", "13MB" // 43-44
};
intentSSLogger = new Intent(this, SSLogger.class);
wm = (WifiManager) this.getSystemService(WIFI_SERVICE);
// assignments
binary_TX_Normal = "normal";
binary_TX_NormalUDP = "normal_udp";
binary_TX_Sendfile = "sendfile";
binary_TX_RawNormal = "bypassl3";
binary_TX_Splice = "splice";
binary_RX_Normal = "normal_recv";
binary_RX_NormalUDP = "normal_udp_recv";
binary_RX_Splice = "splice_recv";
binary_RX_RawNormal = "bypassl3_recv";
coreNum = Utilities.getNumCores();
outFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SSLogger";
isUsingWifi = (wm.isWifiEnabled())?true:false;
// find view elements
txt_results = (TextView) findViewById(R.id.txt_results);
btn_startTransmit = (Button) findViewById(R.id.btn_startTransmit);
btn_startReceive = (Button) findViewById(R.id.btn_startReceive);
btn_setByte2send = (Button) findViewById(R.id.btn_setByte2send);
btn_setRepeatTimes = (Button) findViewById(R.id.btn_setRepeatTimes);
btn_setTCPDumpInterface = (Button) findViewById(R.id.btn_setTCPDumpInterface);
btn_setOthers = (Button) findViewById(R.id.btn_setOthers);
btn_setLogFreq = (Button) findViewById(R.id.btn_setLogFreq);
btn_clearStatus = (Button) findViewById(R.id.btn_clearStatus);
if (coreNum > 2) {
txt_results.append("Only support 2 cores now! Contact Yanzi to add "+coreNum+" cores support!\n");
}
txt_results.append(isUsingWifi?getString(R.string.stat_wifion):getString(R.string.stat_wifioff));
// click listener
btn_startTransmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startRecording(false);
}
});
btn_startReceive.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startRecording(true);
}
});
btn_setByte2send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final CharSequence[] mItems={
(bytes2send == (oneMB/2))?"Current: 0.5MB":"0.5MB",
(bytes2send == (oneMB))?"Current: 1MB":"1MB",
(bytes2send == (2*oneMB))?"Current: 2MB":"2MB",
(bytes2send == (5*oneMB))?"Current: 5MB":"5MB",
(bytes2send == (10*oneMB))?"Current: 10MB":"10MB",
(bytes2send == (20*oneMB))?"Current: 20MB":"20MB",
(bytes2send == (50*oneMB))?"Current: 50MB":"50MB",
(bytes2send == (100*oneMB))?"Current: 100MB":"100MB",
(bytes2send == (200*oneMB))?"Current: 200MB":"200MB"};
AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this);
mDialog.setItems(mItems, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which < 3) {
bytes2send = oneMB/2;
for (int i = 0; i < which; ++i)
bytes2send *= 2;
} else if (which < 6) {
bytes2send = 5 * oneMB;
for (int i = 3; i < which; ++i)
bytes2send *= 2;
} else if (which < 9) {
bytes2send = 50 * oneMB;
for (int i = 6; i < which; ++i)
bytes2send *= 2;
} else {
bytes2send = 10 * oneMB; // default 10MB
}
if (isVerbose) {
Log.d(TAG, "outgoing/incoming bytes is set to " + bytes2send);
}
}
});
mDialog.create().show();
}
});
btn_setRepeatTimes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final CharSequence[] mItems={
(repeatCounts == 1)?"Current: once (1)":"once (1)",
(repeatCounts == 2)?"Current: twice (2)":"twice (2)",
(repeatCounts == 3)?"Current: tripple (3)":"tripple (3)",
(repeatCounts == 4)?"Current: quad (4)":"quad (4)",
(repeatCounts == 5)?"Current: quint (5)":"quint (5)",
(repeatCounts == 10)?"Current: 10":"10",
(repeatCounts == 20)?"Current: 20":"20"};
AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this);
mDialog.setItems(mItems, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
repeatCounts = which + 1;
if (which == 5) repeatCounts = 10;
else if (which == 6) repeatCounts = 20;
if (isVerbose) {
Log.d(TAG, "repeatCounts is set to " + repeatCounts);
}
}
});
mDialog.create().show();
}
});
btn_setTCPDumpInterface.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ArrayList<String> out = new ArrayList<>();
if (!isUsingTCPDump) {
out.add("Current: TCPDump OFF");
} else {
out.add("Disable TCPDump");
}
try {
Process proc = Runtime.getRuntime().exec("ls /sys/class/net");
proc.waitFor();
String line;
BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while ((line = is.readLine()) != null) {
if (isUsingTCPDump && line.equals(tcpdumpInterface)) {
out.add("Current: " + line);
} else {
out.add(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
final CharSequence mTmp[] = out.toArray(new CharSequence[out.size()]);
AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this);
mDialog.setItems(mTmp, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
isUsingTCPDump = false;
if (isVerbose) {
myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("TCPDump is disabled\n");
}
});
Log.d(TAG, "TCPDump is disabled");
}
} else {
tcpdumpInterface = ((String) mTmp[which]).replace("Current: ", "");
isUsingTCPDump = true;
Toast.makeText(MainActivity.this, "TCPDump interface is changed to " + tcpdumpInterface, Toast.LENGTH_SHORT).show();
if (isVerbose) {
Log.d(TAG, "TCPDump interface is set to " + tcpdumpInterface);
}
}
}
});
mDialog.create().show();
}
});
btn_setOthers.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CharSequence[] items = {"Verbose Mode", "Only Run Locally", "CPULog (Per Proc)", "CPULog (WiFi Driver)", "CPULog (This App)", "CPULog (TCPDump)", "Force on CPU0"};
boolean[] checkedItems = {isVerbose, isLocal, isLoggingPerProcPID, (wifiDriverPID!=-1), isLoggingAppSelf, isLoggingTCPDump, isForcingCPU0};
AlertDialog.Builder adb = new AlertDialog.Builder(MainActivity.this);
adb.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
switch (which) {
case 0:
isVerbose = isChecked;
Toast.makeText(MainActivity.this, "Set to be " + (isVerbose ? "verbose" : "NOT verbose"), Toast.LENGTH_SHORT).show();
break;
case 1:
isLocal = isChecked;
binary_TX_Normal = isLocal ? "normal_lo" : "normal";
binary_TX_NormalUDP = isLocal ? "normal_udp_lo" : "normal_udp";
binary_TX_Sendfile = isLocal ? "sendfile_lo" : "sendfile";
binary_TX_Splice = isLocal ? "splice_lo" : "splice";
binary_TX_RawNormal = isLocal ? "bypassl3_lo" : "bypassl3";
binary_RX_Normal = isLocal ? "normal_recv_lo" : "normal_recv";
binary_RX_NormalUDP = isLocal ? "normal_udp_recv_lo" : "normal_udp_recv";
binary_RX_Splice = isLocal ? "splice_recv_lo" : "splice_recv";
binary_RX_RawNormal = isLocal ? "bypassl3_recv_lo" : "bypassl3_recv";
if (isLocal) {
isUsingTCPDump = false;
Toast.makeText(MainActivity.this, "Remember to set IP to 192.168.1.15\n" +
"Will start TCPSdr/Rcvr locally\ntcpdump disabled", Toast.LENGTH_LONG).show();
} else {
isUsingTCPDump = true;
tcpdumpInterface = "wlan0";
Toast.makeText(MainActivity.this, "Back to original\ntcpdump enabled to wlan0", Toast.LENGTH_LONG).show();
}
break;
case 2:
isLoggingPerProcPID = isChecked;
Toast.makeText(MainActivity.this, isLoggingPerProcPID?"Will log per process cpu":"Will NOT log per process cpu", Toast.LENGTH_SHORT).show();
break;
case 3:
wifiDriverPID = isChecked?Utilities.getMyPID("dhd_dpc", true):-1;
Toast.makeText(MainActivity.this, (wifiDriverPID!=-1)?"Will log wifi driver cpu":"Will NOT log wifi driver cpu", Toast.LENGTH_SHORT).show();
break;
case 4:
isLoggingAppSelf = isChecked;
Toast.makeText(MainActivity.this, isLoggingAppSelf?"Will log app itself cpu":"Will NOT log app itself cpu", Toast.LENGTH_SHORT).show();
break;
case 5:
isLoggingTCPDump = isChecked;
Toast.makeText(MainActivity.this, isLoggingTCPDump?"Will log tcpdump cpu":"Will NOT log tcpdump cpu", Toast.LENGTH_SHORT).show();
break;
case 6:
isForcingCPU0 = isChecked;
Toast.makeText(MainActivity.this, (isForcingCPU0?"Force running on cpu 0":"Will run on any cpu"), Toast.LENGTH_SHORT).show();
break;
}
}
});
adb.setPositiveButton("OK", null);
adb.create().show();
}
});
btn_clearStatus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myHandler.post(new Runnable() {
@Override
public void run() {
txt_results.setText("");
}
});
}
});
btn_setLogFreq.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final CharSequence[] mItems={
(time_wait_for == 50)?"Current: every 50ms":"every 50ms",
(time_wait_for == 100)?"Current: every 100ms":"every 100ms",
(time_wait_for == 200)?"Current: every 200ms":"every 200ms",
(time_wait_for == 500)?"Current: every 500ms":"every 500ms",
(time_wait_for == 1000)?"Current: every 1s":"every 1s"};
AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this);
mDialog.setItems(mItems, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
time_wait_for = 50;
break;
case 1:
time_wait_for = 100;
break;
case 2:
time_wait_for = 200;
break;
case 3:
time_wait_for = 500;
break;
case 4:
time_wait_for = 1000;
break;
default:
time_wait_for = 100; // default 100ms
}
if (isVerbose) {
myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("time_wait_for is set to " + time_wait_for + "ms\n");
}
});
Log.d(TAG, "time_wait_for is set to " + time_wait_for + "ms");
}
}
});
mDialog.create().show();
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialization();
checkBinaryFilesExist();
}
}

View File

@ -0,0 +1,371 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
/**
* Created by yanzi on 9/20/15.
* two core only right now
*/
public class SSLogger extends Service {
private static final String TAG = "SSLogger";
private boolean isRunning = false;
private boolean isRunningPollingThread = false;
private String ssFileName, cpuFileName,
cpuWiFiDriverPIDFileName, cpuPerProcPIDFileName, cpuTCPDumpFileName, cpuAppSelfFileName;
private int wifiRSS, gsmRSS;
private static int tcpdumpPID = -1, appSelfPID = -1;
private WifiManager wm;
private FileOutputStream os_ss = null, os_cpu = null,
os_cpuWiFiDriverPID = null, os_cpuPerProcPID = null,
os_cpuTCPDump = null, os_cpuAppSelf = null;
public class PollingThread extends Thread {
public void run() {
if (isRunningPollingThread) {
Log.d(TAG, "already running polling thread");
return;
}
isRunningPollingThread = true;
while(isRunning) {
// get current system time
String mTime = Long.toString(System.currentTimeMillis());
String[] raws = new String[5]; // assume 4 cores, [0] is total
// read current cpu usage
readUsage(raws);
String myTmp = mTime + " " + raws[0] + " ";
for (int i = 0; i < MainActivity.coreNum-1; ++i) {
myTmp += raws[i+1] + " " + cpuFrequency(i) + " ";
}
myTmp += raws[MainActivity.coreNum] + " " + cpuFrequency(MainActivity.coreNum-1) + "\n";
// // cpuTotal
// String[] cpuTotal = raws[0].split("\\s+");
// String cpuTotalsum = parseProcStat(cpuTotal);
// // cpu 1 - N (N = coreNum)
// String[] cpu1 = raws[1].split("\\s+");
// String cpu1sum = parseProcStat(cpu1);
// String[] cpu2 = null, cpu3 = null, cpu4 = null;
// String cpu2sum = null, cpu3sum = null, cpu4sum = null;
// // parse lines
// if (MainActivity.coreNum > 1) {
// cpu2 = raws[2].split("\\s+");
// cpu2sum = parseProcStat(cpu2);
// }
// if (MainActivity.coreNum > 2) {
// cpu3 = raws[3].split("\\s+");
// cpu3sum = parseProcStat(cpu3);
// }
// if (MainActivity.coreNum > 3) {
// cpu4 = raws[4].split("\\s+");
// cpu4sum = parseProcStat(cpu4);
// }
byte[] cpuStuff, ssStuff = null,
cpuWiFiDriverPIDStuff = null, cpuPerPIDStuff = null, cpuTCPDumpStuff = null,
cpuAppSelfStuff = null;
cpuStuff = myTmp.getBytes();
if (MainActivity.wifiDriverPID != -1)
cpuWiFiDriverPIDStuff = (mTime + " " + parseProcPIDStat(readUsagePID(MainActivity.wifiDriverPID)) + "\n").getBytes();
if (MainActivity.isLoggingPerProcPID)
cpuPerPIDStuff = (mTime + " " + parseProcPIDStat(readUsagePID(MainActivity.perProcPID)) + "\n").getBytes();
if (tcpdumpPID != -1)
cpuTCPDumpStuff = (mTime + " " + parseProcPIDStat(readUsagePID(tcpdumpPID)) + "\n").getBytes();
if (MainActivity.isLoggingAppSelf)
cpuAppSelfStuff = (mTime + " " + parseProcPIDStat(readUsagePID(appSelfPID)) + "\n").getBytes();
if (wifiRSS != 0)
ssStuff = (mTime + " wifi " + wifiRSS + "\n").getBytes();
try {
if (isRunning) {
if (wifiRSS != 0)
os_ss.write(ssStuff);
os_cpu.write(cpuStuff);
if (MainActivity.wifiDriverPID != -1)
os_cpuWiFiDriverPID.write(cpuWiFiDriverPIDStuff);
if (MainActivity.isLoggingPerProcPID)
os_cpuPerProcPID.write(cpuPerPIDStuff);
if (tcpdumpPID != -1)
os_cpuTCPDump.write(cpuTCPDumpStuff);
if (MainActivity.isLoggingAppSelf)
os_cpuAppSelf.write(cpuAppSelfStuff);
}
} catch (IOException unimportant) {
Log.w(TAG, "IO error at SSLogger");
}
try {
Thread.sleep(MainActivity.time_wait_for);
} catch (Exception unimportant) {
Log.w(TAG, "Can't wait..");
}
}
isRunningPollingThread = false;
}
}
/**
* my initialization
*/
public void initialization() {
// run tcpdump
if (MainActivity.isUsingTCPDump) {
try {
Runtime.getRuntime().exec("su -c " + MainActivity.binaryFolderPath
+ "tcpdump -i " + MainActivity.tcpdumpInterface
+ " -w " + MainActivity.outFolderPath + "/tcpdump_wifionly_"
+ MainActivity.btn_click_time + " &"
).waitFor();
if (MainActivity.isVerbose) {
Log.d(TAG, "TCPDump started");
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (MainActivity.isLoggingTCPDump)
tcpdumpPID = Utilities.getMyPID(MainActivity.binary_tcpdump, true);
}
if (MainActivity.isLoggingAppSelf)
appSelfPID = Utilities.getMyPID("offloading", true);
if (!Utilities.canWriteOnExternalStorage()) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Can't write sdcard\n");
}
});
onDestroy();
}
// get the initial WiFi signal strength
wm = (WifiManager) this.getSystemService(WIFI_SERVICE);
if (!wm.isWifiEnabled() && MainActivity.isVerbose) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("WiFi remains OFF!\n");
}
});
wifiRSS = 0;
} else {
wifiRSS = wm.getConnectionInfo().getRssi();
this.registerReceiver(this.myWifiReceiver, new IntentFilter(WifiManager.RSSI_CHANGED_ACTION));
}
// create folder
File mDir = new File(MainActivity.outFolderPath);
mDir.mkdir();
if (wifiRSS != 0)
ssFileName = MainActivity.btn_click_time.concat(".ss");
cpuFileName = MainActivity.btn_click_time.concat(".cpuRaw");
if (MainActivity.wifiDriverPID != -1)
cpuWiFiDriverPIDFileName = MainActivity.btn_click_time.concat(".cpuPID");
if (MainActivity.isLoggingPerProcPID)
cpuPerProcPIDFileName = MainActivity.btn_click_time.concat(".cpuProcPID");
if (tcpdumpPID != -1)
cpuTCPDumpFileName = MainActivity.btn_click_time.concat(".cpuTCPDump");
if (MainActivity.isLoggingAppSelf)
cpuAppSelfFileName = MainActivity.btn_click_time.concat(".cpuAppSelf");
try {
if (wifiRSS != 0)
os_ss = new FileOutputStream(new File(mDir, ssFileName));
os_cpu = new FileOutputStream(new File(mDir, cpuFileName));
if (MainActivity.wifiDriverPID != -1)
os_cpuWiFiDriverPID = new FileOutputStream(new File(mDir, cpuWiFiDriverPIDFileName));
if (MainActivity.isLoggingPerProcPID)
os_cpuPerProcPID = new FileOutputStream(new File(mDir, cpuPerProcPIDFileName));
if (tcpdumpPID != -1)
os_cpuTCPDump = new FileOutputStream(new File(mDir, cpuTCPDumpFileName));
if (MainActivity.isLoggingAppSelf)
os_cpuAppSelf = new FileOutputStream(new File(mDir, cpuAppSelfFileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
isRunning = true;
initialization();
// collect signals
PollingThread pt = new PollingThread();
pt.start();
return START_STICKY;
}
@Override
public void onCreate(){
super.onCreate();
// Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy(){
isRunning = false;
if (wifiRSS != 0)
this.unregisterReceiver(this.myWifiReceiver);
// kill tcpdump
if (MainActivity.isUsingTCPDump) {
try {
Runtime.getRuntime().exec("su -c killall -9 tcpdump").waitFor();
if (MainActivity.isVerbose)
Log.d(TAG, "TCPDump ended");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (MainActivity.isLoggingTCPDump)
tcpdumpPID = -1;
}
try {
if (os_ss != null)
os_ss.close();
if (os_cpu != null)
os_cpu.close();
if (os_cpuWiFiDriverPID != null)
os_cpuWiFiDriverPID.close();
if (os_cpuPerProcPID != null)
os_cpuPerProcPID.close();
if (os_cpuTCPDump != null)
os_cpuTCPDump.close();
if (os_cpuAppSelf != null)
os_cpuAppSelf.close();
} catch (IOException e) {
e.printStackTrace();
}
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private BroadcastReceiver myWifiReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent arg1){
wifiRSS = arg1.getIntExtra(WifiManager.EXTRA_NEW_RSSI, 0);
if (MainActivity.isVerbose) {
Log.d(TAG, "WiFi RSSI: " + wifiRSS);
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("wifiRSS: " + wifiRSS + "\n");
}
});
}
}
};
/**
* parse one string line of proc (faster)
* @param toks each part
* @return string that's been aggregated
*/
private static String parseProcStat(String[] toks) {
// the columns are:
// 0 "cpu": the string "cpu" that identifies the line
// 1 user: normal processes executing in user mode
// 2 nice: niced processes executing in user mode
// 3 system: processes executing in kernel mode
// 4 idle: twiddling thumbs
// 5 iowait: waiting for I/O to complete
// 6 irq: servicing interrupts
// 7 softirq: servicing softirqs
long idle = Long.parseLong(toks[4]);
long cpu = Long.parseLong(toks[1]) + Long.parseLong(toks[2]) + Long.parseLong(toks[3])
+ Long.parseLong(toks[5]) + Long.parseLong(toks[6]) + Long.parseLong(toks[7]);
return idle + " " + cpu;
}
/**
* parse one string line of procpid
* @param line the line
* @return string that's been parsed
*/
private static String parseProcPIDStat(String line) {
if (line == null) return "-1 -1 -1"; // -1 means it does not exist
String[] toks = line.split("\\s+");
long idle = Long.parseLong(toks[15]) + Long.parseLong(toks[16]);
long cpu = Long.parseLong(toks[13]) + Long.parseLong(toks[14]);
long whichcpu = Long.parseLong(toks[38]);
return idle + " " + cpu + " " + whichcpu;
}
/**
* read the cpu usage (faster)
* @param raws String[]
*/
private static void readUsage(String[] raws) {
try {
RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
String load = reader.readLine();
raws[0] = load;
load = reader.readLine();
raws[1] = load;
if (MainActivity.coreNum > 1) {
load = reader.readLine();
raws[2] = load;
}
if (MainActivity.coreNum > 2) {
load = reader.readLine();
raws[3] = load;
}
if (MainActivity.coreNum > 3) {
load = reader.readLine();
raws[4] = load;
}
reader.close();
} catch (IOException unimportant) {
Log.w(TAG, "exception on readUsage (faster)");
}
}
private static String readUsagePID(int currentPID) {
if (currentPID == -1) return null;
// changed by Yanzi
try {
RandomAccessFile reader = new RandomAccessFile("/proc/" + currentPID +"/stat", "r");
String load = reader.readLine();
reader.close();
return load;
} catch (IOException unimportant) {
Log.w(TAG, "exception on readUsagePID on pid: " + currentPID);
}
return null;
}
/**
* get the frequency of the cpu
* @param cpuid which cpu
* @return long
*/
private static long cpuFrequency(int cpuid) {
try {
String pathFile = "/sys/devices/system/cpu/cpu" + cpuid + "/cpufreq/scaling_cur_freq";
RandomAccessFile reader = new RandomAccessFile(pathFile, "r");
String load = reader.readLine();
String[] toks = load.split("\\s+");
long cpuScaling = Long.parseLong(toks[0]);
reader.close();
return cpuScaling;
} catch (FileNotFoundException unimportant) {
// Log.w(TAG, "exception on cpuFreq");
return -1;
} catch (IOException unimportant) {
// Log.w(TAG, "exception on cpuFreq");
return -1;
}
}
}

View File

@ -0,0 +1,73 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_RX_CNormal implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_RX_Normal)
return;
if (MainActivity.isVerbose)
Log.d("RX_Normal", "Start RX Normal");
MainActivity.isRunning_RX_Normal = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_RX_Normal + " "
+ MainActivity.bytes2send + " " + MainActivity.RXportNum;
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_RX_Normal, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in RX_Normal at port " + MainActivity.RXportNum + "\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
final String mOut = out.toString().trim();
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
if (MainActivity.isVerbose) {
Log.d("Thread_RX_CNormal", mOut + "ms");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("RX_Normal", "Stop RX Normal");
MainActivity.isRunning_RX_Normal = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,76 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_RX_CNormalUDP implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_RX_NormalUDP)
return;
if (MainActivity.isVerbose)
Log.d("RX_NormalUDP", "Start RX NormalUDP");
MainActivity.isRunning_RX_NormalUDP = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_RX_NormalUDP + " "
+ MainActivity.bytes2send + " 32000";
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_RX_NormalUDP, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in RX_NormalUDP at port 32000\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (out.length() > 0) {
MainActivity.UDPfinishTime = (int)Float.parseFloat(out.toString().trim());
}
final String mOut = out.toString().trim();
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
if (MainActivity.isVerbose) {
Log.d("Thread_RX_CNormalUDP", mOut + "ms");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("RX_NormalUDP", "Stop RX NormalUDP");
MainActivity.isRunning_RX_NormalUDP = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,76 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_RX_CRawNormal implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_RX_RawNormal)
return;
if (MainActivity.isVerbose)
Log.d("RX_RawNormal", "Start RX RawNormal");
MainActivity.isRunning_RX_RawNormal = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_RX_RawNormal + " "
+ MainActivity.bytes2send;
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_RX_RawNormal, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in RX_RawNormal at port " + MainActivity.RXportNum + "\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (out.length() > 0) {
MainActivity.UDPfinishTime = (int)Float.parseFloat(out.toString().trim());
}
final String mOut = out.toString().trim();
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
if (MainActivity.isVerbose) {
Log.d("Thread_RX_CRawNormal", mOut + "ms");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("RX_RawNormal", "Stop RX RawNormal");
MainActivity.isRunning_RX_RawNormal = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,73 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_RX_CSendfile implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_RX_Sendfile)
return;
if (MainActivity.isVerbose)
Log.d("RX_Sendfile", "Start RX Sendfile");
MainActivity.isRunning_RX_Sendfile = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_RX_Sendfile + " "
+ MainActivity.bytes2send + " " + MainActivity.RXportNum;
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_RX_Sendfile, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in RX_Sendfile at port " + MainActivity.RXportNum + "\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
final String mOut = out.toString().trim();
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
if (MainActivity.isVerbose) {
Log.d("Thread_RX_CSendfile", mOut + "ms");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("RX_Sendfile", "Stop RX Sendfile");
MainActivity.isRunning_RX_Sendfile = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,73 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_RX_CSplice implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_RX_Splice)
return;
if (MainActivity.isVerbose)
Log.d("RX_Splicee", "Start RX Splice");
MainActivity.isRunning_RX_Splice = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_RX_Splice + " "
+ MainActivity.bytes2send + " " + MainActivity.RXportNum;
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_RX_Splice, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in RX_Splice at port " + MainActivity.RXportNum + "\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
final String mOut = out.toString().trim();
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
if (MainActivity.isVerbose) {
Log.d("Thread_RX_CSplice", mOut + "ms");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("RX_Splice", "Stop RX Splice");
MainActivity.isRunning_RX_Splice = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,76 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_TX_CNormal implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_Normal)
return;
if (MainActivity.isVerbose)
Log.d("TX_Normal", "Start TX Normal");
MainActivity.isRunning_TX_Normal = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_Normal + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
// Log.d("Thread_TX_CNormal", "per proc: " + MainActivity.perProcPID);
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_Normal, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_Normal\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
final String mOut = out.toString().trim();
if (mOut != "")
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
else
MainActivity.reportedFinishTime = 0.0;
if (MainActivity.isVerbose) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_Normal", "Stop TX Normal");
MainActivity.isRunning_TX_Normal = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,73 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_TX_CNormalUDP implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_NormalUDP)
return;
if (MainActivity.isVerbose)
Log.d("TX_NormalUDP", "Start TX Normal UDP");
MainActivity.isRunning_TX_NormalUDP = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_NormalUDP + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
// Log.d("Thread_TX_CNormalUDP", "per proc: " + MainActivity.perProcPID);
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_NormalUDP, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_NormalUDP\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
final String mOut = out.toString().trim();
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
if (MainActivity.isVerbose) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_NormalUDP", "Stop TX Normal UDP");
MainActivity.isRunning_TX_NormalUDP = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,72 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/19/15.
*/
public class Thread_TX_CRawNormal implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_RawNormal)
return;
if (MainActivity.isVerbose)
Log.d("TX_RawNormal", "Start TX RawNormal");
MainActivity.isRunning_TX_RawNormal = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_RawNormal + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_RawNormal, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_RawNormal\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
final String mOut = out.toString().trim();
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
if (MainActivity.isVerbose) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_RawNormal", "Stop TX RawNormal");
MainActivity.isRunning_TX_RawNormal = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,72 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_TX_CRawSplice implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_RawSplice)
return;
if (MainActivity.isVerbose)
Log.d("TX_RawSplice", "Start TX RawSplice");
MainActivity.isRunning_TX_RawSplice = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_RawSplice + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_RawSplice, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_RawSplice\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
final String mOut = out.toString().trim();
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
if (MainActivity.isVerbose) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_RawSplice", "Stop TX RawSplice");
MainActivity.isRunning_TX_RawSplice = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,72 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/19/15.
*/
public class Thread_TX_CSendfile implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_Sendfile)
return;
if (MainActivity.isVerbose)
Log.d("TX_Sendfile", "Start TX Sendfile");
MainActivity.isRunning_TX_Sendfile = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_Sendfile + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_Sendfile, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_Sendfile\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
final String mOut = out.toString().trim();
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
if (MainActivity.isVerbose) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_Sendfile", "Stop TX Sendfile");
MainActivity.isRunning_TX_Sendfile = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,72 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_TX_CSplice implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_Splice)
return;
if (MainActivity.isVerbose)
Log.d("TX_Splice", "Start TX Splice");
MainActivity.isRunning_TX_Splice = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_Splice + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) {
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_Splice, false);
}
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_Splice\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
final String mOut = out.toString().trim();
MainActivity.reportedFinishTime = Double.parseDouble(mOut);
if (MainActivity.isVerbose) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_Splice", "Stop TX Splice");
MainActivity.isRunning_TX_Splice = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,263 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.os.Environment;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
/**
* Created by yanzi on 10/1/15.
*/
public class Utilities {
private static final String TAG = "Utilities";
/**
* check if we can write on external storage
* @return true/false
*/
public static boolean canWriteOnExternalStorage() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/**
* get the number of cores of device
* @return int > 0
*/
protected static int getNumCores() {
Process proc;
try {
proc = Runtime.getRuntime().exec("grep -c processor /proc/cpuinfo");
InputStream stdout = proc.getInputStream();
byte[] buff = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buff);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.setText("Failed to get cores\n");
}
});
return 1;
}
out.append(new String(buff, 0, read));
if(read<20){
break;
}
}
proc.waitFor();
stdout.close();
//Return the number of cores (virtual CPU devices)
return Integer.parseInt(out.toString().trim());
} catch(Exception e) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.setText("Failed to get cores\n");
}
});
//Default to return 1 core
return 1;
}
}
/**
* get pid of the binary process
* @param inName the name of process
* @return true/false - succeed or not
*/
protected static int getMyPID(String inName, boolean flag) {
String commd;
if (flag)
commd = "su -c busybox ps | grep " + inName + " | grep -v grep | head -1 | awk '{print $1}'";
else
commd = "su -c busybox ps | grep " + inName + " | grep -v grep | head -1 | awk '{print $3}'";
try {
Process proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
String line;
StringBuilder out = new StringBuilder();
BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while ((line = is.readLine()) != null) {
out.append(line).append("\n");
}
String tmp = out.toString().trim();
if (!tmp.equals("")) {
return Integer.parseInt(tmp);
}
} catch (InterruptedException unimportant) {
Log.d(TAG, "InterruptedException but unimportant");
} catch (IOException e) {
Log.d(TAG, "IOException but unimportant");
}
return -1;
}
/**
* check if a file exists
* @param myFile
* @return true/false
*/
protected static boolean fileExist(String myFile) {
File file = new File(myFile);
if (file.exists() && file.isFile())
return true;
return false;
}
/**
* parse CPU for a folder
* @param folderName
* @return true/false
*/
protected static boolean parseCPUforFolder(String folderName) {
try {
Process proc = Runtime.getRuntime().exec("su && cd " + MainActivity.outFolderPath + "/" + folderName
+ " && ls *.cpuRaw");
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
Log.d(TAG, "Failed in parseCPUforFolder: ls nothing");
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (!out.toString().equals("")) {
String[] cpuFiles = out.toString().split("\\n");
for (int i = 0; i < cpuFiles.length; ++i) {
try {
BufferedReader br = new BufferedReader(
new FileReader(MainActivity.outFolderPath + "/" + folderName + "/" + cpuFiles[i]));
FileOutputStream os_cpu = new FileOutputStream(
new File(MainActivity.outFolderPath + "/" + folderName, cpuFiles[i].replace("cpuRaw", "cpu")));
String line;
while ((line = br.readLine()) != null) {
String[] toks = line.split("\\s+");
// format for Ana's script:
// time
// cpuTotal idle
// cpuTotal used
// cpu0 idle
// cpu0 used
// cpu0 freq
// cpu1 freq
// cpuTotal normal process user mode
// cpuTotal niced process in user mode
// cpuTotal kernal mode
// cpuTotal IO
// cpuTotal hardware interrupts
// cpuTotal software interrupts
// cpu0 normal process user mode
// cpu0 niced process in user mode
// cpu0 kernal mode
// cpu0 IO
// cpu0 hardware interrupts
// cpu0 software interrupts
os_cpu.write((toks[0] + " " // time
// cpuTotal toks[1-11]
+ toks[5] + " " // cpuTotal idle
// cpuTotal used
+ (Long.parseLong(toks[2]) + Long.parseLong(toks[3])
+ Long.parseLong(toks[4]) + Long.parseLong(toks[6])
+ Long.parseLong(toks[7]) + Long.parseLong(toks[8])) + " "
// cpu 0 toks[12-22]
+ toks[16] + " " // cpu0 idle
// cpu0 used
+ (Long.parseLong(toks[13]) + Long.parseLong(toks[14])
+ Long.parseLong(toks[15]) + Long.parseLong(toks[17])
+ Long.parseLong(toks[18]) + Long.parseLong(toks[19])) + " "
// cpu 0 freq toks[23]
+ toks[23] + " "
// cpu 1 freq toks[35]
+ toks[35] + " "
// cpuTotal details
+ toks[2] + " " + toks[3] + " " + toks[4] + " "
+ toks[6] + " " + toks[7] + " " + toks[8] + " "
// cpu0 details
+ toks[13] + " " + toks[14] + " " + toks[15] + " "
+ toks[17] + " " + toks[18] + " " + toks[19]).getBytes());
// cpu 1 toks[24-34]
os_cpu.write("\n".getBytes());
os_cpu.flush();
}
os_cpu.close();
} catch (IOException unimportant) {
return false;
}
}
}
} catch (IOException e) {
// e.printStackTrace();
return false;
} catch (InterruptedException e) {
// e.printStackTrace();
return false;
}
return true;
}
protected static int findCorrespondingThrpt(int myI) {
if (myI == 0) {
return 50000;
} else if (myI == 1) {
return 100000;
} else if (myI < 6) {
return 250000 * (myI - 1);
} else if (myI < 24) {
return 1500000 + 500000 * (myI - 6);
} else if (myI > 24 && myI < 43) {
return 15000000 + 5000000 * (myI - 25);
} else if (myI == 43) {
return 11000000;
} else if (myI == 44){
return 13000000;
} else { // default unlimited
if (MainActivity.isLocal)
return 100000000;
else
return 20000000;
}
}
protected static void estimateTime(int numRepeats, int numSelectedItems, int totalBytes, ArrayList<Integer> selectedItemsThrpt) {
int time = 0;
if (MainActivity.isLocal) {
for (int k = 0; k < selectedItemsThrpt.size(); ++k)
time += (Math.max(totalBytes / findCorrespondingThrpt(selectedItemsThrpt.get(k)) + 20, 20));
} else {
for (int k = 0; k < selectedItemsThrpt.size(); ++k)
time += (Math.max(totalBytes / findCorrespondingThrpt(selectedItemsThrpt.get(k)) + 20, 60));
}
time = (time + 15) * numSelectedItems * numRepeats * 1000;
final String estimatedTime = new SimpleDateFormat("MM/dd HH:mm:ss").format(new Date(System.currentTimeMillis() + time));
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Estimated ending @ " + estimatedTime + "\n");
}
});
}
}

View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:id="@+id/container">
<LinearLayout
android:id="@+id/container_txrx"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="1">
<Button
android:theme="@style/theme_btn_tx"
android:id="@+id/btn_startTransmit"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/btn_begintx"
android:textStyle="bold"
android:textSize="20dp"
android:textColor="#FFFFFF"/>
<Button
android:theme="@style/theme_btn_rx"
android:id="@+id/btn_startReceive"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/btn_beginrx"
android:textStyle="bold"
android:textSize="20dp"
android:textColor="#FFFFFF"/>
</LinearLayout>
<HorizontalScrollView
android:id="@+id/container_config"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="@string/txt_configs"
android:textStyle="bold"
android:layout_gravity="center"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_setByte2send"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/btn_setbytes"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_setRepeatTimes"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/btn_setrepeat"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_setTCPDumpInterface"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/btn_setuptcpdump"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_setLogFreq"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Set\nLog Freq"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_setOthers"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/btn_setothers"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_clearStatus"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/btn_clear"
android:textSize="16dp"/>
</LinearLayout>
</HorizontalScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/txt_results"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text=""
android:gravity="center"
android:textStyle="bold"
android:textSize="20dp"
android:textColor="@color/indiego"/>
</LinearLayout>
</ScrollView>
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -0,0 +1,14 @@
<resources>
<string name="app_name">Offloading Demo</string>
<string name="txt_configs">Configs →</string>
<string name="btn_setbytes">Set\nBytes</string>
<string name="btn_setrepeat">Set\nRepeats</string>
<string name="btn_setuptcpdump">Setup\nTCPDump</string>
<string name="btn_setothers">Misc.</string>
<string name="btn_clear">Clear</string>
<string name="btn_beginrx">Begin RX</string>
<string name="btn_begintx">Begin TX</string>
<string name="warn_root">Not rooted!! Must be rooted!</string>
<string name="stat_wifion">WiFi is ON!\n</string>
<string name="stat_wifioff">WiFi is NOT On!\n</string>
</resources>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="indiego">#3F51B5</color>
<color name="pink">#FF4081</color>
<style name="theme_btn_tx" parent="android:Theme.Material">
<item name="android:colorButtonNormal">@color/indiego</item>
</style>
<style name="theme_btn_rx" parent="android:Theme.Material">
<item name="android:colorButtonNormal">@color/pink</item>
</style>
</resources>

View File

@ -0,0 +1,15 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* To work on unit tests, switch the Test Artifact in the Build Variants view.
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}

View File

@ -0,0 +1 @@
include ':mobile', ':wear'

1
OffloadingDemo/wear/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,27 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "edu.ucsb.cs.sandlab.offloadingdemo"
minSdkVersion 21
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.support:wearable:1.3.0'
compile 'com.google.android.gms:play-services-wearable:7.8.0'
}

17
OffloadingDemo/wear/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/yanzi/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.ucsb.cs.sandlab.offloadingdemo" >
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE"/>
<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.READ_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault" >
<uses-library
android:name="com.google.android.wearable"
android:required="false" />
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="orientation|screenSize"
android:theme="@android:style/Theme.DeviceDefault.Light" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".SSLogger"
android:label="SSLogger"
android:exported="false"/>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,132 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
/**
* Created by yanzi on 7/10/15.
*/
public class Connectivity {
/**
* Get the network info
* @param context
* @return
*/
public static NetworkInfo getNetworkInfo(Context context){
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo();
}
/**
* Check if there is any connectivity
* @param context
* @return
*/
public static boolean isConnected(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected());
}
/**
* Check if there is any connectivity to a Wifi network
* @param context
* @param type
* @return
*/
public static boolean isConnectedWifi(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
}
/**
* Check if there is any connectivity to a mobile network
* @param context
* @param type
* @return
*/
public static boolean isConnectedMobile(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
}
/**
* Check if there is any connectivity to a mobile network
* @param context
* @param type
* @return
*/
public static boolean isConnectedLTE(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && info.getSubtype() == TelephonyManager.NETWORK_TYPE_LTE);
}
/**
* Check if there is fast connectivity
* @param context
* @return
*/
public static boolean isConnectedFast(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(),info.getSubtype()));
}
/**
* Check if the connection is fast
* @param type
* @param subType
* @return
*/
public static boolean isConnectionFast(int type, int subType){
if(type== ConnectivityManager.TYPE_WIFI){
return true;
}else if(type== ConnectivityManager.TYPE_MOBILE){
switch(subType){
case TelephonyManager.NETWORK_TYPE_1xRTT:
return false; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_CDMA:
return false; // ~ 14-64 kbps
case TelephonyManager.NETWORK_TYPE_EDGE:
return false; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_EVDO_0:
return true; // ~ 400-1000 kbps
case TelephonyManager.NETWORK_TYPE_EVDO_A:
return true; // ~ 600-1400 kbps
case TelephonyManager.NETWORK_TYPE_GPRS:
return false; // ~ 100 kbps
case TelephonyManager.NETWORK_TYPE_HSDPA:
return true; // ~ 2-14 Mbps
case TelephonyManager.NETWORK_TYPE_HSPA:
return true; // ~ 700-1700 kbps
case TelephonyManager.NETWORK_TYPE_HSUPA:
return true; // ~ 1-23 Mbps
case TelephonyManager.NETWORK_TYPE_UMTS:
return true; // ~ 400-7000 kbps
/*
* Above API level 7, make sure to set android:targetSdkVersion
* to appropriate level to use these
*/
// case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11
// return true; // ~ 1-2 Mbps
// case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
// return true; // ~ 5 Mbps
case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
return true; // ~ 10-20 Mbps
// case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
// return false; // ~25 kbps
case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
return true; // ~ 10+ Mbps
// Unknown
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
default:
return false;
}
}else{
return false;
}
}
}

View File

@ -0,0 +1,875 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.wearable.activity.WearableActivity;
import android.support.wearable.view.BoxInsetLayout;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class MainActivity extends WearableActivity {
// unchanged stuff
protected static final String sshlinklab = "ssh linklab@hotcrp.cs.ucsb.edu -i /data/.ssh/id_rsa -o StrictHostKeyChecking=no";
protected static final String sshlinklablocal = "ssh linklab@128.111.68.220 -i /data/.ssh/id_rsa -o StrictHostKeyChecking=no";
protected static final String udpserver_pathport = "~/mobileRDMABeach/UDPServer 32000 ";
protected static final String binaryFolderPath = "/data/local/tmp/";
protected static final String binary_tcpdump = "tcpdump";
protected static final int oneMB = 1048576;
private static final String TAG = "MainActivity";
private static final int mVersion = Build.VERSION.SDK_INT;
// the configs
protected static boolean isForcingCPU0 = false;
protected static boolean isVerbose = true;
protected static boolean isLocal = false;
protected static boolean isLoggingTCPDump = false;
protected static boolean isUsingTCPDump = true;
protected static boolean isLoggingPerProcPID = false;
protected static boolean isLoggingAppSelf = false;
protected static int time_wait_for = 100; // ms
protected static int wifiDriverPID = -1;
// maintained variables
private BoxInsetLayout mContainerView;
private LinearLayout mContainerViewTXRX;
private HorizontalScrollView mContainerViewConfig;
private Button btn_startTransmit, btn_startReceive;
private Button btn_setByte2send, btn_setRepeatTimes, btn_setTCPDumpInterface,
btn_clearStatus, btn_setLogFreq, btn_setOthers;
private CharSequence[] existedItems;
private CharSequence[] existedItemsThrpt;
private WifiManager wm;
private Intent intentSSLogger;
protected static int coreNum = 1;
protected static int perProcPID = -1;
protected static int UDPfinishTime = 0;
protected static double reportedFinishTime = 0.0;
protected static int repeatCounts = 3;
protected static int bytes2send = 10*oneMB; // default 10MB
protected static int currentBandwidth = 20000000; // bytes per sec, default unlimited (not for loopback)
protected static TextView txt_results;
protected static Handler myHandler;
protected static String RXportNum = "4445";
protected static String outFolderPath;
protected static String btn_click_time;
protected static String tcpdumpInterface = "wlan0";
protected static String binary_TX_Normal = "normal";
protected static String binary_TX_NormalUDP = "normal_udp";
protected static String binary_TX_Sendfile = "sendfile";
protected static String binary_TX_Splice = "splice";
protected static String binary_TX_RawNormal = "bypassl3";
protected static final String binary_TX_RawSplice = "";
protected static String binary_RX_Normal = "normal_recv";
protected static String binary_RX_NormalUDP = "normal_udp_recv";
protected static final String binary_RX_Sendfile = "";
protected static String binary_RX_Splice = "splice_recv";
protected static String binary_RX_RawNormal = "bypassl3_recv";
protected static boolean isUsingWifi = true;
protected static boolean isRunning_TX_Normal = false;
protected static boolean isRunning_TX_NormalUDP = false;
protected static boolean isRunning_TX_Sendfile = false;
protected static boolean isRunning_TX_Splice = false;
protected static boolean isRunning_TX_RawNormal = false;
protected static boolean isRunning_TX_RawSplice = false;
protected static boolean isRunning_RX_Normal = false;
protected static boolean isRunning_RX_NormalUDP = false;
protected static boolean isRunning_RX_Sendfile = false;
protected static boolean isRunning_RX_Splice = false;
protected static boolean isRunning_RX_RawNormal = false;
/**
* Check whether a service is running
* @param serviceClass
* @return true/false
*/
private boolean isServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
/**
* Check if service is still running in the background, if so tell me in logcat
*/
private void myServiceCheck() {
if (!isVerbose) return;
if (isServiceRunning(SSLogger.class)) {
Log.d(TAG, "SSLogger running..");
} else {
Log.d(TAG, "SSLogger stopped..");
}
}
private boolean checkBinaryFilesExist() {
String missingFiles = "";
if (!Utilities.fileExist(binaryFolderPath + binary_tcpdump))
missingFiles += binary_tcpdump;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Normal))
missingFiles += " " + binary_TX_Normal;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Normal + "_lo"))
missingFiles += " " + binary_TX_Normal + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_TX_NormalUDP))
missingFiles += " " + binary_TX_NormalUDP;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_NormalUDP + "_lo"))
missingFiles += " " + binary_TX_NormalUDP + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Sendfile))
missingFiles += " " + binary_TX_Sendfile;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Sendfile + "_lo"))
missingFiles += " " + binary_TX_Sendfile + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Splice))
missingFiles += " " + binary_TX_Splice;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_Splice + "_lo"))
missingFiles += " " + binary_TX_Splice + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_TX_RawNormal))
missingFiles += " " + binary_TX_RawNormal;
if (!Utilities.fileExist(binaryFolderPath + binary_TX_RawNormal + "_lo"))
missingFiles += " " + binary_TX_RawNormal + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_RX_Normal))
missingFiles += " " + binary_RX_Normal;
if (!Utilities.fileExist(binaryFolderPath + binary_RX_Normal + "_lo"))
missingFiles += " " + binary_RX_Normal + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_RX_NormalUDP))
missingFiles += " " + binary_RX_NormalUDP;
if (!Utilities.fileExist(binaryFolderPath + binary_RX_NormalUDP + "_lo"))
missingFiles += " " + binary_RX_NormalUDP + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_RX_Splice))
missingFiles += " " + binary_RX_Splice;
if (!Utilities.fileExist(binaryFolderPath + binary_RX_Splice + "_lo"))
missingFiles += " " + binary_RX_Splice + "_lo";
if (!Utilities.fileExist(binaryFolderPath + binary_RX_RawNormal))
missingFiles += " " + binary_RX_RawNormal;
if (!Utilities.fileExist(binaryFolderPath + binary_RX_RawNormal + "_lo"))
missingFiles += " " + binary_RX_RawNormal + "_lo";
if (!missingFiles.equals("")) {
final String mFiles = missingFiles;
myHandler.post(new Runnable() {
@Override
public void run() {
txt_results.setText("Failed to find following files:\n" + mFiles);
btn_startTransmit.setEnabled(false);
btn_startReceive.setEnabled(false);
}
});
return false;
} else {
btn_startTransmit.setEnabled(true);
btn_startReceive.setEnabled(true);
}
return true;
}
/**
* start the record
* @param myflag
*/
protected void startRecording(boolean myflag) {
final boolean flagRecv = myflag;
final ArrayList<Integer> selectedItems = new ArrayList<>();
AlertDialog.Builder adb = new AlertDialog.Builder(MainActivity.this);
adb.setMultiChoiceItems(existedItems, null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (which == 5 || (flagRecv && which == 2) || (mVersion < 21 && which == 3)) {
Toast.makeText(MainActivity.this, "not working", Toast.LENGTH_SHORT).show();
return;
}
if (isChecked) {
selectedItems.add(which);
} else if (selectedItems.contains(which)) {
selectedItems.remove(Integer.valueOf(which));
}
}
});
adb.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (selectedItems.size() < 1) {
Toast.makeText(MainActivity.this, "Nothing is selected", Toast.LENGTH_SHORT).show();
return;
}
final ArrayList<Integer> selectedItemsThrpt = new ArrayList<>();
AlertDialog.Builder adb = new AlertDialog.Builder(MainActivity.this);
adb.setMultiChoiceItems(existedItemsThrpt, null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (isChecked) {
selectedItemsThrpt.add(which);
} else if (selectedItemsThrpt.contains(which)) {
selectedItemsThrpt.remove(Integer.valueOf(which));
}
}
});
adb.setPositiveButton("Go!", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (selectedItemsThrpt.size() < 1) {
Toast.makeText(MainActivity.this, "Nothing is selected", Toast.LENGTH_SHORT).show();
return;
}
if (isVerbose) {
Log.d(TAG, "selected variations " + selectedItemsThrpt);
}
Utilities.estimateTime(repeatCounts, selectedItems.size(), bytes2send, selectedItemsThrpt);
new Thread(new Runnable() {
@Override
public void run() {
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "&&";
myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Begin..\n");
}
});
// prepare
try {
Runtime.getRuntime().exec("su -c killall -9 normal").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_udp").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_udp_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 sendfile").waitFor();
Runtime.getRuntime().exec("su -c killall -9 sendfile_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 splice").waitFor();
Runtime.getRuntime().exec("su -c killall -9 splice_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 bypassl3").waitFor();
Runtime.getRuntime().exec("su -c killall -9 bypassl3_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_recv").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_recv_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_udp_recv").waitFor();
Runtime.getRuntime().exec("su -c killall -9 normal_udp_recv_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 splice_recv").waitFor();
Runtime.getRuntime().exec("su -c killall -9 splice_recv_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 bypassl3_recv").waitFor();
Runtime.getRuntime().exec("su -c killall -9 bypassl3_recv_lo").waitFor();
Runtime.getRuntime().exec("su -c killall -9 tcpdump").waitFor();
Runtime.getRuntime().exec("su -c killall -9 TCPReceiver_mobile").waitFor();
Runtime.getRuntime().exec("su -c killall -9 TCPSender_mobile").waitFor();
Runtime.getRuntime().exec("su -c killall -9 UDPServer_mobile").waitFor();
if (isLocal) {
if (flagRecv)
Runtime.getRuntime().exec("su && /data/local/tmp/Run_for_Download.sh").waitFor();
else
Runtime.getRuntime().exec("su && /data/local/tmp/Run_for_Upload.sh").waitFor();
} else {
myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("In case you forget, remember to run " + ((flagRecv) ? "Run_for_Download.sh" : "Run_for_Upload.sh") + "\n");
}
});
}
// check if is charging, if yes, then we can safely turn on theater mode
Intent intent = registerReceiver(null,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
if (plugged == BatteryManager.BATTERY_PLUGGED_AC
|| plugged == BatteryManager.BATTERY_PLUGGED_USB) {
commd[2] = "settings put global theater_mode_on 1";
}
Runtime.getRuntime().exec(commd).waitFor();
Thread.sleep(11000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// start iteration
for (int k = 0; k < selectedItemsThrpt.size(); ++k) {
int myI = selectedItemsThrpt.get(k);
currentBandwidth = Utilities.findCorrespondingThrpt(myI);
RXportNum = Integer.toString(4445 - myI + 24);
if (isVerbose) {
Log.d(TAG, "bandwidth is set to " + currentBandwidth
+ "\nRXportNum is set to " + RXportNum);
}
// start
try {
commd[2] = "cd " + outFolderPath
+ " && ls | grep -v '.tar.gz' | busybox xargs rm -rf";
Runtime.getRuntime().exec(commd).waitFor();
commd[2] = "mkdir -p";
for (int i = 0; i < selectedItems.size(); ++i) {
commd[2] += " " + outFolderPath + "/" + existedItems[selectedItems.get(i)];
}
Runtime.getRuntime().exec(commd).waitFor();
Thread.sleep(1000);
// start repeating
int waitTimeSec = 0;
for (int i = 0; i < repeatCounts; ++i) {
for (int j = 0; j < selectedItems.size(); ++j) {
if (flagRecv && (selectedItems.get(j) == 1 || selectedItems.get(j) == 4)) {
if (isLocal) {
waitTimeSec = (Math.max(bytes2send / currentBandwidth + 20, 20));
Runtime.getRuntime().exec("su -c /data/local/tmp/UDPServer_mobile 32000 "
+ currentBandwidth + " " + waitTimeSec + " &").waitFor();
} else {
waitTimeSec = (Math.max(bytes2send / currentBandwidth + 20, 60));
Process proc = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(proc.getOutputStream());
if (isUsingWifi) {
os.writeBytes(sshlinklablocal + "\n");
os.flush();
Thread.sleep(5001);
} else {
os.writeBytes(sshlinklab + "\n");
os.flush();
Thread.sleep(10001);
}
os.writeBytes(udpserver_pathport + currentBandwidth + " " + waitTimeSec + " &\n");
os.flush();
Thread.sleep(1001);
os.writeBytes("exit\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
Thread.sleep(501);
os.close();
proc.destroy();
Thread.sleep(805);
}
}
Thread.sleep(1000);
btn_click_time = Long.toString(System.currentTimeMillis());
startService(intentSSLogger);
Thread.sleep(500);
myServiceCheck();
Thread.sleep(1000);
if (flagRecv) { // Starting Receiving
switch (selectedItems.get(j)) {
case 0: // normal
new Thread(new Thread_RX_CNormal()).start();
Thread.sleep(1005);
while (isRunning_RX_Normal) {
Thread.sleep(1005);
}
break;
case 1: // normal udp
new Thread(new Thread_RX_CNormalUDP()).start();
Thread.sleep(1005);
while (isRunning_TX_NormalUDP) {
Thread.sleep(1005);
}
break;
case 2: // sendfile unimplemented
break;
case 3: // splice
new Thread(new Thread_RX_CSplice()).start();
Thread.sleep(1005);
while (isRunning_TX_Splice) {
Thread.sleep(1005);
}
break;
case 4: // rawsocket
new Thread(new Thread_RX_CRawNormal()).start();
Thread.sleep(1005);
while (isRunning_TX_RawNormal) {
Thread.sleep(1005);
}
break;
default: // do nothing
break;
}
} else { // Starting Transmitting
switch (selectedItems.get(j)) {
case 0: // normal
new Thread(new Thread_TX_CNormal()).start();
Thread.sleep(1005);
while (isRunning_TX_Normal) {
Thread.sleep(1005);
}
break;
case 1: // normal udp
new Thread(new Thread_TX_CNormalUDP()).start();
Thread.sleep(1005);
while (isRunning_TX_NormalUDP) {
Thread.sleep(1005);
}
break;
case 2: // sendfile
new Thread(new Thread_TX_CSendfile()).start();
Thread.sleep(1005);
while (isRunning_TX_Sendfile) {
Thread.sleep(1005);
}
break;
case 3: // splice
new Thread(new Thread_TX_CSplice()).start();
Thread.sleep(1005);
while (isRunning_TX_Splice) {
Thread.sleep(1005);
}
break;
case 4: // rawsocket
new Thread(new Thread_TX_CRawNormal()).start();
Thread.sleep(1005);
while (isRunning_TX_RawNormal) {
Thread.sleep(1005);
}
break;
case 5: // rawsocket splice
break;
default: // do nothing
break;
}
}
stopService(intentSSLogger);
myServiceCheck();
Thread.sleep(500);
if (flagRecv && (selectedItems.get(j) == 1 || selectedItems.get(j) == 4)) {
Thread.sleep(Math.abs(waitTimeSec * 1000 - UDPfinishTime));
}
commd[2] = "cd " + outFolderPath + " && mv *" + btn_click_time
+ "* " + existedItems[selectedItems.get(j)] + "/";
Runtime.getRuntime().exec(commd).waitFor();
Log.d(TAG, "Finished " + (currentBandwidth / 1000000.0) + "MBps, " + i + "th repeat on " + existedItems[selectedItems.get(j)]);
Thread.sleep(2000);
}
}
// parse and zip it
for (int i = 0; i < selectedItems.size(); ++i) {
if (Utilities.parseCPUforFolder((String) existedItems[selectedItems.get(i)])) {
String tarName = ((flagRecv) ? "download_" : "upload_")
+ existedItems[selectedItems.get(i)] + "_"
+ (bytes2send / 1024) + "KB_" + repeatCounts + "repeats_thrpt_"
+ (currentBandwidth / 1000000.0) + "MBps_"
+ new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())
+ ".tar.gz";
commd[2] = "cd " + outFolderPath + "/"
+ existedItems[selectedItems.get(i)]
+ " && busybox tar -czf ../" + tarName + " *";
Runtime.getRuntime().exec(commd).waitFor();
} else {
final CharSequence failedFolderName = existedItems[selectedItems.get(i)];
myHandler.post(new Runnable() {
@Override
public void run() {
txt_results.append("Failed for folder "
+ failedFolderName + "\n");
}
});
}
}
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
myHandler.post(new Runnable() {
@Override
public void run() {
txt_results.append("All Done\n");
}
});
try {
commd[2] = "settings put global theater_mode_on 0";
Runtime.getRuntime().exec(commd).waitFor();
Thread.sleep(1005);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
});
adb.setNegativeButton("Cancel", null);
adb.create().show();
}
});
adb.setNegativeButton("Cancel", null);
adb.create().show();
}
/**
* Intialize every parameters etc.
*/
protected void initialization() {
// must have root privilege in order to run
try {
Runtime.getRuntime().exec("su");
} catch (Throwable e) {
Toast.makeText(this, R.string.warn_root, Toast.LENGTH_LONG).show();
}
// handler that updates the ui at main thread
// it's used in sslogger thus will be modded in receiver activity also
// do not modify this
myHandler = new Handler();
existedItems = new CharSequence[] {
"Socket_Normal", "Socket_NormalUDP", "Socket_Sendfile",
"Socket_Splice", "RawSocket_Normal"
};
existedItemsThrpt = new CharSequence[]{
"50KB", "100KB", "250KB", "0.5MB", "0.75MB", "1MB", "1.5MB", "2MB", // 0-7
"2.5MB", "3MB", "3.5MB", "4MB", "4.5MB", "5MB", "5.5MB", "6MB", // 8-15
"6.5MB", "7MB", "7.5MB", "8MB", "8.5MB", "9MB", "9.5MB", "10MB", // 16-23
"Unlimited", // 24
"15MB", "20MB", "25MB", "30MB", "35MB", "40MB", "45MB", "50MB", // 25-32
"55MB", "60MB", "65MB", "70MB", "75MB", "80MB", "85MB", "90MB", // 33-40
"95MB", "100MB" // 41-42
};
intentSSLogger = new Intent(this, SSLogger.class);
wm = (WifiManager) this.getSystemService(WIFI_SERVICE);
// assignments
binary_TX_Normal = "normal";
binary_TX_NormalUDP = "normal_udp";
binary_TX_Sendfile = "sendfile";
binary_TX_Splice = "splice";
binary_TX_RawNormal = "bypassl3";
binary_RX_Normal = "normal_recv";
binary_RX_NormalUDP = "normal_udp_recv";
binary_RX_Splice = "splice_recv";
binary_RX_RawNormal = "bypassl3_recv";
coreNum = Utilities.getNumCores();
outFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SSLogger";
isUsingWifi = (wm.isWifiEnabled())?true:false;
// find view elements
txt_results = (TextView) findViewById(R.id.txt_results);
mContainerView = (BoxInsetLayout) findViewById(R.id.container);
mContainerViewTXRX = (LinearLayout) findViewById(R.id.container_txrx);
mContainerViewConfig = (HorizontalScrollView) findViewById(R.id.container_config);
btn_startTransmit = (Button) findViewById(R.id.btn_startTransmit);
btn_startReceive = (Button) findViewById(R.id.btn_startReceive);
btn_setByte2send = (Button) findViewById(R.id.btn_setByte2send);
btn_setRepeatTimes = (Button) findViewById(R.id.btn_setRepeatTimes);
btn_setTCPDumpInterface = (Button) findViewById(R.id.btn_setTCPDumpInterface);
btn_setOthers = (Button) findViewById(R.id.btn_setOthers);
btn_setLogFreq = (Button) findViewById(R.id.btn_setLogFreq);
btn_clearStatus = (Button) findViewById(R.id.btn_clearStatus);
if (coreNum > 2) {
txt_results.append("Only support 2 cores now! Contact Yanzi to add "+coreNum+" cores support!\n");
}
txt_results.append(isUsingWifi ? getString(R.string.stat_wifion) : getString(R.string.stat_wifioff));
// click listener
btn_startTransmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startRecording(false);
}
});
btn_startReceive.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startRecording(true);
}
});
btn_setByte2send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final CharSequence[] mItems={
(bytes2send == (oneMB/2))?"Current: 0.5MB":"0.5MB",
(bytes2send == (oneMB))?"Current: 1MB":"1MB",
(bytes2send == (2*oneMB))?"Current: 2MB":"2MB",
(bytes2send == (5*oneMB))?"Current: 5MB":"5MB",
(bytes2send == (10*oneMB))?"Current: 10MB":"10MB",
(bytes2send == (20*oneMB))?"Current: 20MB":"20MB",
(bytes2send == (50*oneMB))?"Current: 50MB":"50MB",
(bytes2send == (100*oneMB))?"Current: 100MB":"100MB",
(bytes2send == (200*oneMB))?"Current: 200MB":"200MB"};
AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this);
mDialog.setItems(mItems, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which < 3) {
bytes2send = oneMB/2;
for (int i = 0; i < which; ++i)
bytes2send *= 2;
} else if (which < 6) {
bytes2send = 5 * oneMB;
for (int i = 3; i < which; ++i)
bytes2send *= 2;
} else if (which < 9) {
bytes2send = 50 * oneMB;
for (int i = 6; i < which; ++i)
bytes2send *= 2;
} else {
bytes2send = 10 * oneMB; // default 10MB
}
if (isVerbose) {
Log.d(TAG, "outgoing/incoming bytes is set to " + bytes2send);
}
}
});
mDialog.create().show();
}
});
btn_setRepeatTimes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final CharSequence[] mItems={
(repeatCounts == 1)?"Current: once (1)":"once (1)",
(repeatCounts == 2)?"Current: twice (2)":"twice (2)",
(repeatCounts == 3)?"Current: tripple (3)":"tripple (3)",
(repeatCounts == 4)?"Current: quad (4)":"quad (4)",
(repeatCounts == 5)?"Current: quint (5)":"quint (5)",
(repeatCounts == 10)?"Current: 10":"10",
(repeatCounts == 20)?"Current: 20":"20"};
AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this);
mDialog.setItems(mItems, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
repeatCounts = which + 1;
if (which == 5) repeatCounts = 10;
else if (which == 6) repeatCounts = 20;
if (isVerbose) {
Log.d(TAG, "repeatCounts is set to " + repeatCounts);
}
}
});
mDialog.create().show();
}
});
btn_setTCPDumpInterface.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ArrayList<String> out = new ArrayList<>();
if (!isUsingTCPDump) {
out.add("Current: TCPDump OFF");
} else {
out.add("Disable TCPDump");
}
try {
Process proc = Runtime.getRuntime().exec("ls /sys/class/net");
proc.waitFor();
String line;
BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while ((line = is.readLine()) != null) {
if (isUsingTCPDump && line.equals(tcpdumpInterface)) {
out.add("Current: " + line);
} else {
out.add(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
final CharSequence mTmp[] = out.toArray(new CharSequence[out.size()]);
AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this);
mDialog.setItems(mTmp, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
isUsingTCPDump = false;
if (isVerbose) {
myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("TCPDump is disabled\n");
}
});
Log.d(TAG, "TCPDump is disabled");
}
} else {
tcpdumpInterface = ((String) mTmp[which]).replace("Current: ", "");
isUsingTCPDump = true;
Toast.makeText(MainActivity.this, "TCPDump interface is changed to " + tcpdumpInterface, Toast.LENGTH_SHORT).show();
if (isVerbose) {
Log.d(TAG, "TCPDump interface is set to " + tcpdumpInterface);
}
}
}
});
mDialog.create().show();
}
});
btn_setOthers.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CharSequence[] items = {"Verbose", "Locally", "Log PerProc", "Log WiFiDriver", "Log ThisApp", "Log TCPDump", "Force CPU0"};
boolean[] checkedItems = {isVerbose, isLocal, isLoggingPerProcPID, (wifiDriverPID!=-1), isLoggingAppSelf, isLoggingTCPDump, isForcingCPU0};
AlertDialog.Builder adb = new AlertDialog.Builder(MainActivity.this);
adb.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
switch (which) {
case 0:
isVerbose = isChecked;
Toast.makeText(MainActivity.this, "Set to be " + (isVerbose ? "verbose" : "NOT verbose"), Toast.LENGTH_SHORT).show();
break;
case 1:
isLocal = isChecked;
binary_TX_Normal = isLocal ? "normal_lo" : "normal";
binary_TX_NormalUDP = isLocal ? "normal_udp_lo" : "normal_udp";
binary_TX_Sendfile = isLocal ? "sendfile_lo" : "sendfile";
binary_TX_Splice = isLocal ? "splice_lo" : "splice";
binary_TX_RawNormal = isLocal ? "bypassl3_lo" : "bypassl3";
binary_RX_Normal = isLocal ? "normal_recv_lo" : "normal_recv";
binary_RX_NormalUDP = isLocal ? "normal_udp_recv_lo" : "normal_udp_recv";
binary_RX_Splice = isLocal ? "splice_recv_lo" : "splice_recv";
binary_RX_RawNormal = isLocal ? "bypassl3_recv_lo" : "bypassl3_recv";
if (isLocal) {
isUsingTCPDump = false;
Toast.makeText(MainActivity.this, "Remember to set IP to 192.168.1.15\n" +
"Will start TCPSdr/Rcvr locally\ntcpdump disabled", Toast.LENGTH_LONG).show();
} else {
isUsingTCPDump = true;
tcpdumpInterface = "wlan0";
Toast.makeText(MainActivity.this, "Back to original\ntcpdump enabled to wlan0", Toast.LENGTH_LONG).show();
}
break;
case 2:
isLoggingPerProcPID = isChecked;
Toast.makeText(MainActivity.this, isLoggingPerProcPID?"Will log per process cpu":"Will NOT log per process cpu", Toast.LENGTH_SHORT).show();
break;
case 3:
wifiDriverPID = isChecked?Utilities.getMyPID("dhd_dpc"):-1;
Toast.makeText(MainActivity.this, (wifiDriverPID!=-1)?"Will log wifi driver cpu":"Will NOT log wifi driver cpu", Toast.LENGTH_SHORT).show();
break;
case 4:
isLoggingAppSelf = isChecked;
Toast.makeText(MainActivity.this, isLoggingAppSelf?"Will log app itself cpu":"Will NOT log app itself cpu", Toast.LENGTH_SHORT).show();
break;
case 5:
isLoggingTCPDump = isChecked;
Toast.makeText(MainActivity.this, isLoggingTCPDump?"Will log tcpdump cpu":"Will NOT log tcpdump cpu", Toast.LENGTH_SHORT).show();
break;
case 6:
isForcingCPU0 = isChecked;
Toast.makeText(MainActivity.this, (isForcingCPU0?"Force running on cpu 0":"Will run on any cpu"), Toast.LENGTH_SHORT).show();
break;
}
}
});
adb.create().show();
}
});
btn_clearStatus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myHandler.post(new Runnable() {
@Override
public void run() {
txt_results.setText("");
}
});
}
});
btn_setLogFreq.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final CharSequence[] mItems={
(time_wait_for == 50)?"Current: per 50ms":"per 50ms",
(time_wait_for == 100)?"Current: per 100ms":"per 100ms",
(time_wait_for == 200)?"Current: per 200ms":"per 200ms",
(time_wait_for == 500)?"Current: per 500ms":"per 500ms",
(time_wait_for == 1000)?"Current: per 1s":"per 1s"};
AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this);
mDialog.setItems(mItems, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
time_wait_for = 50;
break;
case 1:
time_wait_for = 100;
break;
case 2:
time_wait_for = 200;
break;
case 3:
time_wait_for = 500;
break;
case 4:
time_wait_for = 1000;
break;
default:
time_wait_for = 100; // default 100ms
}
if (isVerbose) {
myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("time_wait_for is set to " + time_wait_for + "ms\n");
}
});
Log.d(TAG, "time_wait_for is set to " + time_wait_for + "ms");
}
}
});
mDialog.create().show();
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAmbientEnabled();
initialization();
checkBinaryFilesExist();
}
@Override
public void onEnterAmbient(Bundle ambientDetails) {
super.onEnterAmbient(ambientDetails);
updateDisplay();
}
@Override
public void onUpdateAmbient() {
super.onUpdateAmbient();
updateDisplay();
}
@Override
public void onExitAmbient() {
updateDisplay();
super.onExitAmbient();
}
private void updateDisplay() {
if (isAmbient()) {
mContainerView.setBackgroundColor(getResources().getColor(R.color.black));
txt_results.setTextColor(getResources().getColor(R.color.white));
mContainerViewTXRX.setVisibility(View.GONE);
mContainerViewConfig.setVisibility(View.GONE);
// mClockView.setText(AMBIENT_DATE_FORMAT.format(new Date()));
} else {
mContainerView.setBackground(null);
txt_results.setTextColor(getResources().getColor(R.color.indiego));
mContainerViewTXRX.setVisibility(View.VISIBLE);
mContainerViewConfig.setVisibility(View.VISIBLE);
}
}
}

View File

@ -0,0 +1,367 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
/**
* Created by yanzi on 9/17/15.
* two core only right now
*/
public class SSLogger extends Service {
private static final String TAG = "SSLogger";
private boolean isRunning = false;
private boolean isRunningPollingThread = false;
private String ssFileName, cpuFileName,
cpuWiFiDriverPIDFileName, cpuPerProcPIDFileName, cpuTCPDumpFileName, cpuAppSelfFileName;
private int wifiRSS, gsmRSS;
private static int tcpdumpPID = -1, appSelfPID = -1;
private WifiManager wm;
private FileOutputStream os_ss = null, os_cpu = null,
os_cpuWiFiDriverPID = null, os_cpuPerProcPID = null,
os_cpuTCPDump = null, os_cpuAppSelf = null;
public class PollingThread extends Thread {
public void run() {
if (isRunningPollingThread) {
Log.d(TAG, "already running polling thread");
return;
}
isRunningPollingThread = true;
while(isRunning) {
// get current system time
String mTime = Long.toString(System.currentTimeMillis());
String[] raws = new String[5]; // assume 4 cores, [0] is total
// read current cpu usage
readUsage(raws);
String myTmp = mTime + " " + raws[0] + " ";
for (int i = 0; i < MainActivity.coreNum-1; ++i) {
myTmp += raws[i+1] + " " + cpuFrequency(i) + " ";
}
myTmp += raws[MainActivity.coreNum] + " " + cpuFrequency(MainActivity.coreNum-1) + "\n";
// // cpuTotal
// String[] cpuTotal = raws[0].split("\\s+");
// String cpuTotalsum = parseProcStat(cpuTotal);
// // cpu 1 - N (N = coreNum)
// String[] cpu1 = raws[1].split("\\s+");
// String cpu1sum = parseProcStat(cpu1);
// String[] cpu2 = null, cpu3 = null, cpu4 = null;
// String cpu2sum = null, cpu3sum = null, cpu4sum = null;
// // parse lines
// if (MainActivity.coreNum > 1) {
// cpu2 = raws[2].split("\\s+");
// cpu2sum = parseProcStat(cpu2);
// }
// if (MainActivity.coreNum > 2) {
// cpu3 = raws[3].split("\\s+");
// cpu3sum = parseProcStat(cpu3);
// }
// if (MainActivity.coreNum > 3) {
// cpu4 = raws[4].split("\\s+");
// cpu4sum = parseProcStat(cpu4);
// }
byte[] cpuStuff, ssStuff,
cpuWiFiDriverPIDStuff = null, cpuPerPIDStuff = null, cpuTCPDumpStuff = null,
cpuAppSelfStuff = null;
cpuStuff = myTmp.getBytes();
if (MainActivity.wifiDriverPID != -1)
cpuWiFiDriverPIDStuff = (mTime + " " + parseProcPIDStat(readUsagePID(MainActivity.wifiDriverPID)) + "\n").getBytes();
if (MainActivity.isLoggingPerProcPID)
cpuPerPIDStuff = (mTime + " " + parseProcPIDStat(readUsagePID(MainActivity.perProcPID)) + "\n").getBytes();
if (tcpdumpPID != -1)
cpuTCPDumpStuff = (mTime + " " + parseProcPIDStat(readUsagePID(tcpdumpPID)) + "\n").getBytes();
if (MainActivity.isLoggingAppSelf)
cpuAppSelfStuff = (mTime + " " + parseProcPIDStat(readUsagePID(appSelfPID)) + "\n").getBytes();
ssStuff = (mTime + " wifi " + wifiRSS + "\n").getBytes();
try {
if (isRunning) {
os_ss.write(ssStuff);
os_cpu.write(cpuStuff);
if (MainActivity.wifiDriverPID != -1)
os_cpuWiFiDriverPID.write(cpuWiFiDriverPIDStuff);
if (MainActivity.isLoggingPerProcPID)
os_cpuPerProcPID.write(cpuPerPIDStuff);
if (tcpdumpPID != -1)
os_cpuTCPDump.write(cpuTCPDumpStuff);
if (MainActivity.isLoggingAppSelf)
os_cpuAppSelf.write(cpuAppSelfStuff);
}
} catch (IOException unimportant) {
Log.w(TAG, "IO error at SSLogger");
}
try {
Thread.sleep(MainActivity.time_wait_for);
} catch (Exception unimportant) {
Log.w(TAG, "Can't wait..");
}
}
isRunningPollingThread = false;
}
}
/**
* my initialization
*/
public void initialization() {
// run tcpdump
if (MainActivity.isUsingTCPDump) {
try {
Runtime.getRuntime().exec("su -c " + MainActivity.binaryFolderPath
+ "tcpdump -i " + MainActivity.tcpdumpInterface
+ " -w " + MainActivity.outFolderPath + "/tcpdump_wifionly_"
+ MainActivity.btn_click_time + " &"
).waitFor();
if (MainActivity.isVerbose) {
Log.d(TAG, "TCPDump started");
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (MainActivity.isLoggingTCPDump)
tcpdumpPID = Utilities.getMyPID(MainActivity.binary_tcpdump);
}
if (MainActivity.isLoggingAppSelf)
appSelfPID = Utilities.getMyPID("offloading");
if (!Utilities.canWriteOnExternalStorage()) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Can't write sdcard\n");
}
});
onDestroy();
}
// get the initial WiFi signal strength
wm = (WifiManager) this.getSystemService(WIFI_SERVICE);
if (!wm.isWifiEnabled()) {
wm.setWifiEnabled(true);
if (!wm.isWifiEnabled()) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("WiFi remains OFF!\n");
}
});
}
}
wifiRSS = wm.getConnectionInfo().getRssi();
this.registerReceiver(this.myWifiReceiver, new IntentFilter(WifiManager.RSSI_CHANGED_ACTION));
// create folder
File mDir = new File(MainActivity.outFolderPath);
mDir.mkdir();
ssFileName = MainActivity.btn_click_time.concat(".ss");
cpuFileName = MainActivity.btn_click_time.concat(".cpuRaw");
if (MainActivity.wifiDriverPID != -1)
cpuWiFiDriverPIDFileName = MainActivity.btn_click_time.concat(".cpuPID");
if (MainActivity.isLoggingPerProcPID)
cpuPerProcPIDFileName = MainActivity.btn_click_time.concat(".cpuProcPID");
if (tcpdumpPID != -1)
cpuTCPDumpFileName = MainActivity.btn_click_time.concat(".cpuTCPDump");
if (MainActivity.isLoggingAppSelf)
cpuAppSelfFileName = MainActivity.btn_click_time.concat(".cpuAppSelf");
try {
os_ss = new FileOutputStream(new File(mDir, ssFileName));
os_cpu = new FileOutputStream(new File(mDir, cpuFileName));
if (MainActivity.wifiDriverPID != -1)
os_cpuWiFiDriverPID = new FileOutputStream(new File(mDir, cpuWiFiDriverPIDFileName));
if (MainActivity.isLoggingPerProcPID)
os_cpuPerProcPID = new FileOutputStream(new File(mDir, cpuPerProcPIDFileName));
if (tcpdumpPID != -1)
os_cpuTCPDump = new FileOutputStream(new File(mDir, cpuTCPDumpFileName));
if (MainActivity.isLoggingAppSelf)
os_cpuAppSelf = new FileOutputStream(new File(mDir, cpuAppSelfFileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
isRunning = true;
initialization();
// collect signals
PollingThread pt = new PollingThread();
pt.start();
return START_STICKY;
}
@Override
public void onCreate(){
super.onCreate();
// Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy(){
isRunning = false;
this.unregisterReceiver(this.myWifiReceiver);
// kill tcpdump
if (MainActivity.isUsingTCPDump) {
try {
Runtime.getRuntime().exec("su -c killall -9 tcpdump").waitFor();
if (MainActivity.isVerbose)
Log.d(TAG, "TCPDump ended");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (MainActivity.isLoggingTCPDump)
tcpdumpPID = -1;
}
try {
if (os_ss != null)
os_ss.close();
if (os_cpu != null)
os_cpu.close();
if (os_cpuWiFiDriverPID != null)
os_cpuWiFiDriverPID.close();
if (os_cpuPerProcPID != null)
os_cpuPerProcPID.close();
if (os_cpuTCPDump != null)
os_cpuTCPDump.close();
if (os_cpuAppSelf != null)
os_cpuAppSelf.close();
} catch (IOException e) {
e.printStackTrace();
}
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private BroadcastReceiver myWifiReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent arg1){
wifiRSS = arg1.getIntExtra(WifiManager.EXTRA_NEW_RSSI, 0);
if (MainActivity.isVerbose) {
Log.d(TAG, "WiFi RSSI: " + wifiRSS);
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("wifiRSS: " + wifiRSS + "\n");
}
});
}
}
};
/**
* parse one string line of proc (faster)
* @param toks each part
* @return string that's been aggregated
*/
private static String parseProcStat(String[] toks) {
// the columns are:
// 0 "cpu": the string "cpu" that identifies the line
// 1 user: normal processes executing in user mode
// 2 nice: niced processes executing in user mode
// 3 system: processes executing in kernel mode
// 4 idle: twiddling thumbs
// 5 iowait: waiting for I/O to complete
// 6 irq: servicing interrupts
// 7 softirq: servicing softirqs
long idle = Long.parseLong(toks[4]);
long cpu = Long.parseLong(toks[1]) + Long.parseLong(toks[2]) + Long.parseLong(toks[3])
+ Long.parseLong(toks[5]) + Long.parseLong(toks[6]) + Long.parseLong(toks[7]);
return idle + " " + cpu;
}
/**
* parse one string line of procpid
* @param line the line
* @return string that's been parsed
*/
private static String parseProcPIDStat(String line) {
if (line == null) return "-1 -1 -1"; // -1 means it does not exist
String[] toks = line.split("\\s+");
long idle = Long.parseLong(toks[15]) + Long.parseLong(toks[16]);
long cpu = Long.parseLong(toks[13]) + Long.parseLong(toks[14]);
long whichcpu = Long.parseLong(toks[38]);
return idle + " " + cpu + " " + whichcpu;
}
/**
* read the cpu usage (faster)
* @param raws String[]
*/
private static void readUsage(String[] raws) {
try {
RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
String load = reader.readLine();
raws[0] = load;
load = reader.readLine();
raws[1] = load;
if (MainActivity.coreNum > 1) {
load = reader.readLine();
raws[2] = load;
}
if (MainActivity.coreNum > 2) {
load = reader.readLine();
raws[3] = load;
}
if (MainActivity.coreNum > 3) {
load = reader.readLine();
raws[4] = load;
}
reader.close();
} catch (IOException unimportant) {
Log.w(TAG, "exception on readUsage (faster)");
}
}
private static String readUsagePID(int currentPID) {
if (currentPID == -1) return null;
// changed by Yanzi
try {
RandomAccessFile reader = new RandomAccessFile("/proc/" + currentPID +"/stat", "r");
String load = reader.readLine();
reader.close();
return load;
} catch (IOException unimportant) {
Log.w(TAG, "exception on readUsagePID on pid: " + currentPID);
}
return null;
}
/**
* get the frequency of the cpu
* @param cpuid which cpu
* @return long
*/
private static long cpuFrequency(int cpuid) {
try {
String pathFile = "/sys/devices/system/cpu/cpu" + cpuid + "/cpufreq/scaling_cur_freq";
RandomAccessFile reader = new RandomAccessFile(pathFile, "r");
String load = reader.readLine();
String[] toks = load.split("\\s+");
long cpuScaling = Long.parseLong(toks[0]);
reader.close();
return cpuScaling;
} catch (FileNotFoundException unimportant) {
// Log.w(TAG, "exception on cpuFreq");
return -1;
} catch (IOException unimportant) {
// Log.w(TAG, "exception on cpuFreq");
return -1;
}
}
}

View File

@ -0,0 +1,71 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_RX_CNormal implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_RX_Normal)
return;
if (MainActivity.isVerbose)
Log.d("RX_Normal", "Start RX Normal");
MainActivity.isRunning_RX_Normal = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_RX_Normal + " "
+ MainActivity.bytes2send + " " + MainActivity.RXportNum;
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_RX_Normal);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in RX_Normal at port " + MainActivity.RXportNum + "\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
Log.d("Thread_RX_CNormal", mOut + "ms");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("RX_Normal", "Stop RX Normal");
MainActivity.isRunning_RX_Normal = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,74 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_RX_CNormalUDP implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_RX_NormalUDP)
return;
if (MainActivity.isVerbose)
Log.d("RX_NormalUDP", "Start RX NormalUDP");
MainActivity.isRunning_RX_NormalUDP = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_RX_NormalUDP + " "
+ MainActivity.bytes2send + " 32000";
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_RX_NormalUDP);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in RX_NormalUDP at port 32000\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (out.length() > 0) {
MainActivity.UDPfinishTime = (int)Float.parseFloat(out.toString().trim());
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
Log.d("Thread_RX_CNormalUDP", mOut + "ms");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("RX_NormalUDP", "Stop RX NormalUDP");
MainActivity.isRunning_RX_NormalUDP = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,74 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_RX_CRawNormal implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_RX_RawNormal)
return;
if (MainActivity.isVerbose)
Log.d("RX_RawNormal", "Start RX RawNormal");
MainActivity.isRunning_RX_RawNormal = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_RX_RawNormal + " "
+ MainActivity.bytes2send;
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_RX_RawNormal);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in RX_RawNormal at port " + MainActivity.RXportNum + "\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (out.length() > 0) {
MainActivity.UDPfinishTime = (int)Float.parseFloat(out.toString().trim());
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
Log.d("Thread_RX_CRawNormal", mOut + "ms");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("RX_RawNormal", "Stop RX RawNormal");
MainActivity.isRunning_RX_RawNormal = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,71 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_RX_CSendfile implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_RX_Sendfile)
return;
if (MainActivity.isVerbose)
Log.d("RX_Sendfile", "Start RX Sendfile");
MainActivity.isRunning_RX_Sendfile = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_RX_Sendfile + " "
+ MainActivity.bytes2send + " " + MainActivity.RXportNum;
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_RX_Sendfile);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in RX_Sendfile at port " + MainActivity.RXportNum + "\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
Log.d("Thread_RX_CSendfile", mOut + "ms");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("RX_Sendfile", "Stop RX Sendfile");
MainActivity.isRunning_RX_Sendfile = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,71 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_RX_CSplice implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_RX_Splice)
return;
if (MainActivity.isVerbose)
Log.d("RX_Splicee", "Start RX Splice");
MainActivity.isRunning_RX_Splice = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_RX_Splice + " "
+ MainActivity.bytes2send + " " + MainActivity.RXportNum;
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_RX_Splice);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in RX_Splice at port " + MainActivity.RXportNum + "\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
Log.d("Thread_RX_CSplice", mOut + "ms");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("RX_Splice", "Stop RX Splice");
MainActivity.isRunning_RX_Splice = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,70 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_TX_CNormal implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_Normal)
return;
if (MainActivity.isVerbose)
Log.d("TX_Normal", "Start TX Normal");
MainActivity.isRunning_TX_Normal = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_Normal + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_Normal);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_Normal\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_Normal", "Stop TX Normal");
MainActivity.isRunning_TX_Normal = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,70 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_TX_CNormalUDP implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_NormalUDP)
return;
if (MainActivity.isVerbose)
Log.d("TX_NormalUDP", "Start TX Normal UDP");
MainActivity.isRunning_TX_NormalUDP = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_NormalUDP + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_NormalUDP);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_NormalUDP\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_NormalUDP", "Stop TX Normal UDP");
MainActivity.isRunning_TX_NormalUDP = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,70 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/19/15.
*/
public class Thread_TX_CRawNormal implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_RawNormal)
return;
if (MainActivity.isVerbose)
Log.d("TX_RawNormal", "Start TX RawNormal");
MainActivity.isRunning_TX_RawNormal = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_RawNormal + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_RawNormal);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_RawNormal\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_RawNormal", "Stop TX RawNormal");
MainActivity.isRunning_TX_RawNormal = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,70 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_TX_CRawSplice implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_RawSplice)
return;
if (MainActivity.isVerbose)
Log.d("TX_RawSplice", "Start TX RawSplice");
MainActivity.isRunning_TX_RawSplice = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_RawSplice + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_RawSplice);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_RawSplice\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_RawSplice", "Stop TX RawSplice");
MainActivity.isRunning_TX_RawSplice = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,70 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/19/15.
*/
public class Thread_TX_CSendfile implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_Sendfile)
return;
if (MainActivity.isVerbose)
Log.d("TX_Sendfile", "Start TX Sendfile");
MainActivity.isRunning_TX_Sendfile = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_Sendfile + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_Sendfile);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_Sendfile\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_Sendfile", "Stop TX Sendfile");
MainActivity.isRunning_TX_Sendfile = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,71 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by yanzi on 9/18/15.
*/
public class Thread_TX_CSplice implements Runnable {
@Override
public void run() {
if (MainActivity.isRunning_TX_Splice)
return;
if (MainActivity.isVerbose)
Log.d("TX_Splice", "Start TX Splice");
MainActivity.isRunning_TX_Splice = true;
Process proc;
String[] commd = new String[3];
commd[0] = "su";
commd[1] = "-c";
commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"")
+ MainActivity.binaryFolderPath + MainActivity.binary_TX_Splice + " "
+ MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth);
try {
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
boolean gotit = false;
StringBuilder out = new StringBuilder();
while(true){
if (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1)
MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_Splice);
read = stdout.read(buffer);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Failed in TX_Splice\n");
}
});
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (MainActivity.isVerbose) {
final String mOut = out.toString().trim();
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Time: " + mOut + "ms\n");
}
});
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (MainActivity.isVerbose)
Log.d("TX_Splice", "Stop TX Splice");
MainActivity.isRunning_TX_Splice = false;
MainActivity.perProcPID = -1;
}
}

View File

@ -0,0 +1,255 @@
package edu.ucsb.cs.sandlab.offloadingdemo;
import android.os.Environment;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
/**
* Created by yanzi on 10/1/15.
*/
public class Utilities {
private static final String TAG = "Utilities";
/**
* check if we can write on external storage
* @return true/false
*/
public static boolean canWriteOnExternalStorage() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/**
* get the number of cores of device
* @return int > 0
*/
protected static int getNumCores() {
Process proc;
try {
proc = Runtime.getRuntime().exec("grep -c processor /proc/cpuinfo");
InputStream stdout = proc.getInputStream();
byte[] buff = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buff);
if(read<0){
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.setText("Failed to get cores\n");
}
});
return 1;
}
out.append(new String(buff, 0, read));
if(read<20){
break;
}
}
proc.waitFor();
stdout.close();
//Return the number of cores (virtual CPU devices)
return Integer.parseInt(out.toString().trim());
} catch(Exception e) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.setText("Failed to get cores\n");
}
});
//Default to return 1 core
return 1;
}
}
/**
* get pid of the binary process
* @param inName the name of process
* @return true/false - succeed or not
*/
protected static int getMyPID(String inName) {
String commd = "su -c busybox ps | grep " + inName + " | grep -v grep | head -1 | awk '{print $1}'";
try {
Process proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
String line;
StringBuilder out = new StringBuilder();
BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while ((line = is.readLine()) != null) {
out.append(line).append("\n");
}
String tmp = out.toString().trim();
if (!tmp.equals("")) {
return Integer.parseInt(tmp);
}
} catch (InterruptedException unimportant) {
Log.d(TAG, "InterruptedException but unimportant");
} catch (IOException e) {
Log.d(TAG, "IOException but unimportant");
}
return -1;
}
/**
* check if a file exists
* @param myFile
* @return true/false
*/
protected static boolean fileExist(String myFile) {
File file = new File(myFile);
if (file.exists() && file.isFile())
return true;
return false;
}
/**
* parse CPU for a folder
* @param folderName
* @return true/false
*/
protected static boolean parseCPUforFolder(String folderName) {
try {
Process proc = Runtime.getRuntime().exec("su && cd " + MainActivity.outFolderPath + "/" + folderName
+ " && ls *.cpuRaw");
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
Log.d(TAG, "Failed in parseCPUforFolder: ls nothing");
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (!out.toString().equals("")) {
String[] cpuFiles = out.toString().split("\\n");
for (int i = 0; i < cpuFiles.length; ++i) {
try {
BufferedReader br = new BufferedReader(
new FileReader(MainActivity.outFolderPath + "/" + folderName + "/" + cpuFiles[i]));
FileOutputStream os_cpu = new FileOutputStream(
new File(MainActivity.outFolderPath + "/" + folderName, cpuFiles[i].replace("cpuRaw", "cpu")));
String line;
while ((line = br.readLine()) != null) {
String[] toks = line.split("\\s+");
// format for Ana's script:
// time
// cpuTotal idle
// cpuTotal used
// cpu0 idle
// cpu0 used
// cpu0 freq
// cpu1 freq
// cpuTotal normal process user mode
// cpuTotal niced process in user mode
// cpuTotal kernal mode
// cpuTotal IO
// cpuTotal hardware interrupts
// cpuTotal software interrupts
// cpu0 normal process user mode
// cpu0 niced process in user mode
// cpu0 kernal mode
// cpu0 IO
// cpu0 hardware interrupts
// cpu0 software interrupts
os_cpu.write((toks[0] + " " // time
// cpuTotal toks[1-11]
+ toks[5] + " " // cpuTotal idle
// cpuTotal used
+ (Long.parseLong(toks[2]) + Long.parseLong(toks[3])
+ Long.parseLong(toks[4]) + Long.parseLong(toks[6])
+ Long.parseLong(toks[7]) + Long.parseLong(toks[8])) + " "
// cpu 0 toks[12-22]
+ toks[16] + " " // cpu0 idle
// cpu0 used
+ (Long.parseLong(toks[13]) + Long.parseLong(toks[14])
+ Long.parseLong(toks[15]) + Long.parseLong(toks[17])
+ Long.parseLong(toks[18]) + Long.parseLong(toks[19])) + " "
// cpu 0 freq toks[23]
+ toks[23] + " "
// cpu 1 freq toks[35]
+ toks[35] + " "
// cpuTotal details
+ toks[2] + " " + toks[3] + " " + toks[4] + " "
+ toks[6] + " " + toks[7] + " " + toks[8] + " "
// cpu0 details
+ toks[13] + " " + toks[14] + " " + toks[15] + " "
+ toks[17] + " " + toks[18] + " " + toks[19]).getBytes());
// cpu 1 toks[24-34]
os_cpu.write("\n".getBytes());
os_cpu.flush();
}
os_cpu.close();
} catch (IOException unimportant) {
return false;
}
}
}
} catch (IOException e) {
// e.printStackTrace();
return false;
} catch (InterruptedException e) {
// e.printStackTrace();
return false;
}
return true;
}
protected static int findCorrespondingThrpt(int myI) {
if (myI == 0) {
return 50000;
} else if (myI == 1) {
return 100000;
} else if (myI < 6) {
return 250000 * (myI - 1);
} else if (myI < 24) {
return 1500000 + 500000 * (myI - 6);
} else if (myI > 24) {
return 15000000 + 5000000 * (myI - 25);
} else { // default unlimited
if (MainActivity.isLocal)
return 100000000;
else
return 20000000;
}
}
protected static void estimateTime(int numRepeats, int numSelectedItems, int totalBytes, ArrayList<Integer> selectedItemsThrpt) {
int time = 0;
if (MainActivity.isLocal) {
for (int k = 0; k < selectedItemsThrpt.size(); ++k)
time += (Math.max(totalBytes / findCorrespondingThrpt(selectedItemsThrpt.get(k)) + 20, 20));
} else {
for (int k = 0; k < selectedItemsThrpt.size(); ++k)
time += (Math.max(totalBytes / findCorrespondingThrpt(selectedItemsThrpt.get(k)) + 20, 60));
}
time = (time + 15) * numSelectedItems * numRepeats * 1000;
final String estimatedTime = new SimpleDateFormat("MM/dd HH:mm:ss").format(new Date(System.currentTimeMillis() + time));
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Estimated ending @ " + estimatedTime + "\n");
}
});
}
}

View File

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/container"
tools:context=".MainActivity"
tools:deviceIds="wear">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/container_txrx"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="2">
<Button
android:theme="@style/theme_btn_tx"
android:id="@+id/btn_startTransmit"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/btn_begintx"
android:textStyle="bold"
android:textSize="20dp"
android:textColor="#FFFFFF"/>
<Button
android:theme="@style/theme_btn_rx"
android:id="@+id/btn_startReceive"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/btn_beginrx"
android:textStyle="bold"
android:textSize="20dp"
android:textColor="#FFFFFF"/>
</LinearLayout>
<HorizontalScrollView
android:id="@+id/container_config"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="@string/txt_configs"
android:textStyle="bold"
android:layout_gravity="center"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_setByte2send"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/btn_setbytes"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_setRepeatTimes"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/btn_setrepeat"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_setTCPDumpInterface"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/btn_setuptcpdump"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_setLogFreq"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Set\nLog Freq"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_setOthers"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/btn_setothers"
android:textSize="16dp"/>
<Button
android:id="@+id/btn_clearStatus"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/btn_clear"
android:textSize="16dp"/>
</LinearLayout>
</HorizontalScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/txt_results"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text=""
android:gravity="center"
android:textStyle="bold"
android:textSize="20dp"
android:textColor="@color/indiego"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
<!--<TextView-->
<!--android:id="@+id/text"-->
<!--app:layout_box="all"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:text="@string/hello_world"/>-->
<!--<TextView-->
<!--android:id="@+id/clock"-->
<!--app:layout_box="all"-->
<!--android:layout_gravity="bottom|start"-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:textColor="@android:color/white"/>-->
</android.support.wearable.view.BoxInsetLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -0,0 +1,14 @@
<resources>
<string name="app_name">Offloading Demo</string>
<string name="txt_configs">Configs →</string>
<string name="btn_setbytes">Bytes</string>
<string name="btn_setrepeat">Repeats</string>
<string name="btn_setuptcpdump">TCPDump</string>
<string name="btn_setothers">Misc.</string>
<string name="btn_clear">Clear</string>
<string name="btn_beginrx">RX Go!</string>
<string name="btn_begintx">TX Go!</string>
<string name="warn_root">Not rooted!! Must be rooted!</string>
<string name="stat_wifion">WiFi is ON!\n</string>
<string name="stat_wifioff">WiFi is NOT On!\n</string>
</resources>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="indiego">#3F51B5</color>
<color name="pink">#FF4081</color>
<style name="theme_btn_tx" parent="android:Theme.Material">
<item name="android:colorButtonNormal">@color/indiego</item>
</style>
<style name="theme_btn_rx" parent="android:Theme.Material">
<item name="android:colorButtonNormal">@color/pink</item>
</style>
</resources>

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":wear" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="OffloadingDemo" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":wear" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<afterSyncTasks>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/debug" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/22.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.2.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-base/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-wearable/7.8.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.support/wearable/1.3.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/mockable-android-23.jar" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/tmp" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="play-services-wearable-7.8.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-22.2.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.2.0" level="project" />
<orderEntry type="library" exported="" name="play-services-base-7.8.0" level="project" />
<orderEntry type="library" exported="" name="wearable-1.3.0" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-22.0.0" level="project" />
</component>
</module>