diff options
author | Kevin Jin <kjin@google.com> | 2015-03-05 00:48:44 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-03-05 00:48:44 +0000 |
commit | 3c34ee0c7e6a74c37483c4e0fdd3691e639cc8c2 (patch) | |
tree | d2837fe8234298033d445050b363ce641cb82ca2 | |
parent | db520b012ee7345624d0277be45427db2a8e8496 (diff) | |
parent | f2c5634785d05fbdaff81a8b5f781910dd7a2894 (diff) | |
download | droiddriver-3c34ee0c7e6a74c37483c4e0fdd3691e639cc8c2.tar.gz |
am f2c56347: Merge "Add droiddriver-android_support_test"
* commit 'f2c5634785d05fbdaff81a8b5f781910dd7a2894':
Add droiddriver-android_support_test
7 files changed, 240 insertions, 7 deletions
diff --git a/droiddriver-android_support_test/Android.mk b/droiddriver-android_support_test/Android.mk new file mode 100644 index 0000000..22c6c0a --- /dev/null +++ b/droiddriver-android_support_test/Android.mk @@ -0,0 +1,19 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_MODULE := droiddriver-android_support_test +LOCAL_MODULE_TAGS := optional +LOCAL_SDK_VERSION := 19 + +LOCAL_JAVACFLAGS += -Xlint:deprecation -Xlint:unchecked + +# android-support-test requires /frameworks/testing, /external/junit, /external/hamcrest +LOCAL_JAVA_LIBRARIES := droiddriver android-support-test + +include $(BUILD_STATIC_JAVA_LIBRARY) + +include $(CLEAR_VARS) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/droiddriver-android_support_test/AndroidManifest.xml b/droiddriver-android_support_test/AndroidManifest.xml new file mode 100644 index 0000000..f9f47f8 --- /dev/null +++ b/droiddriver-android_support_test/AndroidManifest.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest + package="io.appium.droiddriver.android_support_test"> + +</manifest> diff --git a/droiddriver-android_support_test/build.gradle b/droiddriver-android_support_test/build.gradle new file mode 100644 index 0000000..8dab32a --- /dev/null +++ b/droiddriver-android_support_test/build.gradle @@ -0,0 +1,58 @@ +buildscript { + repositories { + jcenter() + } + dependencies { + // this requires Gradle 2 + classpath 'com.android.tools.build:gradle:1.0.1' + classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0' + } +} + +apply plugin: 'android-sdk-manager' +apply plugin: 'com.android.library' + +repositories { + jcenter() +} + +dependencies { + // During development, this should be set to droiddriver SNAPSHOT + compile 'io.appium:droiddriver:0.9.1' + compile 'com.android.support.test:testing-support-lib:0.1' +} + +tasks.withType(JavaCompile) { + options.compilerArgs << '-Xlint:deprecation' +} + +android { + compileSdkVersion 21 + buildToolsVersion '21.1.2' + + defaultConfig { + minSdkVersion 8 + targetSdkVersion 21 + versionCode 1 + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + } + + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = ['src'] + } + } + + lintOptions { + // Aborting on lint errors prevents jenkins from processing the Lint output + // https://wiki.jenkins-ci.org/display/JENKINS/Android%20Lint%20Plugin + abortOnError false + } +} + +//TODO: add script for publishing diff --git a/droiddriver-android_support_test/readme.md b/droiddriver-android_support_test/readme.md new file mode 100644 index 0000000..f4d7ebb --- /dev/null +++ b/droiddriver-android_support_test/readme.md @@ -0,0 +1,5 @@ +# droiddriver-android_support_test + +An optional library that integrates DroidDriver with [the Android Support Test Library](https://code.google.com/p/android-test-kit/wiki/AndroidJUnitRunnerUserGuide). +This is an experimental library because the Android Support Test Library is at early stage and many +APIs are in internal packages.
\ No newline at end of file diff --git a/droiddriver-android_support_test/src/io/appium/droiddriver/android_support_test/D2AndroidJUnitRunner.java b/droiddriver-android_support_test/src/io/appium/droiddriver/android_support_test/D2AndroidJUnitRunner.java new file mode 100644 index 0000000..7924380 --- /dev/null +++ b/droiddriver-android_support_test/src/io/appium/droiddriver/android_support_test/D2AndroidJUnitRunner.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2015 DroidDriver committers + * + * 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 io.appium.droiddriver.android_support_test; + +import android.app.Activity; +import android.os.Bundle; +import android.os.Looper; +import android.support.test.internal.runner.lifecycle.ActivityLifecycleMonitorRegistry; +import android.support.test.runner.AndroidJUnitRunner; +import android.support.test.runner.lifecycle.Stage; +import android.util.Log; + +import java.util.Iterator; +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; + +import io.appium.droiddriver.exceptions.DroidDriverException; +import io.appium.droiddriver.exceptions.TimeoutException; +import io.appium.droiddriver.helpers.DroidDrivers; +import io.appium.droiddriver.util.ActivityUtils; +import io.appium.droiddriver.util.Logs; + +/** + * Integrates DroidDriver with AndroidJUnitRunner. <p> TODO: support DroidDriver test filter + * annotations. + */ +public class D2AndroidJUnitRunner extends AndroidJUnitRunner { + private static final Callable<Activity> GET_RUNNING_ACTIVITY = new Callable<Activity>() { + @Override + public Activity call() { + Iterator<Activity> activityIterator = ActivityLifecycleMonitorRegistry.getInstance() + .getActivitiesInStage(Stage.RESUMED).iterator(); + return activityIterator.hasNext() ? activityIterator.next() : null; + } + }; + + /** + * {@inheritDoc} <p> Sets the values for the convenience methods {@link + * DroidDrivers#getInstrumentation()} and {@link DroidDrivers#getOptions()}. + */ + @Override + public void onCreate(Bundle arguments) { + DroidDrivers.initInstrumentation(this, arguments); + super.onCreate(arguments); + } + + /** + * {@inheritDoc} <p> Hooks {@link ActivityUtils#setRunningActivitySupplier} to {@link + * ActivityLifecycleMonitorRegistry}. + */ + @Override + public void onStart() { + ActivityUtils.setRunningActivitySupplier(new ActivityUtils.Supplier<Activity>() { + @Override + public Activity get() { + try { + // If this is called on main (UI) thread, don't call runOnMainSync + if (Looper.myLooper() == Looper.getMainLooper()) { + return GET_RUNNING_ACTIVITY.call(); + } + + return runOnMainSyncWithTimeout(GET_RUNNING_ACTIVITY); + } catch (Exception e) { + Logs.log(Log.WARN, e); + return null; + } + } + }); + super.onStart(); + } + + /** + * Runs {@code callable} on the main thread on best-effort basis up to a time limit, which + * defaults to {@code 10000L} and can be set as an <a href= "http://developer.android.com/tools/testing/testing_otheride.html#AMOptionsSyntax"> + * am instrument option</a> under the key {@code dd.runOnMainSyncTimeout}. <p>This is a safer + * variation of {@link #runOnMainSync} because the latter may hang. But it is heavy because a new + * thread is created for each call unless the am command line specifies {@code + * dd.runOnMainSyncTimeout <=0} such as "-e dd.runOnMainSyncTimeout 0".</p>The {@code callable} + * may never run, for example, in case that the main Looper has exited due to uncaught exception. + */ + // TODO: move this to DroidDrivers + // TODO: call runOnMainSync on a single worker thread? + private <V> V runOnMainSyncWithTimeout(Callable<V> callable) { + final RunOnMainSyncFutureTask<V> futureTask = new RunOnMainSyncFutureTask<>(callable); + + String timeoutMillisString = DroidDrivers.getOptions().getString("dd.runOnMainSyncTimeout"); + long timeoutMillis = timeoutMillisString == null? 10000L : Long.parseLong(timeoutMillisString); + if (timeoutMillis <= 0L) { + // Call runOnMainSync on current thread without time limit. + futureTask.runOnMainSyncNoThrow(); + } else { + new Thread() { + @Override + public void run() { + futureTask.runOnMainSyncNoThrow(); + } + }.start(); + } + + try { + return futureTask.get(timeoutMillis, TimeUnit.MILLISECONDS); + } catch (java.util.concurrent.TimeoutException e) { + throw new TimeoutException("Timed out after " + timeoutMillis + + " milliseconds waiting for Instrumentation.runOnMainSync", e); + } catch (Throwable e) { + throw new DroidDriverException(e); + } finally { + futureTask.cancel(false); + } + } + + private class RunOnMainSyncFutureTask<V> extends FutureTask<V> { + public RunOnMainSyncFutureTask(Callable<V> callable) { + super(callable); + } + + public void runOnMainSyncNoThrow() { + try { + runOnMainSync(this); + } catch (Throwable e) { + setException(e); + } + } + } +} diff --git a/manualtest/build.gradle b/manualtest/build.gradle index 91fb5eb..a732fe3 100644 --- a/manualtest/build.gradle +++ b/manualtest/build.gradle @@ -16,7 +16,7 @@ android { buildToolsVersion '21.1.2' defaultConfig { - minSdkVersion 12 + minSdkVersion 8 targetSdkVersion 21 // Force remove the suffix '.test' testApplicationId 'io.appium.droiddriver.manualtest' diff --git a/src/io/appium/droiddriver/runner/TestRunner.java b/src/io/appium/droiddriver/runner/TestRunner.java index ec97f9c..be92b44 100644 --- a/src/io/appium/droiddriver/runner/TestRunner.java +++ b/src/io/appium/droiddriver/runner/TestRunner.java @@ -16,7 +16,6 @@ package io.appium.droiddriver.runner; -import android.annotation.TargetApi; import android.app.Activity; import android.os.Build; import android.os.Bundle; @@ -64,15 +63,22 @@ public class TestRunner extends InstrumentationTestRunner { /** * {@inheritDoc} * <p> + * Sets the values for the convenience methods {@link DroidDrivers#getInstrumentation()} and + * {@link DroidDrivers#getOptions()}. + */ + @Override + public void onCreate(Bundle arguments) { + DroidDrivers.initInstrumentation(this, arguments); + super.onCreate(arguments); + } + + /** + * {@inheritDoc} + * <p> * Adds a {@link TestListener} that finishes all created activities. */ @Override - @TargetApi(18) public void onStart() { - if (Build.VERSION.SDK_INT >= 18) { - DroidDrivers.initInstrumentation(this, getArguments()); - } - getAndroidTestRunner().addTestListener(new TestListener() { @Override public void endTest(Test test) { |