Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Unified Diff: content/browser/navigator_connect/service_port_service_impl.cc

Issue 1192713004: Update client side navigator.connect API to use ServicePortCollection [2/3] (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address comments Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698