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

Side by Side Diff: content/child/navigator_connect/navigator_connect_provider.cc

Issue 781723002: Pass navigator.connect calls through to the browser process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 years 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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.
4
5 #include "content/child/navigator_connect/navigator_connect_provider.h"
6
7 #include "base/lazy_instance.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/task_runner_util.h"
10 #include "content/child/thread_safe_sender.h"
11 #include "content/child/webmessageportchannel_impl.h"
12 #include "content/common/navigator_connect_messages.h"
13 #include "content/common/navigator_connect_types.h"
14 #include "third_party/WebKit/public/platform/WebCallbacks.h"
15 #include "third_party/WebKit/public/platform/WebURL.h"
16
17 namespace content {
18
19 namespace {
20
21 base::LazyInstance<base::ThreadLocalPointer<NavigatorConnectProvider>>::Leaky
22 g_provider_tls = LAZY_INSTANCE_INITIALIZER;
23
24 NavigatorConnectProvider* const kHasBeenDeleted =
25 reinterpret_cast<NavigatorConnectProvider*>(0x1);
26
27 int CurrentWorkerId() {
28 return WorkerTaskRunner::Instance()->CurrentWorkerId();
29 }
30
31 // Extracts the message_port_id from a message port, and queues messages for the
32 // port. This is a separate method since while all of this can be done on any
33 // thread, to get ordering right it is easiest to do both these things on the
34 // main thread.
35 int QueueMessagesAndGetMessagePortId(WebMessagePortChannelImpl* webchannel) {
36 int message_port_id = webchannel->message_port_id();
37 DCHECK(message_port_id != MSG_ROUTING_NONE);
38 webchannel->QueueMessages();
39 return message_port_id;
40 }
41
42 void SendConnectMessage(const scoped_refptr<ThreadSafeSender>& sender,
43 int thread_id,
44 int request_id,
45 const GURL& target_url,
46 const GURL& origin,
47 int message_port_id) {
48 sender->Send(new NavigatorConnectHostMsg_Connect(
49 thread_id, request_id,
50 CrossOriginServiceWorkerClient(target_url, origin, message_port_id)));
51 }
52
53 } // namespace
54
55 NavigatorConnectProvider::NavigatorConnectProvider(
56 ThreadSafeSender* thread_safe_sender,
57 const scoped_refptr<base::SingleThreadTaskRunner>& main_loop)
58 : thread_safe_sender_(thread_safe_sender), main_loop_(main_loop) {
59 g_provider_tls.Pointer()->Set(this);
60 }
61
62 NavigatorConnectProvider::~NavigatorConnectProvider() {
63 g_provider_tls.Pointer()->Set(kHasBeenDeleted);
64 }
65
66 void NavigatorConnectProvider::connect(
67 const blink::WebURL& target_url,
68 const blink::WebString& origin,
69 blink::WebMessagePortChannel* port,
70 blink::WebCallbacks<void, void>* callbacks) {
71 int request_id = requests_.Add(callbacks);
72
73 WebMessagePortChannelImpl* webchannel =
74 static_cast<WebMessagePortChannelImpl*>(port);
75
76 if (main_loop_->BelongsToCurrentThread()) {
77 SendConnectMessage(thread_safe_sender_, CurrentWorkerId(), request_id,
78 target_url, GURL(origin),
79 QueueMessagesAndGetMessagePortId(webchannel));
80 } else {
81 // WebMessagePortChannelImpl is mostly thread safe, but is only fully
82 // initialized after a round-trip to the main thread. This means that at
83 // this point the class might not be fully initialized yet. To work around
84 // this, call QueueMessages and extract the message_port_id on the main
85 // thread.
86 // Furthermore the last reference to WebMessagePortChannelImpl has to be
87 // released on the main thread as well. To ensure this happens correctly,
88 // it is passed using base::Unretained. Without that the closure could
89 // hold the last reference, which would be deleted on the wrong thread.
90 PostTaskAndReplyWithResult(
91 main_loop_.get(), FROM_HERE,
92 base::Bind(&QueueMessagesAndGetMessagePortId,
93 base::Unretained(webchannel)),
94 base::Bind(&SendConnectMessage, thread_safe_sender_, CurrentWorkerId(),
95 request_id, target_url, GURL(origin)));
96 }
97 }
98
99 void NavigatorConnectProvider::OnMessageReceived(const IPC::Message& msg) {
100 bool handled = true;
101 IPC_BEGIN_MESSAGE_MAP(NavigatorConnectProvider, msg)
102 IPC_MESSAGE_HANDLER(NavigatorConnectMsg_ConnectResult, OnConnectResult)
103 IPC_MESSAGE_UNHANDLED(handled = false)
104 IPC_END_MESSAGE_MAP()
105 DCHECK(handled) << "Unhandled message:" << msg.type();
106 }
107
108 NavigatorConnectProvider* NavigatorConnectProvider::ThreadSpecificInstance(
109 ThreadSafeSender* thread_safe_sender,
110 const scoped_refptr<base::SingleThreadTaskRunner>& main_loop) {
111 if (g_provider_tls.Pointer()->Get() == kHasBeenDeleted) {
112 NOTREACHED() << "Re-instantiating TLS NavigatorConnectProvider.";
113 g_provider_tls.Pointer()->Set(NULL);
114 }
115 if (g_provider_tls.Pointer()->Get())
116 return g_provider_tls.Pointer()->Get();
117
118 NavigatorConnectProvider* provider =
119 new NavigatorConnectProvider(thread_safe_sender, main_loop);
120 if (WorkerTaskRunner::Instance()->CurrentWorkerId())
121 WorkerTaskRunner::Instance()->AddStopObserver(provider);
122 return provider;
123 }
124
125 void NavigatorConnectProvider::OnConnectResult(int thread_id,
126 int request_id,
127 bool allow_connect) {
128 ConnectCallback* callbacks = requests_.Lookup(request_id);
129 DCHECK(callbacks);
130
131 if (allow_connect) {
132 callbacks->onSuccess();
133 } else {
134 callbacks->onError();
135 }
136 requests_.Remove(request_id);
137 }
138
139 void NavigatorConnectProvider::OnWorkerRunLoopStopped() {
140 delete this;
141 }
142
143 } // namespace content
OLDNEW
« no previous file with comments | « content/child/navigator_connect/navigator_connect_provider.h ('k') | content/common/content_message_generator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698