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"
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(
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
);
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
));
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(
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 // Second, pass of the actual to MessagePortService now ServicePort instances
114 // are still backed by MessagePort.
115 mps
->PostMessage(port_id
, MessagePortMessage(message
.To
<base::string16
>()),
119 void ServicePortServiceImpl::ClosePort(int32_t port_id
) {
120 MessagePortService::GetInstance()->Destroy(port_id
);
123 void ServicePortServiceImpl::OnConnectResult(const ConnectCallback
& callback
,
126 callback
.Run(success
? SERVICE_PORT_CONNECT_RESULT_ACCEPT
127 : SERVICE_PORT_CONNECT_RESULT_REJECT
,
131 } // namespace content