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

Side by Side Diff: content/browser/navigator_connect/navigator_connect_context_impl.cc

Issue 1278483004: Revert of Refactor browser side navigator.connect code to not use MessagePortService. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@serviceport-serviceside
Patch Set: Created 5 years, 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/navigator_connect/navigator_connect_context_impl.h" 5 #include "content/browser/navigator_connect/navigator_connect_context_impl.h"
6 6
7 #include "content/browser/message_port_message_filter.h"
7 #include "content/browser/message_port_service.h" 8 #include "content/browser/message_port_service.h"
8 #include "content/browser/navigator_connect/service_port_service_impl.h" 9 #include "content/browser/navigator_connect/service_port_service_impl.h"
9 #include "content/browser/service_worker/service_worker_context_wrapper.h" 10 #include "content/public/browser/message_port_provider.h"
10 #include "content/browser/service_worker/service_worker_utils.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/navigator_connect_service_factory.h" 11 #include "content/public/browser/navigator_connect_service_factory.h"
13 #include "content/public/common/navigator_connect_client.h" 12 #include "content/public/common/navigator_connect_client.h"
14 13
15 namespace content { 14 namespace content {
16 15
17 struct NavigatorConnectContextImpl::Port { 16 struct NavigatorConnectContextImpl::Port {
18 // ID of this port. 17 int message_port_id;
19 int id;
20 // ID of the port this port is connected to.
21 int entangled_id;
22
23 // Service url and client origin describing this connection. These fields will
24 // always be the same as the same fields for the entangled port.
25 GURL target_url;
26 GURL client_origin;
27
28 // Set to nullptr when the ServicePortService goes away. 18 // Set to nullptr when the ServicePortService goes away.
29 ServicePortServiceImpl* service; 19 ServicePortServiceImpl* service;
30
31 // If this port is associated with a service worker, these fields store that
32 // information.
33 int64 service_worker_registration_id = kInvalidServiceWorkerRegistrationId;
34 GURL service_worker_registration_origin;
35 }; 20 };
36 21
37 NavigatorConnectContextImpl::NavigatorConnectContextImpl( 22 NavigatorConnectContextImpl::NavigatorConnectContextImpl() {
38 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context) 23 }
39 : service_worker_context_(service_worker_context), next_port_id_(0) {}
40 24
41 NavigatorConnectContextImpl::~NavigatorConnectContextImpl() { 25 NavigatorConnectContextImpl::~NavigatorConnectContextImpl() {
42 } 26 }
43 27
44 void NavigatorConnectContextImpl::AddFactory( 28 void NavigatorConnectContextImpl::AddFactory(
45 scoped_ptr<NavigatorConnectServiceFactory> factory) { 29 scoped_ptr<NavigatorConnectServiceFactory> factory) {
46 DCHECK_CURRENTLY_ON(BrowserThread::UI); 30 DCHECK_CURRENTLY_ON(BrowserThread::UI);
47 BrowserThread::PostTask( 31 BrowserThread::PostTask(
48 BrowserThread::IO, FROM_HERE, 32 BrowserThread::IO, FROM_HERE,
49 base::Bind(&NavigatorConnectContextImpl::AddFactoryOnIOThread, this, 33 base::Bind(&NavigatorConnectContextImpl::AddFactoryOnIOThread, this,
50 base::Passed(&factory))); 34 base::Passed(&factory)));
51 } 35 }
52 36
53 void NavigatorConnectContextImpl::AddFactoryOnIOThread( 37 void NavigatorConnectContextImpl::AddFactoryOnIOThread(
54 scoped_ptr<NavigatorConnectServiceFactory> factory) { 38 scoped_ptr<NavigatorConnectServiceFactory> factory) {
55 DCHECK_CURRENTLY_ON(BrowserThread::IO); 39 DCHECK_CURRENTLY_ON(BrowserThread::IO);
56 service_factories_.push_back(factory.release()); 40 service_factories_.push_back(factory.release());
57 } 41 }
58 42
59 void NavigatorConnectContextImpl::Connect( 43 void NavigatorConnectContextImpl::Connect(
60 const GURL& target_url, 44 const GURL& target_url,
61 const GURL& origin, 45 const GURL& origin,
62 ServicePortServiceImpl* service_port_service, 46 ServicePortServiceImpl* service_port_service,
63 const ConnectCallback& callback) { 47 const ConnectCallback& callback) {
64 DCHECK_CURRENTLY_ON(BrowserThread::IO); 48 DCHECK_CURRENTLY_ON(BrowserThread::IO);
65 // Create a new message channel. 49 // Create a new message channel. Use |this| as delegate for both ports until
66 int client_port_id = next_port_id_++; 50 // the real delegate for the service port is known later on.
67 int service_port_id = next_port_id_++; 51 int client_port_id;
52 int service_port;
53 MessagePortProvider::CreateMessageChannel(this, &client_port_id,
54 &service_port);
55 // Hold messages send to the client while setting up connection.
56 MessagePortService::GetInstance()->HoldMessages(client_port_id);
68 57
69 Port& client_port = ports_[client_port_id]; 58 Port& client_port = ports_[client_port_id];
70 client_port.id = client_port_id; 59 client_port.message_port_id = client_port_id;
71 client_port.entangled_id = service_port_id;
72 client_port.target_url = target_url;
73 client_port.client_origin = origin;
74 client_port.service = service_port_service; 60 client_port.service = service_port_service;
75 61
76 Port& service_port = ports_[service_port_id]; 62 // The message_port_id stored in the client object is the one associated with
77 service_port.id = service_port_id; 63 // the service.
78 service_port.entangled_id = client_port_id; 64 NavigatorConnectClient client(target_url, origin, service_port);
79 service_port.target_url = target_url;
80 service_port.client_origin = origin;
81 65
82 // Find the right service worker to service this connection. 66 // Find factory to handle request, more recently added factories should take
83 service_worker_context_->FindRegistrationForDocument( 67 // priority as per comment at NavigatorConnectContext::AddFactory..
84 target_url, 68 NavigatorConnectServiceFactory* factory = nullptr;
85 base::Bind(&NavigatorConnectContextImpl::GotServiceWorkerRegistration, 69 for (auto it = service_factories_.rbegin(); it != service_factories_.rend();
86 this, callback, client_port_id, service_port_id)); 70 ++it) {
87 } 71 if ((*it)->HandlesUrl(client.target_url)) {
88 72 factory = *it;
89 void NavigatorConnectContextImpl::PostMessage( 73 break;
90 int sender_port_id, 74 }
91 const MessagePortMessage& message,
92 const std::vector<TransferredMessagePort>& sent_message_ports) {
93 DCHECK_CURRENTLY_ON(BrowserThread::IO);
94 DCHECK(ports_.find(sender_port_id) != ports_.end());
95 DCHECK(message.message_as_value.empty());
96
97 const Port& sender_port = ports_[sender_port_id];
98 DCHECK(ports_.find(sender_port.entangled_id) != ports_.end());
99 const Port& port = ports_[sender_port.entangled_id];
100
101 if (port.service_worker_registration_id !=
102 kInvalidServiceWorkerRegistrationId) {
103 // Port is associated with service worker, dispatch message event via
104 // ServiceWorkerVersion.
105
106 // Hold messages on transferred message ports. Actual delivery of the
107 // message by the service can be asynchronous. When a message is delivered,
108 // WebMessagePortChannelImpl instances will be constructed which send
109 // MessagePortHostMsg_ReleaseMessages to release messages.
110 for (const auto& sent_port : sent_message_ports)
111 MessagePortService::GetInstance()->HoldMessages(sent_port.id);
112
113 service_worker_context_->FindRegistrationForId(
114 port.service_worker_registration_id,
115 port.service_worker_registration_origin,
116 base::Bind(&NavigatorConnectContextImpl::DeliverMessage, this, port.id,
117 message.message_as_string, sent_message_ports));
118 } 75 }
119 76
120 if (!port.service) { 77 if (!factory) {
121 // TODO(mek): Figure out what to do in this situation. 78 // No factories found.
122 return; 79 OnConnectResult(client, client_port_id, callback, nullptr, false);
123 }
124 port.service->PostMessageToClient(port.id, message, sent_message_ports);
125 }
126
127 void NavigatorConnectContextImpl::GotServiceWorkerRegistration(
128 const ConnectCallback& callback,
129 int client_port_id,
130 int service_port_id,
131 ServiceWorkerStatusCode status,
132 const scoped_refptr<ServiceWorkerRegistration>& registration) {
133 DCHECK_CURRENTLY_ON(BrowserThread::IO);
134 DCHECK(ports_.find(client_port_id) != ports_.end());
135 DCHECK(ports_.find(service_port_id) != ports_.end());
136
137 if (status != SERVICE_WORKER_OK) {
138 // No service worker found, reject connection attempt.
139 OnConnectResult(callback, client_port_id, service_port_id, registration,
140 status, false, base::string16(), base::string16());
141 return; 80 return;
142 } 81 }
143 82
144 ServiceWorkerVersion* active_version = registration->active_version(); 83 // Actually initiate connection.
145 if (!active_version) { 84 factory->Connect(
146 // No active version, reject connection attempt. 85 client, base::Bind(&NavigatorConnectContextImpl::OnConnectResult, this,
147 OnConnectResult(callback, client_port_id, service_port_id, registration, 86 client, client_port_id, callback));
148 status, false, base::string16(), base::string16());
149 return;
150 }
151
152 Port& service_port = ports_[service_port_id];
153 service_port.service_worker_registration_id = registration->id();
154 service_port.service_worker_registration_origin =
155 registration->pattern().GetOrigin();
156
157 active_version->DispatchServicePortConnectEvent(
158 base::Bind(&NavigatorConnectContextImpl::OnConnectResult, this, callback,
159 client_port_id, service_port_id, registration),
160 service_port.target_url, service_port.client_origin, service_port_id);
161 } 87 }
162 88
163 void NavigatorConnectContextImpl::ServicePortServiceDestroyed( 89 void NavigatorConnectContextImpl::ServicePortServiceDestroyed(
164 ServicePortServiceImpl* service_port_service) { 90 ServicePortServiceImpl* service_port_service) {
165 DCHECK_CURRENTLY_ON(BrowserThread::IO);
166 for (auto& port : ports_) { 91 for (auto& port : ports_) {
167 if (port.second.service != service_port_service) 92 if (port.second.service != service_port_service)
168 continue; 93 continue;
169 port.second.service = nullptr; 94 port.second.service = nullptr;
170 // TODO(mek): Should actually inform other side of connections that the 95 // TODO(mek): Should actually inform other side of connections that the
171 // connection was closed, or in the case of service workers somehow keep 96 // connection was closed, or in the case of service workers somehow keep
172 // track of the connection. 97 // track of the connection.
173 } 98 }
174 } 99 }
175 100
101 void NavigatorConnectContextImpl::SendMessage(
102 int route_id,
103 const MessagePortMessage& message,
104 const std::vector<TransferredMessagePort>& sent_message_ports) {
105 DCHECK(ports_.find(route_id) != ports_.end());
106 const Port& port = ports_[route_id];
107 if (!port.service) {
108 // TODO(mek): Figure out what to do in this situation.
109 return;
110 }
111
112 port.service->PostMessageToClient(route_id, message, sent_message_ports);
113 }
114
115 void NavigatorConnectContextImpl::SendMessagesAreQueued(int route_id) {
116 NOTREACHED() << "navigator.services endpoints should never queue messages.";
117 }
118
176 void NavigatorConnectContextImpl::OnConnectResult( 119 void NavigatorConnectContextImpl::OnConnectResult(
120 const NavigatorConnectClient& client,
121 int client_message_port_id,
177 const ConnectCallback& callback, 122 const ConnectCallback& callback,
178 int client_port_id, 123 MessagePortDelegate* delegate,
179 int service_port_id, 124 bool data_as_values) {
180 const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
181 ServiceWorkerStatusCode status,
182 bool accept_connection,
183 const base::string16& name,
184 const base::string16& data) {
185 DCHECK_CURRENTLY_ON(BrowserThread::IO); 125 DCHECK_CURRENTLY_ON(BrowserThread::IO);
186 if (accept_connection) { 126 if (delegate) {
127 DCHECK(!data_as_values) << "Data as values is not currently implemented";
187 // TODO(mek): Might have to do something else if the client connection got 128 // TODO(mek): Might have to do something else if the client connection got
188 // severed while the service side connection was being set up. 129 // severed while the service side connection was being set up.
189 callback.Run(client_port_id, true); 130
131 // Update service side port with delegate.
132 MessagePortService::GetInstance()->UpdateMessagePort(
133 client.message_port_id, delegate, client.message_port_id);
134 callback.Run(client_message_port_id, true);
135 MessagePortService::GetInstance()->ReleaseMessages(client_message_port_id);
190 } else { 136 } else {
191 // Destroy ports since connection failed. 137 // Destroy ports since connection failed.
192 ports_.erase(service_port_id); 138 MessagePortService::GetInstance()->Destroy(client.message_port_id);
193 ports_.erase(client_port_id); 139 MessagePortService::GetInstance()->Destroy(client_message_port_id);
140 ports_.erase(client_message_port_id);
194 callback.Run(MSG_ROUTING_NONE, false); 141 callback.Run(MSG_ROUTING_NONE, false);
195 } 142 }
196 } 143 }
197 144
198 void NavigatorConnectContextImpl::DeliverMessage(
199 int port_id,
200 const base::string16& message,
201 const std::vector<TransferredMessagePort>& sent_message_ports,
202 ServiceWorkerStatusCode service_worker_status,
203 const scoped_refptr<ServiceWorkerRegistration>&
204 service_worker_registration) {
205 DCHECK_CURRENTLY_ON(BrowserThread::IO);
206 DCHECK(ports_.find(port_id) != ports_.end());
207
208 if (service_worker_status != SERVICE_WORKER_OK) {
209 // TODO(mek): Do something when no service worker was found.
210 return;
211 }
212
213 ServiceWorkerVersion* active_version =
214 service_worker_registration->active_version();
215 if (!active_version) {
216 // TODO(mek): Do something when no active version exists.
217 return;
218 }
219
220 const Port& port = ports_[port_id];
221 NavigatorConnectClient client(port.target_url, port.client_origin, port_id);
222 active_version->DispatchCrossOriginMessageEvent(
223 client, message, sent_message_ports,
224 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
225 }
226
227 } // namespace content 145 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698