Skip to content

Commit

Permalink
Throw an exception if a secondary isolate tries to send a platform me…
Browse files Browse the repository at this point in the history
…ssage (flutter#5069)

Platform messages are only support in the UI isolate.  Secondary isolates
do not have a window that can receive incoming messages, and outgoing messages
are not tagged with a destination isolate and thus will always be dispatched
to the UI isolate.

Fixes flutter/flutter#16846
  • Loading branch information
jason-simmons authored Apr 25, 2018
1 parent cb2092b commit 8da9398
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 10 deletions.
11 changes: 7 additions & 4 deletions lib/ui/window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -681,11 +681,14 @@ class Window {
void sendPlatformMessage(String name,
ByteData data,
PlatformMessageResponseCallback callback) {
_sendPlatformMessage(name, _zonedPlatformMessageResponseCallback(callback), data);
final String error =
_sendPlatformMessage(name, _zonedPlatformMessageResponseCallback(callback), data);
if (error != null)
throw new Exception(error);
}
void _sendPlatformMessage(String name,
PlatformMessageResponseCallback callback,
ByteData data) native 'Window_sendPlatformMessage';
String _sendPlatformMessage(String name,
PlatformMessageResponseCallback callback,
ByteData data) native 'Window_sendPlatformMessage';

/// Called whenever this window receives a message from a platform-specific
/// plugin.
Expand Down
20 changes: 14 additions & 6 deletions lib/ui/window/window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,29 +54,37 @@ void UpdateSemantics(Dart_NativeArguments args) {
UIDartState::Current()->window()->client()->UpdateSemantics(update);
}

void SendPlatformMessage(Dart_Handle window,
const std::string& name,
Dart_Handle callback,
const tonic::DartByteData& data) {
Dart_Handle SendPlatformMessage(Dart_Handle window,
const std::string& name,
Dart_Handle callback,
const tonic::DartByteData& data) {
UIDartState* dart_state = UIDartState::Current();

if (!dart_state->window()) {
// Must release the TypedData buffer before allocating other Dart objects.
data.Release();
return ToDart("Platform messages can only be sent from the main isolate");
}

fxl::RefPtr<PlatformMessageResponse> response;
if (!Dart_IsNull(callback)) {
response = fxl::MakeRefCounted<PlatformMessageResponseDart>(
tonic::DartPersistentValue(dart_state, callback),
dart_state->GetTaskRunners().GetUITaskRunner());
}
if (Dart_IsNull(data.dart_handle())) {
UIDartState::Current()->window()->client()->HandlePlatformMessage(
dart_state->window()->client()->HandlePlatformMessage(
fxl::MakeRefCounted<PlatformMessage>(name, response));
} else {
const uint8_t* buffer = static_cast<const uint8_t*>(data.data());

UIDartState::Current()->window()->client()->HandlePlatformMessage(
dart_state->window()->client()->HandlePlatformMessage(
fxl::MakeRefCounted<PlatformMessage>(
name, std::vector<uint8_t>(buffer, buffer + data.length_in_bytes()),
response));
}

return Dart_Null();
}

void _SendPlatformMessage(Dart_NativeArguments args) {
Expand Down

0 comments on commit 8da9398

Please sign in to comment.