Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 88aa46c

Browse files
committed
Allowed MessageCodec's to specify if they want direct ByteBuffers.
1 parent 64ba011 commit 88aa46c

21 files changed

+227
-21
lines changed

shell/platform/android/android_shell_holder.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,4 +303,17 @@ std::optional<RunConfiguration> AndroidShellHolder::BuildRunConfiguration(
303303
}
304304
return config;
305305
}
306+
307+
void AndroidShellHolder::ClearDirectByteBufferDecodingPreference(
308+
const std::string& channel) {
309+
jni_facade_->ClearDirectByteBufferDecodingPreference(channel);
310+
}
311+
312+
void AndroidShellHolder::SetDirectByteBufferDecodingPreference(
313+
const std::string& channel,
314+
bool wants_direct_byte_buffer_for_decoding) {
315+
jni_facade_->SetDirectByteBufferDecodingPreference(
316+
channel, wants_direct_byte_buffer_for_decoding);
317+
}
318+
306319
} // namespace flutter

shell/platform/android/android_shell_holder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ class AndroidShellHolder {
9696

9797
void NotifyLowMemoryWarning();
9898

99+
void ClearDirectByteBufferDecodingPreference(const std::string& channel);
100+
101+
void SetDirectByteBufferDecodingPreference(
102+
const std::string& channel,
103+
bool wants_direct_byte_buffer_for_decoding);
104+
99105
private:
100106
const flutter::Settings settings_;
101107
const std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;

shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,32 @@ public void handlePlatformMessage(
822822
// (https://github.com/flutter/flutter/issues/25391)
823823
}
824824

825+
@SuppressWarnings("unused")
826+
@VisibleForTesting
827+
public void handleIndirectPlatformMessage(
828+
@NonNull final String channel, ByteBuffer message, final int replyId) {
829+
ByteBuffer indirectByteBuffer = ByteBuffer.allocate(message.capacity());
830+
indirectByteBuffer.put(message);
831+
indirectByteBuffer.rewind();
832+
handlePlatformMessage(channel, indirectByteBuffer, replyId);
833+
}
834+
835+
private native void nativeClearDirectByteBufferDecodingPreference(
836+
long nativeShellHolderId, String channel);
837+
838+
public void clearDirectByteBufferDecodingPreference(@NonNull String channel) {
839+
nativeClearDirectByteBufferDecodingPreference(nativeShellHolderId, channel);
840+
}
841+
842+
private native void nativeSetDirectByteBufferDecodingPreference(
843+
long nativeShellHolderId, String channel, boolean wantsDirectByteBufferForDecoding);
844+
845+
public void setDirectByteBufferDecodingPreference(
846+
@NonNull String channel, boolean wantsDirectByteBufferForDecoding) {
847+
nativeSetDirectByteBufferDecodingPreference(
848+
nativeShellHolderId, channel, wantsDirectByteBufferForDecoding);
849+
}
850+
825851
// Called by native to respond to a platform message that we sent.
826852
// TODO(mattcarroll): determine if reply is nonull or nullable
827853
@SuppressWarnings("unused")

shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public DartExecutor(@NonNull FlutterJNI flutterJNI, @NonNull AssetManager assetM
5959
this.flutterJNI = flutterJNI;
6060
this.assetManager = assetManager;
6161
this.dartMessenger = new DartMessenger(flutterJNI);
62-
dartMessenger.setMessageHandler("flutter/isolate", isolateChannelMessageHandler);
62+
dartMessenger.setMessageHandler("flutter/isolate", isolateChannelMessageHandler, true);
6363
this.binaryMessenger = new DefaultBinaryMessenger(dartMessenger);
6464
// The JNI might already be attached if coming from a spawned engine. If so, correctly report
6565
// that this DartExecutor is already running.
@@ -192,8 +192,10 @@ public void send(
192192
@Override
193193
@UiThread
194194
public void setMessageHandler(
195-
@NonNull String channel, @Nullable BinaryMessenger.BinaryMessageHandler handler) {
196-
binaryMessenger.setMessageHandler(channel, handler);
195+
@NonNull String channel,
196+
@Nullable BinaryMessenger.BinaryMessageHandler handler,
197+
boolean wantsDirectByteBufferForDecoding) {
198+
binaryMessenger.setMessageHandler(channel, handler, wantsDirectByteBufferForDecoding);
197199
}
198200
// ------ END BinaryMessenger -----
199201

@@ -413,8 +415,10 @@ public void send(
413415
@Override
414416
@UiThread
415417
public void setMessageHandler(
416-
@NonNull String channel, @Nullable BinaryMessenger.BinaryMessageHandler handler) {
417-
messenger.setMessageHandler(channel, handler);
418+
@NonNull String channel,
419+
@Nullable BinaryMessenger.BinaryMessageHandler handler,
420+
boolean wantsDirectByteBufferForDecoding) {
421+
messenger.setMessageHandler(channel, handler, wantsDirectByteBufferForDecoding);
418422
}
419423
}
420424
}

shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,16 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler {
3838

3939
@Override
4040
public void setMessageHandler(
41-
@NonNull String channel, @Nullable BinaryMessenger.BinaryMessageHandler handler) {
41+
@NonNull String channel,
42+
@Nullable BinaryMessenger.BinaryMessageHandler handler,
43+
boolean wantsDirectByteBufferForDecoding) {
4244
if (handler == null) {
4345
Log.v(TAG, "Removing handler for channel '" + channel + "'");
46+
flutterJNI.clearDirectByteBufferDecodingPreference(channel);
4447
messageHandlers.remove(channel);
4548
} else {
4649
Log.v(TAG, "Setting handler for channel '" + channel + "'");
50+
flutterJNI.setDirectByteBufferDecodingPreference(channel, wantsDirectByteBufferForDecoding);
4751
messageHandlers.put(channel, handler);
4852
}
4953
}

shell/platform/android/io/flutter/plugin/common/BasicMessageChannel.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ public void send(@Nullable T message, @Nullable final Reply<T> callback) {
101101
*/
102102
@UiThread
103103
public void setMessageHandler(@Nullable final MessageHandler<T> handler) {
104-
messenger.setMessageHandler(name, handler == null ? null : new IncomingMessageHandler(handler));
104+
messenger.setMessageHandler(
105+
name,
106+
handler == null ? null : new IncomingMessageHandler(handler),
107+
codec.wantsDirectByteBufferForDecoding());
105108
}
106109

107110
/**

shell/platform/android/io/flutter/plugin/common/BinaryCodec.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,23 @@
1818
public final class BinaryCodec implements MessageCodec<ByteBuffer> {
1919
// This codec must match the Dart codec of the same name in package flutter/services.
2020
public static final BinaryCodec INSTANCE = new BinaryCodec();
21+
/** A BinaryCodec that calls decodeMessage with direct ByteBuffers for better performance. */
22+
public static final BinaryCodec INSTANCE_DIRECT = new BinaryCodec(true);
2123

22-
private BinaryCodec() {}
24+
private final boolean wantsDirectByteBufferForDecoding;
25+
26+
private BinaryCodec() {
27+
this.wantsDirectByteBufferForDecoding = false;
28+
}
29+
30+
private BinaryCodec(boolean wantsDirectByteBufferForDecoding) {
31+
this.wantsDirectByteBufferForDecoding = wantsDirectByteBufferForDecoding;
32+
}
33+
34+
@Override
35+
public boolean wantsDirectByteBufferForDecoding() {
36+
return wantsDirectByteBufferForDecoding;
37+
}
2338

2439
@Override
2540
public ByteBuffer encodeMessage(ByteBuffer message) {

shell/platform/android/io/flutter/plugin/common/BinaryMessenger.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
package io.flutter.plugin.common;
66

7+
import android.annotation.SuppressLint;
78
import androidx.annotation.NonNull;
89
import androidx.annotation.Nullable;
910
import androidx.annotation.UiThread;
@@ -50,6 +51,12 @@ public interface BinaryMessenger {
5051
@UiThread
5152
void send(@NonNull String channel, @Nullable ByteBuffer message, @Nullable BinaryReply callback);
5253

54+
@UiThread
55+
@SuppressLint("NewApi")
56+
default void setMessageHandler(@NonNull String channel, @Nullable BinaryMessageHandler handler) {
57+
setMessageHandler(channel, handler, true);
58+
}
59+
5360
/**
5461
* Registers a handler to be invoked when the Flutter application sends a message to its host
5562
* platform.
@@ -64,7 +71,10 @@ public interface BinaryMessenger {
6471
* @param handler a {@link BinaryMessageHandler} to be invoked on incoming messages, or null.
6572
*/
6673
@UiThread
67-
void setMessageHandler(@NonNull String channel, @Nullable BinaryMessageHandler handler);
74+
void setMessageHandler(
75+
@NonNull String channel,
76+
@Nullable BinaryMessageHandler handler,
77+
boolean wantsDirectByteBufferForDecoding);
6878

6979
/** Handler for incoming binary messages from Flutter. */
7080
interface BinaryMessageHandler {

shell/platform/android/io/flutter/plugin/common/EventChannel.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ public EventChannel(BinaryMessenger messenger, String name, MethodCodec codec) {
8484
@UiThread
8585
public void setStreamHandler(final StreamHandler handler) {
8686
messenger.setMessageHandler(
87-
name, handler == null ? null : new IncomingStreamRequestHandler(handler));
87+
name,
88+
handler == null ? null : new IncomingStreamRequestHandler(handler),
89+
/*wantsDirectByteBufferForDecoding=*/ true);
8890
}
8991

9092
/**

shell/platform/android/io/flutter/plugin/common/JSONMessageCodec.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ public final class JSONMessageCodec implements MessageCodec<Object> {
2727

2828
private JSONMessageCodec() {}
2929

30+
@Override
31+
public boolean wantsDirectByteBufferForDecoding() {
32+
return true;
33+
}
34+
3035
@Override
3136
public ByteBuffer encodeMessage(Object message) {
3237
if (message == null) {

0 commit comments

Comments
 (0)