Skip to content

Commit

Permalink
Deprecated DartExecutor as BinaryMessenger and added a getBinaryMesse…
Browse files Browse the repository at this point in the history
…nger() method. (flutter#43202) (flutter#13349)
  • Loading branch information
matthew-carroll authored Oct 26, 2019
1 parent 1c104d4 commit 3ebf006
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 31 deletions.
1 change: 1 addition & 0 deletions shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ action("robolectric_tests") {
"test/io/flutter/embedding/android/FlutterAndroidComponentTest.java",
"test/io/flutter/embedding/android/FlutterFragmentTest.java",
"test/io/flutter/embedding/android/FlutterViewTest.java",
"test/io/flutter/embedding/engine/dart/DartExecutorTest.java",
"test/io/flutter/embedding/engine/FlutterEngineCacheTest.java",
"test/io/flutter/embedding/engine/FlutterJNITest.java",
"test/io/flutter/embedding/engine/RenderingComponentTest.java",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
/**
* Configures, bootstraps, and starts executing Dart code.
* <p>
* WARNING: THIS CLASS IS EXPERIMENTAL. DO NOT SHIP A DEPENDENCY ON THIS CODE.
* IF YOU USE IT, WE WILL BREAK YOU.
* <p>
* To specify a top-level Dart function to execute, use a {@link DartEntrypoint} to tell
* {@link DartExecutor} where to find the Dart code to execute, and which Dart function to use as
* the entrypoint. To execute the entrypoint, pass the {@link DartEntrypoint} to
Expand All @@ -46,7 +43,9 @@ public class DartExecutor implements BinaryMessenger {
@NonNull
private final AssetManager assetManager;
@NonNull
private final DartMessenger messenger;
private final DartMessenger dartMessenger;
@NonNull
private final BinaryMessenger binaryMessenger;
private boolean isApplicationRunning = false;
@Nullable
private String isolateServiceId;
Expand All @@ -67,8 +66,9 @@ public void onMessage(ByteBuffer message, final BinaryReply callback) {
public DartExecutor(@NonNull FlutterJNI flutterJNI, @NonNull AssetManager assetManager) {
this.flutterJNI = flutterJNI;
this.assetManager = assetManager;
this.messenger = new DartMessenger(flutterJNI);
messenger.setMessageHandler("flutter/isolate", isolateChannelMessageHandler);
this.dartMessenger = new DartMessenger(flutterJNI);
dartMessenger.setMessageHandler("flutter/isolate", isolateChannelMessageHandler);
this.binaryMessenger = new DefaultBinaryMessenger(dartMessenger);
}

/**
Expand All @@ -84,7 +84,7 @@ public DartExecutor(@NonNull FlutterJNI flutterJNI, @NonNull AssetManager assetM
*/
public void onAttachedToJNI() {
Log.v(TAG, "Attached to JNI. Registering the platform message handler for this Dart execution context.");
flutterJNI.setPlatformMessageHandler(messenger);
flutterJNI.setPlatformMessageHandler(dartMessenger);
}

/**
Expand Down Expand Up @@ -158,48 +158,49 @@ public void executeDartCallback(@NonNull DartCallback dartCallback) {
isApplicationRunning = true;
}

//------ START BinaryMessenger -----
/**
* Returns a {@link BinaryMessenger} that can be used to send messages to, and receive
* messages from, Dart code that this {@code DartExecutor} is executing.
*/
@NonNull
public BinaryMessenger getBinaryMessenger() {
return binaryMessenger;
}

//------ START BinaryMessenger (Deprecated: use getBinaryMessenger() instead) -----
/**
* Sends the given {@code message} from Android to Dart over the given {@code channel}.
*
* @param channel the name of the logical channel used for the message.
* @param message the message payload, a direct-allocated {@link ByteBuffer} with the message bytes
* @deprecated
* Use {@link #getBinaryMessenger()} instead.
*/
@Deprecated
@Override
@UiThread
public void send(@NonNull String channel, @Nullable ByteBuffer message) {
messenger.send(channel, message, null);
binaryMessenger.send(channel, message);
}

/**
* Sends the given {@code messages} from Android to Dart over the given {@code channel} and
* then has the provided {@code callback} invoked when the Dart side responds.
*
* @param channel the name of the logical channel used for the message.
* @param message the message payload, a direct-allocated {@link ByteBuffer} with the message bytes
* between position zero and current position, or null.
* @param callback a callback invoked when the Dart application responds to the message
* @deprecated
* Use {@link #getBinaryMessenger()} instead.
*/
@Deprecated
@Override
@UiThread
public void send(@NonNull String channel, @Nullable ByteBuffer message, @Nullable BinaryMessenger.BinaryReply callback) {
messenger.send(channel, message, callback);
binaryMessenger.send(channel, message, callback);
}

/**
* Sets the given {@link io.flutter.plugin.common.BinaryMessenger.BinaryMessageHandler} as the
* singular handler for all incoming messages received from the Dart side of this Dart execution
* context.
*
* @param channel the name of the channel.
* @param handler a {@link BinaryMessageHandler} to be invoked on incoming messages, or null.
* @deprecated
* Use {@link #getBinaryMessenger()} instead.
*/
@Deprecated
@Override
@UiThread
public void setMessageHandler(@NonNull String channel, @Nullable BinaryMessenger.BinaryMessageHandler handler) {
messenger.setMessageHandler(channel, handler);
binaryMessenger.setMessageHandler(channel, handler);
}
//------ END BinaryMessenger -----

/**
* Returns the number of pending channel callback replies.
Expand All @@ -217,11 +218,9 @@ public void setMessageHandler(@NonNull String channel, @Nullable BinaryMessenger
*/
@UiThread
public int getPendingChannelResponseCount() {
return messenger.getPendingChannelResponseCount();
return dartMessenger.getPendingChannelResponseCount();
}

//------ END BinaryMessenger -----

/**
* Returns an identifier for this executor's primary isolate. This identifier can be used
* in queries to the Dart service protocol.
Expand Down Expand Up @@ -345,4 +344,53 @@ public String toString() {
+ ", function: " + callbackHandle.callbackName + " )";
}
}

private static class DefaultBinaryMessenger implements BinaryMessenger {
private final DartMessenger messenger;

private DefaultBinaryMessenger(@NonNull DartMessenger messenger) {
this.messenger = messenger;
}

/**
* Sends the given {@code message} from Android to Dart over the given {@code channel}.
*
* @param channel the name of the logical channel used for the message.
* @param message the message payload, a direct-allocated {@link ByteBuffer} with the message bytes
*/
@Override
@UiThread
public void send(@NonNull String channel, @Nullable ByteBuffer message) {
messenger.send(channel, message, null);
}

/**
* Sends the given {@code messages} from Android to Dart over the given {@code channel} and
* then has the provided {@code callback} invoked when the Dart side responds.
*
* @param channel the name of the logical channel used for the message.
* @param message the message payload, a direct-allocated {@link ByteBuffer} with the message bytes
* between position zero and current position, or null.
* @param callback a callback invoked when the Dart application responds to the message
*/
@Override
@UiThread
public void send(@NonNull String channel, @Nullable ByteBuffer message, @Nullable BinaryMessenger.BinaryReply callback) {
messenger.send(channel, message, callback);
}

/**
* Sets the given {@link io.flutter.plugin.common.BinaryMessenger.BinaryMessageHandler} as the
* singular handler for all incoming messages received from the Dart side of this Dart execution
* context.
*
* @param channel the name of the channel.
* @param handler a {@link BinaryMessageHandler} to be invoked on incoming messages, or null.
*/
@Override
@UiThread
public void setMessageHandler(@NonNull String channel, @Nullable BinaryMessenger.BinaryMessageHandler handler) {
messenger.setMessageHandler(channel, handler);
}
}
}
2 changes: 2 additions & 0 deletions shell/platform/android/test/io/flutter/FlutterTestSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
import io.flutter.plugin.editing.TextInputPluginTest;
import io.flutter.plugin.platform.SingleViewPresentationTest;
import io.flutter.util.PreconditionsTest;
import test.io.flutter.embedding.engine.dart.DartExecutorTest;

@RunWith(Suite.class)
@SuiteClasses({
//FlutterActivityAndFragmentDelegateTest.class, //TODO(mklim): Fix and re-enable this
DartExecutorTest.class,
FlutterActivityTest.class,
FlutterAndroidComponentTest.class,
FlutterEngineCacheTest.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package test.io.flutter.embedding.engine.dart;

import android.content.res.AssetManager;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import java.nio.ByteBuffer;

import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.embedding.engine.dart.DartExecutor;

import static junit.framework.TestCase.assertNotNull;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

@Config(manifest=Config.NONE)
@RunWith(RobolectricTestRunner.class)
public class DartExecutorTest {
@Test
public void itSendsBinaryMessages() {
// Setup test.
FlutterJNI fakeFlutterJni = mock(FlutterJNI.class);

// Create object under test.
DartExecutor dartExecutor = new DartExecutor(fakeFlutterJni, mock(AssetManager.class));

// Verify a BinaryMessenger exists.
assertNotNull(dartExecutor.getBinaryMessenger());

// Execute the behavior under test.
ByteBuffer fakeMessage = mock(ByteBuffer.class);
dartExecutor.getBinaryMessenger().send("fake_channel", fakeMessage);

// Verify that DartExecutor sent our message to FlutterJNI.
verify(fakeFlutterJni, times(1)).dispatchPlatformMessage(
eq("fake_channel"),
eq(fakeMessage),
anyInt(),
anyInt()
);
}
}

0 comments on commit 3ebf006

Please sign in to comment.