From be5997bd3f7cf1c28023dea5050367c75e140a2d Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Wed, 19 Oct 2016 22:36:00 -0700 Subject: [PATCH] Switch engine over to platform messages (flutter/engine#3153) This patch removes the use of the host messages mojom and switch all message routing over to platform messages. --- .../flutter/lib/ui/window/platform_message.cc | 4 +- .../flutter/lib/ui/window/platform_message.h | 4 +- engine/src/flutter/lib/ui/window/window.cc | 5 +- engine/src/flutter/shell/common/engine.cc | 2 +- .../android/io/flutter/view/FlutterView.java | 130 ++---------------- .../platform/android/platform_view_android.cc | 13 +- .../shell/platform/darwin/common/BUILD.gn | 4 +- .../darwin/common/string_conversions.h | 20 +++ .../darwin/common/string_conversions.mm | 25 ++++ .../darwin/common/view_service_provider.cc | 30 ---- .../darwin/common/view_service_provider.h | 40 ------ .../darwin/desktop/platform_view_mac.mm | 9 -- .../shell/platform/darwin/ios/BUILD.gn | 6 +- .../framework/Source/FlutterViewController.mm | 81 +++++++---- .../Source/application_messages_impl.mm | 115 ---------------- ...sages_impl.h => platform_message_router.h} | 27 ++-- .../Source/platform_message_router.mm | 64 +++++++++ .../platform/darwin/ios/platform_view_ios.h | 13 +- .../platform/darwin/ios/platform_view_ios.mm | 35 +---- 19 files changed, 210 insertions(+), 417 deletions(-) create mode 100644 engine/src/flutter/shell/platform/darwin/common/string_conversions.h create mode 100644 engine/src/flutter/shell/platform/darwin/common/string_conversions.mm delete mode 100644 engine/src/flutter/shell/platform/darwin/common/view_service_provider.cc delete mode 100644 engine/src/flutter/shell/platform/darwin/common/view_service_provider.h delete mode 100644 engine/src/flutter/shell/platform/darwin/ios/framework/Source/application_messages_impl.mm rename engine/src/flutter/shell/platform/darwin/ios/framework/Source/{application_messages_impl.h => platform_message_router.h} (50%) create mode 100644 engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.mm diff --git a/engine/src/flutter/lib/ui/window/platform_message.cc b/engine/src/flutter/lib/ui/window/platform_message.cc index 4446ba13d6..d23997fc92 100644 --- a/engine/src/flutter/lib/ui/window/platform_message.cc +++ b/engine/src/flutter/lib/ui/window/platform_message.cc @@ -8,10 +8,10 @@ namespace blink { -PlatformMessage::PlatformMessage(std::string name, +PlatformMessage::PlatformMessage(std::string channel, std::vector data, ftl::RefPtr response) - : name_(std::move(name)), + : channel_(std::move(channel)), data_(std::move(data)), response_(std::move(response)) {} diff --git a/engine/src/flutter/lib/ui/window/platform_message.h b/engine/src/flutter/lib/ui/window/platform_message.h index ad91182c5f..e645b44c96 100644 --- a/engine/src/flutter/lib/ui/window/platform_message.h +++ b/engine/src/flutter/lib/ui/window/platform_message.h @@ -19,7 +19,7 @@ class PlatformMessage : public ftl::RefCountedThreadSafe { FRIEND_MAKE_REF_COUNTED(PlatformMessage); public: - const std::string& name() const { return name_; } + const std::string& channel() const { return channel_; } const std::vector& data() const { return data_; } const ftl::RefPtr& response() const { @@ -32,7 +32,7 @@ class PlatformMessage : public ftl::RefCountedThreadSafe { ftl::RefPtr response); ~PlatformMessage(); - std::string name_; + std::string channel_; std::vector data_; ftl::RefPtr response_; }; diff --git a/engine/src/flutter/lib/ui/window/window.cc b/engine/src/flutter/lib/ui/window/window.cc index f5b0c490bb..7e1795f0fd 100644 --- a/engine/src/flutter/lib/ui/window/window.cc +++ b/engine/src/flutter/lib/ui/window/window.cc @@ -193,8 +193,9 @@ void Window::DispatchPlatformMessage(ftl::RefPtr message) { pending_responses_[response_id] = response; } - DartInvokeField(library_.value(), "_dispatchPlatformMessage", - {ToDart(message->name()), data_handle, ToDart(response_id)}); + DartInvokeField( + library_.value(), "_dispatchPlatformMessage", + {ToDart(message->channel()), data_handle, ToDart(response_id)}); } void Window::DispatchPointerDataPacket(const PointerDataPacket& packet) { diff --git a/engine/src/flutter/shell/common/engine.cc b/engine/src/flutter/shell/common/engine.cc index 47aa1c6f9c..4a5b4385f4 100644 --- a/engine/src/flutter/shell/common/engine.cc +++ b/engine/src/flutter/shell/common/engine.cc @@ -371,7 +371,7 @@ void Engine::UpdateSemantics(std::vector update) { void Engine::HandlePlatformMessage( ftl::RefPtr message) { - if (message->name() == kAssetPluginChannel) { + if (message->channel() == kAssetPluginChannel) { HandleAssetPlatformMessage(std::move(message)); return; } diff --git a/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterView.java b/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterView.java index c478d09c51..30d1230675 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterView.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterView.java @@ -42,7 +42,6 @@ import org.chromium.mojo.system.MessagePipeHandle; import org.chromium.mojo.system.MojoException; import org.chromium.mojo.system.Pair; import org.chromium.mojo.system.impl.CoreImpl; -import org.chromium.mojom.flutter.platform.ApplicationMessages; import org.chromium.mojom.mojo.ServiceProvider; import org.chromium.mojom.sky.AppLifecycleState; import org.chromium.mojom.sky.ServicesData; @@ -78,10 +77,6 @@ public class FlutterView extends SurfaceView private SkyEngine.Proxy mSkyEngine; private ServiceProviderImpl mPlatformServiceProvider; private Binding mPlatformServiceProviderBinding; - private ServiceProviderImpl mViewServiceProvider; - private Binding mViewServiceProviderBinding; - private ServiceProvider.Proxy mDartServiceProvider; - private ApplicationMessages.Proxy mFlutterAppMessages; private HashMap mOnMessageListeners; private HashMap mAsyncOnMessageListeners; private final SurfaceHolder.Callback mSurfaceCallback; @@ -138,10 +133,6 @@ public class FlutterView extends SurfaceView mPlatformServiceProvider = new ServiceProviderImpl(core, this, ServiceRegistry.SHARED); - ServiceRegistry localRegistry = new ServiceRegistry(); - configureLocalServices(localRegistry); - mViewServiceProvider = new ServiceProviderImpl(core, this, localRegistry); - mAccessibilityManager = (AccessibilityManager)getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); mOnMessageListeners = new HashMap(); @@ -250,18 +241,11 @@ public class FlutterView extends SurfaceView mPlatformServiceProvider.unbindServices(); } - if (mViewServiceProviderBinding != null) { - mViewServiceProviderBinding.unbind().close(); - mViewServiceProvider.unbindServices(); - } - getHolder().removeCallback(mSurfaceCallback); nativeDetach(mNativePlatformView); mNativePlatformView = 0; mSkyEngine.close(); - mDartServiceProvider.close(); - mFlutterAppMessages.close(); } @Override @@ -452,15 +436,6 @@ public class FlutterView extends SurfaceView return super.onApplyWindowInsets(insets); } - private void configureLocalServices(ServiceRegistry registry) { - registry.register(ApplicationMessages.MANAGER.getName(), new ServiceFactory() { - @Override - public Binding connectToService(FlutterView view, Core core, MessagePipeHandle pipe) { - return ApplicationMessages.MANAGER.bind(new ApplicationMessagesImpl(), pipe); - } - }); - } - private void attach() { Core core = CoreImpl.getInstance(); Pair> engine = @@ -475,34 +450,16 @@ public class FlutterView extends SurfaceView mPlatformServiceProviderBinding.unbind().close(); mPlatformServiceProvider.unbindServices(); } - if (mViewServiceProviderBinding != null) { - mViewServiceProviderBinding.unbind().close(); - mViewServiceProvider.unbindServices(); - } - if (mDartServiceProvider != null) { - mDartServiceProvider.close(); - } Core core = CoreImpl.getInstance(); - Pair> dartServiceProvider = - ServiceProvider.MANAGER.getInterfaceRequest(core); - mDartServiceProvider = dartServiceProvider.first; - Pair> platformServiceProvider = ServiceProvider.MANAGER.getInterfaceRequest(core); mPlatformServiceProviderBinding = ServiceProvider.MANAGER.bind( mPlatformServiceProvider, platformServiceProvider.second); - Pair> viewServiceProvider = - ServiceProvider.MANAGER.getInterfaceRequest(core); - mViewServiceProviderBinding = ServiceProvider.MANAGER.bind( - mViewServiceProvider, viewServiceProvider.second); - ServicesData services = new ServicesData(); services.incomingServices = platformServiceProvider.first; - services.outgoingServices = dartServiceProvider.second; - services.viewServices = viewServiceProvider.first; mSkyEngine.setServices(services); resetAccessibilityTree(); @@ -510,12 +467,6 @@ public class FlutterView extends SurfaceView private void postRun() { Core core = CoreImpl.getInstance(); - // Connect to the ApplicationMessages service exported by the Flutter framework - Pair> appMessages = - ApplicationMessages.MANAGER.getInterfaceRequest(core); - mDartServiceProvider.connectToService(ApplicationMessages.MANAGER.getName(), - appMessages.second.passHandle()); - mFlutterAppMessages = appMessages.first; } public void runFromBundle(String bundlePath, String snapshotPath) { @@ -582,7 +533,7 @@ public class FlutterView extends SurfaceView private static native Bitmap nativeGetBitmap(long nativePlatformViewAndroid); // Send a platform message to Dart. - private static native void nativeDispatchPlatformMessage(long nativePlatformViewAndroid, String name, String message, int responseId); + private static native void nativeDispatchPlatformMessage(long nativePlatformViewAndroid, String channel, String message, int responseId); private static native void nativeDispatchPointerDataPacket(long nativePlatformViewAndroid, ByteBuffer buffer, int position); private static native void nativeDispatchSemanticsAction(long nativePlatformViewAndroid, int id, int action); private static native void nativeSetSemanticsEnabled(long nativePlatformViewAndroid, boolean enabled); @@ -592,14 +543,14 @@ public class FlutterView extends SurfaceView // Called by native to send us a platform message. @CalledByNative - private void handlePlatformMessage(String name, String message, final int responseId) { - OnMessageListener listener = mOnMessageListeners.get(name); + private void handlePlatformMessage(String channel, String message, final int responseId) { + OnMessageListener listener = mOnMessageListeners.get(channel); if (listener != null) { nativeInvokePlatformMessageResponseCallback(mNativePlatformView, responseId, listener.onMessage(this, message)); return; } - OnMessageListenerAsync asyncListener = mAsyncOnMessageListeners.get(name); + OnMessageListenerAsync asyncListener = mAsyncOnMessageListeners.get(channel); if (asyncListener != null) { asyncListener.onMessage(this, message, new MessageResponse() { @Override @@ -742,36 +693,25 @@ public class FlutterView extends SurfaceView * register a platform message handler that will receive these messages with * the PlatformMessages object. */ - public void sendPlatformMessage(String name, String message, MessageReplyCallback callback) { + public void sendPlatformMessage(String channel, String message, MessageReplyCallback callback) { int responseId = 0; if (callback != null) { responseId = mNextResponseId++; mPendingResponses.put(responseId, callback); } - nativeDispatchPlatformMessage(mNativePlatformView, name, message, responseId); + nativeDispatchPlatformMessage(mNativePlatformView, channel, message, responseId); } /** * Send a message to the Flutter application. The Flutter Dart code can register a * host message handler that will receive these messages. */ - public void sendToFlutter(String messageName, String message, - final MessageReplyCallback callback) { - // TODO(abarth): Switch to dispatchPlatformMessage once the framework - // side has been converted. - mFlutterAppMessages.sendString(messageName, message, - new ApplicationMessages.SendStringResponse() { - @Override - public void call(String reply) { - if (callback != null) { - callback.onReply(reply); - } - } - }); + public void sendToFlutter(String channel, String message, MessageReplyCallback callback) { + sendPlatformMessage(channel, message, callback); } - public void sendToFlutter(String messageName, String message) { - sendToFlutter(messageName, message, null); + public void sendToFlutter(String channel, String message) { + sendToFlutter(channel, message, null); } /** Callback invoked when the app replies to a message sent with sendToFlutter. */ @@ -783,16 +723,16 @@ public class FlutterView extends SurfaceView * Register a callback to be invoked when the Flutter application sends a message * to its host. */ - public void addOnMessageListener(String messageName, OnMessageListener listener) { - mOnMessageListeners.put(messageName, listener); + public void addOnMessageListener(String channel, OnMessageListener listener) { + mOnMessageListeners.put(channel, listener); } /** * Register a callback to be invoked when the Flutter application sends a message * to its host. The reply to the message can be provided asynchronously. */ - public void addOnMessageListenerAsync(String messageName, OnMessageListenerAsync listener) { - mAsyncOnMessageListeners.put(messageName, listener); + public void addOnMessageListenerAsync(String channel, OnMessageListenerAsync listener) { + mAsyncOnMessageListeners.put(channel, listener); } public interface OnMessageListener { @@ -815,48 +755,6 @@ public class FlutterView extends SurfaceView void send(String reply); } - private class ApplicationMessagesImpl implements ApplicationMessages { - @Override - public void close() {} - - @Override - public void onConnectionError(MojoException e) {} - - @Override - public void sendString(String messageName, String message, SendStringResponse callback) { - OnMessageListener listener = mOnMessageListeners.get(messageName); - if (listener != null) { - callback.call(listener.onMessage(FlutterView.this, message)); - return; - } - - OnMessageListenerAsync asyncListener = mAsyncOnMessageListeners.get(messageName); - if (asyncListener != null) { - asyncListener.onMessage(FlutterView.this, message, new MessageResponseAdapter(callback)); - return; - } - - callback.call(null); - } - } - - /** - * This class wraps the raw Mojo callback object in an interface that is owned - * by Flutter and can be safely given to host apps. - */ - private static class MessageResponseAdapter implements MessageResponse { - private ApplicationMessages.SendStringResponse callback; - - MessageResponseAdapter(ApplicationMessages.SendStringResponse callback) { - this.callback = callback; - } - - @Override - public void send(String reply) { - callback.call(reply); - } - } - /** Broadcast receiver used to discover active Flutter instances. */ private class DiscoveryReceiver extends BroadcastReceiver { @Override diff --git a/engine/src/flutter/shell/platform/android/platform_view_android.cc b/engine/src/flutter/shell/platform/android/platform_view_android.cc index 76b26d4a0b..6d7ebf1104 100644 --- a/engine/src/flutter/shell/platform/android/platform_view_android.cc +++ b/engine/src/flutter/shell/platform/android/platform_view_android.cc @@ -39,13 +39,13 @@ class PlatformMessageResponseAndroid : public blink::PlatformMessageResponse { void Complete(std::vector data) override { ftl::RefPtr self(this); blink::Threads::Platform()->PostTask( - [ self, data = std::move(data) ]() mutable { + ftl::MakeCopyable([ self, data = std::move(data) ]() mutable { if (!self->view_) return; static_cast(self->view_.get()) ->HandlePlatformMessageResponse(self->response_id_, std::move(data)); - }); + })); } void CompleteWithError() override { Complete(std::vector()); } @@ -206,21 +206,18 @@ void PlatformViewAndroid::HandlePlatformMessage( pending_responses_[response_id] = response; } - base::StringPiece message_name = message->name(); - auto data = message->data(); base::StringPiece message_data(reinterpret_cast(data.data()), data.size()); - auto java_message_name = - base::android::ConvertUTF8ToJavaString(env, message_name); + auto java_channel = + base::android::ConvertUTF8ToJavaString(env, message->channel()); auto java_message_data = base::android::ConvertUTF8ToJavaString(env, message_data); message = nullptr; // This call can re-enter in InvokePlatformMessageResponseCallback. - Java_FlutterView_handlePlatformMessage(env, view.obj(), - java_message_name.obj(), + Java_FlutterView_handlePlatformMessage(env, view.obj(), java_channel.obj(), java_message_data.obj(), response_id); } diff --git a/engine/src/flutter/shell/platform/darwin/common/BUILD.gn b/engine/src/flutter/shell/platform/darwin/common/BUILD.gn index 5b661dafae..71c969df10 100644 --- a/engine/src/flutter/shell/platform/darwin/common/BUILD.gn +++ b/engine/src/flutter/shell/platform/darwin/common/BUILD.gn @@ -11,8 +11,8 @@ source_set("common") { "platform_mac.mm", "platform_service_provider.cc", "platform_service_provider.h", - "view_service_provider.cc", - "view_service_provider.h", + "string_conversions.mm", + "string_conversions.h", ] set_sources_assignment_filter(sources_assignment_filter) diff --git a/engine/src/flutter/shell/platform/darwin/common/string_conversions.h b/engine/src/flutter/shell/platform/darwin/common/string_conversions.h new file mode 100644 index 0000000000..d5f4ae64be --- /dev/null +++ b/engine/src/flutter/shell/platform/darwin/common/string_conversions.h @@ -0,0 +1,20 @@ +// Copyright 2015 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. + +#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_COMMON_STRING_CONVERSIONS_H_ +#define FLUTTER_SHELL_PLATFORM_DARWIN_COMMON_STRING_CONVERSIONS_H_ + +#include + +#include + +namespace shell { + +std::vector GetVectorFromNSString(NSString* string); + +NSString* GetNSStringFromVector(const std::vector& buffer); + +} // namespace shell + +#endif // FLUTTER_SHELL_PLATFORM_DARWIN_COMMON_STRING_CONVERSIONS_H_ diff --git a/engine/src/flutter/shell/platform/darwin/common/string_conversions.mm b/engine/src/flutter/shell/platform/darwin/common/string_conversions.mm new file mode 100644 index 0000000000..de933bfd5c --- /dev/null +++ b/engine/src/flutter/shell/platform/darwin/common/string_conversions.mm @@ -0,0 +1,25 @@ +// Copyright 2016 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. + +#include "flutter/shell/platform/darwin/common/string_conversions.h" + +namespace shell { + +std::vector GetVectorFromNSString(NSString* string) { + if (!string.length) + return std::vector(); + const char* chars = string.UTF8String; + const uint8_t* bytes = reinterpret_cast(chars); + return std::vector(bytes, bytes + strlen(chars)); +} + +NSString* GetNSStringFromVector(const std::vector& buffer) { + NSString* string = [[NSString alloc] initWithBytes:buffer.data() + length:buffer.size() + encoding:NSUTF8StringEncoding]; + [string autorelease]; + return string; +} + +} // namespace shell diff --git a/engine/src/flutter/shell/platform/darwin/common/view_service_provider.cc b/engine/src/flutter/shell/platform/darwin/common/view_service_provider.cc deleted file mode 100644 index 9ab38f8ee1..0000000000 --- a/engine/src/flutter/shell/platform/darwin/common/view_service_provider.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2015 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. - -#include "flutter/shell/platform/darwin/common/view_service_provider.h" - -#include - -namespace shell { - -ViewServiceProvider::ViewServiceProvider( - AppMesssagesConnector connect_to_app_messages, - mojo::InterfaceRequest request) - : binding_(this, request.Pass()), - connect_to_app_messages_(connect_to_app_messages) {} - -ViewServiceProvider::~ViewServiceProvider() {} - -void ViewServiceProvider::ConnectToService( - const mojo::String& service_name, - mojo::ScopedMessagePipeHandle client_handle) { - if (service_name == ::flutter::platform::ApplicationMessages::Name_) { - connect_to_app_messages_( - mojo::InterfaceRequest<::flutter::platform::ApplicationMessages>( - std::move(client_handle))); - return; - } -} - -} // namespace shell diff --git a/engine/src/flutter/shell/platform/darwin/common/view_service_provider.h b/engine/src/flutter/shell/platform/darwin/common/view_service_provider.h deleted file mode 100644 index ea1f318aac..0000000000 --- a/engine/src/flutter/shell/platform/darwin/common/view_service_provider.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2016 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. - -#ifndef SHELL_PLATFORM_MAC_VIEW_SERVICE_PROVIDER_H_ -#define SHELL_PLATFORM_MAC_VIEW_SERVICE_PROVIDER_H_ - -#include - -#include "flutter/services/platform/app_messages.mojom.h" -#include "flutter/sky/engine/wtf/Assertions.h" -#include "lib/ftl/macros.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/public/interfaces/application/service_provider.mojom.h" - -namespace shell { - -typedef std::function)> - AppMesssagesConnector; - -class ViewServiceProvider : public mojo::ServiceProvider { - public: - ViewServiceProvider(AppMesssagesConnector connect_to_app_messages, - mojo::InterfaceRequest request); - ~ViewServiceProvider() override; - - void ConnectToService(const mojo::String& service_name, - mojo::ScopedMessagePipeHandle client_handle) override; - - private: - mojo::StrongBinding binding_; - AppMesssagesConnector connect_to_app_messages_; - - FTL_DISALLOW_COPY_AND_ASSIGN(ViewServiceProvider); -}; - -} // namespace shell - -#endif // SHELL_PLATFORM_MAC_VIEW_SERVICE_PROVIDER_H_ diff --git a/engine/src/flutter/shell/platform/darwin/desktop/platform_view_mac.mm b/engine/src/flutter/shell/platform/darwin/desktop/platform_view_mac.mm index 42186ab511..e720a4bdb2 100644 --- a/engine/src/flutter/shell/platform/darwin/desktop/platform_view_mac.mm +++ b/engine/src/flutter/shell/platform/darwin/desktop/platform_view_mac.mm @@ -13,7 +13,6 @@ #include "flutter/shell/gpu/gpu_rasterizer.h" #include "flutter/shell/platform/darwin/common/platform_mac.h" #include "flutter/shell/platform/darwin/common/platform_service_provider.h" -#include "flutter/shell/platform/darwin/common/view_service_provider.h" #include "lib/ftl/synchronization/waitable_event.h" namespace shell { @@ -34,22 +33,14 @@ PlatformViewMac::PlatformViewMac(NSOpenGLView* gl_view) PlatformViewMac::~PlatformViewMac() = default; -static void IgnoreRequest( - mojo::InterfaceRequest) {} - void PlatformViewMac::ConnectToEngineAndSetupServices() { ConnectToEngine(mojo::GetProxy(&sky_engine_)); mojo::ServiceProviderPtr service_provider; new PlatformServiceProvider(mojo::GetProxy(&service_provider)); - mojo::ServiceProviderPtr view_service_provider; - new ViewServiceProvider(IgnoreRequest, - mojo::GetProxy(&view_service_provider)); - sky::ServicesDataPtr services = sky::ServicesData::New(); services->incoming_services = service_provider.Pass(); - services->view_services = view_service_provider.Pass(); sky_engine_->SetServices(services.Pass()); } diff --git a/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn b/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn index 5eb322aaa6..80d8db5527 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn +++ b/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn @@ -25,13 +25,11 @@ shared_library("flutter_framework_dylib") { "framework/Headers/FlutterViewController.h", "framework/Source/accessibility_bridge.h", "framework/Source/accessibility_bridge.mm", - "framework/Source/application_messages_impl.h", - "framework/Source/application_messages_impl.mm", "framework/Source/flutter_touch_mapper.h", "framework/Source/flutter_touch_mapper.mm", "framework/Source/FlutterAppDelegate.mm", - "framework/Source/FlutterDartProject.mm", "framework/Source/FlutterDartProject_Internal.h", + "framework/Source/FlutterDartProject.mm", "framework/Source/FlutterDartSource.h", "framework/Source/FlutterDartSource.mm", "framework/Source/FlutterJSONMessageListener.mm", @@ -43,6 +41,8 @@ shared_library("flutter_framework_dylib") { "framework/Source/FlutterView.h", "framework/Source/FlutterView.mm", "framework/Source/FlutterViewController.mm", + "framework/Source/platform_message_router.h", + "framework/Source/platform_message_router.mm", "platform_view_ios.h", "platform_view_ios.mm", ] diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 999eb8cf82..0b4ab8b598 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -13,6 +13,7 @@ #include "flutter/shell/gpu/gpu_rasterizer.h" #include "flutter/shell/gpu/gpu_surface_gl.h" #include "flutter/shell/platform/darwin/common/platform_mac.h" +#include "flutter/shell/platform/darwin/common/string_conversions.h" #include "flutter/shell/platform/darwin/ios/framework/Source/flutter_touch_mapper.h" #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h" #include "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" @@ -22,6 +23,33 @@ #include "lib/ftl/functional/make_copyable.h" #include "lib/ftl/time/time_delta.h" +namespace { + +typedef void (^PlatformMessageResponseCallback)(NSString*); + +class PlatformMessageResponseDarwin : public blink::PlatformMessageResponse { + FRIEND_MAKE_REF_COUNTED(PlatformMessageResponseDarwin); + + public: + void Complete(std::vector data) override { + ftl::RefPtr self(this); + blink::Threads::Platform()->PostTask( + ftl::MakeCopyable([ self, data = std::move(data) ]() mutable { + self->callback_.get()(shell::GetNSStringFromVector(data)); + })); + } + + void CompleteWithError() override { Complete(std::vector()); } + + private: + explicit PlatformMessageResponseDarwin(PlatformMessageResponseCallback callback) + : callback_(callback, base::scoped_policy::RETAIN) {} + + base::mac::ScopedBlock callback_; +}; + +} // namespace + @interface FlutterViewController () @end @@ -461,56 +489,55 @@ static inline PointerChangeMapperPhase PointerChangePhaseFromUITouchPhase( #pragma mark - Application Messages -- (void)sendString:(NSString*)message withMessageName:(NSString*)messageName { +- (void)sendString:(NSString*)message withMessageName:(NSString*)channel { NSAssert(message, @"The message must not be null"); - NSAssert(messageName, @"The messageName must not be null"); - _platformView->AppMessageSender()->SendString( - messageName.UTF8String, message.UTF8String, - [](const mojo::String& response) {}); + NSAssert(channel, @"The channel must not be null"); + _platformView->DispatchPlatformMessage( + ftl::MakeRefCounted( + channel.UTF8String, + shell::GetVectorFromNSString(message), + nullptr)); } - (void)sendString:(NSString*)message - withMessageName:(NSString*)messageName + withMessageName:(NSString*)channel callback:(void (^)(NSString*))callback { NSAssert(message, @"The message must not be null"); - NSAssert(messageName, @"The messageName must not be null"); + NSAssert(channel, @"The channel must not be null"); NSAssert(callback, @"The callback must not be null"); - base::mac::ScopedBlock callback_ptr( - callback, base::scoped_policy::RETAIN); - _platformView->AppMessageSender()->SendString( - messageName.UTF8String, message.UTF8String, - [callback_ptr](const mojo::String& response) { - callback_ptr.get()(base::SysUTF8ToNSString(response)); - }); + _platformView->DispatchPlatformMessage( + ftl::MakeRefCounted( + channel.UTF8String, + shell::GetVectorFromNSString(message), + ftl::MakeRefCounted(callback))); } -// TODO(abarth): Switch sendString over to using platform messages. -- (void)sendJSON:(NSDictionary*)message withMessageName:(NSString*)messageName { +- (void)sendJSON:(NSDictionary*)message withMessageName:(NSString*)channel { NSData* data = [NSJSONSerialization dataWithJSONObject:message options:0 error:nil]; if (!data) return; const uint8_t* bytes = static_cast(data.bytes); _platformView->DispatchPlatformMessage( ftl::MakeRefCounted( - messageName.UTF8String, + channel.UTF8String, std::vector(bytes, bytes + data.length), nullptr)); } - (void)addMessageListener:(NSObject*)listener { NSAssert(listener, @"The listener must not be null"); - NSString* messageName = listener.messageName; - NSAssert(messageName, @"The messageName must not be null"); - _platformView->AppMessageReceiver().SetMessageListener(messageName.UTF8String, - listener); + NSString* channel = listener.messageName; + NSAssert(channel, @"The channel must not be null"); + _platformView->platform_message_router().SetMessageListener(channel.UTF8String, + listener); } - (void)removeMessageListener:(NSObject*)listener { NSAssert(listener, @"The listener must not be null"); - NSString* messageName = listener.messageName; - NSAssert(messageName, @"The messageName must not be null"); - _platformView->AppMessageReceiver().SetMessageListener(messageName.UTF8String, - nil); + NSString* channel = listener.messageName; + NSAssert(channel, @"The channel must not be null"); + _platformView->platform_message_router().SetMessageListener(channel.UTF8String, + nil); } - (void)addAsyncMessageListener: @@ -518,7 +545,7 @@ static inline PointerChangeMapperPhase PointerChangePhaseFromUITouchPhase( NSAssert(listener, @"The listener must not be null"); NSString* messageName = listener.messageName; NSAssert(messageName, @"The messageName must not be null"); - _platformView->AppMessageReceiver().SetAsyncMessageListener( + _platformView->platform_message_router().SetAsyncMessageListener( messageName.UTF8String, listener); } @@ -527,7 +554,7 @@ static inline PointerChangeMapperPhase PointerChangePhaseFromUITouchPhase( NSAssert(listener, @"The listener must not be null"); NSString* messageName = listener.messageName; NSAssert(messageName, @"The messageName must not be null"); - _platformView->AppMessageReceiver().SetAsyncMessageListener( + _platformView->platform_message_router().SetAsyncMessageListener( messageName.UTF8String, nil); } diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/application_messages_impl.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/application_messages_impl.mm deleted file mode 100644 index 09fd9dacae..0000000000 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/application_messages_impl.mm +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2016 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. - -#include "flutter/shell/platform/darwin/ios/framework/Source/application_messages_impl.h" - -#include - -#include "base/strings/sys_string_conversions.h" - -namespace shell { -namespace { - -std::vector SysNSStringToVector(NSString* string) { - if (!string.length) - return std::vector(); - const char* chars = string.UTF8String; - const uint8_t* bytes = reinterpret_cast(chars); - return std::vector(bytes, bytes + strlen(chars)); -} - -} // namespace - -ApplicationMessagesImpl::ApplicationMessagesImpl() : weak_factory_(this) {} - -ApplicationMessagesImpl::~ApplicationMessagesImpl() {} - -ftl::WeakPtr ApplicationMessagesImpl::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -void ApplicationMessagesImpl::AddBinding( - mojo::InterfaceRequest request) { - binding_.AddBinding(this, request.Pass()); -} - -void ApplicationMessagesImpl::HandlePlatformMessage( - ftl::RefPtr message) { - const auto& buffer = message->data(); - NSString* string = [[NSString alloc] initWithBytes:buffer.data() - length:buffer.size() - encoding:NSUTF8StringEncoding]; - [string autorelease]; - - ftl::RefPtr completer = message->response(); - { - auto it = listeners_.find(message->name()); - if (it != listeners_.end()) { - NSString* response = [it->second didReceiveString:string]; - if (completer) - completer->Complete(SysNSStringToVector(response)); - return; - } - } - - { - auto it = async_listeners_.find(message->name()); - if (it != async_listeners_.end()) { - [it->second - didReceiveString:string - callback:^(NSString* response) { - if (completer) - completer->Complete(SysNSStringToVector(response)); - }]; - } - } -} - -void ApplicationMessagesImpl::SetMessageListener( - const std::string& message_name, - NSObject* listener) { - if (listener) - listeners_[message_name] = listener; - else - listeners_.erase(message_name); -} - -void ApplicationMessagesImpl::SetAsyncMessageListener( - const std::string& message_name, - NSObject* listener) { - if (listener) - async_listeners_[message_name] = listener; - else - async_listeners_.erase(message_name); -} - -void ApplicationMessagesImpl::SendString(const mojo::String& message_name, - const mojo::String& message, - const SendStringCallback& callback) { - std::string message_name_str = message_name; - NSString* ns_message = base::SysUTF8ToNSString(message); - - { - auto it = listeners_.find(message_name_str); - if (it != listeners_.end()) { - NSString* response = [it->second didReceiveString:ns_message]; - callback.Run(base::SysNSStringToUTF8(response)); - return; - } - } - - { - auto it = async_listeners_.find(message_name_str); - if (it != async_listeners_.end()) { - SendStringCallback local_callback = callback; - [it->second - didReceiveString:ns_message - callback:^(NSString* response) { - local_callback.Run(base::SysNSStringToUTF8(response)); - }]; - } - } -} - -} // namespace shell diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/application_messages_impl.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h similarity index 50% rename from engine/src/flutter/shell/platform/darwin/ios/framework/Source/application_messages_impl.h rename to engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h index 81bbe9bdda..ccccfbd2c4 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/application_messages_impl.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h @@ -2,48 +2,37 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_APPLICATION_MESSAGES_IMPL_H_ -#define SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_APPLICATION_MESSAGES_IMPL_H_ +#ifndef SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_PLATFORM_MESSAGE_ROUTER_H_ +#define SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_PLATFORM_MESSAGE_ROUTER_H_ #include #include "flutter/lib/ui/window/platform_message.h" -#include "flutter/services/platform/app_messages.mojom.h" #include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterAsyncMessageListener.h" #include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterMessageListener.h" #include "lib/ftl/memory/weak_ptr.h" -#include "mojo/public/cpp/bindings/binding_set.h" namespace shell { -class ApplicationMessagesImpl : public flutter::platform::ApplicationMessages { +class PlatformMessageRouter { public: - ApplicationMessagesImpl(); - ~ApplicationMessagesImpl() override; - - ftl::WeakPtr GetWeakPtr(); - void AddBinding( - mojo::InterfaceRequest request); + PlatformMessageRouter(); + ~PlatformMessageRouter(); void HandlePlatformMessage(ftl::RefPtr message); - void SetMessageListener(const std::string& message_name, + void SetMessageListener(const std::string& channel, NSObject* listener); - void SetAsyncMessageListener(const std::string& message_name, + void SetAsyncMessageListener(const std::string& channel, NSObject* listener); private: - void SendString(const mojo::String& message_name, - const mojo::String& message, - const SendStringCallback& callback) override; - - mojo::BindingSet binding_; std::unordered_map*> listeners_; std::unordered_map*> async_listeners_; - ftl::WeakPtrFactory weak_factory_; + FTL_DISALLOW_COPY_AND_ASSIGN(PlatformMessageRouter); }; } // namespace shell diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.mm new file mode 100644 index 0000000000..c4400349fa --- /dev/null +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.mm @@ -0,0 +1,64 @@ +// Copyright 2016 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. + +#include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h" + +#include + +#include "base/strings/sys_string_conversions.h" +#include "flutter/shell/platform/darwin/common/string_conversions.h" + +namespace shell { + +PlatformMessageRouter::PlatformMessageRouter() = default; + +PlatformMessageRouter::~PlatformMessageRouter() = default; + +void PlatformMessageRouter::HandlePlatformMessage( + ftl::RefPtr message) { + NSString* string = GetNSStringFromVector(message->data()); + + ftl::RefPtr completer = message->response(); + { + auto it = listeners_.find(message->channel()); + if (it != listeners_.end()) { + NSString* response = [it->second didReceiveString:string]; + if (completer) + completer->Complete(GetVectorFromNSString(response)); + return; + } + } + + { + auto it = async_listeners_.find(message->channel()); + if (it != async_listeners_.end()) { + [it->second + didReceiveString:string + callback:^(NSString* response) { + if (completer) + completer->Complete(GetVectorFromNSString(response)); + }]; + } + } +} + +void PlatformMessageRouter::SetMessageListener( + const std::string& channel, + NSObject* listener) { + if (listener) + listeners_[channel] = listener; + else + listeners_.erase(channel); +} + +void PlatformMessageRouter::SetAsyncMessageListener( + const std::string& channel, + NSObject* listener) { + if (listener) + async_listeners_[channel] = listener; + else + async_listeners_.erase(channel); +} + +} // namespace shell diff --git a/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.h b/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.h index 476c6325a3..1b289312b6 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.h +++ b/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.h @@ -8,11 +8,10 @@ #include #include "base/mac/scoped_nsobject.h" -#include "flutter/services/platform/app_messages.mojom.h" #include "flutter/shell/common/platform_view.h" #include "flutter/shell/gpu/gpu_surface_gl.h" #include "flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h" -#include "flutter/shell/platform/darwin/ios/framework/Source/application_messages_impl.h" +#include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h" #include "lib/ftl/macros.h" #include "lib/ftl/memory/weak_ptr.h" @@ -35,9 +34,9 @@ class PlatformViewIOS : public PlatformView, public GPUSurfaceGLDelegate { sky::SkyEnginePtr& engineProxy(); - flutter::platform::ApplicationMessagesPtr& AppMessageSender(); - - ApplicationMessagesImpl& AppMessageReceiver(); + PlatformMessageRouter& platform_message_router() { + return platform_message_router_; + } bool ResourceContextMakeCurrent() override; @@ -61,9 +60,7 @@ class PlatformViewIOS : public PlatformView, public GPUSurfaceGLDelegate { private: std::unique_ptr context_; sky::SkyEnginePtr engine_; - mojo::ServiceProviderPtr dart_services_; - flutter::platform::ApplicationMessagesPtr app_message_sender_; - ApplicationMessagesImpl app_message_receiver_; + PlatformMessageRouter platform_message_router_; std::unique_ptr accessibility_bridge_; void SetupAndLoadFromSource(const std::string& main, diff --git a/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm b/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm index e1f6de8f3c..78062d6bb9 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm @@ -15,7 +15,6 @@ #include "base/trace_event/trace_event.h" #include "flutter/shell/gpu/gpu_rasterizer.h" #include "flutter/shell/platform/darwin/common/platform_service_provider.h" -#include "flutter/shell/platform/darwin/common/view_service_provider.h" #include "lib/ftl/synchronization/waitable_event.h" #include "mojo/public/cpp/application/connect.h" @@ -289,14 +288,6 @@ sky::SkyEnginePtr& PlatformViewIOS::engineProxy() { return engine_; } -flutter::platform::ApplicationMessagesPtr& PlatformViewIOS::AppMessageSender() { - return app_message_sender_; -} - -shell::ApplicationMessagesImpl& PlatformViewIOS::AppMessageReceiver() { - return app_message_receiver_; -} - void PlatformViewIOS::ToggleAccessibility(UIView* view, bool enabled) { if (enabled) { if (!accessibility_bridge_) { @@ -313,33 +304,11 @@ void PlatformViewIOS::ConnectToEngineAndSetupServices() { ConnectToEngine(mojo::GetProxy(&engine_)); mojo::ServiceProviderPtr service_provider; - - auto service_provider_proxy = mojo::GetProxy(&service_provider); - - new PlatformServiceProvider(service_provider_proxy.Pass()); - - ftl::WeakPtr appplication_messages_impl = - app_message_receiver_.GetWeakPtr(); - - mojo::ServiceProviderPtr viewServiceProvider; - - new ViewServiceProvider( - [appplication_messages_impl]( - mojo::InterfaceRequest - request) { - if (appplication_messages_impl) - appplication_messages_impl->AddBinding(std::move(request)); - }, - mojo::GetProxy(&viewServiceProvider)); + new PlatformServiceProvider(mojo::GetProxy(&service_provider)); sky::ServicesDataPtr services = sky::ServicesData::New(); services->incoming_services = service_provider.Pass(); - services->outgoing_services = mojo::GetProxy(&dart_services_); - services->view_services = viewServiceProvider.Pass(); engine_->SetServices(services.Pass()); - - mojo::ConnectToService(dart_services_.get(), - mojo::GetProxy(&app_message_sender_)); } void PlatformViewIOS::SetupAndLoadFromSource( @@ -380,7 +349,7 @@ void PlatformViewIOS::UpdateSemantics( void PlatformViewIOS::HandlePlatformMessage( ftl::RefPtr message) { - app_message_receiver_.HandlePlatformMessage(std::move(message)); + platform_message_router_.HandlePlatformMessage(std::move(message)); } void PlatformViewIOS::RunFromSource(const std::string& main,