Skip to content
Merged
Prev Previous commit
Next Next commit
espresso v1 embedding removal
  • Loading branch information
Gray Mackall committed Jun 17, 2024
commit 53f8f88c11c2ac00cc78dbcd91b72099de5ced75
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import okhttp3.OkHttpClient;
import org.hamcrest.Matcher;

import javax.annotation.Nonnull;

/**
* A {@code ViewAction} which performs an action on the given {@code FlutterView}.
*
Expand Down Expand Up @@ -97,14 +99,19 @@ public String getDescription() {

@ExperimentalTestApi
@Override
public void perform(UiController uiController, View flutterView) {
public void perform(UiController uiController, View view) {
checkNotNull(view, "The Flutter View instance cannot be null.");
if (!(view instanceof FlutterView)) {
throw new FlutterProtocolException(
String.format("This is not a Flutter View instance [id: %d].", view.getId()));
}
FlutterView flutterView = (FlutterView) view;
// There could be a gap between when the Flutter view is available in the view hierarchy and the
// engine & Dart isolates are actually up and running. Check whether the first frame has been
// rendered before proceeding in an unblocking way.
loopUntilFlutterViewRendered(flutterView, uiController);
// The url {@code FlutterNativeView} returns is the http url that the Dart VM Observatory http
// server serves at. Need to convert to the one that the WebSocket uses.

URI dartVmServiceProtocolUrl =
DartVmServiceUtil.getServiceProtocolUri(FlutterJNI.getVMServiceUri());
String isolateId = DartVmServiceUtil.getDartIsolateId(flutterView);
Expand Down Expand Up @@ -171,7 +178,7 @@ public T waitUntilCompleted(long timeout, TimeUnit unit)
return resultFuture.get(timeout, unit);
}

private static void loopUntilFlutterViewRendered(View flutterView, UiController uiController) {
private static void loopUntilFlutterViewRendered(@Nonnull FlutterView flutterView, UiController uiController) {
FlutterViewRenderedIdlingResource idlingResource =
new FlutterViewRenderedIdlingResource(flutterView);
try {
Expand All @@ -188,31 +195,22 @@ private static void loopUntilFlutterViewRendered(View flutterView, UiController
*/
static final class FlutterViewRenderedIdlingResource implements IdlingResource {

private final View flutterView;
private final FlutterView flutterView;
// Written from main thread, read from any thread.
private volatile ResourceCallback resourceCallback;

FlutterViewRenderedIdlingResource(View flutterView) {
this.flutterView = checkNotNull(flutterView);
FlutterViewRenderedIdlingResource(@Nonnull FlutterView flutterView) {
this.flutterView = flutterView;
}

@Override
public String getName() {
return FlutterViewRenderedIdlingResource.class.getSimpleName();
}

@SuppressWarnings("deprecation")
@Override
public boolean isIdleNow() {
boolean isIdle = false;
if (flutterView instanceof FlutterView) {
isIdle = ((FlutterView) flutterView).hasRenderedFirstFrame();
} else if (flutterView instanceof io.flutter.view.FlutterView) {
isIdle = ((io.flutter.view.FlutterView) flutterView).hasRenderedFirstFrame();
} else {
throw new FlutterProtocolException(
String.format("This is not a Flutter View instance [id: %d].", flutterView.getId()));
}
boolean isIdle = flutterView.hasRenderedFirstFrame();
if (isIdle) {
resourceCallback.onTransitionToIdle();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* action that's performed via Flutter engine. It's supposed to be used for complex interactions or
* those that are brittle if performed through Android system. Most of the actions should be
* associated with a {@link WidgetMatcher}, but some may not, e.g. an action that checks the
* rendering status of the entire {@link io.flutter.view.FlutterView}.
* rendering status of the entire {@link io.flutter.embedding.android.FlutterView}.
*/
@Beta
public abstract class SyntheticAction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@

package androidx.test.espresso.flutter.internal.protocol.impl;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;

import android.util.Log;
import android.view.View;

import io.flutter.embedding.android.FlutterView;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.dart.DartExecutor;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import javax.annotation.Nonnull;

/** Util class for dealing with Dart VM service protocols. */
public final class DartVmServiceUtil {
private static final String TAG = DartVmServiceUtil.class.getSimpleName();
Expand Down Expand Up @@ -59,8 +61,7 @@ public static URI getServiceProtocolUri(String observatoryUrl) {
}

/** Gets the Dart isolate ID for the given {@code flutterView}. */
public static String getDartIsolateId(View flutterView) {
checkNotNull(flutterView, "The Flutter View instance cannot be null.");
public static String getDartIsolateId(FlutterView flutterView) {
String uiIsolateId = getDartExecutor(flutterView).getIsolateServiceId();
Log.d(
TAG,
Expand All @@ -71,25 +72,15 @@ public static String getDartIsolateId(View flutterView) {
}

/** Gets the Dart executor for the given {@code flutterView}. */
@SuppressWarnings("deprecation")
public static DartExecutor getDartExecutor(View flutterView) {
checkNotNull(flutterView, "The Flutter View instance cannot be null.");
// Flutter's embedding is in the phase of rewriting/refactoring. Let's be compatible with both
// the old and the new FlutterView classes.
if (flutterView instanceof io.flutter.view.FlutterView) {
return ((io.flutter.view.FlutterView) flutterView).getDartExecutor();
} else if (flutterView instanceof io.flutter.embedding.android.FlutterView) {
FlutterEngine flutterEngine =
((io.flutter.embedding.android.FlutterView) flutterView).getAttachedFlutterEngine();
if (flutterEngine == null) {
throw new FlutterProtocolException(
String.format(
"No Flutter engine attached to the Flutter view [id: %d].", flutterView.getId()));
}
return flutterEngine.getDartExecutor();
} else {
public static DartExecutor getDartExecutor(@Nonnull FlutterView flutterView) {
// TODO(gmackall): getAttachedFlutterEngine() is marked as @visibleForTesting - determine if
// this method should change its behavior, or if that annotation should be removed.
FlutterEngine flutterEngine = flutterView.getAttachedFlutterEngine();
if (flutterEngine == null) {
throw new FlutterProtocolException(
String.format("This is not a Flutter View instance [id: %d].", flutterView.getId()));
String.format(
"No Flutter engine attached to the Flutter view [id: %d].", flutterView.getId()));
}
return flutterEngine.getDartExecutor();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ public void describeTo(Description description) {
@SuppressWarnings("deprecation")
@Override
public boolean matchesSafely(View flutterView) {
return flutterView instanceof FlutterView
|| (flutterView instanceof io.flutter.view.FlutterView);
return flutterView instanceof FlutterView;
}
}
}

This file was deleted.