aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorAng Li <angli@google.com>2018-01-12 11:54:03 -0800
committerGitHub <noreply@github.com>2018-01-12 11:54:03 -0800
commitc2d947efa173968571cbcc11376159647a9ff356 (patch)
treec8e06f22c7dffb5ffed4f7824120fb0dff8a5354 /examples
parent4d02684ade1a312b39591a94a92328dc0b65b883 (diff)
downloadmobly-snippet-lib-c2d947efa173968571cbcc11376159647a9ff356.tar.gz
Support custom converters of non-primitive types. (#86)
Now users can supply custom logic for object serialization/de-serialization through a centralized class, and snippet lib will automatically use the custom converters. Added a new example to demonstrate this feature.
Diffstat (limited to 'examples')
-rw-r--r--examples/ex1_standalone_app/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet.java30
-rw-r--r--examples/ex1_standalone_app/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet2.java47
-rw-r--r--examples/ex6_complex_type_conversion/README.md108
-rw-r--r--examples/ex6_complex_type_conversion/build.gradle27
-rw-r--r--examples/ex6_complex_type_conversion/src/main/AndroidManifest.xml23
-rw-r--r--examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/CustomType.java21
-rw-r--r--examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/ExampleObjectConverter.java36
-rw-r--r--examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet.java57
8 files changed, 349 insertions, 0 deletions
diff --git a/examples/ex1_standalone_app/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet.java b/examples/ex1_standalone_app/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet.java
new file mode 100644
index 0000000..6f5af65
--- /dev/null
+++ b/examples/ex1_standalone_app/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.android.mobly.snippet.example6;
+
+import com.google.android.mobly.snippet.Snippet;
+import com.google.android.mobly.snippet.rpc.Rpc;
+
+public class ExampleSnippet implements Snippet {
+ @Rpc(description = "Returns the given integer with the prefix \"foo\"")
+ public String getFoo(Integer input) {
+ return "foo " + input;
+ }
+
+ @Override
+ public void shutdown() {}
+}
diff --git a/examples/ex1_standalone_app/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet2.java b/examples/ex1_standalone_app/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet2.java
new file mode 100644
index 0000000..10a259e
--- /dev/null
+++ b/examples/ex1_standalone_app/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet2.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.android.mobly.snippet.example6;
+
+import com.google.android.mobly.snippet.Snippet;
+import com.google.android.mobly.snippet.rpc.Rpc;
+
+import com.google.android.mobly.snippet.rpc.RunOnUiThread;
+import java.io.IOException;
+
+public class ExampleSnippet2 implements Snippet {
+ @Rpc(description = "Returns the given string with the prefix \"bar\"")
+ public String getBar(String input) {
+ return "bar " + input;
+ }
+
+ @Rpc(description = "Throws an exception")
+ public String throwSomething() throws IOException {
+ throw new IOException("Example exception from throwSomething()");
+ }
+
+ @Rpc(description = "Throws an exception from the main thread")
+ // @RunOnUiThread makes this method execute on the main thread, but only has effect when
+ // invoked as an RPC. It does not affect how this method executes if invoked directly in Java.
+ // This annotation can also be applied to the constructor and the shutdown() method.
+ @RunOnUiThread
+ public String throwSomethingFromMainThread() throws IOException {
+ throw new IOException("Example exception from throwSomethingFromMainThread()");
+ }
+
+ @Override
+ public void shutdown() {}
+}
diff --git a/examples/ex6_complex_type_conversion/README.md b/examples/ex6_complex_type_conversion/README.md
new file mode 100644
index 0000000..70d0289
--- /dev/null
+++ b/examples/ex6_complex_type_conversion/README.md
@@ -0,0 +1,108 @@
+# Complex Type Conversion in Snippet Example
+
+This tutorial shows you how to use a custom object in Snippet Lib.
+
+This example assumes basic familiarity with Snippet Lib as demonstrated in
+[Example 1](../ex1_standalone_app/README.md).
+
+## Tutorial
+
+1. Use Android Studio to create a new app project, similar to
+ [Example 1](../ex1_standalone_app/README.md).
+
+1. Create a complex type in Java:
+ ```java
+ public class CustomType {
+ private String myValue;
+ CustomType(String value) {
+ myValue = value;
+ }
+
+ String getMyValue() {
+ return myValue;
+ }
+ public void setMyValue(String newValue) {
+ myValue = newValue;
+ }
+ }
+ ```
+1. Create a Java class implementing `SnippetObjectConverter`, which defines how the complex type
+ should be converted against `JSONObject`:
+ ```java
+ public class ExampleObjectConverter implements SnippetObjectConverter {
+ @Override
+ public JSONObject serialize(Object object) throws JSONException {
+ JSONObject result = new JSONObject();
+ if (object instanceof CustomType) {
+ CustomType input = (CustomType) object;
+ result.put("Value", input.getMyValue());
+ return result;
+ }
+ return null;
+ }
+
+ @Override
+ public Object deserialize(JSONObject jsonObject, Type type) throws JSONException {
+ if (type == CustomType.class) {
+ return new CustomType(jsonObject.getString("Value"));
+ }
+ return null;
+ }
+ }
+ ```
+1. Write a Java class implementing `Snippet` and add Rpc methods that takes your complex type as
+ a parameter and another Rpc method that returns the complext type directly.
+
+ ```java
+ package com.my.app;
+ ...
+ public class ExampleSnippet implements Snippet {
+ @Rpc(description = "Pass a complex type as a snippet parameter.")
+ public String passComplexTypeToSnippet(CustomType input) {
+ Log.i("Old value is: " + input.getMyValue());
+ return "The value in CustomType is: " + input.getMyValue();
+ }
+
+ @Rpc(description = "Returns a complex type from snippet.")
+ public CustomType returnComplexTypeFromSnippet(String value) {
+ return new CustomType(value);
+ }
+ @Override
+ public void shutdown() {}
+ }
+ ```
+
+1. In `AndroidManifest.xml`, specify the converter class as a `meta-data` named
+ `mobly-object-converter`
+
+ ```xml
+ <manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.my.app">
+ <application>
+ <meta-data
+ android:name="mobly-object-converter"
+ android:value="com.my.app.ExampleObjectConverter" />
+ ...
+ ```
+
+## Running the example code
+
+This folder contains a fully working example of a standalone snippet apk.
+
+1. Compile the example
+
+ ./gradlew examples:ex6_complex_type_conversion:assembleDebug
+
+1. Install the apk on your phone
+
+ adb install -r ./examples/ex6_complex_type_conversion/build/outputs/apk/ex6_complex_type_conversion-debug.apk
+
+1. Use Mobly's `snippet_shell` from mobly to trigger the Rpc methods:
+
+ snippet_shell.py com.google.android.mobly.snippet.example6
+
+ >>> s.passComplexTypeToSnippet({'Value': 'Hello'})
+ 'The value in CustomType is: Hello'
+ >>> s.returnComplexTypeFromSnippet('Bye')
+ {'Value': 'Bye'}
diff --git a/examples/ex6_complex_type_conversion/build.gradle b/examples/ex6_complex_type_conversion/build.gradle
new file mode 100644
index 0000000..40d45bc
--- /dev/null
+++ b/examples/ex6_complex_type_conversion/build.gradle
@@ -0,0 +1,27 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion '26.0.2'
+
+ defaultConfig {
+ applicationId "com.google.android.mobly.snippet.example6"
+ minSdkVersion 16
+ targetSdkVersion 26
+ versionCode 1
+ versionName "0.0.1"
+ }
+ lintOptions {
+ abortOnError true
+ checkAllWarnings true
+ warningsAsErrors true
+ }
+}
+
+dependencies {
+ // The 'implementation project' dep is to compile against the snippet lib source in
+ // this repo. For your own snippets, you'll want to use the regular
+ // 'implementation' dep instead:
+ //implementation 'com.google.android.mobly:mobly-snippet-lib:1.2.0'
+ implementation project(':mobly-snippet-lib')
+}
diff --git a/examples/ex6_complex_type_conversion/src/main/AndroidManifest.xml b/examples/ex6_complex_type_conversion/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..c1548e7
--- /dev/null
+++ b/examples/ex6_complex_type_conversion/src/main/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.google.android.mobly.snippet.example6">
+
+ <application>
+ <!-- Required: list of all classes with @Rpc methods. -->
+ <meta-data
+ android:name="mobly-snippets"
+ android:value="com.google.android.mobly.snippet.example6.ExampleSnippet" />
+ <!-- Optional: a class used for converting Java objects to/from JSON. -->
+ <meta-data
+ android:name="mobly-object-converter"
+ android:value="com.google.android.mobly.snippet.example6.ExampleObjectConverter" />
+ <meta-data
+ android:name="mobly-log-tag"
+ android:value="MoblySnippetLibExample6" />
+ </application>
+
+ <instrumentation
+ android:name="com.google.android.mobly.snippet.SnippetRunner"
+ android:targetPackage="com.google.android.mobly.snippet.example6" />
+</manifest>
diff --git a/examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/CustomType.java b/examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/CustomType.java
new file mode 100644
index 0000000..223b63e
--- /dev/null
+++ b/examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/CustomType.java
@@ -0,0 +1,21 @@
+package com.google.android.mobly.snippet.example6;
+
+/**
+ * A data class that defines a non-primitive type.
+ *
+ * This type is used to demonstrate serialization and de-serialization of complex type objects in
+ * Mobly Snippet Lib for Android.
+ */
+public class CustomType {
+ private String myValue;
+ CustomType(String value) {
+ myValue = value;
+ }
+
+ String getMyValue() {
+ return myValue;
+ }
+ public void setMyValue(String newValue) {
+ myValue = newValue;
+ }
+}
diff --git a/examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/ExampleObjectConverter.java b/examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/ExampleObjectConverter.java
new file mode 100644
index 0000000..5fc4f22
--- /dev/null
+++ b/examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/ExampleObjectConverter.java
@@ -0,0 +1,36 @@
+package com.google.android.mobly.snippet.example6;
+
+import android.os.Bundle;
+
+import com.google.android.mobly.snippet.SnippetObjectConverter;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.lang.reflect.Type;
+
+
+/**
+ * Example showing how to supply custom object converter to Mobly Snippet Lib.
+ */
+
+public class ExampleObjectConverter implements SnippetObjectConverter {
+ @Override
+ public JSONObject serialize(Object object) throws JSONException {
+ JSONObject result = new JSONObject();
+ if (object instanceof CustomType) {
+ CustomType input = (CustomType) object;
+ result.put("Value", input.getMyValue());
+ return result;
+ }
+ return null;
+ }
+
+ @Override
+ public Object deserialize(JSONObject jsonObject, Type type) throws JSONException {
+ if (type == CustomType.class) {
+ return new CustomType(jsonObject.getString("Value"));
+ }
+ return null;
+ }
+}
diff --git a/examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet.java b/examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet.java
new file mode 100644
index 0000000..3306f85
--- /dev/null
+++ b/examples/ex6_complex_type_conversion/src/main/java/com/google/android/mobly/snippet/example6/ExampleSnippet.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.android.mobly.snippet.example6;
+
+import com.google.android.mobly.snippet.Snippet;
+import com.google.android.mobly.snippet.rpc.Rpc;
+import com.google.android.mobly.snippet.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * Example snippet showing converting complex type objects using custom logic.
+ *
+ * For complex types in Java, one can supply a custom object converter to Snippet Lib to specify how
+ * each complex type should be serialized/de-serialized. With this, users don't have to explicitly
+ * call a serializer or de-serializer in every single Rpc method, which simplifies code.
+ */
+public class ExampleSnippet implements Snippet {
+ @Rpc(description = "Pass a complex type as a snippet parameter.")
+ public String passComplexTypeToSnippet(CustomType input) {
+ Log.i("Old value is: " + input.getMyValue());
+ return "The value in CustomType is: " + input.getMyValue();
+ }
+
+ @Rpc(description = "Returns a complex type from snippet.")
+ public CustomType returnComplexTypeFromSnippet(String value) {
+ return new CustomType(value);
+ }
+
+ /**
+ * Demonstrates serialization/de-serialization of a collection of custom type objects.
+ */
+ @Rpc(description = "Update values for multiple CustomType objects.")
+ public ArrayList<CustomType> updateValues(ArrayList<CustomType> objects, String newValue) {
+ for (CustomType obj : objects) {
+ obj.setMyValue(newValue);
+ }
+ return objects;
+ }
+
+ @Override
+ public void shutdown() {}
+}