提交 b1c0ea79 编写于 作者: A Adam Barth 提交者: GitHub

Switch engine over to platform messages (#3153)

This patch removes the use of the host messages mojom and switch all
message routing over to platform messages.
上级 f1b740c8
......@@ -8,10 +8,10 @@
namespace blink {
PlatformMessage::PlatformMessage(std::string name,
PlatformMessage::PlatformMessage(std::string channel,
std::vector<uint8_t> data,
ftl::RefPtr<PlatformMessageResponse> response)
: name_(std::move(name)),
: channel_(std::move(channel)),
data_(std::move(data)),
response_(std::move(response)) {}
......
......@@ -19,7 +19,7 @@ class PlatformMessage : public ftl::RefCountedThreadSafe<PlatformMessage> {
FRIEND_MAKE_REF_COUNTED(PlatformMessage);
public:
const std::string& name() const { return name_; }
const std::string& channel() const { return channel_; }
const std::vector<uint8_t>& data() const { return data_; }
const ftl::RefPtr<PlatformMessageResponse>& response() const {
......@@ -32,7 +32,7 @@ class PlatformMessage : public ftl::RefCountedThreadSafe<PlatformMessage> {
ftl::RefPtr<PlatformMessageResponse> response);
~PlatformMessage();
std::string name_;
std::string channel_;
std::vector<uint8_t> data_;
ftl::RefPtr<PlatformMessageResponse> response_;
};
......
......@@ -193,8 +193,9 @@ void Window::DispatchPlatformMessage(ftl::RefPtr<PlatformMessage> 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) {
......
......@@ -371,7 +371,7 @@ void Engine::UpdateSemantics(std::vector<blink::SemanticsNode> update) {
void Engine::HandlePlatformMessage(
ftl::RefPtr<blink::PlatformMessage> message) {
if (message->name() == kAssetPluginChannel) {
if (message->channel() == kAssetPluginChannel) {
HandleAssetPlatformMessage(std::move(message));
return;
}
......
......@@ -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<String, OnMessageListener> mOnMessageListeners;
private HashMap<String, OnMessageListenerAsync> 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<String, OnMessageListener>();
......@@ -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<SkyEngine.Proxy, InterfaceRequest<SkyEngine>> 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<ServiceProvider.Proxy, InterfaceRequest<ServiceProvider>> dartServiceProvider =
ServiceProvider.MANAGER.getInterfaceRequest(core);
mDartServiceProvider = dartServiceProvider.first;
Pair<ServiceProvider.Proxy, InterfaceRequest<ServiceProvider>> platformServiceProvider =
ServiceProvider.MANAGER.getInterfaceRequest(core);
mPlatformServiceProviderBinding = ServiceProvider.MANAGER.bind(
mPlatformServiceProvider, platformServiceProvider.second);
Pair<ServiceProvider.Proxy, InterfaceRequest<ServiceProvider>> 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<ApplicationMessages.Proxy, InterfaceRequest<ApplicationMessages>> 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
......
......@@ -39,13 +39,13 @@ class PlatformMessageResponseAndroid : public blink::PlatformMessageResponse {
void Complete(std::vector<uint8_t> data) override {
ftl::RefPtr<PlatformMessageResponseAndroid> 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<PlatformViewAndroid*>(self->view_.get())
->HandlePlatformMessageResponse(self->response_id_,
std::move(data));
});
}));
}
void CompleteWithError() override { Complete(std::vector<uint8_t>()); }
......@@ -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<const char*>(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);
}
......
......@@ -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)
......
// 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 <Foundation/Foundation.h>
#include <vector>
namespace shell {
std::vector<uint8_t> GetVectorFromNSString(NSString* string);
NSString* GetNSStringFromVector(const std::vector<uint8_t>& buffer);
} // namespace shell
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_COMMON_STRING_CONVERSIONS_H_
// 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<uint8_t> GetVectorFromNSString(NSString* string) {
if (!string.length)
return std::vector<uint8_t>();
const char* chars = string.UTF8String;
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(chars);
return std::vector<uint8_t>(bytes, bytes + strlen(chars));
}
NSString* GetNSStringFromVector(const std::vector<uint8_t>& buffer) {
NSString* string = [[NSString alloc] initWithBytes:buffer.data()
length:buffer.size()
encoding:NSUTF8StringEncoding];
[string autorelease];
return string;
}
} // namespace shell
// 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 <utility>
namespace shell {
ViewServiceProvider::ViewServiceProvider(
AppMesssagesConnector connect_to_app_messages,
mojo::InterfaceRequest<mojo::ServiceProvider> 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
// 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 <functional>
#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<void(
mojo::InterfaceRequest<flutter::platform::ApplicationMessages>)>
AppMesssagesConnector;
class ViewServiceProvider : public mojo::ServiceProvider {
public:
ViewServiceProvider(AppMesssagesConnector connect_to_app_messages,
mojo::InterfaceRequest<mojo::ServiceProvider> request);
~ViewServiceProvider() override;
void ConnectToService(const mojo::String& service_name,
mojo::ScopedMessagePipeHandle client_handle) override;
private:
mojo::StrongBinding<mojo::ServiceProvider> binding_;
AppMesssagesConnector connect_to_app_messages_;
FTL_DISALLOW_COPY_AND_ASSIGN(ViewServiceProvider);
};
} // namespace shell
#endif // SHELL_PLATFORM_MAC_VIEW_SERVICE_PROVIDER_H_
......@@ -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<flutter::platform::ApplicationMessages>) {}
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());
}
......
......@@ -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",
]
......
......@@ -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<uint8_t> data) override {
ftl::RefPtr<PlatformMessageResponseDarwin> 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<uint8_t>()); }
private:
explicit PlatformMessageResponseDarwin(PlatformMessageResponseCallback callback)
: callback_(callback, base::scoped_policy::RETAIN) {}
base::mac::ScopedBlock<PlatformMessageResponseCallback> callback_;
};
} // namespace
@interface FlutterViewController ()<UIAlertViewDelegate, FlutterTextInputDelegate>
@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<blink::PlatformMessage>(
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<void (^)(NSString*)> 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<blink::PlatformMessage>(
channel.UTF8String,
shell::GetVectorFromNSString(message),
ftl::MakeRefCounted<PlatformMessageResponseDarwin>(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<const uint8_t*>(data.bytes);
_platformView->DispatchPlatformMessage(
ftl::MakeRefCounted<blink::PlatformMessage>(
messageName.UTF8String,
channel.UTF8String,
std::vector<uint8_t>(bytes, bytes + data.length),
nullptr));
}
- (void)addMessageListener:(NSObject<FlutterMessageListener>*)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<FlutterMessageListener>*)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);
}
......
// 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 <vector>
#include "base/strings/sys_string_conversions.h"
namespace shell {
namespace {
std::vector<uint8_t> SysNSStringToVector(NSString* string) {
if (!string.length)
return std::vector<uint8_t>();
const char* chars = string.UTF8String;
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(chars);
return std::vector<uint8_t>(bytes, bytes + strlen(chars));
}
} // namespace
ApplicationMessagesImpl::ApplicationMessagesImpl() : weak_factory_(this) {}
ApplicationMessagesImpl::~ApplicationMessagesImpl() {}
ftl::WeakPtr<ApplicationMessagesImpl> ApplicationMessagesImpl::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void ApplicationMessagesImpl::AddBinding(
mojo::InterfaceRequest<flutter::platform::ApplicationMessages> request) {
binding_.AddBinding(this, request.Pass());
}
void ApplicationMessagesImpl::HandlePlatformMessage(
ftl::RefPtr<blink::PlatformMessage> message) {
const auto& buffer = message->data();
NSString* string = [[NSString alloc] initWithBytes:buffer.data()
length:buffer.size()
encoding:NSUTF8StringEncoding];
[string autorelease];
ftl::RefPtr<blink::PlatformMessageResponse> 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<FlutterMessageListener>* listener) {
if (listener)
listeners_[message_name] = listener;
else
listeners_.erase(message_name);
}
void ApplicationMessagesImpl::SetAsyncMessageListener(
const std::string& message_name,
NSObject<FlutterAsyncMessageListener>* 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
......@@ -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 <unordered_map>
#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<ApplicationMessagesImpl> GetWeakPtr();
void AddBinding(
mojo::InterfaceRequest<flutter::platform::ApplicationMessages> request);
PlatformMessageRouter();
~PlatformMessageRouter();
void HandlePlatformMessage(ftl::RefPtr<blink::PlatformMessage> message);
void SetMessageListener(const std::string& message_name,
void SetMessageListener(const std::string& channel,
NSObject<FlutterMessageListener>* listener);
void SetAsyncMessageListener(const std::string& message_name,
void SetAsyncMessageListener(const std::string& channel,
NSObject<FlutterAsyncMessageListener>* listener);
private:
void SendString(const mojo::String& message_name,
const mojo::String& message,
const SendStringCallback& callback) override;
mojo::BindingSet<flutter::platform::ApplicationMessages> binding_;
std::unordered_map<std::string, NSObject<FlutterMessageListener>*> listeners_;
std::unordered_map<std::string, NSObject<FlutterAsyncMessageListener>*>
async_listeners_;
ftl::WeakPtrFactory<ApplicationMessagesImpl> weak_factory_;
FTL_DISALLOW_COPY_AND_ASSIGN(PlatformMessageRouter);
};
} // namespace shell
......
// 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 <vector>
#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<blink::PlatformMessage> message) {
NSString* string = GetNSStringFromVector(message->data());
ftl::RefPtr<blink::PlatformMessageResponse> 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<FlutterMessageListener>* listener) {
if (listener)
listeners_[channel] = listener;
else
listeners_.erase(channel);
}
void PlatformMessageRouter::SetAsyncMessageListener(
const std::string& channel,
NSObject<FlutterAsyncMessageListener>* listener) {
if (listener)
async_listeners_[channel] = listener;
else
async_listeners_.erase(channel);
}
} // namespace shell
......@@ -8,11 +8,10 @@
#include <memory>
#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<IOSGLContext> 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<AccessibilityBridge> accessibility_bridge_;
void SetupAndLoadFromSource(const std::string& main,
......
......@@ -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<ApplicationMessagesImpl> appplication_messages_impl =
app_message_receiver_.GetWeakPtr();
mojo::ServiceProviderPtr viewServiceProvider;
new ViewServiceProvider(
[appplication_messages_impl](
mojo::InterfaceRequest<flutter::platform::ApplicationMessages>
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<blink::PlatformMessage> message) {
app_message_receiver_.HandlePlatformMessage(std::move(message));
platform_message_router_.HandlePlatformMessage(std::move(message));
}
void PlatformViewIOS::RunFromSource(const std::string& main,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册