-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Use System.currentTimeMillis() instead of Instant * Added android app which can run samples * Updated to v0.5.4 of CRT, added android docs
- Loading branch information
Justin Boswell
authored
Apr 22, 2020
1 parent
1509462
commit e124a1d
Showing
39 changed files
with
973 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
*.iml | ||
.gradle | ||
/local.properties | ||
/.idea/caches | ||
/.idea/libraries | ||
/.idea/modules.xml | ||
/.idea/workspace.xml | ||
/.idea/navEditor.xml | ||
/.idea/assetWizardSettings.xml | ||
.DS_Store | ||
/build | ||
/captures | ||
.externalNativeBuild | ||
.cxx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
apply plugin: 'com.android.application' | ||
apply plugin: 'kotlin-android' | ||
apply plugin: 'kotlin-android-extensions' | ||
|
||
android { | ||
compileSdkVersion 29 | ||
buildToolsVersion "29.0.3" | ||
|
||
defaultConfig { | ||
applicationId "software.amazon.awssdk.iotsamples" | ||
minSdkVersion 26 | ||
targetSdkVersion 29 | ||
ndkVersion "21.0.6113669" | ||
versionCode 1 | ||
versionName "1.0" | ||
|
||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
} | ||
|
||
sourceSets { | ||
main { | ||
java.srcDir '../../sdk/src/main/java' | ||
java.srcDir '../../samples/BasicPubSub/src/main/java' | ||
java.srcDir '../../samples/Jobs/src/main/java' | ||
java.srcDir '../../samples/PubSubStress/src/main/java' | ||
java.srcDir '../../samples/Shadow/src/main/java' | ||
java.srcDir 'src/main/java' | ||
} | ||
} | ||
|
||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
} | ||
} | ||
compileOptions { | ||
sourceCompatibility = 1.8 | ||
targetCompatibility = 1.8 | ||
} | ||
|
||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
maven { | ||
url System.getenv('HOME') + "/.m2/repository" | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation fileTree(dir: 'libs', include: ['*.jar']) | ||
implementation 'software.amazon.awssdk.crt:android:0.5.4' | ||
implementation 'com.google.code.gson:gson:2.8.5' | ||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" | ||
implementation 'androidx.appcompat:appcompat:1.1.0' | ||
implementation 'androidx.core:core:1.2.0' | ||
implementation 'androidx.core:core-ktx:1.2.0' | ||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' | ||
testImplementation 'junit:junit:4.13' | ||
androidTestImplementation 'androidx.test.ext:junit:1.1.1' | ||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Add project specific ProGuard rules here. | ||
# You can control the set of applied configuration files using the | ||
# proguardFiles setting in build.gradle. | ||
# | ||
# For more details, see | ||
# http://developer.android.com/guide/developing/tools/proguard.html | ||
|
||
# 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 *; | ||
#} | ||
|
||
# Uncomment this to preserve the line number information for | ||
# debugging stack traces. | ||
#-keepattributes SourceFile,LineNumberTable | ||
|
||
# If you keep the line number information, uncomment this to | ||
# hide the original source file name. | ||
#-renamesourcefileattribute SourceFile |
24 changes: 24 additions & 0 deletions
24
...oid/app/src/androidTest/java/software/amazon/awssdk/iotsamples/ExampleInstrumentedTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package software.amazon.awssdk.iotsamples | ||
|
||
import androidx.test.platform.app.InstrumentationRegistry | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
|
||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
import org.junit.Assert.* | ||
|
||
/** | ||
* Instrumented test, which will execute on an Android device. | ||
* | ||
* See [testing documentation](http://d.android.com/tools/testing). | ||
*/ | ||
@RunWith(AndroidJUnit4::class) | ||
class ExampleInstrumentedTest { | ||
@Test | ||
fun useAppContext() { | ||
// Context of the app under test. | ||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext | ||
assertEquals("software.amazon.awssdk.iotsamples", appContext.packageName) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="software.amazon.awssdk.iotsamples"> | ||
|
||
<application | ||
android:allowBackup="true" | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:roundIcon="@mipmap/ic_launcher_round" | ||
android:supportsRtl="true" | ||
android:theme="@style/AppTheme"> | ||
<activity android:name=".MainActivity"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
|
||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
</application> | ||
|
||
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.txt | ||
*.pem |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Files required to run samples: | ||
ca-certificates.crt - Taken from any recent Linux /etc/ssl | ||
certificate.pem - IoT Thing Certificate | ||
privatekey.pem - IoT Thing Private Key | ||
endpoint.txt - IoT ATS Endpoint | ||
AmazonRootCA1.pem - Available from https://www.amazontrust.com/repository/AmazonRootCA1.pem | ||
|
||
Optional: | ||
clientId.txt - specifies --clientId CLI argument | ||
topic.txt - specifies --topic CLI argument | ||
message.txt - specifies --message CLI argument | ||
port.txt - specifies --port CLI argument | ||
thingName.txt - specifies --thingName CLI argument |
172 changes: 172 additions & 0 deletions
172
android/app/src/main/java/software/amazon/awssdk/iotsamples/MainActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
package software.amazon.awssdk.iotsamples | ||
|
||
import androidx.appcompat.app.AppCompatActivity | ||
import android.os.Bundle | ||
import android.view.View | ||
import android.widget.AdapterView | ||
import android.widget.ArrayAdapter | ||
import android.widget.Spinner | ||
import android.widget.TextView | ||
import java.io.FileNotFoundException | ||
import java.io.FileOutputStream | ||
import java.io.OutputStream | ||
import java.io.PrintStream | ||
import java.lang.Exception | ||
import kotlin.concurrent.thread | ||
|
||
val SAMPLES = mapOf( | ||
"Publish/Subscribe Sample" to "pubsub.PubSub", | ||
"Jobs Client Sample" to "jobs.JobsSample", | ||
"Shadow Client Sample" to "shadow.ShadowSample", | ||
"Publish/Subscribe Load Test" to "pubsubstress.PubSubStress" | ||
) | ||
|
||
class MainActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener { | ||
|
||
private class StreamTee(val source: OutputStream, val log: (message: String) -> Unit) | ||
: PrintStream(source, true) { | ||
init { | ||
if (source == System.out) { | ||
System.setOut(this) | ||
} else if (source == System.err) { | ||
System.setErr(this) | ||
} | ||
} | ||
|
||
override fun write(buf: ByteArray, off: Int, len: Int) { | ||
source.write(buf, off, len) | ||
log(String(buf.slice(IntRange(off, off+len-1)).toByteArray())) | ||
} | ||
|
||
override fun write(b: ByteArray) { | ||
source.write(b) | ||
log(String(b)) | ||
} | ||
} | ||
|
||
private val stdout : StreamTee; | ||
private val stderr : StreamTee; | ||
|
||
private var console: TextView? = null; | ||
private var sampleSelect: Spinner? = null; | ||
|
||
init { | ||
stdout = StreamTee(System.out) { writeToConsole(it) } | ||
stderr = StreamTee(System.err) { writeToConsole(it) } | ||
} | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContentView(R.layout.activity_main) | ||
|
||
console = findViewById<TextView>(R.id.console) | ||
console?.isEnabled = false | ||
|
||
sampleSelect = findViewById<Spinner>(R.id.sampleSelect); | ||
|
||
val samples = SAMPLES.keys.toMutableList() | ||
samples.add(0, "Please select a sample") | ||
val samplesAdapter = ArrayAdapter<String>(this, R.layout.support_simple_spinner_dropdown_item, samples) | ||
sampleSelect?.adapter = samplesAdapter | ||
|
||
sampleSelect?.onItemSelectedListener = this | ||
} | ||
|
||
private fun clearConsole() { | ||
runOnUiThread() { | ||
console?.text = "" | ||
} | ||
} | ||
|
||
private fun writeToConsole(message: String) { | ||
runOnUiThread() { | ||
console?.append(message) | ||
} | ||
} | ||
|
||
private fun onSampleComplete() { | ||
runOnUiThread() { | ||
sampleSelect?.isEnabled = true | ||
} | ||
} | ||
|
||
private fun assetContents(assetName: String) : String { | ||
resources.assets.open(assetName).use {res -> | ||
val bytes = ByteArray(res.available()) | ||
res.read(bytes) | ||
return String(bytes).trim() | ||
} | ||
} | ||
|
||
private fun assetContentsOr(assetName: String, defaultValue: String) : String { | ||
return try { | ||
assetContents(assetName) | ||
} catch (fnf: FileNotFoundException) { | ||
defaultValue | ||
} | ||
} | ||
|
||
private fun runSample(name: String) { | ||
val classLoader = Thread.currentThread().contextClassLoader | ||
val sampleClass = classLoader.loadClass(name); | ||
if (sampleClass == null) { | ||
clearConsole() | ||
writeToConsole("Could not find sample '${name}'") | ||
} | ||
|
||
thread(name="sample_runner", contextClassLoader = classLoader) { | ||
// find resources, copy them into the cache so samples can get paths to them | ||
val resourceNames = listOf("AmazonRootCA1.pem", "certificate.pem", "privatekey.pem") | ||
val resourceMap = HashMap<String, String>() | ||
for (resourceName in resourceNames) { | ||
resources.assets.open(resourceName).use { res -> | ||
val cachedName = "${externalCacheDir}/${resourceName}" | ||
FileOutputStream(cachedName).use { cachedRes -> | ||
res.copyTo(cachedRes) | ||
} | ||
|
||
resourceMap[resourceName] = cachedName | ||
} | ||
} | ||
|
||
val args = mutableListOf( | ||
"--endpoint", assetContents("endpoint.txt"), | ||
"--rootca", resourceMap["AmazonRootCA1.pem"], | ||
"--cert", resourceMap["certificate.pem"], | ||
"--key", resourceMap["privatekey.pem"], | ||
"--port", assetContentsOr("port.txt", "8883"), | ||
"--clientId", assetContentsOr("clientId.txt", "android-java-crt-test") | ||
) | ||
if (name == "pubsub.PubSub") { | ||
args.addAll(arrayOf( | ||
"--topic", assetContentsOr("topic.txt", "/samples/test"), | ||
"--message", assetContentsOr("message.txt", "Hello World From Android"))) | ||
} else if (name in arrayOf("jobs.JobsSample", "shadow.ShadowSample")) { | ||
args.addAll(arrayOf( | ||
"--thingName", assetContentsOr("thingName.txt", "aws-iot-unit-test") | ||
)) | ||
} | ||
val main = sampleClass.getMethod("main", Array<String>::class.java) | ||
try { | ||
main.invoke(null, args.toTypedArray()) | ||
} catch (e: Exception) { | ||
writeToConsole(e.toString()) | ||
} | ||
onSampleComplete(); | ||
} | ||
} | ||
|
||
override fun onNothingSelected(p0: AdapterView<*>?) { | ||
clearConsole() | ||
writeToConsole("Please select a sample above") | ||
} | ||
|
||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, pos: Int, id: Long) { | ||
clearConsole() | ||
val sampleName = parent?.getItemAtPosition(pos).toString() | ||
val sampleClassName = SAMPLES[sampleName] | ||
if (sampleClassName != null) { | ||
return runSample(sampleClassName) | ||
} | ||
} | ||
} |
Oops, something went wrong.