Commit c9182205 authored by mek's avatar mek Committed by Commit bot

Make it possible for a navigator.connect service to receive messages as base::Value.

Also adds a simple service to allow layout tests to test all this.

This is part of a series of changes:
[1/5] Blink side changes in https://codereview.chromium.org/924983002/ that expose a needed v8 context
[2/5] https://codereview.chromium.org/921013002/ allow MessagePort to send messages as values
[3/5] https://codereview.chromium.org/944443003/ which causes the send_messages_as_values flag to be propagated
[4/5] This CL
[5/5] https://codereview.chromium.org/940423004/ adds layout tests to blink to test these new features

BUG=426458

Review URL: https://codereview.chromium.org/938403005

Cr-Commit-Position: refs/heads/master@{#318903}
parent 27ff109c
...@@ -68,8 +68,8 @@ void NavigatorConnectContextImpl::Connect( ...@@ -68,8 +68,8 @@ void NavigatorConnectContextImpl::Connect(
if (!factory) { if (!factory) {
// No factories found. // No factories found.
OnConnectResult(client, client_port, client_port_route_id, OnConnectResult(client, client_port, client_port_route_id, callback,
callback, nullptr); nullptr, false);
return; return;
} }
...@@ -84,7 +84,8 @@ void NavigatorConnectContextImpl::OnConnectResult( ...@@ -84,7 +84,8 @@ void NavigatorConnectContextImpl::OnConnectResult(
int client_message_port_id, int client_message_port_id,
int client_port_route_id, int client_port_route_id,
const ConnectCallback& callback, const ConnectCallback& callback,
MessagePortDelegate* delegate) { MessagePortDelegate* delegate,
bool data_as_values) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (delegate) { if (delegate) {
// Update service side port with delegate. // Update service side port with delegate.
...@@ -92,7 +93,7 @@ void NavigatorConnectContextImpl::OnConnectResult( ...@@ -92,7 +93,7 @@ void NavigatorConnectContextImpl::OnConnectResult(
client.message_port_id, delegate, client.message_port_id); client.message_port_id, delegate, client.message_port_id);
TransferredMessagePort port; TransferredMessagePort port;
port.id = client_message_port_id; port.id = client_message_port_id;
// TODO(mek): Set port.send_value_as_messages depending on connect result. port.send_messages_as_values = data_as_values;
callback.Run(port, client_port_route_id, true); callback.Run(port, client_port_route_id, true);
} else { } else {
// Destroy ports since connection failed. // Destroy ports since connection failed.
......
...@@ -53,7 +53,8 @@ class NavigatorConnectContextImpl : public NavigatorConnectContext { ...@@ -53,7 +53,8 @@ class NavigatorConnectContextImpl : public NavigatorConnectContext {
int client_message_port_id, int client_message_port_id,
int client_port_route_id, int client_port_route_id,
const ConnectCallback& callback, const ConnectCallback& callback,
MessagePortDelegate* delegate); MessagePortDelegate* delegate,
bool data_as_values);
// List of factories to try to handle URLs. // List of factories to try to handle URLs.
ScopedVector<NavigatorConnectServiceFactory> service_factories_; ScopedVector<NavigatorConnectServiceFactory> service_factories_;
......
...@@ -185,14 +185,17 @@ void NavigatorConnectServiceWorkerServiceFactory::OnConnectResult( ...@@ -185,14 +185,17 @@ void NavigatorConnectServiceWorkerServiceFactory::OnConnectResult(
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (status != SERVICE_WORKER_OK || !accept_connection) { if (status != SERVICE_WORKER_OK || !accept_connection) {
callback.Run(nullptr); callback.Run(nullptr, false);
return; return;
} }
// TODO(mek): Keep track of NavigatorConnectServiceWorkerService instances and // TODO(mek): http://crbug.com/462744 Keep track of these
// clean them up when a service worker registration is deleted. // NavigatorConnectServiceWorkerService instances and clean them up when a
callback.Run(new NavigatorConnectServiceWorkerService( // service worker registration is deleted.
service_worker_context_, client, service_worker_registration)); callback.Run(
new NavigatorConnectServiceWorkerService(service_worker_context_, client,
service_worker_registration),
false);
} }
} // namespace content } // namespace content
...@@ -112,6 +112,8 @@ ...@@ -112,6 +112,8 @@
'shell/browser/layout_test/layout_test_javascript_dialog_manager.h', 'shell/browser/layout_test/layout_test_javascript_dialog_manager.h',
'shell/browser/layout_test/layout_test_message_filter.cc', 'shell/browser/layout_test/layout_test_message_filter.cc',
'shell/browser/layout_test/layout_test_message_filter.h', 'shell/browser/layout_test/layout_test_message_filter.h',
'shell/browser/layout_test/layout_test_navigator_connect_service_factory.cc',
'shell/browser/layout_test/layout_test_navigator_connect_service_factory.h',
'shell/browser/layout_test/layout_test_notification_manager.cc', 'shell/browser/layout_test/layout_test_notification_manager.cc',
'shell/browser/layout_test/layout_test_notification_manager.h', 'shell/browser/layout_test/layout_test_notification_manager.h',
'shell/browser/layout_test/layout_test_push_messaging_service.cc', 'shell/browser/layout_test/layout_test_push_messaging_service.cc',
......
...@@ -24,7 +24,11 @@ class NavigatorConnectServiceFactory { ...@@ -24,7 +24,11 @@ class NavigatorConnectServiceFactory {
// remains with the factory. It is assumed that for the passed // remains with the factory. It is assumed that for the passed
// MessagePortDelegate implementation the route_id and message_port_id of a // MessagePortDelegate implementation the route_id and message_port_id of a
// connection are the same. // connection are the same.
using ConnectCallback = base::Callback<void(MessagePortDelegate*)>; // Pass true to |data_as_values| if the delegate expects to receive messages
// from the client encoded as base::Value instead of the normal serialization
// format.
using ConnectCallback =
base::Callback<void(MessagePortDelegate*, bool data_as_values)>;
virtual ~NavigatorConnectServiceFactory() {} virtual ~NavigatorConnectServiceFactory() {}
......
...@@ -59,6 +59,8 @@ static_library("content_shell_lib") { ...@@ -59,6 +59,8 @@ static_library("content_shell_lib") {
"browser/layout_test/layout_test_javascript_dialog_manager.h", "browser/layout_test/layout_test_javascript_dialog_manager.h",
"browser/layout_test/layout_test_message_filter.cc", "browser/layout_test/layout_test_message_filter.cc",
"browser/layout_test/layout_test_message_filter.h", "browser/layout_test/layout_test_message_filter.h",
"browser/layout_test/layout_test_navigator_connect_service_factory.cc",
"browser/layout_test/layout_test_navigator_connect_service_factory.h",
"browser/layout_test/layout_test_notification_manager.cc", "browser/layout_test/layout_test_notification_manager.cc",
"browser/layout_test/layout_test_notification_manager.h", "browser/layout_test/layout_test_notification_manager.h",
"browser/layout_test/layout_test_push_messaging_service.cc", "browser/layout_test/layout_test_push_messaging_service.cc",
......
...@@ -6,10 +6,12 @@ ...@@ -6,10 +6,12 @@
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigator_connect_context.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_partition.h"
#include "content/shell/browser/layout_test/layout_test_browser_context.h" #include "content/shell/browser/layout_test/layout_test_browser_context.h"
#include "content/shell/browser/layout_test/layout_test_message_filter.h" #include "content/shell/browser/layout_test/layout_test_message_filter.h"
#include "content/shell/browser/layout_test/layout_test_navigator_connect_service_factory.h"
#include "content/shell/browser/layout_test/layout_test_notification_manager.h" #include "content/shell/browser/layout_test/layout_test_notification_manager.h"
#include "content/shell/browser/shell_browser_context.h" #include "content/shell/browser/shell_browser_context.h"
#include "content/shell/common/shell_messages.h" #include "content/shell/common/shell_messages.h"
...@@ -109,4 +111,10 @@ LayoutTestContentBrowserClient::GetPlatformNotificationService() { ...@@ -109,4 +111,10 @@ LayoutTestContentBrowserClient::GetPlatformNotificationService() {
return layout_test_notification_manager_.get(); return layout_test_notification_manager_.get();
} }
void LayoutTestContentBrowserClient::GetAdditionalNavigatorConnectServices(
const scoped_refptr<NavigatorConnectContext>& context) {
context->AddFactory(
make_scoped_ptr(new LayoutTestNavigatorConnectServiceFactory));
}
} // namespace content } // namespace content
...@@ -36,6 +36,8 @@ class LayoutTestContentBrowserClient : public ShellContentBrowserClient { ...@@ -36,6 +36,8 @@ class LayoutTestContentBrowserClient : public ShellContentBrowserClient {
bool user_gesture, bool user_gesture,
const base::Callback<void(PermissionStatus)>& callback) override; const base::Callback<void(PermissionStatus)>& callback) override;
PlatformNotificationService* GetPlatformNotificationService() override; PlatformNotificationService* GetPlatformNotificationService() override;
void GetAdditionalNavigatorConnectServices(
const scoped_refptr<NavigatorConnectContext>& context) override;
private: private:
scoped_ptr<LayoutTestNotificationManager> layout_test_notification_manager_; scoped_ptr<LayoutTestNotificationManager> layout_test_notification_manager_;
......
// 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/shell/browser/layout_test/layout_test_navigator_connect_service_factory.h"
#include "base/values.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/message_port_delegate.h"
#include "content/public/browser/message_port_provider.h"
#include "content/public/common/message_port_types.h"
#include "content/public/common/navigator_connect_client.h"
#include "url/gurl.h"
namespace content {
namespace {
const char* kTestScheme = "chrome-layout-test";
const char* kEchoService = "echo";
const char* kAnnotateService = "annotate";
const char* kAsValue = "as-value";
}
class LayoutTestNavigatorConnectServiceFactory::Service
: public MessagePortDelegate {
public:
Service();
~Service() override;
void RegisterConnection(int message_port_id, const std::string& service);
// MessagePortDelegate implementation.
void SendMessage(
int message_port_id,
const MessagePortMessage& message,
const std::vector<TransferredMessagePort>& sent_message_ports) override;
void SendMessagesAreQueued(int message_port_id) override;
private:
std::map<int, std::string> connections_;
};
LayoutTestNavigatorConnectServiceFactory::Service::Service() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
LayoutTestNavigatorConnectServiceFactory::Service::~Service() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
MessagePortProvider::OnMessagePortDelegateClosing(this);
}
void LayoutTestNavigatorConnectServiceFactory::Service::RegisterConnection(
int message_port_id,
const std::string& service) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
connections_[message_port_id] = service;
}
void LayoutTestNavigatorConnectServiceFactory::Service::SendMessage(
int message_port_id,
const MessagePortMessage& message,
const std::vector<TransferredMessagePort>& sent_message_ports) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(connections_.find(message_port_id) != connections_.end());
if (connections_[message_port_id] == kAnnotateService) {
scoped_ptr<base::DictionaryValue> reply(new base::DictionaryValue);
reply->SetString("message_as_string", message.message_as_string);
reply->Set("message_as_value", message.message_as_value.DeepCopy());
MessagePortProvider::PostMessageToPort(
message_port_id, MessagePortMessage(reply.Pass()), sent_message_ports);
} else {
MessagePortProvider::PostMessageToPort(message_port_id, message,
sent_message_ports);
}
}
void LayoutTestNavigatorConnectServiceFactory::Service::SendMessagesAreQueued(
int message_port_id) {
NOTREACHED() << "This method should never be called.";
}
LayoutTestNavigatorConnectServiceFactory::
LayoutTestNavigatorConnectServiceFactory()
: service_(nullptr) {
}
LayoutTestNavigatorConnectServiceFactory::
~LayoutTestNavigatorConnectServiceFactory() {
if (service_)
BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, service_);
}
bool LayoutTestNavigatorConnectServiceFactory::HandlesUrl(
const GURL& target_url) {
return target_url.SchemeIs(kTestScheme);
}
void LayoutTestNavigatorConnectServiceFactory::Connect(
const NavigatorConnectClient& client,
const ConnectCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::string service = client.target_url.path();
if (service != kEchoService && service != kAnnotateService) {
callback.Run(nullptr, false);
return;
}
if (!service_)
service_ = new Service;
service_->RegisterConnection(client.message_port_id, service);
callback.Run(service_, client.target_url.query() == kAsValue);
if (service == kAnnotateService) {
scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue);
value->SetString("origin", client.origin.spec());
MessagePortProvider::PostMessageToPort(
client.message_port_id, MessagePortMessage(value.Pass()),
std::vector<TransferredMessagePort>());
}
}
} // namespace content
// 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.
#ifndef CONTENT_SHELL_BROWSER_LAYOUT_TEST_LAYOUT_TEST_NAVIGATOR_CONNECT_SERVICE_FACTORY_H_
#define CONTENT_SHELL_BROWSER_LAYOUT_TEST_LAYOUT_TEST_NAVIGATOR_CONNECT_SERVICE_FACTORY_H_
#include <map>
#include <string>
#include "content/public/browser/navigator_connect_service_factory.h"
namespace content {
// Implementation of NavigatorConnectServiceFactory that provides services
// layout tests can connect to under the chrome-layout-test: schema.
// In particular this implements an 'echo' service, that just sends back any
// message sends to it, and an 'annotate' service, which sends back some extra
// metadata in addition to the message it received.
class LayoutTestNavigatorConnectServiceFactory
: public NavigatorConnectServiceFactory {
public:
LayoutTestNavigatorConnectServiceFactory();
~LayoutTestNavigatorConnectServiceFactory() override;
// NavigatorConnectServiceFactory implementation.
bool HandlesUrl(const GURL& target_url) override;
void Connect(const NavigatorConnectClient& client,
const ConnectCallback& callback) override;
private:
// |service_| is created and destroyed on the IO thread, while
// LayoutTestNavigatorConnectServiceFactory can be destroyed on any thread.
class Service;
Service* service_;
};
} // namespace content
#endif // CONTENT_SHELL_BROWSER_LAYOUT_TEST_LAYOUT_TEST_NAVIGATOR_CONNECT_SERVICE_FACTORY_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment