| Index: content/browser/navigator_connect/navigator_connect_context_impl.cc
|
| diff --git a/content/browser/navigator_connect/navigator_connect_context_impl.cc b/content/browser/navigator_connect/navigator_connect_context_impl.cc
|
| index c5f01f4534a60e52c622eb4c0d66f266a645ae4c..94bdc82e7e64fd53297a5b806a017a62e638cfd3 100644
|
| --- a/content/browser/navigator_connect/navigator_connect_context_impl.cc
|
| +++ b/content/browser/navigator_connect/navigator_connect_context_impl.cc
|
| @@ -6,11 +6,19 @@
|
|
|
| #include "content/browser/message_port_message_filter.h"
|
| #include "content/browser/message_port_service.h"
|
| +#include "content/browser/navigator_connect/service_port_service_impl.h"
|
| +#include "content/public/browser/message_port_provider.h"
|
| #include "content/public/browser/navigator_connect_service_factory.h"
|
| #include "content/public/common/navigator_connect_client.h"
|
|
|
| namespace content {
|
|
|
| +struct NavigatorConnectContextImpl::Port {
|
| + int message_port_id;
|
| + // Set to nullptr when the ServicePortService goes away.
|
| + ServicePortServiceImpl* service;
|
| +};
|
| +
|
| NavigatorConnectContextImpl::NavigatorConnectContextImpl() {
|
| }
|
|
|
| @@ -33,27 +41,27 @@ void NavigatorConnectContextImpl::AddFactoryOnIOThread(
|
| }
|
|
|
| void NavigatorConnectContextImpl::Connect(
|
| - NavigatorConnectClient client,
|
| - MessagePortMessageFilter* message_port_message_filter,
|
| + const GURL& target_url,
|
| + const GURL& origin,
|
| + ServicePortServiceImpl* service_port_service,
|
| const ConnectCallback& callback) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| - // Create a new message channel. Client port is setup to talk to client
|
| - // process, service port is initially setup without a delegate.
|
| - MessagePortService* message_port_service = MessagePortService::GetInstance();
|
| - int client_port;
|
| - int client_port_route_id = message_port_message_filter->GetNextRoutingID();
|
| - message_port_service->Create(client_port_route_id,
|
| - message_port_message_filter, &client_port);
|
| + // Create a new message channel. Use |this| as delegate for both ports until
|
| + // the real delegate for the service port is known later on.
|
| + int client_port_id;
|
| int service_port;
|
| - message_port_service->Create(MSG_ROUTING_NONE, nullptr, &service_port);
|
| - message_port_service->Entangle(client_port, service_port);
|
| - message_port_service->Entangle(service_port, client_port);
|
| - // Hold messages on client port while setting up connection.
|
| - message_port_service->HoldMessages(client_port);
|
| + MessagePortProvider::CreateMessageChannel(this, &client_port_id,
|
| + &service_port);
|
| + // Hold messages send to the client while setting up connection.
|
| + MessagePortService::GetInstance()->HoldMessages(client_port_id);
|
| +
|
| + Port& client_port = ports_[client_port_id];
|
| + client_port.message_port_id = client_port_id;
|
| + client_port.service = service_port_service;
|
|
|
| // The message_port_id stored in the client object is the one associated with
|
| // the service.
|
| - client.message_port_id = service_port;
|
| + NavigatorConnectClient client(target_url, origin, service_port);
|
|
|
| // Find factory to handle request, more recently added factories should take
|
| // priority as per comment at NavigatorConnectContext::AddFactory..
|
| @@ -68,38 +76,69 @@ void NavigatorConnectContextImpl::Connect(
|
|
|
| if (!factory) {
|
| // No factories found.
|
| - OnConnectResult(client, client_port, client_port_route_id, callback,
|
| - nullptr, false);
|
| + OnConnectResult(client, client_port_id, callback, nullptr, false);
|
| return;
|
| }
|
|
|
| // Actually initiate connection.
|
| factory->Connect(
|
| client, base::Bind(&NavigatorConnectContextImpl::OnConnectResult, this,
|
| - client, client_port, client_port_route_id, callback));
|
| + client, client_port_id, callback));
|
| +}
|
| +
|
| +void NavigatorConnectContextImpl::ServicePortServiceDestroyed(
|
| + ServicePortServiceImpl* service_port_service) {
|
| + for (auto& port : ports_) {
|
| + if (port.second.service != service_port_service)
|
| + continue;
|
| + port.second.service = nullptr;
|
| + // TODO(mek): Should actually inform other side of connections that the
|
| + // connection was closed, or in the case of service workers somehow keep
|
| + // track of the connection.
|
| + }
|
| +}
|
| +
|
| +void NavigatorConnectContextImpl::SendMessage(
|
| + int route_id,
|
| + const MessagePortMessage& message,
|
| + const std::vector<TransferredMessagePort>& sent_message_ports) {
|
| + DCHECK(ports_.find(route_id) != ports_.end());
|
| + const Port& port = ports_[route_id];
|
| + if (!port.service) {
|
| + // TODO(mek): Figure out what to do in this situation.
|
| + return;
|
| + }
|
| +
|
| + port.service->PostMessageToClient(route_id, message, sent_message_ports);
|
| +}
|
| +
|
| +void NavigatorConnectContextImpl::SendMessagesAreQueued(int route_id) {
|
| + NOTREACHED() << "navigator.services endpoints should never queue messages.";
|
| }
|
|
|
| void NavigatorConnectContextImpl::OnConnectResult(
|
| const NavigatorConnectClient& client,
|
| int client_message_port_id,
|
| - int client_port_route_id,
|
| const ConnectCallback& callback,
|
| MessagePortDelegate* delegate,
|
| bool data_as_values) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| if (delegate) {
|
| + DCHECK(!data_as_values) << "Data as values is not currently implemented";
|
| + // TODO(mek): Might have to do something else if the client connection got
|
| + // severed while the service side connection was being set up.
|
| +
|
| // Update service side port with delegate.
|
| MessagePortService::GetInstance()->UpdateMessagePort(
|
| client.message_port_id, delegate, client.message_port_id);
|
| - TransferredMessagePort port;
|
| - port.id = client_message_port_id;
|
| - port.send_messages_as_values = data_as_values;
|
| - callback.Run(port, client_port_route_id, true);
|
| + callback.Run(client_message_port_id, true);
|
| + MessagePortService::GetInstance()->ReleaseMessages(client_message_port_id);
|
| } else {
|
| // Destroy ports since connection failed.
|
| MessagePortService::GetInstance()->Destroy(client.message_port_id);
|
| MessagePortService::GetInstance()->Destroy(client_message_port_id);
|
| - callback.Run(TransferredMessagePort(), MSG_ROUTING_NONE, false);
|
| + ports_.erase(client_message_port_id);
|
| + callback.Run(MSG_ROUTING_NONE, false);
|
| }
|
| }
|
|
|
|
|