blob: 799c803980c750e110bbb21c3f693e9288ce41ac [file] [log] [blame]
// Copyright 2020 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.base.test.util;
import android.app.Activity;
import android.support.test.runner.lifecycle.ActivityLifecycleCallback;
import android.support.test.runner.lifecycle.ActivityLifecycleMonitor;
import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import android.support.test.runner.lifecycle.Stage;
import org.junit.Assert;
import org.chromium.base.ThreadUtils;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
/**
* Methods used for testing Application-level behavior.
*/
public class ApplicationTestUtils {
private static final ActivityLifecycleMonitor sMonitor =
ActivityLifecycleMonitorRegistry.getInstance();
/** Waits until the given activity transitions to the given state. */
public static void waitForActivityState(Activity activity, Stage stage) {
CriteriaHelper.pollUiThread(() -> {
return sMonitor.getLifecycleStageOf(activity) == stage;
}, ScalableTimeout.scaleTimeout(10000), CriteriaHelper.DEFAULT_POLLING_INTERVAL);
}
/** Finishes the given activity and waits for its onDestroy() to be called. */
public static void finishActivity(final Activity activity) throws Exception {
ThreadUtils.runOnUiThreadBlocking(() -> {
if (sMonitor.getLifecycleStageOf(activity) != Stage.DESTROYED) {
activity.finish();
}
});
waitForActivityState(activity, Stage.DESTROYED);
}
/**
* Recreates the provided Activity, returning the newly created Activity once it's finished
* starting up.
* @param activity The Activity to recreate.
* @return The newly created Activity.
*/
public static <T extends Activity> T recreateActivity(T activity) {
final Class<?> activityClass = activity.getClass();
final CallbackHelper activityCallback = new CallbackHelper();
final AtomicReference<T> activityRef = new AtomicReference<>();
ActivityLifecycleCallback stateListener = (Activity newActivity, Stage stage) -> {
if (stage == Stage.RESUMED) {
if (!activityClass.isAssignableFrom(newActivity.getClass())) return;
activityRef.set((T) newActivity);
ThreadUtils.postOnUiThread(() -> activityCallback.notifyCalled());
}
};
sMonitor.addLifecycleCallback(stateListener);
try {
ThreadUtils.runOnUiThreadBlocking(() -> activity.recreate());
activityCallback.waitForCallback("Activity did not start as expected", 0);
T createdActivity = activityRef.get();
Assert.assertNotNull("Activity reference is null.", createdActivity);
return createdActivity;
} catch (TimeoutException e) {
throw new RuntimeException(e);
} finally {
sMonitor.removeLifecycleCallback(stateListener);
}
}
}