| Index: content/browser/navigator_connect/service_port_service_impl.cc
|
| diff --git a/content/browser/navigator_connect/service_port_service_impl.cc b/content/browser/navigator_connect/service_port_service_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..432f57fb76a1dac100ef974b8e617472ed83af5d
|
| --- /dev/null
|
| +++ b/content/browser/navigator_connect/service_port_service_impl.cc
|
| @@ -0,0 +1,131 @@
|
| +// 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 "content/browser/navigator_connect/service_port_service_impl.h"
|
| +
|
| +#include "content/browser/message_port_message_filter.h"
|
| +#include "content/browser/message_port_service.h"
|
| +#include "content/browser/navigator_connect/navigator_connect_context_impl.h"
|
| +#include "content/common/service_port_type_converters.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/common/message_port_types.h"
|
| +#include "mojo/common/common_type_converters.h"
|
| +#include "url/gurl.h"
|
| +
|
| +namespace content {
|
| +
|
| +// static
|
| +void ServicePortServiceImpl::Create(
|
| + const scoped_refptr<NavigatorConnectContextImpl>& navigator_connect_context,
|
| + const scoped_refptr<MessagePortMessageFilter>& message_port_message_filter,
|
| + mojo::InterfaceRequest<ServicePortService> request) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&ServicePortServiceImpl::CreateOnIOThread,
|
| + navigator_connect_context, message_port_message_filter,
|
| + base::Passed(&request)));
|
| +}
|
| +
|
| +ServicePortServiceImpl::~ServicePortServiceImpl() {
|
| + // Should always be destroyed on the IO thread, but can't check that with
|
| + // DCHECK_CURRENTLY_ON because this class could be destroyed during thread
|
| + // shutdown, at which point that check doesn't work.
|
| + navigator_connect_context_->ServicePortServiceDestroyed(this);
|
| +}
|
| +
|
| +void ServicePortServiceImpl::PostMessageToClient(
|
| + int port_id,
|
| + const MessagePortMessage& message,
|
| + const std::vector<TransferredMessagePort>& sent_message_ports) {
|
| + DCHECK(client_.get());
|
| + // Hold messages on transferred message ports. Normally this wouldn't be
|
| + // needed, but since MessagePort uses regular IPC while this class uses mojo,
|
| + // without holding messages mojo IPC might overtake regular IPC resulting in a
|
| + // non-functional port. When WebMessagePortChannelImpl instances are
|
| + // constructed in the renderer, they will send
|
| + // MessagePortHostMsg_ReleaseMessages to release messages.
|
| + for (const auto& port : sent_message_ports)
|
| + MessagePortService::GetInstance()->HoldMessages(port.id);
|
| +
|
| + std::vector<int> new_routing_ids;
|
| + message_port_message_filter_->UpdateMessagePortsWithNewRoutes(
|
| + sent_message_ports, &new_routing_ids);
|
| + client_->PostMessage(
|
| + port_id, mojo::String::From(message.message_as_string),
|
| + mojo::Array<MojoTransferredMessagePortPtr>::From(sent_message_ports),
|
| + mojo::Array<int32_t>::From(new_routing_ids));
|
| +}
|
| +
|
| +// static
|
| +void ServicePortServiceImpl::CreateOnIOThread(
|
| + const scoped_refptr<NavigatorConnectContextImpl>& navigator_connect_context,
|
| + const scoped_refptr<MessagePortMessageFilter>& message_port_message_filter,
|
| + mojo::InterfaceRequest<ServicePortService> request) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + new ServicePortServiceImpl(navigator_connect_context,
|
| + message_port_message_filter, request.Pass());
|
| +}
|
| +
|
| +ServicePortServiceImpl::ServicePortServiceImpl(
|
| + const scoped_refptr<NavigatorConnectContextImpl>& navigator_connect_context,
|
| + const scoped_refptr<MessagePortMessageFilter>& message_port_message_filter,
|
| + mojo::InterfaceRequest<ServicePortService> request)
|
| + : binding_(this, request.Pass()),
|
| + navigator_connect_context_(navigator_connect_context),
|
| + message_port_message_filter_(message_port_message_filter),
|
| + weak_ptr_factory_(this) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| +}
|
| +
|
| +void ServicePortServiceImpl::SetClient(ServicePortServiceClientPtr client) {
|
| + DCHECK(!client_.get());
|
| + // TODO(mek): Set ErrorHandler to listen for errors.
|
| + client_ = client.Pass();
|
| +}
|
| +
|
| +void ServicePortServiceImpl::Connect(const mojo::String& target_url,
|
| + const mojo::String& origin,
|
| + const ConnectCallback& callback) {
|
| + navigator_connect_context_->Connect(
|
| + GURL(target_url), GURL(origin), this,
|
| + base::Bind(&ServicePortServiceImpl::OnConnectResult,
|
| + weak_ptr_factory_.GetWeakPtr(), callback));
|
| +}
|
| +
|
| +void ServicePortServiceImpl::PostMessage(
|
| + int32_t port_id,
|
| + const mojo::String& message,
|
| + mojo::Array<MojoTransferredMessagePortPtr> ports) {
|
| + // TODO(mek): Similar to http://crbug.com/490222 this code should make sure
|
| + // port_id belongs to the process this IPC was received from.
|
| + std::vector<TransferredMessagePort> transferred_ports =
|
| + ports.To<std::vector<TransferredMessagePort>>();
|
| +
|
| + MessagePortService* mps = MessagePortService::GetInstance();
|
| + // First, call QueueMessages for all transferred ports, since the ports
|
| + // haven't sent their own IPC for that.
|
| + for (const TransferredMessagePort& port : transferred_ports) {
|
| + mps->QueueMessages(port.id);
|
| + }
|
| +
|
| + // Second, pass of the actual to MessagePortService now ServicePort instances
|
| + // are still backed by MessagePort.
|
| + mps->PostMessage(port_id, MessagePortMessage(message.To<base::string16>()),
|
| + transferred_ports);
|
| +}
|
| +
|
| +void ServicePortServiceImpl::ClosePort(int32_t port_id) {
|
| + MessagePortService::GetInstance()->Destroy(port_id);
|
| +}
|
| +
|
| +void ServicePortServiceImpl::OnConnectResult(const ConnectCallback& callback,
|
| + int message_port_id,
|
| + bool success) {
|
| + callback.Run(success ? SERVICE_PORT_CONNECT_RESULT_ACCEPT
|
| + : SERVICE_PORT_CONNECT_RESULT_REJECT,
|
| + message_port_id);
|
| +}
|
| +
|
| +} // namespace content
|
|
|