Chromium Code Reviews| Index: android_webview/tools/automated_ui_tests/apk/javatests/src/org/chromium/webview_ui_test/test/WebViewUiInstrumentationTestRunner.java |
| diff --git a/android_webview/tools/automated_ui_tests/apk/javatests/src/org/chromium/webview_ui_test/test/WebViewUiInstrumentationTestRunner.java b/android_webview/tools/automated_ui_tests/apk/javatests/src/org/chromium/webview_ui_test/test/WebViewUiInstrumentationTestRunner.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..31fd7b10cceeffd108c147e9c64551e83edaf085 |
| --- /dev/null |
| +++ b/android_webview/tools/automated_ui_tests/apk/javatests/src/org/chromium/webview_ui_test/test/WebViewUiInstrumentationTestRunner.java |
| @@ -0,0 +1,164 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.webview_ui_test.test; |
| + |
| +import android.app.Activity; |
| +import android.app.Application; |
| +import android.os.Bundle; |
| +import android.support.test.InstrumentationRegistry; |
| +import android.support.test.internal.runner.lifecycle.ActivityLifecycleMonitorImpl; |
| +import android.support.test.internal.runner.lifecycle.ApplicationLifecycleMonitorImpl; |
| +import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry; |
| +import android.support.test.runner.lifecycle.ApplicationLifecycleMonitorRegistry; |
| +import android.support.test.runner.lifecycle.ApplicationStage; |
| +import android.support.test.runner.lifecycle.Stage; |
| + |
| +import org.chromium.base.Log; |
| +import org.chromium.base.test.BaseInstrumentationTestRunner; |
| + |
| +import java.util.concurrent.TimeUnit; |
| +import java.util.concurrent.atomic.AtomicInteger; |
| + |
| +/** |
| + * Instrumentation Test Runner that keeps track of activity state to support Espresso tests |
| + */ |
| +public class WebViewUiInstrumentationTestRunner extends BaseInstrumentationTestRunner{ |
| + |
| + private static final long ACTIVITY_STOP_WAIT_INTERVAL_MS = TimeUnit.SECONDS.toMillis(2); |
| + private static final long ACTIVITY_STOP_POLL_INTERVAL_MS = ACTIVITY_STOP_WAIT_INTERVAL_MS / 40; |
| + |
| + private static final String TAG = "WebViewUiITR"; |
| + |
| + private ActivityLifecycleMonitorImpl mLifecycleMonitor = new ActivityLifecycleMonitorImpl(); |
| + private ApplicationLifecycleMonitorImpl mApplicationMonitor = |
| + new ApplicationLifecycleMonitorImpl(); |
| + private AtomicInteger mStartedActivityCounter = new AtomicInteger(0); |
| + |
| + @Override |
| + public void onCreate(Bundle arguments) { |
| + Log.i(TAG, "Instrumentation Started"); |
| + logUncaughtExceptions(); |
| + |
| + InstrumentationRegistry.registerInstance(this, arguments); |
| + ActivityLifecycleMonitorRegistry.registerInstance(mLifecycleMonitor); |
| + ApplicationLifecycleMonitorRegistry.registerInstance(mApplicationMonitor); |
|
aluo
2016/07/15 23:42:13
Missing IntentMonitorRegistry logic (it's more inv
|
| + |
| + super.onCreate(arguments); |
| + } |
| + |
| + private void logUncaughtExceptions() { |
| + final Thread.UncaughtExceptionHandler standardHandler = |
| + Thread.currentThread().getUncaughtExceptionHandler(); |
| + Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { |
| + @Override |
| + public void uncaughtException(Thread t, Throwable e) { |
| + String error = String.format("Exception encountered by: %s.", obj); |
| + Log.e(TAG, error, e); |
| + Log.e(TAG, "Dying now..."); |
| + if (null != standardHandler) { |
| + standardHandler.uncaughtException(t, e); |
| + } |
| + } |
| + }); |
| + } |
| + |
| + @Override |
| + public void onStart() { |
| + super.onStart(); |
| + waitForIdleSync(); |
|
sgurun-gerrit only
2016/07/14 20:32:19
why is this needed?
|
| + } |
| + |
| + @Override |
| + public void finish(int resultCode, Bundle results) { |
| + long startTime = System.currentTimeMillis(); |
| + waitForActivitiesToComplete(); |
| + long endTime = System.currentTimeMillis(); |
| + Log.i(TAG, String.format("waitForActivitiesToComplete() took: %sms", endTime - startTime)); |
| + ActivityLifecycleMonitorRegistry.registerInstance(null); |
| + super.finish(resultCode, results); |
| + } |
| + |
| + protected void waitForActivitiesToComplete() { |
|
sgurun-gerrit only
2016/07/14 20:32:19
would force-stopping activities work instead of wa
|
| + long endTime = System.currentTimeMillis() + ACTIVITY_STOP_WAIT_INTERVAL_MS; |
| + int currentActivityCount = mStartedActivityCounter.get(); |
| + |
| + |
| + while (currentActivityCount > 0 && System.currentTimeMillis() < endTime) { |
| + try { |
| + Log.i(TAG, "Unstopped activity count: " + currentActivityCount); |
| + Thread.sleep(ACTIVITY_STOP_POLL_INTERVAL_MS); |
| + currentActivityCount = mStartedActivityCounter.get(); |
| + } catch (InterruptedException ie) { |
| + Log.i(TAG, "Abandoning activity wait due to interruption.", ie); |
| + break; |
| + } |
| + } |
| + |
| + if (currentActivityCount > 0) { |
| + Log.w(TAG, String.format("Still %s activities active after waiting %s ms.", |
| + currentActivityCount, ACTIVITY_STOP_WAIT_INTERVAL_MS)); |
| + } |
| + } |
| + |
| + @Override |
| + public void callApplicationOnCreate(Application app) { |
| + mApplicationMonitor.signalLifecycleChange(app, ApplicationStage.PRE_ON_CREATE); |
| + super.callApplicationOnCreate(app); |
| + mApplicationMonitor.signalLifecycleChange(app, ApplicationStage.CREATED); |
| + } |
| + |
| + @Override |
| + public void callActivityOnDestroy(Activity activity) { |
| + super.callActivityOnDestroy(activity); |
| + mLifecycleMonitor.signalLifecycleChange(Stage.DESTROYED, activity); |
| + } |
| + |
| + @Override |
| + public void callActivityOnRestart(Activity activity) { |
| + super.callActivityOnRestart(activity); |
| + mLifecycleMonitor.signalLifecycleChange(Stage.RESTARTED, activity); |
| + } |
| + |
| + @Override |
| + public void callActivityOnCreate(Activity activity, Bundle bundle) { |
| + mLifecycleMonitor.signalLifecycleChange(Stage.PRE_ON_CREATE, activity); |
| + super.callActivityOnCreate(activity, bundle); |
| + mLifecycleMonitor.signalLifecycleChange(Stage.CREATED, activity); |
| + } |
| + |
| + @Override |
| + public void callActivityOnStart(Activity activity) { |
| + mStartedActivityCounter.incrementAndGet(); |
| + try { |
| + super.callActivityOnStart(activity); |
| + mLifecycleMonitor.signalLifecycleChange(Stage.STARTED, activity); |
| + } catch (RuntimeException re) { |
| + mStartedActivityCounter.decrementAndGet(); |
| + throw re; |
| + } |
| + } |
| + |
| + @Override |
| + public void callActivityOnStop(Activity activity) { |
| + try { |
| + super.callActivityOnStop(activity); |
| + mLifecycleMonitor.signalLifecycleChange(Stage.STOPPED, activity); |
| + } finally { |
| + mStartedActivityCounter.decrementAndGet(); |
| + } |
| + } |
| + |
| + @Override |
| + public void callActivityOnResume(Activity activity) { |
| + super.callActivityOnResume(activity); |
| + mLifecycleMonitor.signalLifecycleChange(Stage.RESUMED, activity); |
| + } |
| + |
| + @Override |
| + public void callActivityOnPause(Activity activity) { |
| + super.callActivityOnPause(activity); |
| + mLifecycleMonitor.signalLifecycleChange(Stage.PAUSED, activity); |
| + } |
| +} |