Add libhidl_test to native_test_list am: 99295db9a6 am: 0606a72fb0
am: 2ff7b6caed
Change-Id: Ib88b10596361672901f1d07ce5a0cfbd36dd433d
diff --git a/build/tasks/tests/instrumentation_test_list.mk b/build/tasks/tests/instrumentation_test_list.mk
index 0ded95b..c098a42 100644
--- a/build/tasks/tests/instrumentation_test_list.mk
+++ b/build/tasks/tests/instrumentation_test_list.mk
@@ -25,6 +25,7 @@
DocumentsUITests \
ShellTests \
SystemUITests \
+ TestablesTests \
RecyclerViewTests \
FrameworksWifiApiTests \
FrameworksWifiTests \
@@ -44,7 +45,6 @@
EmergencyInfoTests \
CalendarProviderTests \
SettingsLibTests \
- RetailDemoTests \
RSTest \
PrintSpoolerOutOfProcessTests \
CellBroadcastReceiverUnitTests \
@@ -52,4 +52,5 @@
CarrierConfigTests \
TeleServiceTests \
SettingsProviderTest \
- StorageManagerUnitTests
+ StorageManagerUnitTests \
+ SettingsTests
diff --git a/build/tasks/tests/native_test_list.mk b/build/tasks/tests/native_test_list.mk
index 08a6856..755f675 100644
--- a/build/tasks/tests/native_test_list.mk
+++ b/build/tasks/tests/native_test_list.mk
@@ -45,6 +45,7 @@
liblog-unit-tests \
libminijail_unittest_gtest \
libtextclassifier_tests \
+ libvintf_test \
libwifi-system_tests \
linker-unit-tests \
logcat-unit-tests \
@@ -73,6 +74,7 @@
syscall_filter_unittest_gtest \
time-unit-tests \
update_engine_unittests \
+ vintf_object_test \
wificond_unit_test \
wifilogd_unit_test \
ziparchive-tests \
diff --git a/docs/basics/index.md b/docs/basics/index.md
new file mode 100644
index 0000000..78e40a4
--- /dev/null
+++ b/docs/basics/index.md
@@ -0,0 +1,147 @@
+# Basics
+
+[TOC]
+
+## Overview
+
+Before understanding how testing is done on [Android platform](http://source.android.com/devices/index.html),
+please refer to the Android platform architecture for an overview.
+The diagram from that page is embedded below for convenience:
+
+
+
+## What to Test and How to Test
+
+A platform test typically interacts with one or more of the Android system
+services, or HAL layers, exercises the functionalities of the subject under test
+and assert correctness of the testing outcome.
+
+As such, a platform test may:
+
+1. exercise framework APIs via application framework; specific APIs being
+ exercised may include:
+ * public APIs intended for 3rd party applications
+ * hidden APIs intended for privileged applications, aka system APIs
+ * private APIs (@hide, or protected, package private)
+1. invoke Android system services via raw binder/IPC proxies directly
+1. interact directly with HALs via low level APIs or IPC interfaces
+
+Type 1 and 2 above are typically written as **instrumentation tests**, while
+type 3 is typically written as **native tests** using gtest framework.
+
+## Instrumentation Tests for Platform Testing
+
+You may have read the [Testing Fundamentals](https://developer.android.com/tools/testing/testing_android.html)
+on `developer.android.com`, however, there still may be some differences in
+how instrumentation tests are used in platform testing.
+
+In a nutshell, an instrumentation test provides a special test execution
+environment as launched via `am instrument` command, where the targeted
+application process is restarted and initialized with basic application context,
+and an instrumentation thread is started inside the application process VM. Your
+test code starts execution on this instrumentation thread, and is provided with
+an `Instrumentation` instance which provides access to the application context
+and APIs to manipulate the application process under test.
+
+Some key concepts about instrumentation:
+
+* an instrumentation must be declared in an application package, with an
+ [`<instrumentation>`](https://developer.android.com/guide/topics/manifest/instrumentation-element.html)
+ tag nested under the `<manifest>` tag of the application package manifest
+* an application package manifest may technically contain multiple
+ `<instrumentation>` tags, though it's not commonly used in this fashion
+* each `<instrumentation>` must contain:
+ * an `android:name` attribute: it should be the name of a subclass of
+ [`Instrumentation`](https://developer.android.com/reference/android/app/Instrumentation.html)
+ that's included in the test application, which is typically the test
+ runner that's being used, e.g.
+ `android.support.test.runner.AndroidJUnitRunner`
+ * an `android:targetPackage` attribute must be defined. Its value should
+ be set to the application package under test
+
+In the context of platform testing, there are typically two categories of
+instrumentation tests:
+
+### Instrumentation tests targeting application packages included in system
+
+This category of instrumentation test isn't that different from those targeting
+the regular Android applications. It's worth noting that the test application
+that included the instrumentation needs to be signed with the same certificate
+as the application that it's targeting.
+
+To learn more, see our [end-to-end example](../development/instr-app-e2e.md).
+
+### Instrumentation tests targeting itself
+
+As mentioned earlier, when an instrumentation is started, its target package is
+restarted with instrumentation code injected and initiated for execution. One
+exception is that the target package here cannot be the Android application
+framework itself, i.e. the package `android`, because doing so would lead to the
+paradoxical situation where Android framework would need to be restarted, which
+is what supports the system functions, including the instrumentation itself.
+
+This means that an instrumentation test cannot inject itself into Android
+framework, a.k.a. the system server, for execution. In order to test Android
+framework, the test code can only invoke public API surfaces, or those exposed
+via [AIDL](https://developer.android.com/guide/components/aidl.html)s available
+in platform source tree. For this category of tests, it's not meaningful to
+target any particular package, therefore it's customary for such
+instrumentations to be declared to target its own test application package, as
+defined in its own `<manifest>` tag of `AndroidManifest.xml`.
+
+Depending on the requirements, test application packages in this category may
+also:
+
+* Bundle activities needed for testing.
+* Share the user ID with the system.
+* Be signed with the platform key.
+* Be compiled against the framework source rather than the public SDK.
+
+This category of instrumentation tests are sometimes refered to as
+self-instrumentations. Below are some examples of such instrumentation tests in
+platform source:
+
+```
+frameworks/base/core/tests/coretests
+frameworks/base/services/tests/servicestests
+```
+
+To learn more, see our [end-to-end example](../development/instr-self-e2e.md).
+
+## Native Tests for Platform Testing
+
+A native test for platform testing typically accesses lower level HALs, or
+performs raw IPC against various system services, therefore the testing approach
+is typically tightly coupled with the service under test, outside the scope of
+this documentation.
+
+Building native tests using [gtest](https://github.com/google/googletest)
+framework is strongly recommended, and a prerequisite for integration with
+continuous testing infrastructure.
+
+Below are some examples of such native tests in platform source:
+
+```
+frameworks/av/camera/tests
+frameworks/native/libs/gui/tests
+```
+
+To learn more, see our [end-to-end example](../development/native-func-e2e.md).
+
+## Compatibility Test Suite (CTS)
+
+[Android Compatibility Test Suite](https://source.android.com/compatibility/cts/)
+is a suite of various types of tests, used to ensure compatibility of
+Android framework implementations across OEM partners, and across platform
+releases. **The suite also includes instrumentation tests and native tests
+(also using gtest framework).**
+
+CTS and platform tests are not mutually exclusive, and here are some general
+guidelines:
+
+* if a test is asserting correctness of framework API functions/behaviors, and
+ it should be enforced across OEM partners, it should be in CTS
+* if a test is intended to catch regressions during platform development
+ cycle, and may require privileged permission to carry out, and may be
+ dependent on implementation details (as released in AOSP), it should only be
+ platform tests
diff --git a/docs/development/index.md b/docs/development/index.md
new file mode 100644
index 0000000..4a87714
--- /dev/null
+++ b/docs/development/index.md
@@ -0,0 +1,40 @@
+# Test Development Workflow
+
+To integrate tests into platform continuous testing service, they should meet
+the following guidelines.
+
+## Test Types
+
+Supported test types are:
+
+* standard [instrumentation](http://developer.android.com/tools/testing/testing_android.html) tests
+ * supports both functional and metrics tests
+* native tests
+ * functional: [gtest](https://github.com/google/googletest) framework
+ * metrics: native benchmark tests using [google-benchmark](https://github.com/google/benchmark)
+
+Functional tests make assertions of pass or fail on test cases, while metrics
+tests generally performs an action repeatedly to collect timing metrics.
+
+With standardized input/output format, the need for customized result parsing
+and post-processing per test is eliminated, and generic test harnesses can be
+used for all tests that fit into the convention.
+
+### Test Case Guidelines
+
+Test cases executed via continuous testing service are expected to be
+**hermetic**:
+
+* no Google account sign-in
+* no connectivity setup (telephony/wifi/bluetooth/NFC)
+* no test parameters passed in
+* no setup or tear down performed by test harness for a specific test case
+
+### Building Tests
+
+If you are new to the workflow of adding and executing tests, please see:
+
+* [Instrumentation Tests](instrumentation.md) (supports both functional and
+ metrics tests)
+* [Native Tests](native.md)
+* [Native Metric Tests](metrics.md)
diff --git a/docs/development/instr-app-e2e.md b/docs/development/instr-app-e2e.md
new file mode 100644
index 0000000..3b994db
--- /dev/null
+++ b/docs/development/instr-app-e2e.md
@@ -0,0 +1,383 @@
+# Instrumentation Targeting an Application: A Complete Example
+
+[TOC]
+
+If you are new to Android platform development, you might find this complete
+example of adding a brand new instrumentation test from scratch useful to
+demonstrate the typical workflow involved.
+
+Note that this guide assumes that you already have some knowledge in the
+platform source tree workflow. If not, please refer to
+https://source.android.com/source/requirements. The example
+covered here is writing an new instrumentation test with target package set at
+its own test application package. If you are unfamiliar with the concept, please
+read through the [testing basics](../basics/index.md) page.
+
+This guide uses the follow test to serve as an sample:
+
+* frameworks/base/packages/Shell/tests
+
+It's recommended to browse through the code first to get a rough impression
+before proceeding.
+
+## Deciding on a Source Location
+
+Because the instrumentation test will be targeting an application, the convention
+is to place the test source code in a `tests` directory under the root of your
+component source directory in platform source tree.
+
+See more discussions about source location in the [end-to-end example for
+self-instrumenting tests](instr-self-e2e.md#location).
+
+## Makefile
+
+Each new test module must have a makefile to direct the build system with module
+metadata, compile time depdencies and packaging instructions.
+
+frameworks/base/packages/Shell/tests/Android.mk
+
+A snapshot is included here for convenience:
+
+```makefile
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator junit legacy-android-test
+
+LOCAL_PACKAGE_NAME := ShellTests
+LOCAL_INSTRUMENTATION_FOR := Shell
+
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+LOCAL_CERTIFICATE := platform
+include $(BUILD_PACKAGE)
+```
+
+Some select remarks on the makefile:
+
+```makefile
+LOCAL_MODULE_TAGS := tests
+```
+
+This setting declares the module as a test module, which will instruct the build
+system to automatically skip proguard stripping, since that's typically
+problematic for tests.
+
+```makefile
+LOCAL_CERTIFICATE := platform
+```
+
+This setting instructs the build system to sign the test application package
+with the platform certificate. This is because for a test application package to
+be able to instrument on the targeted application package, these two packages
+must be signed with the same certificate; otherwise allowing packages to be
+instrumented on arbitrarily would be a security concern. To find out the signing
+certificate of the application packge you are testing, look for
+`LOCAL_CERTIFICATE` in its `Android.mk`; and if there isn't one, simply skip
+this field in your test application makefile as well.
+
+```makefile
+LOCAL_JAVA_LIBRARIES := android.test.runner
+```
+
+This setting tells the build system to put Java library `android.test.runner` on
+classpath during compilation, as opposed to statically incorporating the library
+into the current package. This is typically done for Java code that is
+referenced by the code in current package, and will be automatically placed on
+package classpath at runtime. In the context of tests for application, strictly
+speaking, both framework APIs and code in application under test fall into this
+category, however, the former is done via implicit rules by build system at
+compile time and by framework at runtime, and the latter is done via
+`LOCAL_INSTRUMENTATION_FOR` (see below) at compile time and via
+`android:targetPackage` (see below) in manifest by instrumentation framework at
+runtime.
+
+```makefile
+LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator junit legacy-android-test
+```
+
+This setting instructs the build system to incorporate the contents of the named
+modules into the resulting apk of current module. This means that each named
+module is expected to produce a `.jar` file, and its content will be used for
+resolving classpath references during compile time, as well as incorporated into
+the resulting apk.
+
+
+The platform source tree also included other useful testing frameworks such as
+`ub-uiautomator`, `easymock` and so on.
+
+```makefile
+LOCAL_PACKAGE_NAME := ShellTests
+```
+
+This setting is required if `BUILD_PACKAGE` when used later: it gives a name to
+your module, and the resulting apk will be named the same and with a `.apk`
+suffix, e.g. in this case, resulting test apk is named as
+`ShellTests.apk`. In addition, this also defines a make target name
+for your module, so that you can use `make [options] <LOCAL_PACKAGE_NAME>` to
+build your test module and all its dependencies.
+
+```makefile {# LOCAL_INSTRUMENTATION_FOR}
+LOCAL_INSTRUMENTATION_FOR := Shell
+```
+
+As mentioned, during execution of an instrumentation test, the application under
+test is restarted with the instrumentation code injected for execution. The test
+can reference any classes and its instances of the application under test. This
+means that the test code may contain references to classes defined by the
+application under test, so during compile time, the build system needs to
+properly resolve such references. This setting provides the module name of
+application under test, which should match the `LOCAL_PACKAGE_NAME` of in the
+makefile for your application. At compile time, the build system will try to
+look up the intermediate files for the named module, and use them on the
+classpath for the Java compiler.
+
+```makefile
+LOCAL_COMPATIBILITY_SUITE := device-tests
+```
+
+This line builds the testcase as part of the device-tests suite, which is
+meant to target a specific device and not a general ABI. If only the ABI
+needs to be targetted, it can be swapped with 'general-tests'.
+
+```makefile
+include $(BUILD_PACKAGE)
+```
+
+This includes a core makefile in build system that performs the necessary steps
+to generate an apk based on the settings provided by the preceding variables.
+The generated apk will be named after `LOCAL_PACKAGE_NAME`, e.g.
+`SettingsGoogleUnitTests.apk`. And if `tests` is used as `LOCAL_MODULE_TAGS` and
+there are no other customizations, you should be able to find your test apk in:
+
+* `${OUT}/data/app/<LOCAL_PACKAGE_NAME>/<LOCAL_PACKAGE_NAME>.apk`
+
+e.g. `${OUT}/data/app/ShellTests/ShellTests.apk`
+
+## Manifest file
+
+Just like a regular application, each instrumentation test module needs a
+manifest file. If you name the file as `AndroidManifest.xml` and provide it next
+to `Android.mk` for your test tmodule, it will get included automatically by the
+`BUILD_PACKAGE` core makefile.
+
+Before proceeding further, it's highly recommended to go through the external
+[documentation on manifest file](https://developer.android.com/guide/topics/manifest/manifest-intro.html)
+first.
+
+This gives an overview of basic components of a manifest file and their
+functionalities.
+
+Latest version of the manifest file for the sample gerrit change can be accessed
+at:
+https://android.googlesource.com/platform/frameworks/base/+/master/packages/Shell/tests/AndroidManifest.xml
+
+A snapshot is included here for convenience:
+
+```xml
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.shell.tests">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+
+ <activity
+ android:name="com.android.shell.ActionSendMultipleConsumerActivity"
+ android:label="ActionSendMultipleConsumer"
+ android:theme="@android:style/Theme.NoDisplay"
+ android:noHistory="true"
+ android:excludeFromRecents="true">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND_MULTIPLE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="*/*" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.shell"
+ android:label="Tests for Shell" />
+
+</manifest>
+```
+
+Some select remarks on the manifest file:
+
+```xml
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.shell.tests">
+```
+
+The `package` attribute is the application package name: this is the unique
+identifier that the Android application framework uses to identify an
+application (or in this context: your test application). Each user in the system
+can only install one application with that package name.
+
+Since this is a test application package, independent from the application
+package under test, a different package name must be used: one common convention
+is to add a suffix `.test`.
+
+Furthermore, this `package` attribute is the same as what
+[`ComponentName#getPackageName()`](https://developer.android.com/reference/android/content/ComponentName.html#getPackageName\(\))
+returns, and also the same you would use to interact with various `pm` sub
+commands via `adb shell`.
+
+Please also note that although the package name is typically in the same style
+as a Java package name, it actually has very few things to do with it. In other
+words, your application (or test) package may contain classes with any package
+names, though on the other hand, you could opt for simplicity and have your top
+level Java package name in your application or test identical to the application
+package name.
+
+```xml
+<uses-library android:name="android.test.runner" />
+```
+
+This is required for all Instrumentation tests since the related classes are
+packaged in a separate framework jar library file, therefore requires additional
+classpath entries when the test package is invoked by application framework.
+
+```xml
+android:targetPackage="com.android.shell"
+```
+
+This sets the target package of the instrumentation to `com.android.shell.tests`.
+When the instrumentation is invoked via `am instrument` command, the framework
+restarts `com.android.shell.tests` process, and injects instrumentation code into
+the process for test execution. This also means that the test code will have
+access to all the class instances running in the application under test and may
+be able to manipulate state depends on the test hooks exposed.
+
+## Test Configuration File
+
+In order to simplify test execution, you also need write a test configuration
+file for Android's test harness, [TradeFederation](https://source.android.com/devices/tech/test_infra/tradefed/).
+
+The test configuration can specify special device setup options and default
+arguments to supply the test class.
+
+The config can be found:
+frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.javast.java
+
+A snapshot is included here for convenience:
+
+```xml
+<configuration description="Runs Tests for Shell.">
+ <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <option name="test-file-name" value="ShellTests.apk" />
+ </target_preparer>
+
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-tag" value="ShellTests" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.shell.tests" />
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+ </test>
+</configuration>
+```
+
+Some select remarks on the test configuration file:
+
+```xml
+<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <option name="test-file-name" value="ShellTests.apk"/>
+</target_preparer>
+```
+This tells TradeFederation to install the ShellTests.apk onto the target
+device using a specified target_preparer. There are many target preparers
+available to developers in TradeFederation and these can be used to ensure
+the device is setup properly prior to test execution.
+
+```xml
+<test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="com.android.shell.tests"/>
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+</test>
+```
+This specifies the TradeFederation test class to use to execute the test and
+passes in the package on the device to be executed and the test runner
+framework which is JUnit in this case.
+
+Look here for more information on [Test Module Configs](../test-config.md)
+
+## JUnit4 Features
+
+Using `android-support-test` library as test runner enables adoptation of new
+JUnit4 style test classes, and the sample gerrit change contains some very basic
+use of its features.
+
+Latest source code for the sample gerrit change can be accessed at:
+frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.javast.java
+
+While testing patterns are usually specific to component teams, there are some
+generally useful usage patterns.
+
+```java
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class FeatureFactoryImplTest {
+```
+
+A significant difference in JUnit4 is that tests are no longer required to
+inherit from a common base test class; instead, you write tests in plain Java
+classes and use annotation to indicate certain test setup and constraints. In
+this example, we are instructing that this class should be run as an Android
+JUnit4 test.
+
+The `@SmallTest` annotation specified a test size for the entire test class: all
+test methods added into this test class inherit this test size annotation.
+pre test class setup, post test tear down, and post test class tear down:
+similar to `setUp` and `tearDown` methods in JUnit4.
+`Test` annotation is used for annotating the actual test.
+
+**Important**: the test methods themselves are annotated with `@Test`
+annotation; and note that for tests to be executed via APCT, they must be
+annotated with test sizes. Such annotation may be applied at method scope, or
+class scope.
+
+```java
+ @Before
+ public void setup() {
+ ...
+ @Test
+ public void testGetProvider_shouldCacheProvider() {
+ ...
+```
+
+The `@Before` annotation is used on methods by JUnit4 to perform pre test setup.
+Although not used in this example, there's also `@After` for post test teardown.
+Similarly, the `@BeforeClass` and `@AfterClass` annotations are can be used on
+methods by JUnit4 to perform setup before executing all tests in a test class,
+and teardown afterwards. Note that the class-scope setup and teardown methods
+must be static.
+
+As for the test methods, unlike in earlier version of JUnit, they no longer need
+to start the method name with `test`, instead, each of them must be annotated
+with `@Test`. As usual, test methods must be public, declare no return value,
+take no parameters, and may throw exceptions.
+
+```java
+ Context context = InstrumentationRegistry.getTargetContext();
+```
+
+Because the JUnit4 tests no longer require a common base class, it's no longer
+necessary to obtain `Context` instances via `getContext()` or
+`getTargetContext()` via base class methods; instead, the new test runner
+manages them via [`InstrumentationRegistry`](https://developer.android.com/reference/android/support/test/InstrumentationRegistry.html)
+where contextual and environmental setup created by instrumentation framework is
+stored. Through this class, you can also call:
+
+* `getInstrumentation()`: the instance to the `Instrumentation` class
+* `getArguments()`: the command line arguments passed to `am instrument` via
+ `-e <key> <value>`
+
+## Build & Test Locally
+
+Follow these [Instructions](../instrumentation.md)
diff --git a/docs/development/instr-self-e2e.md b/docs/development/instr-self-e2e.md
new file mode 100644
index 0000000..0814382
--- /dev/null
+++ b/docs/development/instr-self-e2e.md
@@ -0,0 +1,394 @@
+# Self-Instrumenting Tests: A Complete Example
+
+[TOC]
+
+If you are new to Android platform development, you might find this complete
+example of adding a brand new instrumentation test from scratch useful to
+demonstrate the typical workflow involved.
+
+Note that this guide assumes that you already have some knowledge in the
+platform source tree workflow. If not, please refer to
+https://source.android.com/source/requirements. The example
+covered here is writing an new instrumentation test with target package set at
+its own test application package. If you are unfamiliar with the concept, please
+read through the [testing basics](../basics/index.md) page.
+
+This guide uses the follow test to serve as an sample:
+
+* [Hello World Instrumentation Test](../../tests/example/instrumentation)
+
+It's recommended to browse through the code first to get a rough impression
+before proceeding.
+
+## Deciding on a Source Location {#location}
+
+Typically your team will already have an established pattern of places to check
+in code, and places to add tests. Most team owns a single git repository, or
+share one with other teams but have a dedicated sub directory that contains
+component source code.
+
+Assuming the root location for your component source is at `<component source
+root>`, most components have `src` and `tests` folders under it, and some
+additional files such as `Android.mk` (or broken up into additional `.mk` files),
+the manifest file `AndroidManifest.xml`, and the test configuration file
+'AndroidTest.xml'.
+
+Since you are adding a brand new test, you'll probably need to create the
+`tests` directory next to your component `src`, and populate it with content.
+
+In some cases, your team might have further directory structures under `tests`
+due to the need to package different suites of tests into individual apks. And
+in this case, you'll need to create a new sub directory under `tests`.
+
+Regardless of the structure, you'll end up populating the `tests` directory or
+the newly created sub directory with files similar to what's in
+`instrumentation` directory in the sample gerrit change. The sections below will
+explain in further details of each file.
+
+## Makefile
+
+Each new test module must have a makefile to direct the build system with module
+metadata, compile time depdencies and packaging instructions.
+
+[Latest version of the makefile](../../tests/example/instrumentation/Android.mk)
+
+
+A snapshot is included here for convenience:
+
+```makefile
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_MODULE_TAGS := tests
+LOCAL_PACKAGE_NAME := HelloWorldTests
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_CERTIFICATE := platform
+
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+include $(BUILD_PACKAGE)
+```
+
+Some select remarks on the makefile:
+
+```makefile
+LOCAL_MODULE_TAGS := tests
+```
+
+This setting declares the module as a test module, which will instruct the build
+system to automatically skip proguard stripping, since that's typically
+problematic for tests.
+
+```makefile
+LOCAL_PACKAGE_NAME := HelloWorldTests
+```
+
+This setting is required when `BUILD_PACKAGE` is used later: it gives a name to
+your module, and the resulting apk will be named the same and with a `.apk`
+suffix, e.g. in this case, resulting test apk is named as `HelloWorldTests.apk`.
+In addition, this also defines a make target name for your module, so that you
+can use `make [options] <LOCAL_PACKAGE_NAME>` to build your test module and all
+its dependencies.
+
+```makefile
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+```
+
+This setting instructs the build system to incorporate the contents of the named
+modules into the resulting apk of current module. This means that each named
+module is expected to produce a `.jar` file, and its content will be used for
+resolving classpath references during compile time, as well as incorporated into
+the resulting apk.
+
+In this example, things that might be generally useful for tests:
+
+* `android-support-test` is the prebuilt for Android Test Support Library,
+ which included the new test runner `AndroidJUnitRunner`: a replacement for
+ the now deprecated built-in `InstrumentationTestRunner`, with support for
+ JUnit4 testing framework. Find out more at:
+
+ * https://google.github.io/android-testing-support-library/
+
+ If you are building a new instrumentation module, you should always start
+ with this library as your test runner.
+
+The platform source tree also included other useful testing frameworks such as
+`ub-uiautomator`, `mockito-target`, `easymock` and so on.
+
+```makefile
+LOCAL_CERTIFICATE := platform
+```
+
+This setting instructs the build system to sign the apk with the same
+certificate as the core platform. This is needed if your test uses a signature
+protected permission or API. Note that this is suitable for platform continuous
+testing, but should *not* be used in CTS test modules. Note that this example
+uses this certificat setting only for the purpose of illustration: the test code
+of the example does not actually need for the test apk to be signed with the
+special platform certificate.
+
+If you are writing an instrumentation for your component that lives outside of
+system server, that is, it's packaged more or less like a regular app apk,
+except that it's built into system image and may be a priveleged app, chances
+are that your instrumentation will be targeting the app package (see below
+section about manifest) of your component. In this case, your applicaiton
+makefile may have its own `LOCAL_CERTIFICATE` setting, and your instrumentation
+module should retain the same setting. This is because to target your
+instrumentation on the app under test, your test apk and app apk must be signed
+with the same certificate.
+
+In other cases, you don't need to have this setting at all: the build system
+will simply sign it with a default built-in certificate, based on the build
+variant, and it's typically called the `dev-keys`.
+
+```makefile
+LOCAL_COMPATIBILITY_SUITE := device-tests
+```
+
+This sets up the test to be easily discoverable by the TradeFederation test
+harness. Other suites can be added here such as CTS so that this test may be
+shared.
+
+```makefile
+include $(BUILD_PACKAGE)
+```
+
+This includes a core makefile in build system that performs the necessary steps
+to generate an apk based on the settings provided by the preceding variables.
+The generated apk will be named after `LOCAL_PACKAGE_NAME`, e.g.
+`HelloWorldTests.apk`. And if `tests` is used as `LOCAL_MODULE_TAGS` and there
+are no other customizations, you should be able to find your test apk in:
+
+* `${OUT}/data/app/<LOCAL_PACKAGE_NAME>/<LOCAL_PACKAGE_NAME>.apk`
+
+e.g. `${OUT}/data/app/HelloWorldTests/HelloWorldTests.apk`
+
+## Manifest file
+
+Just like a regular application, each instrumentation test module needs a
+manifest file. If you name the file as `AndroidManifest.xml` and provide it next
+to `Android.mk` for your test tmodule, it will get included automatically by the
+`BUILD_PACKAGE` core makefile.
+
+Before proceeding further, it's highly recommended to go through the external
+[documentation on manifest file](https://developer.android.com/guide/topics/manifest/manifest-intro.html)
+first.
+
+This gives an overview of basic components of a manifest file and their
+functionalities.
+
+[Latest Manifest File](../../tests/example/instrumentation/AndroidManifest.xml)
+
+A snapshot is included here for convenience:
+
+```xml
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.test.example.helloworld"
+ android:sharedUserId="android.uid.system" >
+
+ <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.test.example.helloworld"
+ android:label="Hello World Test"/>
+
+</manifest>
+```
+
+Some select remarks on the manifest file:
+
+```xml
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.test.example.helloworld"
+```
+
+The `package` attribute is the application package name: this is the unique
+identifier that the Android application framework uses to identify an
+application (or in this context: your test application). Each user in the system
+can only install one application with that package name.
+
+Furthermore, this `package` attribute is the same as what
+[`ComponentName#getPackageName()`](https://developer.android.com/reference/android/content/ComponentName.html#getPackageName\(\))
+returns, and also the same you would use to interact with various `pm` sub
+commands via `adb shell`.
+
+Please also note that although the package name is typically in the same style
+as a Java package name, it actually has very few things to do with it. In other
+words, your application (or test) package may contain classes with any package
+names, though on the other hand, you could opt for simplicity and have your top
+level Java package name in your application or test identical to the application
+package name.
+
+```xml
+android:sharedUserId="android.uid.system"
+```
+
+This declares that at installation time, this apk should be granted the same
+user id, i.e. runtime identity, as the core platform. Note that this is
+dependent on the apk being signed with same certificate as the core platform
+(see `LOCAL_CERTIFICATE` in above section), yet they are different concepts:
+
+* some permissions or APIs are signature protected, which requires same
+ signing certificate
+* some permissions or APIs requires the `system` user identity of the caller,
+ which requires the calling package to share user id with `system`, if it's a
+ separate package from core platform itself
+
+```xml
+<uses-library android:name="android.test.runner" />
+```
+
+This is required for all Instrumentation tests since the related classes are
+packaged in a separate framework jar library file, therefore requires additional
+classpath entries when the test package is invoked by application framework.
+
+```xml
+android:targetPackage="android.test.example.helloworld"
+```
+
+You might have noticed that the `targetPackage` here is declared the same as the
+`package` attribute declared in the `manifest` tag of this file. As mentioned in
+[testing basics](../basics/index.md), this category of instrumentation test are
+typically intended for testing framework APIs, so it's not very meaningful for
+them to have a specific targeted application package, other then itself.
+
+## Test Configuration File
+
+In order to simplify test execution, you also need write a test configuration
+file for Android's test harness, [TradeFederation](https://source.android.com/devices/tech/test_infra/tradefed/).
+
+The test configuration can specify special device setup options and default
+arguments to supply the test class.
+
+[Latest Test Config File](../../tests/example/instrumentation/AndroidTest.xml)
+
+A snapshot is included here for convenience:
+
+```xml
+<configuration description="Runs sample instrumentation test.">
+ <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
+ <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <option name="test-file-name" value="HelloWorldTests.apk"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
+ <option name="test-suite-tag" value="apct"/>
+ <option name="test-tag" value="SampleInstrumentationTest"/>
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="android.test.example.helloworld"/>
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+ </test>
+</configuration>
+```
+
+Some select remarks on the test configuration file:
+
+```xml
+<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <option name="test-file-name" value="HelloWorldTests.apk"/>
+</target_preparer>
+```
+This tells TradeFederation to install the HelloWorldTests.apk onto the target
+device using a specified target_preparer. There are many target preparers
+available to developers in TradeFederation and these can be used to ensure
+the device is setup properly prior to test execution.
+
+```xml
+<test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="android.test.example.helloworld"/>
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+</test>
+```
+This specifies the TradeFederation test class to use to execute the test and
+passes in the package on the device to be executed and the test runner
+framework which is JUnit in this case.
+
+Look here for more information on [Test Module Configs](test-config.md)
+
+## JUnit4 Features
+
+Using `android-support-test` library as test runner enables adoptation of new
+JUnit4 style test classes, and the sample gerrit change contains some very basic
+use of its features.
+
+[Latest source code](../../tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java)
+
+While testing patterns are usually specific to component teams, there are some
+generally useful usage patterns.
+
+```java
+@RunWith(JUnit4.class)
+public class HelloWorldTest {
+```
+
+A significant difference in JUnit4 is that tests are no longer required to
+inherit from a common base test class; instead, you write tests in plain Java
+classes and use annotation to indicate certain test setup and constraints. In
+this example, we are instructing that this class should be run as a JUnit4 test.
+
+```java
+ @BeforeClass
+ public static void beforeClass() {
+ ...
+ @AfterClass
+ public static void afterClass() {
+ ...
+ @Before
+ public void before() {
+ ...
+ @After
+ public void after() {
+ ...
+ @Test
+ @SmallTest
+ public void testHelloWorld() {
+ ...
+```
+
+The `@Before` and `@After` annotations are used on methods by JUnit4 to perform
+pre test setup and post test teardown. Similarly, the `@BeforeClass` and
+`@AfterClass` annotations are used on methods by JUnit4 to perform setup before
+executing all tests in a test class, and teardown afterwards. Note that the
+class-scope setup and teardown methods must be static. As for the test methods,
+unlike in earlier version of JUnit, they no longer need to start the method name
+with `test`, instead, each of them must be annotated with `@Test`. As usual,
+test methods must be public, declare no return value, take no parameters, and
+may throw exceptions.
+
+**Important**: the test methods themselves are annotated with `@Test`
+annotation; and note that for tests to be executed via APCT, they must be
+annotated with test sizes: the example annotated method `testHelloWorld` as
+`@SmallTest`. The annotation may be applied at method scope, or class scope.
+
+## Accessing `Instrumentation`
+
+Although not covered in the basic hello world example, it's fairly common for an
+Android test to require access `Instrumentation` instance: this is the core API
+interface that provides access to application contexts, activity lifecycle
+related test APIs and more.
+
+Because the JUnit4 tests no longer require a common base class, it's no longer
+necessary to obtain `Instrumentation` instance via
+`InstrumentationTestCase#getInstrumentation()`, instead, the new test runner
+manages it via [`InstrumentationRegistry`](https://developer.android.com/reference/android/support/test/InstrumentationRegistry.html)
+where contextual and environmental setup created by instrumentation framework is
+stored.
+
+To access the instance of `Instrumentation` class, simply call static method
+`getInstrumentation()` on `InstrumentationRegistry` class:
+
+```java
+Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()
+```
+
+## Build & Test Locally:
+
+Follow these [Instructions](instrumentation.md)
diff --git a/docs/development/instrumentation.md b/docs/development/instrumentation.md
new file mode 100644
index 0000000..6cf74c2
--- /dev/null
+++ b/docs/development/instrumentation.md
@@ -0,0 +1,94 @@
+# Instrumentation Tests
+
+1. Below are common destinations for hermetic tests against framework services:
+
+ ```
+ frameworks/base/core/tests/coretests
+ frameworks/base/services/tests/servicestests
+ ```
+
+ If you are adding a brand new instrumentation module for your component, see
+
+ * [Self-Instrumenting Tests: A Complete Example](instr-self-e2e.md)
+ * [Instrumentation Targeting an Application: A Complete Example]
+ (instr-app-e2e.md)
+
+1. Following the existing convention if you are adding tests into one of the
+ locations above. If you are setting up a new test module, please follow the
+ setup of `AndroidManifest.xml` and `Android.mk` in one of the locations
+ above
+
+1. See https://android.googlesource.com/platform/frameworks/base.git/+/master/core/tests/coretests/ for an example
+
+1. Note: do not forget to mark your test as `@SmallTest`, `@MediumTest` or
+ `@LargeTest`
+
+1. Build the test module with make, e.g.:
+
+ ```
+ make FrameworksCoreTests -j
+ ```
+
+1. Automatic installation and run with the TradeFederation test harness:
+
+ ```
+ make tradefed-all -j
+ tradefed.sh run template/local_min --template:map test=FrameworksCoreTests
+ ```
+
+1. Manually Install and Run:
+ 1. Install the generated apk:
+
+ ```
+ adb install -r ${OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
+ ```
+
+ Tip: you use `adb shell pm list instrumentation` to find the
+ instrumentations inside the apk just installed
+
+ 1. Run the tests with various options:
+
+ 1. all tests in the apk
+
+ ```
+ adb shell am instrument -w com.android.frameworks.coretests\
+ /android.support.test.runner.AndroidJUnitRunner
+ ```
+
+ 1. all tests under a specific Java package
+
+ ```
+ adb shell am instrument -w -e package android.animation \
+ com.android.frameworks.coretests\
+ /android.support.test.runner.AndroidJUnitRunner
+ ```
+
+ 1. all tests under a specific class
+
+ ```
+ adb shell am instrument -w -e class \
+ android.animation.AnimatorSetEventsTest \
+ com.android.frameworks.coretests\
+ /android.support.test.runner.AndroidJUnitRunner
+ ```
+
+ 1. a specific test method
+
+ ```
+ adb shell am instrument -w -e class \
+ android.animation.AnimatorSetEventsTest#testCancel \
+ com.android.frameworks.coretests\
+ /android.support.test.runner.AndroidJUnitRunner
+ ```
+
+Your test can make an explicit assertion on pass or fail using `JUnit` APIs; in
+addition, any uncaught exceptions will also cause a functional failure.
+
+To emit performance metrics, your test code can call
+[`Instrumentation#sendStatus`](http://developer.android.com/reference/android/app/Instrumentation.html#sendStatus\(int, android.os.Bundle\))
+to send out a list of key-value pairs. It's important to note that:
+
+1. metrics can be integer or floating point
+1. any non-numerical values will be discarded
+1. your test apk can be either functional tests or metrics tests, however
+ mixing both are not currently supported
diff --git a/docs/development/metrics.md b/docs/development/metrics.md
new file mode 100644
index 0000000..82055dd
--- /dev/null
+++ b/docs/development/metrics.md
@@ -0,0 +1,34 @@
+# Native Metric Tests
+
+As mentioned earlier, native metric tests are typically used for exercising HAL
+or interacting directly with lower level system services, and to leverage
+continuous testing service, native metric tests should be built with
+[google-benchmark](https://github.com/google/benchmark) framework.
+
+Here are some general instructions:
+
+1. See sample native test module setup at: `bionic/benchmarks/bionic-benchmarks`
+1. Test module makefile should use `BUILD_NATIVE_BENCHMARK` build rule so that
+google-benchmark dependencies are included automatically
+1. Build the test module with make:
+
+ ```shell
+ make -j40 bionic-benchmarks
+ ```
+1. Automatic installation and run with the TradeFederation test harness:
+
+ ```
+ make tradefed-all -j
+ tradefed.sh run template/local_min --template:map test=bionic-benchmarks
+1. Manually Install and Run:
+ 1. Push the generated test binary onto device:
+
+ ```shell
+ adb push ${OUT}/data/benchmarktest/bionic-benchmarks/bionic-benchmarks32 \
+ /data/benchmarktest/bionic-benchmarks/bionic-benchmarks32
+ ```
+ 1. Execute the test by invoking test binary on device:
+
+ ```shell
+ adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks32
+ ```
diff --git a/docs/development/native-func-e2e.md b/docs/development/native-func-e2e.md
new file mode 100644
index 0000000..b58da6d
--- /dev/null
+++ b/docs/development/native-func-e2e.md
@@ -0,0 +1,269 @@
+# Adding a New Native Test: A Complete Example
+
+[TOC]
+
+If you are new to Android platform development, you might find this complete
+example of adding a brand new native test from scratch useful to demonstrate the
+typical workflow involved.
+
+Note that this guide assumes that you already have some knowledge in the
+platform source tree workflow. If not, please refer to
+https://source.android.com/source/requirements.
+
+In addition, if you are also unfamiliar with the gtest framework for C++, please
+check out its project page first:
+
+* https://github.com/google/googletest
+
+This guide uses the follow test to serve as an sample:
+
+* [Hello World Native Test](../../tests/example/native)
+
+It's recommended to browse through the code first to get a rough impression
+before proceeding.
+
+## Deciding on a Source Location
+
+Typically your team will already have an established pattern of places to check
+in code, and places to add tests. Most team owns a single git repository, or
+share one with other teams but have a dedicated sub directory that contains
+component source code.
+
+Assuming the root location for your component source is at `<component source
+root>`, most components have `src` and `tests` folders under it, and some
+additional files such as `Android.mk` (or broken up into additional `.mk`
+files).
+
+Since you are adding a brand new test, you'll probably need to create the
+`tests` directory next to your component `src`, and populate it with content.
+
+In some cases, your team might have further directory structures under `tests`
+due to the need to package different suites of tests into individual binaries.
+And in this case, you'll need to create a new sub directory under `tests`.
+
+To illustrate, here's a typical directory outline for components with a single
+`tests` folder:
+
+```
+\
+ <component source root>
+ \-- Android.mk (component makefile)
+ \-- AndroidTest.mk (test config file)
+ \-- src (component source)
+ | \-- foo.cpp
+ | \-- ...
+ \-- tests (test source root)
+ \-- Android.mk (test makefile)
+ \-- src (test source)
+ \-- foo_test.cpp
+ \-- ...
+```
+
+and here's a typical directory outline for components with multiple test source
+directories:
+
+```
+\
+ <component source root>
+ \-- Android.mk (component makefile)
+ \-- AndroidTest.mk (test config file)
+ \-- src (component source)
+ | \-- foo.cpp
+ | \-- ...
+ \-- tests (test source root)
+ \-- Android.mk (test makefile)
+ \-- testFoo (sub test source root)
+ | \-- Android.mk (sub test makefile)
+ | \-- src (sub test source)
+ | \-- test_foo.cpp
+ | \-- ...
+ \-- testBar
+ | \-- Android.mk
+ | \-- src
+ | \-- test_bar.cpp
+ | \-- ...
+ \-- ...
+```
+
+Regardless of the structure, you'll end up populating the `tests` directory or
+the newly created sub directory with files similar to what's in `native`
+directory in the sample gerrit change. The sections below will explain in
+further details of each file.
+
+## Makefile
+
+Each new test module must have a makefile to direct the build system with module
+metadata, compile time dependencies and packaging instructions.
+
+[Latest version of the makefile](../../tests/example/native/Android.mk)
+
+A snapshot is included here for convenience:
+
+```makefile
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ HelloWorldTest.cpp
+
+LOCAL_MODULE := hello_world_test
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+include $(BUILD_NATIVE_TEST)
+```
+
+Some select remarks on the makefile:
+
+```makefile
+LOCAL_MODULE := hello_world_test
+```
+
+This setting declares the module name, which must be unique in the entire build
+tree. It will also be used as the name as the binary executable of your test, as
+well as a make target name, so that you can use `make [options] <LOCAL_MODULE>`
+to build your test binary and all its dependencies.
+
+```makefile
+LOCAL_MODULE_TAGS := tests
+```
+
+This setting declares the module as a test module, which will instruct the build
+system to generate the native test binaries under "data" output directory, so
+that they can be packaged into test artifact file bundle.
+
+```makefile
+LOCAL_COMPATIBILITY_SUITE := device-tests
+```
+
+This line builds the testcase as part of the device-tests suite, which is
+meant to target a specific device and not a general ABI.
+
+```makefile
+include $(BUILD_NATIVE_TEST)
+```
+
+This includes a core makefile in build system that performs the necessary steps
+to compile your test, together with gtest framework under `external/gtest`, into
+a native test binary. The generated binary will have the same name as
+`LOCAL_MODULE`. And if `tests` is used as `LOCAL_MODULE_TAGS` and there are no
+other customizations, you should be able to find your test binary in:
+
+* `${OUT}/data/nativetest[64]/<LOCAL_MODULE>/<LOCAL_MODULE>`
+
+e.g. `${OUT}/data/nativetest[64]/hello_world_test/hello_world_test`
+
+And you will also find it:
+* ${OUT}/target/product/<target>/testcases/<LOCAL_MODULE>/<arch>/<LOCAL_MODULE>
+
+e.g. ${OUT}/target/product/arm64-generic/testcases/hello_world_test/arm/hello_world_test
+& ${OUT}/target/product/arm64-generic/testcases/hello_world_test/arm64/hello_world_test
+
+Note: if the native ABI type of device is 64bit, such as angler, bullhead etc,
+the directory name will be suffixed with `64`.
+
+Please also note that currently the native tests in APCT does not support use of
+dynamically linked libraries, which means that the dependencies needs to be
+statically linked into the test binary.
+
+## Source code
+
+[Latest source code](../../tests/example/native/HelloWorldTest.cpp)
+
+Annotated source code is listed below:
+
+```c++
+#include <gtest/gtest.h>
+```
+
+Header file include for gtest. Note that the include file dependency is
+automatically resolved by using `BUILD_NATIVE_TEST` in the makefile
+
+```c++
+#include <stdio.h>
+
+TEST(HelloWorldTest, PrintHelloWorld) {
+ printf("Hello, World!");
+}
+```
+
+gtests are written by using `TEST` macro: the first parameter is the test case
+name, and the second is test name; together with test binary name, they form the
+hierarchy below when visualized in result dashboard:
+
+```
+<test binary 1>
+| \-- <test case 1>
+| | \-- <test 1>
+| | \-- <test 2>
+| | \-- ...
+| \-- <test case 2>
+| | \-- <test 1>
+| | \-- ...
+| \-- ...
+<test binary 2>
+|
+...
+```
+
+For more information on writing tests with gtest, see its documentation:
+
+* https://github.com/google/googletest/blob/master/googletest/docs/Primer.md
+
+## Test Config
+
+In order to simplify test execution, you also need write a test configuration
+file for Android's test harness, [TradeFederation](https://source.android.com/devices/tech/test_infra/tradefed/).
+
+The test configuration can specify special device setup options and default
+arguments to supply the test class.
+
+[LATEST TEST CONFIG](../../tests/example/native/AndroidTest.xml)
+
+A snapshot is included here for convenience:
+```xml
+<configuration description="Config for APCT native hello world test cases">
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="hello_world_test->/data/local/tmp/hello_world_test" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="hello_world_test" />
+ <option name="runtime-hint" value="8m" />
+ </test>
+</configuration>
+```
+
+Some select remarks on the test configuration file:
+
+```xml
+<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="hello_world_test->/data/local/tmp/hello_world_test" />
+</target_preparer>
+```
+
+This tells TradeFederation to install the hello_world_test binary onto the target
+device using a specified target_preparer. There are many target preparers
+available to developers in TradeFederation and these can be used to ensure
+the device is setup properly prior to test execution.
+
+```xml
+<test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="hello_world_test" />
+ <option name="runtime-hint" value="8m" />
+</test>
+```
+
+This specifies the TradeFederation test class to use to execute the test and
+passes in the native test location that it was installed.
+
+Look here for more information on [Test Module Configs](../test-config.md)
+
+## Build & Test Locally
+
+Follow these [Instructions](../native.md) to build and execute your test
diff --git a/docs/development/native.md b/docs/development/native.md
new file mode 100644
index 0000000..7f9811c
--- /dev/null
+++ b/docs/development/native.md
@@ -0,0 +1,43 @@
+# Native Tests
+
+As mentioned earlier, native tests are typically used for exercising HAL or
+interacting directly with lower level system services, and to leverage
+continuous testing service, native tests should be built with
+[gtest](https://github.com/google/googletests) framework.
+
+Here are some general instructions:
+
+1. See sample native test module setup at: `libs/hwui/unit_tests`
+1. Test module makefile should use `BUILD_NATIVE_TEST` build rule so that
+gtest dependencies are included automatically
+1. Write a [test config](../test-config.md)
+1. Build the test module with `mmm` or `mma` (depends on if it's an
+incremental or full build), e.g.:
+
+ ```shell
+ make hwui_unit_tests -j
+ ```
+1. Automatic installation and run with the TradeFederation test harness:
+
+ ```
+ make tradefed-all -j
+ tradefed.sh run template/local_min --template:map test=hwui_unit_tests
+ ```
+1. Manually Install and Run:
+ 1. Push the generated test binary onto device:
+
+ ```shell
+ adb push ${OUT}/data/nativetest/hwui_unit_tests/hwui_unit_tests \
+ /data/nativetest/hwui_unit_tests/hwui_unit_tests
+ ```
+ 1. Execute the test by invoking test binary on device:
+
+ ```shell
+ adb shell /data/nativetest/hwui_unit_tests/hwui_unit_tests
+ ```
+
+ This launches the native test. You can also add `--help` parameter to your test
+ binary to find out more about the different ways to customize test execution.
+ You can also check out the gtest advanced guide for more parameters usage:
+
+ * https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md
diff --git a/docs/development/test-config.md b/docs/development/test-config.md
new file mode 100644
index 0000000..1743020
--- /dev/null
+++ b/docs/development/test-config.md
@@ -0,0 +1,155 @@
+## Test Module Config
+
+Some test modules may require customized setup and tear down steps that cannot
+be performed within test case itself. Typical examples may include:
+
+* install other apks (in addition to the test apk)
+* push some files to the device
+* run commands (e.g. adb shell pm ...)
+
+In the past, component teams usually resort to writing a host side test to
+perform such tasks, which requires understanding of TradeFederation harness
+and typically increases the complexity of a test module .
+
+Borrowing from CTS, we introduced the concept of test module config to support
+such tasks, the common tasks list above can be achieved by just a few lines of
+config. For maximum flexibility, you can even implement your own target
+preparer, as defined by [ITargetPreparer]
+(https://source.android.com/reference/com/android/tradefed/targetprep/ITargetPreparer.html)
+or [ITargetCleaner]
+(https://source.android.com/reference/com/android/tradefed/targetprep/ITargetCleaner.html),
+and configure them to use in your own test module config.
+
+A test module config for a test module is a required XML file added to the top
+level module source folder, named ‘AndroidTest.xml’. The XML follows the format
+of a configuration file used by TradeFederation test automation harness.
+Currently the main tags handled via the test module configs are the “target_preparer” and
+"test" tags.
+
+## Target Preparers
+A “target_preparer” tag, as the name suggests, defines a target preparer
+(see [ITargetPreparer](https://source.android.com/reference/com/android/tradefed/targetprep/ITargetPreparer.html))
+that offers a setup method, which gets called before the test module is executed
+for testing; and if the class referenced in the “target_preparer” tag also
+implements
+[ITargetCleaner](https://source.android.com/reference/com/android/tradefed/targetprep/ITargetCleaner.html),
+its teardown method will be invoked after the test module has finished.
+
+To use the built-in common module config, add a new file ‘AndroidTest.xml’ at
+the top level folder for your test module, and populate it with the following
+content:
+
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<!-- [insert standard AOSP copyright here] -->
+<configuration description="Test module config for Foo">
+<!-- insert options here -->
+</configuration>
+```
+
+As an example, we can add the following option tags (at the “insert” comment
+above):
+
+```xml
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="settings put secure accessibility_enabled 1" />
+ <option name="teardown-command" value="settings put secure accessibility_enabled 0" />
+ </target_preparer>
+```
+
+The options will configure the test harness to:
+
+1. before test module is invoked, execute shell command “settings put secure
+ accessibility_enabled 1” on device
+2. after test module is finished, execute shell command “settings put secure
+ accessibility_enabled 0”
+
+In this particular example, accessibility is enabled/disabled before/after the
+test module execution, respectively. With a simple example demonstrated, it’s
+necessary to cover more details on how the “option” tag is used. As shown above,
+the tag can have two attributes: name, value. The name attribute indicated the
+name of the option, and is further broken down into two parts separated by a
+colon: short name for the preparer, and the actual option name offered by the
+preparer. The exact purpose of value field is dependent on how preparer defined
+the option: it can be a string, a number, a boolean, or even a file path etc. In
+the example above, name “run-command:run-command” means that we are setting
+value for the option “run-command” defined by a target preparer with short name
+“run-command”; and name “run-command:teardown-command” means that we are setting
+value for the option “teardown-command” also defined by the same target preparer
+with short name “run-command”. Here's a summary of the 3 common target
+preparers:
+
+* class name: [PushFilePreparer](https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/targetprep/PushFilePreparer.java)
+
+ * **short name**: push-file
+ * **function**: pushes arbitrary files under test case folder into
+ destination on device
+ * **notes**:
+ * this preparer can push from folder to folder, or file to file; that
+ is, you cannot push a file under a folder on device: you must
+ specify the destination filename under that folder as well
+ * **options**:
+ * **push:** A push-spec, formatted as
+ '`/path/to/srcfile.txt->/path/to/destfile.txt`' or
+ '`/path/to/srcfile.txt->/path/to/destdir/`'. May be repeated
+ This path may be relative to the test module directory or the out
+ directory itself.
+ * **post-push: **A command to run on the device (with \``adb shell
+ <your command>`\`) after all pushes have been attempted. Typical use
+ case would be using chmod for permissions
+
+* class name: [InstallApkSetup](https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/targetprep/InstallApkSetup.java)
+
+ * **short name:**install-apk
+ * **function:** pushes arbitrary apk files under into destination on
+ device
+ * **options:**
+ * **test-file-name:** the name of the apk to be installed on to
+ device.
+ * **install-arg:** Additional arguments to be passed to the pm install
+ command, including leading dash, e.g. “-d". May be repeated
+
+* class name: [RunCommandTargetPreparer](https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/targetprep/RunCommandTargetPreparer.java)
+
+ * **short name:** run-command
+ * **function:** executes arbitrary shell commands before or after test
+ module execution
+ * **options:**
+ * **run-command:**adb shell command to run. May be repeated
+ * **teardown-command:**adb shell command to run during teardown phase.
+ May be repeated
+
+## Test Class
+A test class is the TradeFederation class to use to execute the test.
+
+```xml
+<test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="android.test.example.helloworld"/>
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+</test>
+```
+
+Here are 3 common test classes:
+
+* class name: [GTest](https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/testtype/GTest.java)
+
+ * **short name:** gtest
+ * **function:** A Test that runs a native test package on given device.
+ * **options:**
+ * **native-test-device-path:**The path on the device where native tests are located.
+
+* class name: [InstrumentationTest](https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/testtype/InstrumentationTest.java)
+
+ * **short name:** instrumentation
+ * **function:** A Test that runs an instrumentation test package on given device
+ * **options:**
+ * **package:**The manifest package name of the Android test application to run.
+ * **class:**The test class name to run.
+ * **method:**The test method name to run.
+
+* class name: [AndroidJUnitTest](https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/testtype/AndroidJUnitTest.java)
+
+ * **function:** A Test that runs an instrumentation test package on given
+ device using the android.support.test.runner.AndroidJUnitRunner
+ This is the main way to execute an instrumentation test.
+
diff --git a/docs/imgs/ape_fwk_all.png b/docs/imgs/ape_fwk_all.png
new file mode 100644
index 0000000..37f9af2
--- /dev/null
+++ b/docs/imgs/ape_fwk_all.png
Binary files differ
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..55469fd
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,8 @@
+# Overview
+
+Welcome to Android Platform Testing!
+
+This site is geared toward Android platform developers, and provides:
+
+* [Introduction to Android platform testing](basics/index.md)
+* [Development workflow](development/index.md)
\ No newline at end of file
diff --git a/docs/navbar.md b/docs/navbar.md
new file mode 100644
index 0000000..9d974ca
--- /dev/null
+++ b/docs/navbar.md
@@ -0,0 +1,10 @@
+* [Overview](index.md)
+* [Basics](basics/index.md)
+* [Test Development Workflow](development/index.md)
+ * [Test Configuration Files](development/test-config.md)
+ * [Instrumentation Tests](development/instrumentation.md)
+ * [Self-Instrumenting Tests: A Complete Example](development/instr-self-e2e.md)
+ * [Instrumentation Targeting an Application: A Complete Example](development/instr-app-e2e.md)
+ * [Native Tests](development/native.md)
+ * [Adding a New Native Test: A Complete Example](development/native-func-e2e.md)
+ * [Native Metric Tests](development/metrics.md)
\ No newline at end of file
diff --git a/libraries/app-helpers/auto/src/android/platform/test/helpers/auto/AbstractAutoUiProviderHelper.java b/libraries/app-helpers/auto/src/android/platform/test/helpers/auto/AbstractAutoUiProviderHelper.java
index 40b14e4..bf35408 100644
--- a/libraries/app-helpers/auto/src/android/platform/test/helpers/auto/AbstractAutoUiProviderHelper.java
+++ b/libraries/app-helpers/auto/src/android/platform/test/helpers/auto/AbstractAutoUiProviderHelper.java
@@ -20,21 +20,28 @@
import android.app.Instrumentation;
/**
- * AbstractAutoUiProviderHelper used to open menu in different applications like Dial,
+ * AbstractAutoUiProviderHelper used to open drawer in different applications like Dialer,
* Bluetooth Media and Local Media player.
*/
public abstract class AbstractAutoUiProviderHelper extends AbstractStandardAppHelper {
public AbstractAutoUiProviderHelper(Instrumentation instr) {
- super(instr);
- }
+ super(instr);
+ }
/**
- * Setup expectations: The applications like dial,Media should be open.
+ * Setup expectations: The applications like Dialer,Media should be open.
*
- * This method is used to open menu in different applications like Dial and Media.
+ * This method is used to open drawer in different applications like Dialer and Media.
*/
- public abstract void openMenu();
+ public abstract void openDrawer();
+
+ /**
+ * Setup expectations: The drawer in applications like Dialer,Media should be open.
+ *
+ * This method is used to close drawer in different applications like Dialer and Media.
+ */
+ public abstract void closeDrawer();
}
diff --git a/libraries/app-helpers/clockwork/Android.mk b/libraries/app-helpers/clockwork/Android.mk
index abb2d44..752e74f 100644
--- a/libraries/app-helpers/clockwork/Android.mk
+++ b/libraries/app-helpers/clockwork/Android.mk
@@ -18,6 +18,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := clockwork-app-helper-base
LOCAL_STATIC_JAVA_LIBRARIES := app-helpers-common
+LOCAL_JAVA_LIBRARIES := ub-uiautomator
LOCAL_SRC_FILES := $(call all-java-files-under, src)
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractAgendaHelper.java b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractAgendaHelper.java
new file mode 100644
index 0000000..46e2b2a
--- /dev/null
+++ b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractAgendaHelper.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+import android.support.test.uiautomator.Direction;
+
+public abstract class AbstractAgendaHelper extends AbstractStandardAppHelper {
+
+ public AbstractAgendaHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Agenda app is open
+ *
+ * Scroll in direction
+ * @param d direction to scroll
+ * @return boolean scroll successful or not
+ */
+ public abstract boolean scroll(Direction d);
+}
diff --git a/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractRemindersHelper.java b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractRemindersHelper.java
new file mode 100644
index 0000000..a911b16
--- /dev/null
+++ b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractRemindersHelper.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+
+public abstract class AbstractRemindersHelper extends AbstractStandardAppHelper {
+
+ public AbstractRemindersHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Reminders app is open
+ *
+ * Create reminder
+ */
+ public abstract void createReminder();
+
+ /**
+ * Setup expectation: Reminders app is open
+ *
+ * Delete reminder
+ */
+ public abstract void deleteReminder();
+}
diff --git a/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractTranslateHelper.java b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractTranslateHelper.java
new file mode 100644
index 0000000..b12e55e
--- /dev/null
+++ b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractTranslateHelper.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+
+public abstract class AbstractTranslateHelper extends AbstractStandardAppHelper {
+
+ public AbstractTranslateHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Translate app is open
+ *
+ * Inject a voice file for translation
+ */
+ public abstract void translate(String filePath);
+
+ /**
+ * Setup expectation: Translation is showing
+ *
+ * Validate the on-screen translation
+ */
+ public abstract void validate(String expectedTranslation);
+
+ /**
+ * Setup expectation: Translate app is open
+ *
+ * Change the selected languages
+ */
+ public abstract void changeLanguages(String source, String target);
+}
diff --git a/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractVoiceHelper.java b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractVoiceHelper.java
new file mode 100644
index 0000000..76de922
--- /dev/null
+++ b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractVoiceHelper.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+import android.support.test.uiautomator.BySelector;
+
+public abstract class AbstractVoiceHelper extends AbstractStandardAppHelper {
+
+ public AbstractVoiceHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Microphone is open
+ *
+ * Inject audio file
+ */
+ public abstract void inject(String filePath);
+
+ /**
+ * Setup expectation: Some result is showing
+ *
+ * Validate on-screen result
+ */
+ public abstract void validate(BySelector itemToValidate);
+}
diff --git a/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractWatchFacePickerHelper.java b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractWatchFacePickerHelper.java
new file mode 100644
index 0000000..d466c14
--- /dev/null
+++ b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractWatchFacePickerHelper.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+
+public abstract class AbstractWatchFacePickerHelper extends AbstractStandardAppHelper {
+
+ public AbstractWatchFacePickerHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Watch face picker is open
+ *
+ * Select watch face from favorites or add more watch faces
+ */
+ public abstract void selectWatchFace(String watchFaceName);
+
+
+}
diff --git a/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractWeatherHelper.java b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractWeatherHelper.java
new file mode 100644
index 0000000..60c5f06
--- /dev/null
+++ b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractWeatherHelper.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+import android.support.test.uiautomator.Direction;
+
+public abstract class AbstractWeatherHelper extends AbstractStandardAppHelper {
+
+ public AbstractWeatherHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Weather app is open
+ *
+ * Scroll in direction
+ * @param d direction to scroll
+ * @return boolean scroll successful or not
+ */
+ public abstract boolean scroll(Direction d);
+}
diff --git a/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractYourFeedHelper.java b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractYourFeedHelper.java
new file mode 100644
index 0000000..d55e9e1
--- /dev/null
+++ b/libraries/app-helpers/clockwork/src/android/platform/test/helpers/clockwork/AbstractYourFeedHelper.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+import android.support.test.uiautomator.Direction;
+
+public abstract class AbstractYourFeedHelper extends AbstractStandardAppHelper {
+
+ public AbstractYourFeedHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Your Feed is open
+ *
+ * Scroll in direction
+ * @param d direction to scroll
+ * @return boolean scroll successful or not
+ */
+ public abstract boolean scroll(Direction d);
+}
diff --git a/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractAlarmHelper.java b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractAlarmHelper.java
new file mode 100644
index 0000000..3929899
--- /dev/null
+++ b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractAlarmHelper.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+
+public abstract class AbstractAlarmHelper extends AbstractStandardAppHelper {
+
+ public AbstractAlarmHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Alarm app is open
+ *
+ * Create alarm
+ */
+ public abstract void createAlarm();
+
+ /**
+ * Setup expectation: Alarm app is open
+ *
+ * Delete alarm
+ */
+ public abstract void deleteAlarm();
+
+ /**
+ * Setup expectation: Alarm is ringing
+ *
+ * Dismiss alarm
+ */
+ public abstract void dismissAlarm();
+}
diff --git a/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractContactsHelper.java b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractContactsHelper.java
new file mode 100644
index 0000000..2e2da98
--- /dev/null
+++ b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractContactsHelper.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+
+public abstract class AbstractContactsHelper extends AbstractStandardAppHelper {
+
+ public AbstractContactsHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Contacts app is open
+ *
+ * Scroll to contact name and click
+ */
+ public abstract void selectContact(String contactName);
+
+ /**
+ * Setup expectation: Contact is open
+ *
+ * Click the call button
+ */
+ public abstract void call();
+
+ /**
+ * Setup expectation: Contact is open
+ *
+ * Click text button, send text message from quick reply list
+ */
+ public abstract void sendText(String quickReplyText);
+}
diff --git a/libraries/app-helpers/handheld/src/android/platform/test/helpers/handheld/AbstractMapsHelper.java b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractMapsHelper.java
similarity index 100%
rename from libraries/app-helpers/handheld/src/android/platform/test/helpers/handheld/AbstractMapsHelper.java
rename to libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractMapsHelper.java
diff --git a/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractPhoneHelper.java b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractPhoneHelper.java
new file mode 100644
index 0000000..fae527f
--- /dev/null
+++ b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractPhoneHelper.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+
+public abstract class AbstractPhoneHelper extends AbstractStandardAppHelper {
+
+ public AbstractPhoneHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Phone app is open
+ *
+ * Go to number pad and dial number
+ */
+ public abstract void dialNumber(String number);
+
+ /**
+ * Setup expectation: Number is being called
+ *
+ * Hang up
+ */
+ public abstract void hangUp();
+}
diff --git a/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractPlayMusicHelper.java b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractPlayMusicHelper.java
index 7002053..bd3be0f 100644
--- a/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractPlayMusicHelper.java
+++ b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractPlayMusicHelper.java
@@ -26,7 +26,7 @@
/**
* Setup expectations: PlayMusic is open and the navigation bar is visible.
- *
+ * <br/>
* This method will open the navigation bar, press "My Library," and navigate to the songs tab.
* This method blocks until the process is complete.
*/
@@ -34,7 +34,7 @@
/**
* Setup expectations: PlayMusic is open and the navigation bar is visible.
- *
+ * <br/>
* This method will open the navigation bar, press "Home".
* This method blocks until the process is complete.
*/
@@ -43,7 +43,7 @@
/**
* Setup expectations: PlayMusic is open and in Listen Now.
- *
+ * <br/>
* This method will open the first available thumbnail and play the first visible radio.
* This method blocks until the process is complete.
*/
@@ -60,43 +60,55 @@
/**
* Setup expectations: PlayMusic is open and the navigation bar is visible.
- *
+ * <br/>
* This method will navigate to the Albums tab, select the album, and then select the song. The
* method will block until the song is playing.
*/
public abstract void selectSong(String album, String song);
/**
+ * Setup expectations: PlayMusic is open and the navigation bar is visible.
+ * <br/>
+ * This method will navigate to the Library tab, select the Album tab, and then select the
+ * album. The method will block until the song is playing.
+ */
+ public void selectAlbum(String album) {
+ throw new UnsupportedOperationException(
+ "Cannot select a single album as playback for Google Play Music.");
+ }
+
+
+ /**
* Setup expectations: PlayMusic is open with a song playing.
- *
+ * <br/>
* This method will pause the song and block until the song is paused.
*/
public abstract void pauseSong();
/**
* Setup expectations: PlayMusic is open with a song paused.
- *
+ * <br/>
* This method will play the song and block until the song is playing.
*/
public abstract void playSong();
/**
* Setup expectations: PlayMusic is open with a song playing the controls minimized.
- *
+ * <br/>
* This method will press the header and block until the song is expanded.
*/
public abstract void expandMediaControls();
/**
* Setup expectations: PlayMusic is open and on the Songs library tab
- *
+ * <br/>
* This method will press the "Shuffle All" button and block until the song is playing.
*/
public abstract void pressShuffleAll();
/**
* Setup expectations: PlayMusic is open with a song open and expanded.
- *
+ * <br/>
* This method will press the repeat button and cycle to the next state. Unfortunately, the
* limitations of the Accessibility for Play Music means that we cannot tell what state it
* currently is in.
diff --git a/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractStopwatchHelper.java b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractStopwatchHelper.java
new file mode 100644
index 0000000..ba22bc5
--- /dev/null
+++ b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractStopwatchHelper.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+
+public abstract class AbstractStopwatchHelper extends AbstractStandardAppHelper {
+
+ public AbstractStopwatchHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Stopwatch app is open
+ *
+ * Start the stopwatch
+ */
+ public abstract void start();
+
+ /**
+ * Setup expectation: Stopwatch app is open
+ *
+ * Stop the stopwatch
+ */
+ public abstract void stop();
+
+ /**
+ * Setup expectation: Stopwatch app is open
+ *
+ * Reset the stopwatch
+ */
+ public abstract void reset();
+}
diff --git a/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractTimerHelper.java b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractTimerHelper.java
new file mode 100644
index 0000000..f445c8d
--- /dev/null
+++ b/libraries/app-helpers/common/src/android/platform/test/helpers/common/AbstractTimerHelper.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+
+public abstract class AbstractTimerHelper extends AbstractStandardAppHelper {
+
+ public AbstractTimerHelper(Instrumentation instr) {
+ super(instr);
+ }
+
+ /**
+ * Setup expectation: Timer app is open on initial screen
+ *
+ * Create a new timer
+ */
+ public abstract void createTimer();
+
+ /**
+ * Setup expectation: Timer is running
+ *
+ * Pause timer
+ */
+ public abstract void pauseTimer();
+
+ /**
+ * Setup expectation: Timer is paused
+ *
+ * Resume timer
+ */
+ public abstract void resumeTimer();
+
+ /**
+ * Setup expectation: Timer is paused
+ *
+ * Reset timer
+ */
+ public abstract void resetTimer();
+
+ /**
+ * Setup expectation: Timer is paused
+ *
+ * Dismiss timer
+ */
+ public abstract void dismissTimer();
+
+ /**
+ * Setup expectation: Timer app is open on initial screen
+ *
+ * Delete timer from list
+ */
+ public abstract void deleteTimer();
+}
diff --git a/libraries/app-helpers/handheld/src/android/platform/test/helpers/handheld/AbstractGoogleCameraHelper.java b/libraries/app-helpers/handheld/src/android/platform/test/helpers/handheld/AbstractGoogleCameraHelper.java
index 7b8e7a4..60c6582 100644
--- a/libraries/app-helpers/handheld/src/android/platform/test/helpers/handheld/AbstractGoogleCameraHelper.java
+++ b/libraries/app-helpers/handheld/src/android/platform/test/helpers/handheld/AbstractGoogleCameraHelper.java
@@ -19,205 +19,12 @@
import android.app.Instrumentation;
import android.support.test.uiautomator.Direction;
-public abstract class AbstractGoogleCameraHelper extends AbstractStandardAppHelper {
- public static final int HDR_MODE_AUTO = -1;
- public static final int HDR_MODE_OFF = 0;
- public static final int HDR_MODE_ON = 1;
-
- public static final int VIDEO_SD_480 = -2;
- public static final int VIDEO_HD_720 = -1;
- public static final int VIDEO_HD_1080 = 0;
- public static final int VIDEO_4K_MODE_ON = 1;
-
- public static final int VIDEO_30FPS = 0;
- public static final int VIDEO_60FPS = 1;
-
- public static final int HFR_MODE_OFF = 0;
- public static final int HFR_MODE_120_FPS = 1;
- public static final int HFR_MODE_240_FPS = 2;
-
- public static final int FLASH_AUTO = -1;
- public static final int FLASH_OFF = 0;
- public static final int FLASH_ON = 1;
- public static final int NUM_FLASH_MODES = 3;
-
+/**
+ * This class should no longer be extended. Instead, use the {@code IGoogleCameraHelper} interface.
+ */
+@Deprecated public abstract class AbstractGoogleCameraHelper extends AbstractStandardAppHelper
+ implements IGoogleCameraHelper{
public AbstractGoogleCameraHelper(Instrumentation instr) {
super(instr);
}
-
- /**
- * Setup expectations: GoogleCamera is open and idle in video mode.
- *
- * This method will change to camera mode and block until the transition is complete.
- */
- public abstract void goToCameraMode();
-
- /**
- * Setup expectations: GoogleCamera is open and idle in camera mode.
- *
- * This method will change to video mode and block until the transition is complete.
- */
- public abstract void goToVideoMode();
-
- /**
- * Setup expectations: GoogleCamera is open and idle in either camera/video mode.
- *
- * This method will change to back camera and block until the transition is complete.
- */
- public abstract void goToBackCamera();
-
- /**
- * Setup expectations: GoogleCamera is open and idle in either camera/video mode.
- *
- * This method will change to front camera and block until the transition is complete.
- */
- public abstract void goToFrontCamera();
-
- /**
- * Setup expectation: in Camera mode with the capture button present.
- *
- * This method will capture a photo and block until the transaction is complete.
- */
- public abstract void capturePhoto();
-
- /**
- * Setup expectation: in Video mode with the capture button present.
- *
- * This method will capture a video of length timeInMs and block until the transaction is
- * complete.
- * @param time duration of video in milliseconds
- */
- public abstract void captureVideo(long time);
-
- /**
- * Setup expectation:
- * 1. in Video mode with the capture button present.
- * 2. videoTime > snapshotStartTime
- *
- * This method will capture a video of length videoTime, and take a picture at snapshotStartTime.
- * It will block until the the video is captured and the device is again idle in video mode.
- * @param time duration of video in milliseconds
- */
- public abstract void snapshotVideo(long videoTime, long snapshotStartTime);
-
- /**
- * Setup expectation: GoogleCamera is open and idle in camera mode.
- *
- * This method will set HDR to one of the following:
- * - on (mode == HDR_MODE_ON)
- * - auto (mode == HDR_MODE_AUTO)
- * - off (mode == HDR_MODE_OFF)
- * @param mode the integer value of the mode denoted above.
- */
- public abstract void setHdrMode(int mode);
-
- /**
- * Setup expectation: GoogleCamera is open and idle in video mode.
- *
- * This method will set 4K mode to one of the following:
- * - on (mode == VIDEO_4K_MODE_ON)
- * - off (mode != VIDEO_4K_MODE_ON)
- * @param mode the integer value of the mode denoted above.
- */
- public abstract void set4KMode(int mode);
-
- /**
- * Setup expectation: GoogleCamera is open and idle in video mode.
- *
- * This method will set HFR mode to one of the following:
- * - off (mode == HFR_MODE_OFF)
- * - 120 fps (mode == HFR_MODE_120_FPS)
- * - 240 fps (mode == HFR_MODE_240_FPS)
- * @param mode the integer value of the mode denoted above.
- */
- public abstract void setHFRMode(int mode);
-
- /**
- *
- * Setup expectations: GoogleCamera is open and idle in either camera/video mode.
- *
- * This method will set EIS to on(true), or off(false).
- * @param mode the boolean value of the mode denoted above.
- */
- public abstract void setEIS(boolean mode);
-
- /**
- * Setup expectation: GoogleCamera is open and idle in either camera/video mode.
- *
- * This method will set front video capture resolution to one of the following:
- * - SD 480p (mode == VIDEO_SD_480)
- * - HD 720p (mode == VIDEO_HD_720)
- * - HD 1080p (mode == VIDEO_HD_1080)
- * - UHD 4K (mode == VIDEO_4K_MODE_ON)
- * @param mode the integer value of the mode denoted above.
- */
- public abstract void selectFrontVideoResolution(int mode);
-
- /**
- * Setup expectation: GoogleCamera is open and idle in either camera/video mode.
- *
- * This method will set back video capture resolution to one of the following:
- * - SD 480p (mode == VIDEO_SD_480)
- * - HD 720p (mode == VIDEO_HD_720)
- * - HD 1080p (mode == VIDEO_HD_1080)
- * - UHD 4K (mode == VIDEO_4K_MODE_ON)
- * @param mode the integer value of the mode denoted above.
- */
- public abstract void selectBackVideoResolution(int mode);
-
- /**
- *
- * Setup expectations: GoogleCamera is open, idle, in video mode,
- * using back camera, and not in 4k mode
- *
- * This method will set video capture framerate to one of the following:
- * - 30 fps (mode == VIDEO_30FPS)
- * - 60 fps (mode == VIDEO_60FPS)
- * @param mode the integer value of the mode denoted above.
- */
- public abstract void setFrameRate(int mode);
-
- /**
- * Setup expectation: GoogleCamera is open and idle in camera or video mode.
- *
- * This method will set flash to one of the following:
- * - on (mode == FLASH_ON)
- * - auto (mode == FLASH_AUTO)
- * - off (mode == FLASH_OFF)
- * @param mode the integer value of the mode denoted above.
- */
- public abstract void setFlashMode(int mode);
-
- /**
- * Setup expectation: in Camera mode with the capture button present.
- *
- * This method will block until the capture button is enabled for pressing.
- */
- public abstract void waitForCameraShutterEnabled();
-
- /**
- * Setup expectation: in Video mode with the capture button present.
- *
- * This method will block until the capture button is enabled for pressing.
- */
- public abstract void waitForVideoShutterEnabled();
-
- /**
- * Temporary function.
- */
- public abstract String openWithShutterTimeString();
-
- /**
- * Setup expectations: in Camera mode or in Video mode
- */
- public abstract void goToAlbum();
-
- /**
- * Setup expectations:
- * 1. in album view
- * 2. scroll direction is either LEFT or RIGHT
- *
- * @param direction scroll direction, either LEFT or RIGHT
- */
- public abstract void scrollAlbum(Direction direction);
}
diff --git a/libraries/app-helpers/handheld/src/android/platform/test/helpers/handheld/IGoogleCameraHelper.java b/libraries/app-helpers/handheld/src/android/platform/test/helpers/handheld/IGoogleCameraHelper.java
new file mode 100644
index 0000000..aeafcbe
--- /dev/null
+++ b/libraries/app-helpers/handheld/src/android/platform/test/helpers/handheld/IGoogleCameraHelper.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 android.platform.test.helpers;
+
+import android.app.Instrumentation;
+import android.support.test.uiautomator.Direction;
+
+public interface IGoogleCameraHelper extends IStandardAppHelper {
+ public static final int HDR_MODE_AUTO = -1;
+ public static final int HDR_MODE_OFF = 0;
+ public static final int HDR_MODE_ON = 1;
+
+ public static final int VIDEO_SD_480 = -2;
+ public static final int VIDEO_HD_720 = -1;
+ public static final int VIDEO_HD_1080 = 0;
+ public static final int VIDEO_4K_MODE_ON = 1;
+
+ public static final int VIDEO_30FPS = 0;
+ public static final int VIDEO_60FPS = 1;
+
+ public static final int HFR_MODE_OFF = 0;
+ public static final int HFR_MODE_120_FPS = 1;
+ public static final int HFR_MODE_240_FPS = 2;
+
+ public static final int FLASH_AUTO = -1;
+ public static final int FLASH_OFF = 0;
+ public static final int FLASH_ON = 1;
+ public static final int NUM_FLASH_MODES = 3;
+
+ /**
+ * Setup expectations: GoogleCamera is open and idle in video mode.
+ *
+ * This method will change to camera mode and block until the transition is complete.
+ */
+ public void goToCameraMode();
+
+ /**
+ * Setup expectations: GoogleCamera is open and idle in camera mode.
+ *
+ * This method will change to video mode and block until the transition is complete.
+ */
+ public void goToVideoMode();
+
+ /**
+ * Setup expectations: GoogleCamera is open and idle in either camera/video mode.
+ *
+ * This method will change to back camera and block until the transition is complete.
+ */
+ public void goToBackCamera();
+
+ /**
+ * Setup expectations: GoogleCamera is open and idle in either camera/video mode.
+ *
+ * This method will change to front camera and block until the transition is complete.
+ */
+ public void goToFrontCamera();
+
+ /**
+ * Setup expectation: in Camera mode with the capture button present.
+ *
+ * This method will capture a photo and block until the transaction is complete.
+ */
+ public void capturePhoto();
+
+ /**
+ * Setup expectation: in Video mode with the capture button present.
+ *
+ * This method will capture a video of length timeInMs and block until the transaction is
+ * complete.
+ * @param time duration of video in milliseconds
+ */
+ public void captureVideo(long time);
+
+ /**
+ * Setup expectation:
+ * 1. in Video mode with the capture button present.
+ * 2. videoTime > snapshotStartTime
+ *
+ * This method will capture a video of length videoTime, and take a picture at snapshotStartTime.
+ * It will block until the the video is captured and the device is again idle in video mode.
+ * @param time duration of video in milliseconds
+ */
+ public void snapshotVideo(long videoTime, long snapshotStartTime);
+
+ /**
+ * Setup expectation: GoogleCamera is open and idle in camera mode.
+ *
+ * This method will set HDR to one of the following:
+ * - on (mode == HDR_MODE_ON)
+ * - auto (mode == HDR_MODE_AUTO)
+ * - off (mode == HDR_MODE_OFF)
+ * @param mode the integer value of the mode denoted above.
+ */
+ public void setHdrMode(int mode);
+
+ /**
+ * Setup expectation: GoogleCamera is open and idle in video mode.
+ *
+ * This method will set 4K mode to one of the following:
+ * - on (mode == VIDEO_4K_MODE_ON)
+ * - off (mode != VIDEO_4K_MODE_ON)
+ * @param mode the integer value of the mode denoted above.
+ */
+ public void set4KMode(int mode);
+
+ /**
+ * Setup expectation: GoogleCamera is open and idle in video mode.
+ *
+ * This method will set HFR mode to one of the following:
+ * - off (mode == HFR_MODE_OFF)
+ * - 120 fps (mode == HFR_MODE_120_FPS)
+ * - 240 fps (mode == HFR_MODE_240_FPS)
+ * @param mode the integer value of the mode denoted above.
+ */
+ public void setHFRMode(int mode);
+
+ /**
+ *
+ * Setup expectations: GoogleCamera is open and idle in either camera/video mode.
+ *
+ * This method will set EIS to on(true), or off(false).
+ * @param mode the boolean value of the mode denoted above.
+ */
+ public void setEIS(boolean mode);
+
+ /**
+ * Setup expectation: GoogleCamera is open and idle in either camera/video mode.
+ *
+ * This method will set front video capture resolution to one of the following:
+ * - SD 480p (mode == VIDEO_SD_480)
+ * - HD 720p (mode == VIDEO_HD_720)
+ * - HD 1080p (mode == VIDEO_HD_1080)
+ * - UHD 4K (mode == VIDEO_4K_MODE_ON)
+ * @param mode the integer value of the mode denoted above.
+ */
+ public void selectFrontVideoResolution(int mode);
+
+ /**
+ * Setup expectation: GoogleCamera is open and idle in either camera/video mode.
+ *
+ * This method will set back video capture resolution to one of the following:
+ * - SD 480p (mode == VIDEO_SD_480)
+ * - HD 720p (mode == VIDEO_HD_720)
+ * - HD 1080p (mode == VIDEO_HD_1080)
+ * - UHD 4K (mode == VIDEO_4K_MODE_ON)
+ * @param mode the integer value of the mode denoted above.
+ */
+ public void selectBackVideoResolution(int mode);
+
+ /**
+ *
+ * Setup expectations: GoogleCamera is open, idle, in video mode,
+ * using back camera, and not in 4k mode
+ *
+ * This method will set video capture framerate to one of the following:
+ * - 30 fps (mode == VIDEO_30FPS)
+ * - 60 fps (mode == VIDEO_60FPS)
+ * @param mode the integer value of the mode denoted above.
+ */
+ public void setFrameRate(int mode);
+
+ /**
+ * Setup expectation: GoogleCamera is open and idle in camera or video mode.
+ *
+ * This method will set flash to one of the following:
+ * - on (mode == FLASH_ON)
+ * - auto (mode == FLASH_AUTO)
+ * - off (mode == FLASH_OFF)
+ * @param mode the integer value of the mode denoted above.
+ */
+ public void setFlashMode(int mode);
+
+ /**
+ * Setup expectation: in Camera mode with the capture button present.
+ *
+ * This method will block until the capture button is enabled for pressing.
+ */
+ public void waitForCameraShutterEnabled();
+
+ /**
+ * Setup expectation: in Video mode with the capture button present.
+ *
+ * This method will block until the capture button is enabled for pressing.
+ */
+ public void waitForVideoShutterEnabled();
+
+ /**
+ * Temporary function.
+ */
+ public String openWithShutterTimeString();
+
+ /**
+ * Setup expectations: in Camera mode or in Video mode
+ */
+ public void goToAlbum();
+
+ /**
+ * Setup expectations:
+ * 1. in album view
+ * 2. scroll direction is either LEFT or RIGHT
+ *
+ * @param direction scroll direction, either LEFT or RIGHT
+ */
+ public void scrollAlbum(Direction direction);
+}
diff --git a/libraries/aupt-lib/src/android/support/test/aupt/AuptTestRunner.java b/libraries/aupt-lib/src/android/support/test/aupt/AuptTestRunner.java
index 136fddf..2603abb 100644
--- a/libraries/aupt-lib/src/android/support/test/aupt/AuptTestRunner.java
+++ b/libraries/aupt-lib/src/android/support/test/aupt/AuptTestRunner.java
@@ -423,10 +423,9 @@
try {
MemHealthRecord.saveVerbose(mMemHealthRecords,
- mResultsDirectory + "memory-health.txt");
-
+ new File(mResultsDirectory, "memory-health.txt").getPath());
MemHealthRecord.saveCsv(mMemHealthRecords,
- mResultsDirectory + "memory-health-details.txt");
+ new File(mResultsDirectory, "memory-health-details.txt").getPath());
mMemHealthRecords.clear();
} catch (IOException ioex) {
diff --git a/libraries/launcher-helper/Android.mk b/libraries/launcher-helper/Android.mk
index 9c45503..15098fd 100644
--- a/libraries/launcher-helper/Android.mk
+++ b/libraries/launcher-helper/Android.mk
@@ -21,7 +21,7 @@
LOCAL_JAVA_LIBRARIES := ub-uiautomator \
android-support-test \
activity-helper
-LOCAL_STATIC_JAVA_LIBRARIES := dpad-util
+LOCAL_STATIC_JAVA_LIBRARIES := dpad-util commands-helper
LOCAL_SDK_VERSION := 21
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/libraries/launcher-helper/src/android/support/test/launcherhelper/AutoLauncherStrategy.java b/libraries/launcher-helper/src/android/support/test/launcherhelper/AutoLauncherStrategy.java
new file mode 100644
index 0000000..e20e9c6
--- /dev/null
+++ b/libraries/launcher-helper/src/android/support/test/launcherhelper/AutoLauncherStrategy.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.support.test.launcherhelper;
+
+import android.app.Instrumentation;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.system.helpers.CommandsHelper;
+
+public class AutoLauncherStrategy implements IAutoLauncherStrategy {
+
+ private static final String LOG_TAG = AutoLauncherStrategy.class.getSimpleName();
+ private static final String CAR_LENSPICKER = "com.android.support.car.lenspicker";
+
+ private static final long APP_INIT_WAIT = 10000;
+
+ //todo: Remove x and y axis and use resource ID's.
+ private static final int FACET_APPS = 560;
+ private static final int MAP_FACET = 250;
+ private static final int DIAL_FACET = 380;
+ private static final int HOME_FACET = 530;
+ private static final int MEDIA_FACET = 680;
+ private static final int SETTINGS_FACET = 810;
+
+ private static final BySelector R_ID_LENSPICKER_PAGEDOWN =
+ By.res(CAR_LENSPICKER, "page_down");
+
+ protected UiDevice mDevice;
+ private Instrumentation mInstrumentation;
+
+ @Override
+ public String getSupportedLauncherPackage() {
+ return CAR_LENSPICKER;
+ }
+
+ @Override
+ public void setUiDevice(UiDevice uiDevice) {
+ mDevice = uiDevice;
+ }
+
+ @Override
+ public void setInstrumentation(Instrumentation instrumentation) {
+ mInstrumentation = instrumentation;
+ }
+
+ @Override
+ public void open() {
+
+ }
+
+ @Override
+ public void openDialFacet() {
+ CommandsHelper.getInstance(mInstrumentation).executeShellCommand(
+ "input tap " + DIAL_FACET + " " + FACET_APPS);
+ }
+
+ @Override
+ public void openMediaFacet(String appName) {
+ openApp(appName, MEDIA_FACET, FACET_APPS);
+ }
+
+ @Override
+ public void openSettingsFacet(String appName) {
+ openApp(appName, SETTINGS_FACET, FACET_APPS);
+ }
+
+ @Override
+ public void openMapsFacet(String appName) {
+ CommandsHelper.getInstance(mInstrumentation).executeShellCommand(
+ "input tap " + MAP_FACET + " " + FACET_APPS);
+ }
+
+ @Override
+ public void openHomeFacet() {
+ CommandsHelper.getInstance(mInstrumentation).executeShellCommand(
+ "input tap " + HOME_FACET + " " + FACET_APPS);
+ }
+
+ public void openApp(String appName, int x, int y) {
+ do {
+ CommandsHelper.getInstance(mInstrumentation).executeShellCommand(
+ "input tap " + x + " " + y);
+ }
+ while (!mDevice.hasObject(R_ID_LENSPICKER_PAGEDOWN));
+
+ UiObject2 scrollContainer = mDevice.findObject(R_ID_LENSPICKER_PAGEDOWN);
+
+ if (scrollContainer == null) {
+ throw new UnsupportedOperationException("Cannot find scroll container");
+ }
+
+ if (!mDevice.hasObject(By.text(appName))) {
+ do {
+ scrollContainer.scroll(Direction.DOWN, 1.0f);
+ }
+ while (!mDevice.hasObject(By.text(appName)) && scrollContainer.isEnabled());
+ }
+
+ if (!scrollContainer.isEnabled()) {
+ throw new UnsupportedOperationException("Unable to find application " + appName);
+ }
+
+ UiObject2 application = mDevice.wait(Until.findObject(By.text(appName)), APP_INIT_WAIT);
+ if (application != null) {
+ application.click();
+ mDevice.waitForIdle();
+ } else {
+ throw new RuntimeException("Unable to find permission text ok button");
+ }
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public UiObject2 openAllApps(boolean reset) {
+ throw new UnsupportedOperationException(
+ "The feature not supported on Auto");
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public BySelector getAllAppsButtonSelector() {
+ throw new UnsupportedOperationException(
+ "The feature not supported on Auto");
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public BySelector getAllAppsSelector() {
+ throw new UnsupportedOperationException(
+ "The feature not supported on Auto");
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public Direction getAllAppsScrollDirection() {
+ throw new UnsupportedOperationException(
+ "The feature not supported on Auto");
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public UiObject2 openAllWidgets(boolean reset) {
+ throw new UnsupportedOperationException(
+ "The feature not supported on Auto");
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public BySelector getAllWidgetsSelector() {
+ throw new UnsupportedOperationException(
+ "The feature not supported on Auto");
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public Direction getAllWidgetsScrollDirection() {
+ throw new UnsupportedOperationException(
+ "The feature not supported on Auto");
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public BySelector getWorkspaceSelector() {
+ throw new UnsupportedOperationException(
+ "The feature not supported on Auto");
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public BySelector getHotSeatSelector() {
+ throw new UnsupportedOperationException(
+ "The feature not supported on Auto");
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public Direction getWorkspaceScrollDirection() {
+ throw new UnsupportedOperationException(
+ "The feature not supported on Auto");
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ public long launch(String appName, String packageName) {
+ return 0;
+ }
+}
diff --git a/libraries/launcher-helper/src/android/support/test/launcherhelper/IAutoLauncherStrategy.java b/libraries/launcher-helper/src/android/support/test/launcherhelper/IAutoLauncherStrategy.java
new file mode 100644
index 0000000..238ecab
--- /dev/null
+++ b/libraries/launcher-helper/src/android/support/test/launcherhelper/IAutoLauncherStrategy.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 android.support.test.launcherhelper;
+
+import android.app.Instrumentation;
+
+public interface IAutoLauncherStrategy extends ILauncherStrategy {
+
+ /**
+ * Sets an instance of instrumentation
+ */
+ void setInstrumentation(Instrumentation instrumentation);
+
+ /**
+ * Open Dial Facet.
+ */
+ void openDialFacet();
+
+ /**
+ * Open Media Facet.
+ * @param appName open app from media facet.
+ */
+ void openMediaFacet(String appName);
+
+ /**
+ * Open Settings Facet.
+ * @param appName open app from Settings facet.
+ */
+ void openSettingsFacet(String appName);
+
+ /**
+ * Open Maps Facet.
+ * @param appName open app from maps facet.
+ */
+ void openMapsFacet(String appName);
+
+ /**
+ * Open Home Facet to select Dial/Media cards.
+ */
+ void openHomeFacet();
+}
diff --git a/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java b/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java
index c6a52c0..6601d90 100644
--- a/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java
+++ b/libraries/launcher-helper/src/android/support/test/launcherhelper/LauncherStrategyFactory.java
@@ -40,6 +40,7 @@
mInstanceMap = new HashMap<>();
mKnownLauncherStrategies = new HashSet<>();
registerLauncherStrategy(AospLauncherStrategy.class);
+ registerLauncherStrategy(AutoLauncherStrategy.class);
registerLauncherStrategy(GoogleExperienceLauncherStrategy.class);
registerLauncherStrategy(Launcher3Strategy.class);
registerLauncherStrategy(NexusLauncherStrategy.class);
@@ -112,4 +113,17 @@
}
throw new RuntimeException("This LauncherStrategy is suitable for TV.");
}
+
+ /**
+ * Retrieves a {@link IAutoLauncherStrategy} that supports the current default auto
+ * launcher
+ * @return
+ */
+ public IAutoLauncherStrategy getAutoLauncherStrategy() {
+ ILauncherStrategy launcherStrategy = getLauncherStrategy();
+ if (launcherStrategy instanceof IAutoLauncherStrategy) {
+ return (IAutoLauncherStrategy) launcherStrategy;
+ }
+ throw new RuntimeException("This LauncherStrategy is not for auto launcher.");
+ }
}
diff --git a/libraries/system-helpers/settings-helper/src/android/system/helpers/SettingsHelper.java b/libraries/system-helpers/settings-helper/src/android/system/helpers/SettingsHelper.java
index f113a85..962e9e2 100644
--- a/libraries/system-helpers/settings-helper/src/android/system/helpers/SettingsHelper.java
+++ b/libraries/system-helpers/settings-helper/src/android/system/helpers/SettingsHelper.java
@@ -515,7 +515,7 @@
try {
int onSetting = Settings.Global.getInt(mResolver, ZEN_MODE);
launchQuickSettingsAndWait();
- mDevice.wait(Until.findObject(By.descContains(DND)),
+ mDevice.wait(Until.findObject(By.descContains(DND).clazz(Switch.class)),
TIMEOUT * 3).getChildren().get(0).click();
Thread.sleep(TIMEOUT * 3);
int changedSetting = Settings.Global.getInt(mResolver, ZEN_MODE);
@@ -527,7 +527,7 @@
int setting = Settings.Global.getInt(mResolver, ZEN_MODE);
if (setting > 0) {
launchQuickSettingsAndWait();
- mDevice.wait(Until.findObject(By.descContains(DND)),
+ mDevice.wait(Until.findObject(By.descContains(DND).clazz(Switch.class)),
TIMEOUT * 3).getChildren().get(0).click();
Thread.sleep(TIMEOUT * 3);
}
diff --git a/libraries/system-helpers/sysui-helper/Android.mk b/libraries/system-helpers/sysui-helper/Android.mk
index 2adcbcd..a574885 100644
--- a/libraries/system-helpers/sysui-helper/Android.mk
+++ b/libraries/system-helpers/sysui-helper/Android.mk
@@ -22,7 +22,8 @@
activity-helper \
commands-helper \
device-helper \
- legacy-android-test
+ legacy-android-test \
+ app-helpers-common \
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/libraries/system-helpers/sysui-helper/src/android/system/helpers/LockscreenHelper.java b/libraries/system-helpers/sysui-helper/src/android/system/helpers/LockscreenHelper.java
index ece416b..561fdf4 100644
--- a/libraries/system-helpers/sysui-helper/src/android/system/helpers/LockscreenHelper.java
+++ b/libraries/system-helpers/sysui-helper/src/android/system/helpers/LockscreenHelper.java
@@ -16,6 +16,7 @@
package android.system.helpers;
+import android.app.Instrumentation;
import android.app.KeyguardManager;
import android.content.Context;
import android.provider.Settings;
@@ -25,6 +26,9 @@
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.system.helpers.ActivityHelper;
+import android.system.helpers.DeviceHelper;
+import android.graphics.Point;
+import android.graphics.Rect;
import junit.framework.Assert;
@@ -40,12 +44,18 @@
public static final String CAMERA2_PACKAGE = "com.android.camera2";
public static final String CAMERA_PACKAGE = "com.google.android.GoogleCamera";
public static final String MODE_PIN = "PIN";
+ public static final String MODE_PASSWORD = "Password";
+ public static final String MODE_PATTERN = "Pattern";
private static final int SWIPE_MARGIN = 5;
+ private static final int SWIPE_MARGIN_BOTTOM = 100;
private static final int DEFAULT_FLING_STEPS = 5;
private static final int DEFAULT_SCROLL_STEPS = 15;
-
+ private static final String PIN_ENTRY = "com.android.systemui:id/pinEntry";
private static final String SET_PIN_COMMAND = "locksettings set-pin %s";
+ private static final String SET_PASSWORD_COMMAND = "locksettings set-password %s";
+ private static final String SET_PATTERN_COMMAND = "locksettings set-pattern %s";
private static final String CLEAR_COMMAND = "locksettings clear --old %s";
+ private static final String HOTSEAT = "hotseat";
private static LockscreenHelper sInstance = null;
private Context mContext = null;
@@ -62,7 +72,6 @@
mCommandsHelper = CommandsHelper.getInstance(InstrumentationRegistry.getInstrumentation());
mDeviceHelper = DeviceHelper.getInstance();
mIsRyuDevice = mDeviceHelper.isRyuDevice();
-
}
public static LockscreenHelper getInstance() {
@@ -72,6 +81,10 @@
return sInstance;
}
+ public String getLauncherPackage() {
+ return mDevice.getLauncherPackageName();
+ }
+
/**
* Launch Camera on LockScreen
* @return true/false
@@ -94,8 +107,25 @@
* @param mode indicate if its password or PIN
* @throws InterruptedException
*/
- public void setScreenLock(String pwd, String mode, boolean mIsNexusDevice) throws InterruptedException {
- navigateToScreenLock();
+ public void setScreenLock(String pwd, String mode, boolean mIsNexusDevice)
+ throws InterruptedException {
+ enterScreenLockOnce(pwd, mode, mIsNexusDevice);
+ Thread.sleep(LONG_TIMEOUT);
+ // Re-enter password on confirmation screen
+ UiObject2 pinField = mDevice.wait(Until.findObject(By.clazz(EDIT_TEXT_CLASS_NAME)),
+ LONG_TIMEOUT);
+ pinField.setText(pwd);
+ Thread.sleep(LONG_TIMEOUT);
+ mDevice.wait(Until.findObject(By.text("OK")), LONG_TIMEOUT).click();
+ }
+
+ /**
+ * Enters the screen lock once on the setting screen
+ * @param pwd text of Password or Pin for lockscreen
+ * @param mode indicate if its password or PIN
+ * @throws InterruptedException
+ */
+ public void enterScreenLockOnce(String pwd, String mode, boolean mIsNexusDevice) {
mDevice.wait(Until.findObject(By.text(mode)), LONG_TIMEOUT * 2).click();
// set up Secure start-up page
if (!mIsNexusDevice) {
@@ -106,9 +136,26 @@
pinField.setText(pwd);
// enter and verify password
mDevice.pressEnter();
- pinField.setText(pwd);
+ }
+
+ /*
+ * Enters non matching passcodes on both setting screens.
+ * Note: this will fail if you enter matching passcodes.
+ */
+ public void enterNonMatchingPasscodes(String firstPasscode, String secondPasscode,
+ String mode, boolean mIsNexusDevice) throws Exception {
+ enterScreenLockOnce(firstPasscode, mode, mIsNexusDevice);
+ Thread.sleep(LONG_TIMEOUT);
+ UiObject2 pinField = mDevice.wait(Until.findObject(By.clazz(EDIT_TEXT_CLASS_NAME)),
+ LONG_TIMEOUT);
+ pinField.setText(secondPasscode);
mDevice.pressEnter();
- mDevice.wait(Until.findObject(By.text("DONE")), LONG_TIMEOUT).click();
+ Thread.sleep(LONG_TIMEOUT);
+ // Verify that error is thrown.
+ UiObject2 dontMatchMessage = mDevice.wait(Until.findObject
+ (By.textContains("don’t match")), LONG_TIMEOUT);
+ Assert.assertNotNull("Error message for passcode confirmation not visible",
+ dontMatchMessage);
}
/**
@@ -143,11 +190,18 @@
}
/**
- * unlock screen
+ * Enter a screen password or PIN.
+ * Pattern not supported, please use
+ * unlockDeviceWithPattern(String) below.
+ * Method assumes the device is on lockscreen.
+ * with keyguard exposed. It will wake
+ * up the device, swipe up to reveal the keyguard,
+ * and enter the password or pin and hit enter.
* @throws InterruptedException, IOException
*/
public void unlockScreen(String pwd)
throws InterruptedException, IOException {
+ // Press menu key (82 is the code for the menu key)
String command = String.format(" %s %s %s", "input", "keyevent", "82");
mDevice.executeShellCommand(command);
Thread.sleep(SHORT_TIMEOUT);
@@ -181,10 +235,16 @@
/**
* Sets a screen lock via shell.
*/
- public void setScreenLockViaShell(String pwd, String mode) throws Exception {
+ public void setScreenLockViaShell(String passcode, String mode) throws Exception {
switch (mode) {
case MODE_PIN:
- mCommandsHelper.executeShellCommand(String.format(SET_PIN_COMMAND, pwd));
+ mCommandsHelper.executeShellCommand(String.format(SET_PIN_COMMAND, passcode));
+ break;
+ case MODE_PASSWORD:
+ mCommandsHelper.executeShellCommand(String.format(SET_PASSWORD_COMMAND, passcode));
+ break;
+ case MODE_PATTERN:
+ mCommandsHelper.executeShellCommand(String.format(SET_PATTERN_COMMAND, passcode));
break;
default:
throw new IllegalArgumentException("Unsupported mode: " + mode);
@@ -211,4 +271,176 @@
DEFAULT_SCROLL_STEPS);
mDevice.waitForIdle();
}
-}
\ No newline at end of file
+
+ /*
+ * Takes in the correct code (pin or password), the attempted
+ * code (pin or password), the mode for the code (whether pin or password)
+ * and whether or not they are expected to match.
+ * Asserts that the device has been successfully unlocked (or not).
+ */
+ public void setAndEnterLockscreenCode(String actualCode, String attemptedCode,
+ String mode, boolean shouldMatch) throws Exception {
+ setScreenLockViaShell(actualCode, mode);
+ Thread.sleep(LONG_TIMEOUT);
+ enterLockscreenCode(actualCode, attemptedCode, mode, shouldMatch);
+ }
+
+ public void enterLockscreenCode(String actualCode, String attemptedCode,
+ String mode, boolean shouldMatch) throws Exception {
+ mDevice.pressHome();
+ mDeviceHelper.sleepAndWakeUpDevice();
+ unlockScreen(attemptedCode);
+ checkForHotseatOnHome(shouldMatch);
+ removeScreenLockViaShell(actualCode);
+ Thread.sleep(LONG_TIMEOUT);
+ mDevice.pressHome();
+ }
+
+ /*
+ * Takes in the correct pattern, the attempted pattern,
+ * and whether or not they are expected to match.
+ * Asserts that the device has been successfully unlocked (or not).
+ */
+ public void setAndEnterLockscreenPattern(String actualPattern,
+ String attemptedPattern, boolean shouldMatch) throws Exception {
+ setScreenLockViaShell
+ (actualPattern, LockscreenHelper.MODE_PATTERN);
+ unlockDeviceWithPattern(attemptedPattern);
+ checkForHotseatOnHome(shouldMatch);
+ removeScreenLockViaShell(actualPattern);
+ Thread.sleep(LONG_TIMEOUT);
+ mDevice.pressHome();
+ }
+
+ public void checkForHotseatOnHome(boolean deviceUnlocked) throws Exception {
+ mDevice.pressHome();
+ Thread.sleep(LONG_TIMEOUT);
+ UiObject2 hotseat = mDevice.findObject(By.res(getLauncherPackage(), HOTSEAT));
+ if (deviceUnlocked) {
+ Assert.assertNotNull("Device not unlocked correctly", hotseat);
+ }
+ else {
+ Assert.assertNull("Device should not be unlocked", hotseat);
+ }
+ }
+
+ /*
+ * The pattern below is always invalid as you need at least
+ * four dots for a valid lock. That action of changing
+ * directions while dragging is unsupported by
+ * uiautomator.
+ */
+ public void enterInvalidPattern() throws Exception {
+ // Get coordinates for left top dot
+ UiObject2 lockPattern = mDevice.wait(Until.findObject
+ (By.res("com.android.systemui:id/lockPatternView")),
+ LONG_TIMEOUT);
+ // Get coordinates for left side dots
+ int xCoordinate =(int) (lockPattern.getVisibleBounds().left +
+ lockPattern.getVisibleBounds().left*0.16);
+ int y1Coordinate = (int) (lockPattern.getVisibleBounds().top +
+ lockPattern.getVisibleBounds().top*0.16);
+ int y2Coordinate = (int) (lockPattern.getVisibleBounds().bottom -
+ lockPattern.getVisibleBounds().bottom*0.16);
+ // Drag coordinates from one point to another
+ mDevice.swipe(xCoordinate, y1Coordinate, xCoordinate, y2Coordinate, 2);
+ }
+
+ /* Valid pattern unlock attempt
+ * Takes in a contiguous string as input
+ * 1 2 3
+ * 4 5 6
+ * 7 8 9
+ * with each number representing a dot. Eg: "1236"
+ */
+ public void unlockDeviceWithPattern(String unlockPattern) throws Exception {
+ mDeviceHelper.sleepAndWakeUpDevice();
+ unlockScreenSwipeUp();
+ Point[] coordinateArray = new Point[unlockPattern.length()];
+ for (int i=0; i < unlockPattern.length(); i++) {
+ coordinateArray[i] = calculateCoordinatesForPatternDot(unlockPattern.charAt(i),
+ "com.android.systemui:id/lockPatternView");
+ }
+ // Note: 50 controls the speed of the pattern drawing.
+ mDevice.swipe(coordinateArray, 50);
+ Thread.sleep(SHORT_TIMEOUT);
+ }
+
+ /* Pattern lock setting attempt
+ * Takes in a contiguous string as input
+ * 1 2 3
+ * 4 5 6
+ * 7 8 9
+ * with each number representing a dot. Eg: "1236"
+ */
+ public void enterPatternLockOnceForSettingLock(String unlockPattern)
+ throws InterruptedException {
+ Point[] coordinateArray = new Point[unlockPattern.length()];
+ for (int i=0; i < unlockPattern.length(); i++) {
+ coordinateArray[i] = calculateCoordinatesForPatternDot(unlockPattern.charAt(i),
+ "com.android.settings:id/lockPattern");
+ }
+ // Note: 50 controls the speed of the pattern drawing.
+ mDevice.swipe(coordinateArray, 50);
+ Thread.sleep(SHORT_TIMEOUT);
+ }
+
+ /* Pattern lock setting - this enters and reconfirms pattern to set
+ * using the UI.
+ * Takes in a contiguous string as input
+ * 1 2 3
+ * 4 5 6
+ * 7 8 9
+ * with each number representing a dot. Eg: "1236"
+ */
+ public void setPatternLockSettingLock(String unlockPattern) throws Exception {
+ // Enter the same pattern twice, once on the initial set
+ // screen and once on the confirmation screen.
+ for (int i=0; i<2; i++) {
+ enterPatternLockOnceForSettingLock(unlockPattern);
+ mDevice.pressEnter();
+ }
+ mDevice.wait(Until.findObject(By.text("DONE")), LONG_TIMEOUT).click();
+ }
+
+ /* Returns screen coordinates for each pattern dot
+ * for the current device
+ * Represented as follows by chars
+ * 1 2 3
+ * 4 5 6
+ * 7 8 9
+ * this is consistent with the set-pattern command
+ * to avoid confusion.
+ */
+ private Point calculateCoordinatesForPatternDot(char dotNumber, String lockPatternResId) {
+ UiObject2 lockPattern = mDevice.wait(Until.findObject
+ (By.res(lockPatternResId)), LONG_TIMEOUT);
+ // Calculate x coordinate
+ int xCoordinate = 0;
+ int deltaX = (int) ((lockPattern.getVisibleBounds().right -
+ lockPattern.getVisibleBounds().left)*0.16);
+ if (dotNumber == '1' || dotNumber == '4' || dotNumber == '7') {
+ xCoordinate = lockPattern.getVisibleBounds().left + deltaX;
+ }
+ else if (dotNumber == '2' || dotNumber == '5' || dotNumber == '8') {
+ xCoordinate = lockPattern.getVisibleCenter().x;
+ }
+ else if (dotNumber == '3' || dotNumber == '6' || dotNumber == '9') {
+ xCoordinate = lockPattern.getVisibleBounds().right - deltaX;
+ }
+ // Calculate y coordinate
+ int yCoordinate = 0;
+ int deltaY = (int) ((lockPattern.getVisibleBounds().bottom -
+ lockPattern.getVisibleBounds().top)*0.16);
+ if (dotNumber == '1' || dotNumber == '2' || dotNumber == '3') {
+ yCoordinate = lockPattern.getVisibleBounds().top + deltaY;
+ }
+ else if (dotNumber == '4' || dotNumber == '5' || dotNumber == '6') {
+ yCoordinate = lockPattern.getVisibleCenter().y;
+ }
+ else if (dotNumber == '7' || dotNumber == '8' || dotNumber == '9') {
+ yCoordinate = lockPattern.getVisibleBounds().bottom - deltaY;
+ }
+ return new Point(xCoordinate, yCoordinate);
+ }
+}
diff --git a/scripts/perf-setup/wahoo-setup.sh b/scripts/perf-setup/wahoo-setup.sh
new file mode 100644
index 0000000..2a626a5
--- /dev/null
+++ b/scripts/perf-setup/wahoo-setup.sh
@@ -0,0 +1,57 @@
+#Setup for 2017 devices
+
+stop thermal-engine
+stop mpdecision
+stop perfd
+
+cpubase=/sys/devices/system/cpu
+gov=cpufreq/scaling_governor
+
+cpu=4
+top=8
+
+# Enable the gold cores at max frequency.
+# 1248000 1344000 1478400 1555200 1900800 2457600
+S=2457600
+
+while [ $((cpu < $top)) -eq 1 ]; do
+ echo "setting cpu $cpu to $S kHz"
+ echo 1 > $cpubase/cpu${cpu}/online
+ echo userspace > $cpubase/cpu${cpu}/$gov
+ echo $S > $cpubase/cpu${cpu}/cpufreq/scaling_max_freq
+ echo $S > $cpubase/cpu${cpu}/cpufreq/scaling_min_freq
+ echo $S > $cpubase/cpu${cpu}/cpufreq/scaling_setspeed
+ cat $cpubase/cpu${cpu}/cpufreq/scaling_cur_freq
+ cpu=$(($cpu + 1))
+done
+
+cpu=0
+top=4
+
+# Disable the silver cores.
+while [ $((cpu < $top)) -eq 1 ]; do
+ echo "disable cpu $cpu"
+ echo 0 > $cpubase/cpu${cpu}/online
+ cpu=$(($cpu + 1))
+done
+
+echo "setting GPU bus split";
+echo 0 > /sys/class/kgsl/kgsl-3d0/bus_split;
+echo "setting GPU force clocks";
+echo 1 > /sys/class/kgsl/kgsl-3d0/force_clk_on;
+echo "setting GPU idle timer";
+echo 10000 > /sys/class/kgsl/kgsl-3d0/idle_timer;
+
+#0 762 1144 1525 2288 3509 4173 5271 5928 7904 9887 11863 13763
+echo "setting GPU bus frequency";
+echo 13763 > /sys/class/devfreq/soc:qcom,gpubw/min_freq;
+cat /sys/class/devfreq/soc:qcom,gpubw/cur_freq;
+
+# 710000000 600000000 510000000 450000000 390000000 305000000 180000000
+echo "GPU performance mode";
+G=710000000
+echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor;
+echo $G > /sys/class/kgsl/kgsl-3d0/devfreq/min_freq;
+echo $G > /sys/class/kgsl/kgsl-3d0/devfreq/max_freq;
+
+cat /sys/class/kgsl/kgsl-3d0/devfreq/cur_freq;
diff --git a/tests/example/instrumentation/AndroidTest.xml b/tests/example/instrumentation/AndroidTest.xml
index 244d794..3d89bc3 100644
--- a/tests/example/instrumentation/AndroidTest.xml
+++ b/tests/example/instrumentation/AndroidTest.xml
@@ -23,7 +23,7 @@
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="SampleInstrumentationTest" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.test.example.helloworld" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
diff --git a/tests/example/instrumentation/HelloWorldTests_HalloWelt.config b/tests/example/instrumentation/HelloWorldTests_HalloWelt.config
new file mode 100644
index 0000000..4c08548
--- /dev/null
+++ b/tests/example/instrumentation/HelloWorldTests_HalloWelt.config
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ 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.
+-->
+<configuration description="Runs only the HalloWelt test.">
+ <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup" />
+ <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <option name="test-file-name" value="HelloWorldTests.apk" />
+ </target_preparer>
+
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-tag" value="SampleInstrumentationTest" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="android.test.example.helloworld" />
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+ <option name="class" value="android.test.example.helloworld.HelloWorldTest" />
+ <option name="method" value="testHalloWelt" />
+ </test>
+</configuration>
diff --git a/tests/functional/applinktests/Android.mk b/tests/functional/applinktests/Android.mk
index 0d8ecdb..f7550a8 100644
--- a/tests/functional/applinktests/Android.mk
+++ b/tests/functional/applinktests/Android.mk
@@ -30,6 +30,4 @@
LOCAL_PACKAGE_NAME := AppLinkFunctionalTests
LOCAL_CERTIFICATE := platform
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
include $(BUILD_PACKAGE)
diff --git a/tests/functional/applinktests/src/com/android/functional/applinktests/AppLinkTests.java b/tests/functional/applinktests/src/com/android/functional/applinktests/AppLinkTests.java
index 7ef96a0..57e1382 100644
--- a/tests/functional/applinktests/src/com/android/functional/applinktests/AppLinkTests.java
+++ b/tests/functional/applinktests/src/com/android/functional/applinktests/AppLinkTests.java
@@ -20,6 +20,8 @@
import android.content.Context;
import android.content.Intent;
import android.os.ParcelFileDescriptor;
+import android.platform.test.annotations.HermeticTest;
+import android.platform.test.annotations.Presubmit;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
@@ -57,6 +59,8 @@
}
// Ensures that default app link setting set to 'undefined' for 3P apps
+ @Presubmit
+ @HermeticTest
public void testDefaultAppLinkSettting() throws InterruptedException {
String out = getAppLink(TEST_PKG_NAME);
assertTrue("Default app link not set to 'undefined' mode", "undefined".equals(out));
@@ -92,6 +96,8 @@
}
// Ensure verified app always open even candidate but unverified app set to 'always'
+ @Presubmit
+ @HermeticTest
public void testVerifiedAppOpenWhenNotVerifiedSetToAlways() throws InterruptedException {
setAppLink(TEST_PKG_NAME, "always");
setAppLink(YOUTUBE_PKG_NAME, "always");
@@ -101,6 +107,8 @@
}
// Ensure verified app always open even one candidate but unverified app set to 'ask'
+ @Presubmit
+ @HermeticTest
public void testVerifiedAppOpenWhenUnverifiedSetToAsk() throws InterruptedException {
setAppLink(TEST_PKG_NAME, "ask");
setAppLink(YOUTUBE_PKG_NAME, "always");
@@ -124,6 +132,8 @@
// Ensure unverified app always open when unverified app set to always but verified app set to
// never
+ @Presubmit
+ @HermeticTest
public void testTestAppSetToAlwaysVerifiedSetToNever() throws InterruptedException {
setAppLink(TEST_PKG_NAME, "always");
setAppLink(YOUTUBE_PKG_NAME, "never");
@@ -171,6 +181,8 @@
}
// Ensure system apps that claim to open always for set to always
+ @Presubmit
+ @HermeticTest
public void testSysappAppLinkSettings() {
// List of system app that are set to 'Always' for certain urls
List<String> alwaysOpenApps = new ArrayList<String>();
diff --git a/tests/functional/appsmoke/AndroidTest.xml b/tests/functional/appsmoke/AndroidTest.xml
index cd0c9a1..b3e7ce7 100644
--- a/tests/functional/appsmoke/AndroidTest.xml
+++ b/tests/functional/appsmoke/AndroidTest.xml
@@ -19,7 +19,7 @@
</target_preparer>
<option name="test-tag" value="AppSmoke" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.test.appsmoke" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
diff --git a/tests/functional/devicehealthtests/AndroidTest.xml b/tests/functional/devicehealthtests/AndroidTest.xml
index 4febb7a..0a6dab1 100644
--- a/tests/functional/devicehealthtests/AndroidTest.xml
+++ b/tests/functional/devicehealthtests/AndroidTest.xml
@@ -19,7 +19,7 @@
</target_preparer>
<option name="test-tag" value="DeviceHealthTests" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.devicehealth.tests" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
diff --git a/tests/functional/downloadapp/AndroidTest.xml b/tests/functional/downloadapp/AndroidTest.xml
index e478177..bcac407 100644
--- a/tests/functional/downloadapp/AndroidTest.xml
+++ b/tests/functional/downloadapp/AndroidTest.xml
@@ -20,7 +20,7 @@
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="DownloadAppFunctionalTests" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.functional.downloadapp" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
diff --git a/tests/functional/notificationtests/AndroidTest.xml b/tests/functional/notificationtests/AndroidTest.xml
index 9e85023..ba7bd6b 100644
--- a/tests/functional/notificationtests/AndroidTest.xml
+++ b/tests/functional/notificationtests/AndroidTest.xml
@@ -20,7 +20,7 @@
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="android_systemui" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.notification.functional" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
diff --git a/tests/functional/overviewtests/AndroidTest.xml b/tests/functional/overviewtests/AndroidTest.xml
index 8a992a7..30455f3 100644
--- a/tests/functional/overviewtests/AndroidTest.xml
+++ b/tests/functional/overviewtests/AndroidTest.xml
@@ -19,7 +19,7 @@
</target_preparer>
<option name="test-tag" value="android_systemui" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.overview.functional" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
diff --git a/tests/functional/systemmetrics/AndroidTest.xml b/tests/functional/systemmetrics/AndroidTest.xml
index 86d342f..ba43fff 100644
--- a/tests/functional/systemmetrics/AndroidTest.xml
+++ b/tests/functional/systemmetrics/AndroidTest.xml
@@ -19,7 +19,7 @@
</target_preparer>
<option name="test-tag" value="SystemMetricsFunctionalTests" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.systemmetrics.functional" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
diff --git a/tests/jank/UbSystemUiJankTests/src/android/platform/systemui/tests/jank/LauncherJankTests.java b/tests/jank/UbSystemUiJankTests/src/android/platform/systemui/tests/jank/LauncherJankTests.java
index 2ff4cce..a1eca88 100644
--- a/tests/jank/UbSystemUiJankTests/src/android/platform/systemui/tests/jank/LauncherJankTests.java
+++ b/tests/jank/UbSystemUiJankTests/src/android/platform/systemui/tests/jank/LauncherJankTests.java
@@ -212,58 +212,4 @@
allWidgets.fling(Direction.reverse(dir), FLING_SPEED);
}
}
-
- public void launchChrome() {
- Intent chromeIntent = pm.getLaunchIntentForPackage("com.android.chrome");
- chromeIntent.addCategory(Intent.CATEGORY_LAUNCHER);
- chromeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- getInstrumentation().getContext().startActivity(chromeIntent);
- SystemClock.sleep(TIMEOUT);
- }
-
- /** Measures jank while navigating from Chrome to Home */
- @JankTest(beforeTest="goHome", expectedFrames=100)
- @WindowAnimationFrameStatsMonitor
- public void testAppSwitchChrometoHome() throws UiObjectNotFoundException {
- for (int i = 0; i < INNER_LOOP; i++) {
- launchChrome();
- goHome();
- }
- }
-
- public void launchPhotos() {
- Intent photosIntent = pm.getLaunchIntentForPackage("com.google.android.apps.photos");
- photosIntent.addCategory(Intent.CATEGORY_LAUNCHER);
- photosIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- getInstrumentation().getContext().startActivity(photosIntent);
- SystemClock.sleep(TIMEOUT);
- }
-
- /** Measures jank while navigating from Photos to Home */
- @JankTest(beforeTest="goHome", expectedFrames=100)
- @WindowAnimationFrameStatsMonitor
- public void testAppSwitchPhotostoHome() throws UiObjectNotFoundException {
- for (int i = 0; i < INNER_LOOP; i++) {
- launchPhotos();
- goHome();
- }
- }
-
- public void launchGMail() {
- Intent gmailIntent = pm.getLaunchIntentForPackage("com.google.android.gm");
- gmailIntent.addCategory(Intent.CATEGORY_LAUNCHER);
- gmailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- getInstrumentation().getContext().startActivity(gmailIntent);
- SystemClock.sleep(TIMEOUT);
- }
-
- /** Measures jank while navigating from GMail to Home */
- @JankTest(beforeTest="goHome", expectedFrames=100)
- @WindowAnimationFrameStatsMonitor
- public void testAppSwitchGMailtoHome() throws UiObjectNotFoundException {
- for (int i = 0; i < INNER_LOOP; i++) {
- launchPhotos();
- goHome();
- }
- }
}
diff --git a/tests/jank/dialer/Android.mk b/tests/jank/dialer/Android.mk
index 3d662c4..d25ee79 100644
--- a/tests/jank/dialer/Android.mk
+++ b/tests/jank/dialer/Android.mk
@@ -23,7 +23,6 @@
ub-uiautomator \
ub-janktesthelper \
legacy-android-test
-LOCAK_SDK_VERSION := 22
LOCAL_COMPATIBILITY_SUITE := device-tests
diff --git a/tests/perf/BootHelperApp/AndroidTest.xml b/tests/perf/BootHelperApp/AndroidTest.xml
index 71f1288..e187c5a 100644
--- a/tests/perf/BootHelperApp/AndroidTest.xml
+++ b/tests/perf/BootHelperApp/AndroidTest.xml
@@ -19,7 +19,7 @@
</target_preparer>
<option name="test-tag" value="BootHelperApp" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.boothelper" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
diff --git a/tests/perf/PerfTransitionTest/AndroidTest.xml b/tests/perf/PerfTransitionTest/AndroidTest.xml
index b4f361b..8b83129 100644
--- a/tests/perf/PerfTransitionTest/AndroidTest.xml
+++ b/tests/perf/PerfTransitionTest/AndroidTest.xml
@@ -19,7 +19,7 @@
</target_preparer>
<option name="test-tag" value="AppTransitionTests" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.apptransition.tests" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
diff --git a/tests/perf/PerformanceAppTest/AndroidTest.xml b/tests/perf/PerformanceAppTest/AndroidTest.xml
index 2d56796..09686fa 100644
--- a/tests/perf/PerformanceAppTest/AndroidTest.xml
+++ b/tests/perf/PerformanceAppTest/AndroidTest.xml
@@ -19,7 +19,7 @@
</target_preparer>
<option name="test-tag" value="PerformanceAppTest" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.performanceapp.tests" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
diff --git a/tests/perf/PerformanceLaunch/AndroidTest.xml b/tests/perf/PerformanceLaunch/AndroidTest.xml
index df61047..2a9469b 100644
--- a/tests/perf/PerformanceLaunch/AndroidTest.xml
+++ b/tests/perf/PerformanceLaunch/AndroidTest.xml
@@ -19,7 +19,7 @@
</target_preparer>
<option name="test-tag" value="PerformanceLaunch" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.performanceLaunch" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>