Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / browser / navigator_connect / service_port_service_impl.cc
blobc8847a7f5b4413156a1d1f859ba395051f97a3c9
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/navigator_connect/service_port_service_impl.h"
7 #include "content/browser/message_port_message_filter.h"
8 #include "content/browser/message_port_service.h"
9 #include "content/browser/navigator_connect/navigator_connect_context_impl.h"
10 #include "content/common/service_port_type_converters.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/common/message_port_types.h"
13 #include "mojo/common/common_type_converters.h"
14 #include "url/gurl.h"
16 namespace content {
18 // static
19 void ServicePortServiceImpl::Create(
20 const scoped_refptr<NavigatorConnectContextImpl>& navigator_connect_context,
21 const scoped_refptr<MessagePortMessageFilter>& message_port_message_filter,
22 mojo::InterfaceRequest<ServicePortService> request) {
23 DCHECK_CURRENTLY_ON(BrowserThread::UI);
24 BrowserThread::PostTask(
25 BrowserThread::IO, FROM_HERE,
26 base::Bind(&ServicePortServiceImpl::CreateOnIOThread,
27 navigator_connect_context, message_port_message_filter,
28 base::Passed(&request)));
31 ServicePortServiceImpl::~ServicePortServiceImpl() {
32 // Should always be destroyed on the IO thread, but can't check that with
33 // DCHECK_CURRENTLY_ON because this class could be destroyed during thread
34 // shutdown, at which point that check doesn't work.
35 navigator_connect_context_->ServicePortServiceDestroyed(this);
38 void ServicePortServiceImpl::PostMessageToClient(
39 int port_id,
40 const MessagePortMessage& message,
41 const std::vector<TransferredMessagePort>& sent_message_ports) {
42 DCHECK(client_.get());
43 // Hold messages on transferred message ports. Normally this wouldn't be
44 // needed, but since MessagePort uses regular IPC while this class uses mojo,
45 // without holding messages mojo IPC might overtake regular IPC resulting in a
46 // non-functional port. When WebMessagePortChannelImpl instances are
47 // constructed in the renderer, they will send
48 // MessagePortHostMsg_ReleaseMessages to release messages.
49 for (const auto& port : sent_message_ports)
50 MessagePortService::GetInstance()->HoldMessages(port.id);
52 std::vector<int> new_routing_ids;
53 message_port_message_filter_->UpdateMessagePortsWithNewRoutes(
54 sent_message_ports, &new_routing_ids);
55 client_->PostMessage(
56 port_id, mojo::String::From(message.message_as_string),
57 mojo::Array<MojoTransferredMessagePortPtr>::From(sent_message_ports),
58 mojo::Array<int32_t>::From(new_routing_ids));
61 // static
62 void ServicePortServiceImpl::CreateOnIOThread(
63 const scoped_refptr<NavigatorConnectContextImpl>& navigator_connect_context,
64 const scoped_refptr<MessagePortMessageFilter>& message_port_message_filter,
65 mojo::InterfaceRequest<ServicePortService> request) {
66 DCHECK_CURRENTLY_ON(BrowserThread::IO);
67 new ServicePortServiceImpl(navigator_connect_context,
68 message_port_message_filter, request.Pass());
71 ServicePortServiceImpl::ServicePortServiceImpl(
72 const scoped_refptr<NavigatorConnectContextImpl>& navigator_connect_context,
73 const scoped_refptr<MessagePortMessageFilter>& message_port_message_filter,
74 mojo::InterfaceRequest<ServicePortService> request)
75 : binding_(this, request.Pass()),
76 navigator_connect_context_(navigator_connect_context),
77 message_port_message_filter_(message_port_message_filter),
78 weak_ptr_factory_(this) {
79 DCHECK_CURRENTLY_ON(BrowserThread::IO);
82 void ServicePortServiceImpl::SetClient(ServicePortServiceClientPtr client) {
83 DCHECK(!client_.get());
84 // TODO(mek): Set ErrorHandler to listen for errors.
85 client_ = client.Pass();
88 void ServicePortServiceImpl::Connect(const mojo::String& target_url,
89 const mojo::String& origin,
90 const ConnectCallback& callback) {
91 navigator_connect_context_->Connect(
92 GURL(target_url), GURL(origin), this,
93 base::Bind(&ServicePortServiceImpl::OnConnectResult,
94 weak_ptr_factory_.GetWeakPtr(), callback));
97 void ServicePortServiceImpl::PostMessage(
98 int32_t port_id,
99 const mojo::String& message,
100 mojo::Array<MojoTransferredMessagePortPtr> ports) {
101 // TODO(mek): Similar to http://crbug.com/490222 this code should make sure
102 // port_id belongs to the process this IPC was received from.
103 std::vector<TransferredMessagePort> transferred_ports =
104 ports.To<std::vector<TransferredMessagePort>>();
106 MessagePortService* mps = MessagePortService::GetInstance();
107 // First, call QueueMessages for all transferred ports, since the ports
108 // haven't sent their own IPC for that.
109 for (const TransferredMessagePort& port : transferred_ports) {
110 mps->QueueMessages(port.id);
113 navigator_connect_context_->PostMessage(
114 port_id, MessagePortMessage(message.To<base::string16>()),
115 transferred_ports);
118 void ServicePortServiceImpl::ClosePort(int32_t port_id) {
119 MessagePortService::GetInstance()->Destroy(port_id);
122 void ServicePortServiceImpl::OnConnectResult(const ConnectCallback& callback,
123 int message_port_id,
124 bool success) {
125 callback.Run(success ? SERVICE_PORT_CONNECT_RESULT_ACCEPT
126 : SERVICE_PORT_CONNECT_RESULT_REJECT,
127 message_port_id);
130 } // namespace content