summaryrefslogtreecommitdiff
path: root/chromium/fuchsia
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-01-20 13:40:20 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-01-22 12:41:23 +0000
commit7961cea6d1041e3e454dae6a1da660b453efd238 (patch)
treec0eeb4a9ff9ba32986289c1653d9608e53ccb444 /chromium/fuchsia
parentb7034d0803538058e5c9d904ef03cf5eab34f6ef (diff)
downloadqtwebengine-chromium-7961cea6d1041e3e454dae6a1da660b453efd238.tar.gz
BASELINE: Update Chromium to 78.0.3904.130
Change-Id: If185e0c0061b3437531c97c9c8c78f239352a68b Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/fuchsia')
-rw-r--r--chromium/fuchsia/BUILD.gn7
-rw-r--r--chromium/fuchsia/base/BUILD.gn8
-rw-r--r--chromium/fuchsia/base/agent_impl.cc12
-rw-r--r--chromium/fuchsia/base/agent_impl.h23
-rw-r--r--chromium/fuchsia/base/agent_impl_unittests.cc22
-rw-r--r--chromium/fuchsia/base/agent_manager.cc5
-rw-r--r--chromium/fuchsia/base/fake_component_context.cc18
-rw-r--r--chromium/fuchsia/base/fake_component_context.h7
-rw-r--r--chromium/fuchsia/base/frame_test_util.cc2
-rw-r--r--chromium/fuchsia/base/lifecycle_impl.cc6
-rw-r--r--chromium/fuchsia/base/lifecycle_impl.h10
-rw-r--r--chromium/fuchsia/base/mem_buffer_util.cc19
-rw-r--r--chromium/fuchsia/base/mem_buffer_util.h9
-rw-r--r--chromium/fuchsia/base/message_port.cc5
-rw-r--r--chromium/fuchsia/base/string_util.cc19
-rw-r--r--chromium/fuchsia/base/string_util.h24
-rw-r--r--chromium/fuchsia/base/test_devtools_list_fetcher.cc (renamed from chromium/fuchsia/engine/test_devtools_list_fetcher.cc)6
-rw-r--r--chromium/fuchsia/base/test_devtools_list_fetcher.h (renamed from chromium/fuchsia/engine/test_devtools_list_fetcher.h)10
-rw-r--r--chromium/fuchsia/cipd/BUILD.gn68
-rw-r--r--chromium/fuchsia/engine/BUILD.gn47
-rw-r--r--chromium/fuchsia/engine/DEPS3
-rw-r--r--chromium/fuchsia/engine/browser/DEPS13
-rw-r--r--chromium/fuchsia/engine/browser/accessibility_bridge.cc35
-rw-r--r--chromium/fuchsia/engine/browser/accessibility_bridge.h47
-rw-r--r--chromium/fuchsia/engine/browser/accessibility_bridge_unittest.cc102
-rw-r--r--chromium/fuchsia/engine/browser/content_directory_browsertest.cc208
-rw-r--r--chromium/fuchsia/engine/browser/content_directory_loader_factory.cc382
-rw-r--r--chromium/fuchsia/engine/browser/content_directory_loader_factory.h57
-rw-r--r--chromium/fuchsia/engine/browser/context_impl.cc26
-rw-r--r--chromium/fuchsia/engine/browser/context_impl.h16
-rw-r--r--chromium/fuchsia/engine/browser/context_impl_browsertest.cc143
-rw-r--r--chromium/fuchsia/engine/browser/cookie_manager_impl.cc237
-rw-r--r--chromium/fuchsia/engine/browser/cookie_manager_impl.h58
-rw-r--r--chromium/fuchsia/engine/browser/cookie_manager_impl_unittest.cc377
-rw-r--r--chromium/fuchsia/engine/browser/frame_impl.cc166
-rw-r--r--chromium/fuchsia/engine/browser/frame_impl.h25
-rw-r--r--chromium/fuchsia/engine/browser/frame_impl_browsertest.cc273
-rw-r--r--chromium/fuchsia/engine/browser/navigation_controller_impl.cc48
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_browser_context.cc20
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_browser_context.h6
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_browser_main_parts.cc23
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_cdm_service.cc131
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_cdm_service.h37
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_content_browser_client.cc40
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_content_browser_client.h37
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_url_request_context_getter.cc69
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_url_request_context_getter.h53
-rw-r--r--chromium/fuchsia/engine/common.cc2
-rw-r--r--chromium/fuchsia/engine/common.h13
-rw-r--r--chromium/fuchsia/engine/context_provider_impl.cc101
-rw-r--r--chromium/fuchsia/engine/context_provider_impl_unittest.cc13
-rw-r--r--chromium/fuchsia/engine/context_provider_main.cc16
-rw-r--r--chromium/fuchsia/engine/web_engine_content_client.cc6
-rw-r--r--chromium/fuchsia/engine/web_engine_content_client.h2
-rw-r--r--chromium/fuchsia/engine/web_engine_debug_integration_test.cc23
-rw-r--r--chromium/fuchsia/engine/web_engine_integration_test.cc67
-rw-r--r--chromium/fuchsia/engine/web_engine_integration_tests.cmx7
-rw-r--r--chromium/fuchsia/engine/web_engine_main_delegate.cc8
-rw-r--r--chromium/fuchsia/fidl/cast/application_config.fidl4
-rw-r--r--chromium/fuchsia/fidl/cast/application_controller.fidl19
-rw-r--r--chromium/fuchsia/fidl/cast/queryable_data.fidl22
-rw-r--r--chromium/fuchsia/fidl/cast/url_request_rewriter.fidl17
-rw-r--r--chromium/fuchsia/http/BUILD.gn2
-rw-r--r--chromium/fuchsia/http/http.cmx1
-rw-r--r--chromium/fuchsia/http/http_service_main.cc17
-rw-r--r--chromium/fuchsia/http/http_service_unittest.cc10
-rw-r--r--chromium/fuchsia/http/url_loader_impl.cc21
-rw-r--r--chromium/fuchsia/mojo/example.typemap16
-rw-r--r--chromium/fuchsia/mojom/BUILD.gn (renamed from chromium/fuchsia/mojo/BUILD.gn)1
-rw-r--r--chromium/fuchsia/mojom/DEPS (renamed from chromium/fuchsia/mojo/DEPS)0
-rw-r--r--chromium/fuchsia/mojom/OWNERS (renamed from chromium/fuchsia/mojo/OWNERS)0
-rw-r--r--chromium/fuchsia/mojom/example.mojom (renamed from chromium/fuchsia/mojo/example.mojom)0
-rw-r--r--chromium/fuchsia/mojom/example.typemap16
-rw-r--r--chromium/fuchsia/mojom/fidl_interface_request_mojom_traits.h (renamed from chromium/fuchsia/mojo/fidl_interface_request_mojom_traits.h)6
-rw-r--r--chromium/fuchsia/mojom/fidl_interface_request_mojom_traits_unittest.cc (renamed from chromium/fuchsia/mojo/fidl_interface_request_mojom_traits_unittest.cc)10
-rw-r--r--chromium/fuchsia/mojom/test_interface_request_mojom_traits.h (renamed from chromium/fuchsia/mojo/test_interface_request_mojom_traits.h)8
-rw-r--r--chromium/fuchsia/mojom/test_typemaps.gni (renamed from chromium/fuchsia/mojo/test_typemaps.gni)2
-rw-r--r--chromium/fuchsia/runners/BUILD.gn23
-rw-r--r--chromium/fuchsia/runners/cast/api_bindings_client_browsertest.cc5
-rw-r--r--chromium/fuchsia/runners/cast/application_controller_impl.cc31
-rw-r--r--chromium/fuchsia/runners/cast/application_controller_impl.h32
-rw-r--r--chromium/fuchsia/runners/cast/application_controller_impl_unittest.cc91
-rw-r--r--chromium/fuchsia/runners/cast/cast_component.cc30
-rw-r--r--chromium/fuchsia/runners/cast/cast_component.h28
-rw-r--r--chromium/fuchsia/runners/cast/cast_runner.cc47
-rw-r--r--chromium/fuchsia/runners/cast/cast_runner.cmx4
-rw-r--r--chromium/fuchsia/runners/cast/cast_runner.h18
-rw-r--r--chromium/fuchsia/runners/cast/cast_runner_integration_test.cc199
-rw-r--r--chromium/fuchsia/runners/cast/fake_queryable_data.cc40
-rw-r--r--chromium/fuchsia/runners/cast/fake_queryable_data.h41
-rw-r--r--chromium/fuchsia/runners/cast/main.cc23
-rw-r--r--chromium/fuchsia/runners/cast/named_message_port_connector.cc10
-rw-r--r--chromium/fuchsia/runners/cast/named_message_port_connector_browsertest.cc4
-rw-r--r--chromium/fuchsia/runners/cast/not_implemented_api_bindings.js16
-rw-r--r--chromium/fuchsia/runners/cast/not_implemented_api_bindings_browsertest.cc5
-rw-r--r--chromium/fuchsia/runners/cast/touch_input_bindings.cc3
-rw-r--r--chromium/fuchsia/runners/cast/touch_input_bindings.js117
-rw-r--r--chromium/fuchsia/runners/common/web_component.cc14
-rw-r--r--chromium/fuchsia/runners/common/web_content_runner.cc36
-rw-r--r--chromium/fuchsia/runners/common/web_content_runner.h13
-rw-r--r--chromium/fuchsia/runners/web/main.cc22
-rw-r--r--chromium/fuchsia/runners/web/web_runner.cmx4
-rw-r--r--chromium/fuchsia/runners/web/web_runner_smoke_test.cc39
103 files changed, 3430 insertions, 854 deletions
diff --git a/chromium/fuchsia/BUILD.gn b/chromium/fuchsia/BUILD.gn
index ecc9681227c..7b1ad59e489 100644
--- a/chromium/fuchsia/BUILD.gn
+++ b/chromium/fuchsia/BUILD.gn
@@ -13,7 +13,8 @@ fidl_library("cast_fidl") {
sources = [
"fidl/cast/api_bindings.fidl",
"fidl/cast/application_config.fidl",
- "fidl/cast/queryable_data.fidl",
+ "fidl/cast/application_controller.fidl",
+ "fidl/cast/url_request_rewriter.fidl",
]
public_deps = [
@@ -100,9 +101,11 @@ group("gn_all") {
"engine:web_engine_browsertests",
"engine:web_engine_unittests",
"http:http_service_tests",
- "mojo:fuchsia_mojo_unittests",
+ "mojom:fuchsia_mojo_unittests",
"runners:cast_runner",
"runners:cast_runner_browsertests",
+ "runners:cast_runner_integration_tests",
+ "runners:cast_runner_unittests",
"runners:web_runner",
"//chromecast/bindings:bindings_manager_fuchsia",
]
diff --git a/chromium/fuchsia/base/BUILD.gn b/chromium/fuchsia/base/BUILD.gn
index f3db8b88f7d..e8ba2b608c3 100644
--- a/chromium/fuchsia/base/BUILD.gn
+++ b/chromium/fuchsia/base/BUILD.gn
@@ -12,9 +12,11 @@ import("//testing/test.gni")
source_set("base") {
sources = [
"mem_buffer_util.cc",
+ "string_util.cc",
]
public = [
"mem_buffer_util.h",
+ "string_util.h",
]
deps = [
"//base",
@@ -37,6 +39,7 @@ source_set("modular") {
]
public_deps = [
"//third_party/fuchsia-sdk/sdk:modular",
+ "//third_party/fuchsia-sdk/sdk:sys_cpp",
]
}
@@ -66,6 +69,8 @@ source_set("test_support") {
"frame_test_util.cc",
"frame_test_util.h",
"result_receiver.h",
+ "test_devtools_list_fetcher.cc",
+ "test_devtools_list_fetcher.h",
"test_navigation_listener.cc",
"test_navigation_listener.h",
]
@@ -73,6 +78,8 @@ source_set("test_support") {
":base",
":modular",
"//base",
+ "//net",
+ "//net:test_support",
"//third_party/fuchsia-sdk/sdk:modular",
"//third_party/fuchsia-sdk/sdk:web",
"//url",
@@ -90,6 +97,7 @@ test("cr_fuchsia_base_unittests") {
"//base",
"//base:testfidl",
"//base/test:run_all_unittests",
+ "//base/test:test_support",
"//testing/gtest",
]
}
diff --git a/chromium/fuchsia/base/agent_impl.cc b/chromium/fuchsia/base/agent_impl.cc
index 1d95d97e476..1e1268e988a 100644
--- a/chromium/fuchsia/base/agent_impl.cc
+++ b/chromium/fuchsia/base/agent_impl.cc
@@ -4,7 +4,10 @@
#include "fuchsia/base/agent_impl.h"
+#include <lib/sys/cpp/component_context.h>
+
#include "base/bind.h"
+#include "base/fuchsia/default_context.h"
namespace cr_fuchsia {
@@ -14,7 +17,9 @@ AgentImpl::ComponentStateBase::ComponentStateBase(
base::StringPiece component_id)
: component_id_(component_id) {
fidl::InterfaceHandle<::fuchsia::io::Directory> directory;
- service_directory_.Initialize(directory.NewRequest());
+ outgoing_directory_.GetOrCreateDirectory("svc")->Serve(
+ fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
+ directory.NewRequest().TakeChannel());
service_provider_ = std::make_unique<base::fuchsia::ServiceProviderImpl>(
std::move(directory));
@@ -41,12 +46,11 @@ void AgentImpl::ComponentStateBase::TeardownIfUnused() {
}
AgentImpl::AgentImpl(
- base::fuchsia::ServiceDirectory* service_directory,
+ sys::OutgoingDirectory* outgoing_directory,
CreateComponentStateCallback create_component_state_callback)
: create_component_state_callback_(
std::move(create_component_state_callback)),
- agent_binding_(service_directory, this) {
-}
+ agent_binding_(outgoing_directory, this) {}
AgentImpl::~AgentImpl() {
DCHECK(active_components_.empty());
diff --git a/chromium/fuchsia/base/agent_impl.h b/chromium/fuchsia/base/agent_impl.h
index e6b7e7861a4..3165076f442 100644
--- a/chromium/fuchsia/base/agent_impl.h
+++ b/chromium/fuchsia/base/agent_impl.h
@@ -7,14 +7,15 @@
#include <fuchsia/modular/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
+#include <lib/sys/cpp/component_context.h>
#include <lib/zx/channel.h>
#include <memory>
#include <string>
#include <utility>
#include "base/containers/flat_map.h"
+#include "base/fuchsia/default_context.h"
#include "base/fuchsia/scoped_service_binding.h"
-#include "base/fuchsia/service_directory.h"
#include "base/fuchsia/service_provider_impl.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
@@ -28,8 +29,8 @@ namespace cr_fuchsia {
// service state as desired.
class AgentImpl : public ::fuchsia::modular::Agent {
public:
- // Common base for per-component services and state. The base provides a
- // service directory into which specializations publish their services, to
+ // Common base for per-component services and state. The base provides an
+ // outgoing directory into which specializations publish their services, to
// have them made available to the client. Different specializations of the
// ComponentStateBase can be created to suit different components.
//
@@ -39,8 +40,8 @@ class AgentImpl : public ::fuchsia::modular::Agent {
// MyComponentState : public ComponentStateBase {
// public:
// MyComponentState(..) : ComponentStateBase(..)
- // : binding1_(service_directory(), &service1_),
- // binding2_(service_directory(), shared_service2_) {}
+ // : binding1_(outgoing_directory(), &service1_),
+ // binding2_(outgoing_directory(), shared_service2_) {}
// private:
// Service1 service1_;
// ScopedServiceBinding<Service1> binding1_;
@@ -59,8 +60,8 @@ class AgentImpl : public ::fuchsia::modular::Agent {
// Returns the directory into which the ComponentState implementation should
// publish the services that the component may use.
- base::fuchsia::ServiceDirectory* service_directory() {
- return &service_directory_;
+ sys::OutgoingDirectory* outgoing_directory() {
+ return &outgoing_directory_;
}
// Registers |service_binding| to prevent teardown of this
@@ -85,7 +86,7 @@ class AgentImpl : public ::fuchsia::modular::Agent {
const std::string component_id_;
AgentImpl* agent_impl_ = nullptr;
- base::fuchsia::ServiceDirectory service_directory_;
+ sys::OutgoingDirectory outgoing_directory_;
std::unique_ptr<base::fuchsia::ServiceProviderImpl> service_provider_;
std::vector<base::RepeatingCallback<bool()>> keepalive_callbacks_;
@@ -99,10 +100,10 @@ class AgentImpl : public ::fuchsia::modular::Agent {
base::RepeatingCallback<std::unique_ptr<ComponentStateBase>(
base::StringPiece component_id)>;
- // Binds the Agent service in the supplied |service_directory|, and invokes
+ // Binds the Agent service in the supplied |outgoing_directory|, and invokes
// |create_component_state_callback| on each Connect() call, for the caller to
// create per-component data structures and services.
- AgentImpl(base::fuchsia::ServiceDirectory* service_directory,
+ AgentImpl(sys::OutgoingDirectory* outgoing_directory,
CreateComponentStateCallback create_component_state_callback);
~AgentImpl() override;
@@ -121,7 +122,7 @@ class AgentImpl : public ::fuchsia::modular::Agent {
// Returns a ComponentStateBase instance for a given component-Id.
const CreateComponentStateCallback create_component_state_callback_;
- // Binds this Agent implementation into the |service_directory|.
+ // Binds this Agent implementation into the |outgoing_directory|.
base::fuchsia::ScopedServiceBinding<::fuchsia::modular::Agent> agent_binding_;
// Owns the ComponentState instances for each connected component.
diff --git a/chromium/fuchsia/base/agent_impl_unittests.cc b/chromium/fuchsia/base/agent_impl_unittests.cc
index dee70fab458..c11dfdcbb70 100644
--- a/chromium/fuchsia/base/agent_impl_unittests.cc
+++ b/chromium/fuchsia/base/agent_impl_unittests.cc
@@ -5,11 +5,9 @@
#include "fuchsia/base/agent_impl.h"
#include "base/fuchsia/fuchsia_logging.h"
-#include "base/fuchsia/service_directory.h"
-#include "base/fuchsia/service_directory_client.h"
#include "base/fuchsia/testfidl/cpp/fidl.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/task_environment.h"
#include "fuchsia/base/fit_adapter.h"
#include "fuchsia/base/result_receiver.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -50,7 +48,7 @@ class AccumulatorComponentState : public AgentImpl::ComponentStateBase {
public:
AccumulatorComponentState(base::StringPiece component)
: ComponentStateBase(component),
- service_binding_(service_directory(), &service_) {}
+ service_binding_(outgoing_directory(), &service_) {}
protected:
AccumulatingTestInterfaceImpl service_;
@@ -70,8 +68,10 @@ class AgentImplTest : public ::testing::Test {
public:
AgentImplTest() {
fidl::InterfaceHandle<::fuchsia::io::Directory> directory;
- services_ = std::make_unique<base::fuchsia::ServiceDirectory>(
- directory.NewRequest());
+ services_.GetOrCreateDirectory("svc")->Serve(
+ fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
+ directory.NewRequest().TakeChannel());
+
services_client_ = std::make_unique<base::fuchsia::ServiceDirectoryClient>(
std::move(directory));
}
@@ -79,8 +79,8 @@ class AgentImplTest : public ::testing::Test {
fuchsia::modular::AgentPtr CreateAgentAndConnect() {
DCHECK(!agent_impl_);
agent_impl_ = std::make_unique<AgentImpl>(
- services_.get(), base::BindRepeating(&AgentImplTest::OnComponentConnect,
- base::Unretained(this)));
+ &services_, base::BindRepeating(&AgentImplTest::OnComponentConnect,
+ base::Unretained(this)));
fuchsia::modular::AgentPtr agent;
services_client_->ConnectToService(agent.NewRequest());
return agent;
@@ -100,8 +100,10 @@ class AgentImplTest : public ::testing::Test {
return nullptr;
}
- base::MessageLoopForIO message_loop_;
- std::unique_ptr<base::fuchsia::ServiceDirectory> services_;
+ base::test::TaskEnvironment task_environment_{
+ base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
+ base::test::TaskEnvironment::MainThreadType::IO};
+ sys::OutgoingDirectory services_;
std::unique_ptr<base::fuchsia::ServiceDirectoryClient> services_client_;
std::unique_ptr<AgentImpl> agent_impl_;
diff --git a/chromium/fuchsia/base/agent_manager.cc b/chromium/fuchsia/base/agent_manager.cc
index a777b1d5c58..730f8b7f62f 100644
--- a/chromium/fuchsia/base/agent_manager.cc
+++ b/chromium/fuchsia/base/agent_manager.cc
@@ -28,8 +28,9 @@ void AgentManager::ConnectToAgentServiceUnsafe(base::StringPiece agent,
it->second.services.NewRequest(),
it->second.controller.NewRequest());
it->second.services.set_error_handler(
- [agent = agent.as_string()](zx_status_t status) {
- ZX_LOG(FATAL, status) << "Agent disconnected: " << agent;
+ [this, agent = agent.as_string()](zx_status_t status) {
+ ZX_LOG(WARNING, status) << "Agent disconnected: " << agent;
+ agents_.erase(agent);
});
}
it->second.services->ConnectToService(interface.as_string(),
diff --git a/chromium/fuchsia/base/fake_component_context.cc b/chromium/fuchsia/base/fake_component_context.cc
index 4353c203673..b551d18b19c 100644
--- a/chromium/fuchsia/base/fake_component_context.cc
+++ b/chromium/fuchsia/base/fake_component_context.cc
@@ -5,6 +5,7 @@
#include "fuchsia/base/fake_component_context.h"
#include <fuchsia/base/agent_impl.h>
+
#include <memory>
#include <string>
#include <utility>
@@ -15,12 +16,12 @@ namespace cr_fuchsia {
FakeComponentContext::FakeComponentContext(
AgentImpl::CreateComponentStateCallback create_component_state_callback,
- base::fuchsia::ServiceDirectory* service_directory,
+ sys::OutgoingDirectory* outgoing_directory,
base::StringPiece component_url)
- : binding_(service_directory, this),
- // Publishing the Agent to |service_directory| is not necessary, but
+ : binding_(outgoing_directory, this),
+ // Publishing the Agent to |outgoing_directory| is not necessary, but
// also shouldn't do any harm.
- agent_impl_(service_directory,
+ agent_impl_(outgoing_directory,
std::move(create_component_state_callback)),
component_url_(component_url.as_string()) {}
@@ -31,6 +32,15 @@ void FakeComponentContext::ConnectToAgent(
agent_impl_.Connect(component_url_, std::move(services));
}
+void FakeComponentContext::ConnectToAgentService(
+ fuchsia::modular::AgentServiceRequest request) {
+ if (!agent_services_) {
+ ConnectToAgent(component_url_, agent_services_.NewRequest(), nullptr);
+ }
+ agent_services_->ConnectToService(std::move(request.service_name()),
+ std::move(*request.mutable_channel()));
+}
+
void FakeComponentContext::NotImplemented_(const std::string& name) {
NOTIMPLEMENTED() << " API: " << name;
}
diff --git a/chromium/fuchsia/base/fake_component_context.h b/chromium/fuchsia/base/fake_component_context.h
index da2a4924be8..c5187c2194f 100644
--- a/chromium/fuchsia/base/fake_component_context.h
+++ b/chromium/fuchsia/base/fake_component_context.h
@@ -18,7 +18,7 @@ namespace cr_fuchsia {
// Used to test interactions with an Agent in unit-tests for a component.
// |create_component_state_callback| can be used with a test-specific
// ComponentStateBase to serve fake services to the component.
-// |service_directory| specifies the directory into which the ComponentContext
+// |outgoing_directory| specifies the directory into which the ComponentContext
// should be published, alongside any other services the test wishes to provide
// to the component's default service namespace. |component_url| specifies the
// component identity that should be reported to the Agent
@@ -27,7 +27,7 @@ class FakeComponentContext
public:
explicit FakeComponentContext(
AgentImpl::CreateComponentStateCallback create_component_state_callback,
- base::fuchsia::ServiceDirectory* service_directory,
+ sys::OutgoingDirectory* outgoing_directory,
base::StringPiece component_url);
~FakeComponentContext() override;
@@ -37,6 +37,8 @@ class FakeComponentContext
fidl::InterfaceRequest<::fuchsia::sys::ServiceProvider> services,
fidl::InterfaceRequest<fuchsia::modular::AgentController> controller)
override;
+ void ConnectToAgentService(
+ fuchsia::modular::AgentServiceRequest request) override;
void NotImplemented_(const std::string& name) override;
private:
@@ -44,6 +46,7 @@ class FakeComponentContext
binding_;
AgentImpl agent_impl_;
const std::string component_url_;
+ fuchsia::sys::ServiceProviderPtr agent_services_;
DISALLOW_COPY_AND_ASSIGN(FakeComponentContext);
};
diff --git a/chromium/fuchsia/base/frame_test_util.cc b/chromium/fuchsia/base/frame_test_util.cc
index 9bd182e7269..50fedd625c3 100644
--- a/chromium/fuchsia/base/frame_test_util.cc
+++ b/chromium/fuchsia/base/frame_test_util.cc
@@ -33,7 +33,7 @@ base::Optional<base::Value> ExecuteJavaScript(fuchsia::web::Frame* frame,
base::RunLoop run_loop;
ResultReceiver<fuchsia::web::Frame_ExecuteJavaScript_Result> result(
run_loop.QuitClosure());
- frame->ExecuteJavaScript({"*"}, MemBufferFromString(script),
+ frame->ExecuteJavaScript({"*"}, MemBufferFromString(script, "test"),
CallbackToFitFunction(result.GetReceiveCallback()));
run_loop.Run();
diff --git a/chromium/fuchsia/base/lifecycle_impl.cc b/chromium/fuchsia/base/lifecycle_impl.cc
index 2193ab0f3dd..f8f635befa4 100644
--- a/chromium/fuchsia/base/lifecycle_impl.cc
+++ b/chromium/fuchsia/base/lifecycle_impl.cc
@@ -4,13 +4,11 @@
#include "fuchsia/base/lifecycle_impl.h"
-#include "base/fuchsia/service_directory.h"
-
namespace cr_fuchsia {
-LifecycleImpl::LifecycleImpl(base::fuchsia::ServiceDirectory* service_directory,
+LifecycleImpl::LifecycleImpl(sys::OutgoingDirectory* outgoing_directory,
base::OnceClosure on_terminate)
- : binding_(service_directory, this),
+ : binding_(outgoing_directory, this),
on_terminate_(std::move(on_terminate)) {}
LifecycleImpl::~LifecycleImpl() = default;
diff --git a/chromium/fuchsia/base/lifecycle_impl.h b/chromium/fuchsia/base/lifecycle_impl.h
index ecc7bde7dc7..ef8c79df101 100644
--- a/chromium/fuchsia/base/lifecycle_impl.h
+++ b/chromium/fuchsia/base/lifecycle_impl.h
@@ -10,11 +10,9 @@
#include "base/fuchsia/scoped_service_binding.h"
#include "base/macros.h"
-namespace base {
-namespace fuchsia {
-class ServiceDirectory;
-} // namespace fuchsia
-} // namespace base
+namespace sys {
+class OutgoingDirectory;
+} // namespace sys
namespace cr_fuchsia {
@@ -23,7 +21,7 @@ namespace cr_fuchsia {
// client drops the channel.
class LifecycleImpl : public ::fuchsia::modular::Lifecycle {
public:
- LifecycleImpl(base::fuchsia::ServiceDirectory* service_directory,
+ LifecycleImpl(sys::OutgoingDirectory* outgoing_directory,
base::OnceClosure on_terminate);
~LifecycleImpl() override;
diff --git a/chromium/fuchsia/base/mem_buffer_util.cc b/chromium/fuchsia/base/mem_buffer_util.cc
index c71f2180da1..4ae3ec9f547 100644
--- a/chromium/fuchsia/base/mem_buffer_util.cc
+++ b/chromium/fuchsia/base/mem_buffer_util.cc
@@ -26,12 +26,16 @@ bool ReadUTF8FromVMOAsUTF16(const fuchsia::mem::Buffer& buffer,
return base::UTF8ToUTF16(&output_utf8.front(), output_utf8.size(), output);
}
-fuchsia::mem::Buffer MemBufferFromString(const base::StringPiece& data) {
+fuchsia::mem::Buffer MemBufferFromString(base::StringPiece data,
+ base::StringPiece name) {
fuchsia::mem::Buffer buffer;
zx_status_t status = zx::vmo::create(data.size(), 0, &buffer.vmo);
ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create";
+ status = buffer.vmo.set_property(ZX_PROP_NAME, name.data(), name.size());
+ ZX_DCHECK(status == ZX_OK, status);
+
status = buffer.vmo.write(data.data(), 0, data.size());
ZX_CHECK(status == ZX_OK, status) << "zx_vmo_write";
@@ -39,10 +43,12 @@ fuchsia::mem::Buffer MemBufferFromString(const base::StringPiece& data) {
return buffer;
}
-fuchsia::mem::Buffer MemBufferFromString16(const base::StringPiece16& data) {
+fuchsia::mem::Buffer MemBufferFromString16(const base::StringPiece16& data,
+ base::StringPiece name) {
return MemBufferFromString(
base::StringPiece(reinterpret_cast<const char*>(data.data()),
- data.size() * sizeof(base::char16)));
+ data.size() * sizeof(base::char16)),
+ name);
}
bool StringFromMemBuffer(const fuchsia::mem::Buffer& buffer,
@@ -74,12 +80,17 @@ fuchsia::mem::Buffer MemBufferFromFile(base::File file) {
return output;
}
-fuchsia::mem::Buffer CloneBuffer(const fuchsia::mem::Buffer& buffer) {
+fuchsia::mem::Buffer CloneBuffer(const fuchsia::mem::Buffer& buffer,
+ base::StringPiece name) {
fuchsia::mem::Buffer output;
output.size = buffer.size;
zx_status_t status = buffer.vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE, 0,
buffer.size, &output.vmo);
ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create_child";
+
+ status = output.vmo.set_property(ZX_PROP_NAME, name.data(), name.size());
+ ZX_DCHECK(status == ZX_OK, status);
+
return output;
}
diff --git a/chromium/fuchsia/base/mem_buffer_util.h b/chromium/fuchsia/base/mem_buffer_util.h
index cf204192cac..4eb39c84427 100644
--- a/chromium/fuchsia/base/mem_buffer_util.h
+++ b/chromium/fuchsia/base/mem_buffer_util.h
@@ -20,10 +20,12 @@ bool ReadUTF8FromVMOAsUTF16(const fuchsia::mem::Buffer& buffer,
base::string16* output);
// Creates a Fuchsia memory buffer from |data|.
-fuchsia::mem::Buffer MemBufferFromString(const base::StringPiece& data);
+fuchsia::mem::Buffer MemBufferFromString(base::StringPiece data,
+ base::StringPiece name);
// Creates a Fuchsia memory buffer from the UTF-16 string |data|.
-fuchsia::mem::Buffer MemBufferFromString16(const base::StringPiece16& data);
+fuchsia::mem::Buffer MemBufferFromString16(const base::StringPiece16& data,
+ base::StringPiece name);
// Reads the contents of |buffer| into |output|.
// Returns true if the read operation succeeded.
@@ -35,7 +37,8 @@ bool StringFromMemBuffer(const fuchsia::mem::Buffer& buffer,
fuchsia::mem::Buffer MemBufferFromFile(base::File file);
// Creates a non-resizeable, copy-on-write shared memory clone of |buffer|.
-fuchsia::mem::Buffer CloneBuffer(const fuchsia::mem::Buffer& buffer);
+fuchsia::mem::Buffer CloneBuffer(const fuchsia::mem::Buffer& buffer,
+ base::StringPiece name);
} // namespace cr_fuchsia
diff --git a/chromium/fuchsia/base/message_port.cc b/chromium/fuchsia/base/message_port.cc
index 55d3820e265..8485d747834 100644
--- a/chromium/fuchsia/base/message_port.cc
+++ b/chromium/fuchsia/base/message_port.cc
@@ -19,7 +19,7 @@
#include "mojo/public/cpp/system/message_pipe.h"
#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/common/messaging/string_message_codec.h"
-#include "third_party/blink/public/common/messaging/transferable_message_struct_traits.h"
+#include "third_party/blink/public/common/messaging/transferable_message_mojom_traits.h"
#include "third_party/blink/public/mojom/messaging/transferable_message.mojom.h"
namespace cr_fuchsia {
@@ -87,7 +87,8 @@ base::Optional<fuchsia::web::WebMessage> FidlWebMessageFromMojo(
base::STLClearObject(&data_utf16);
- fuchsia::mem::Buffer data = cr_fuchsia::MemBufferFromString(data_utf8);
+ fuchsia::mem::Buffer data =
+ cr_fuchsia::MemBufferFromString(data_utf8, "cr-web-message-from-mojo");
if (!data.vmo)
return {};
diff --git a/chromium/fuchsia/base/string_util.cc b/chromium/fuchsia/base/string_util.cc
new file mode 100644
index 00000000000..7b1b242b546
--- /dev/null
+++ b/chromium/fuchsia/base/string_util.cc
@@ -0,0 +1,19 @@
+// Copyright 2019 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 "fuchsia/base/string_util.h"
+
+namespace cr_fuchsia {
+
+std::vector<uint8_t> StringToBytes(base::StringPiece str) {
+ const uint8_t* raw_data = reinterpret_cast<const uint8_t*>(str.data());
+ return std::vector<uint8_t>(raw_data, raw_data + str.length());
+}
+
+base::StringPiece BytesAsString(const std::vector<uint8_t>& bytes) {
+ return base::StringPiece(reinterpret_cast<const char*>(bytes.data()),
+ bytes.size());
+}
+
+} // namespace cr_fuchsia
diff --git a/chromium/fuchsia/base/string_util.h b/chromium/fuchsia/base/string_util.h
new file mode 100644
index 00000000000..377444939da
--- /dev/null
+++ b/chromium/fuchsia/base/string_util.h
@@ -0,0 +1,24 @@
+// Copyright 2019 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 FUCHSIA_BASE_STRING_UTIL_H_
+#define FUCHSIA_BASE_STRING_UTIL_H_
+
+#include <cstdint>
+#include <vector>
+
+#include "base/containers/span.h"
+#include "base/strings/string_piece.h"
+
+namespace cr_fuchsia {
+
+// Creates a byte vector from a string.
+std::vector<uint8_t> StringToBytes(base::StringPiece str);
+
+// Creates a string from a byte vector.
+base::StringPiece BytesAsString(const std::vector<uint8_t>& bytes);
+
+} // namespace cr_fuchsia
+
+#endif // FUCHSIA_BASE_STRING_UTIL_H_
diff --git a/chromium/fuchsia/engine/test_devtools_list_fetcher.cc b/chromium/fuchsia/base/test_devtools_list_fetcher.cc
index 0cca8984da1..e8b0335837c 100644
--- a/chromium/fuchsia/engine/test_devtools_list_fetcher.cc
+++ b/chromium/fuchsia/base/test_devtools_list_fetcher.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "fuchsia/engine/test_devtools_list_fetcher.h"
+#include "fuchsia/base/test_devtools_list_fetcher.h"
#include "base/callback.h"
#include "base/json/json_reader.h"
@@ -68,7 +68,11 @@ class DevToolsListFetcher : public net::URLFetcherDelegate {
} // namespace
+namespace cr_fuchsia {
+
base::Value GetDevToolsListFromPort(uint16_t port) {
DevToolsListFetcher devtools_fetcher;
return devtools_fetcher.GetDevToolsListFromPort(port);
}
+
+} // namespace cr_fuchsia
diff --git a/chromium/fuchsia/engine/test_devtools_list_fetcher.h b/chromium/fuchsia/base/test_devtools_list_fetcher.h
index b133cbf4974..6971e496994 100644
--- a/chromium/fuchsia/engine/test_devtools_list_fetcher.h
+++ b/chromium/fuchsia/base/test_devtools_list_fetcher.h
@@ -2,13 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef FUCHSIA_ENGINE_TEST_DEVTOOLS_LIST_FETCHER_H_
-#define FUCHSIA_ENGINE_TEST_DEVTOOLS_LIST_FETCHER_H_
+#ifndef FUCHSIA_BASE_TEST_DEVTOOLS_LIST_FETCHER_H_
+#define FUCHSIA_BASE_TEST_DEVTOOLS_LIST_FETCHER_H_
#include "base/values.h"
+namespace cr_fuchsia {
+
// Returns the JSON value of the list URL for the DevTools service listening
// on port |port| on localhost. Returns an empty value on error.
base::Value GetDevToolsListFromPort(uint16_t port);
-#endif // FUCHSIA_ENGINE_TEST_DEVTOOLS_LIST_FETCHER_H_
+} // namespace cr_fuchsia
+
+#endif // FUCHSIA_BASE_TEST_DEVTOOLS_LIST_FETCHER_H_
diff --git a/chromium/fuchsia/cipd/BUILD.gn b/chromium/fuchsia/cipd/BUILD.gn
index 5f7c1f1bc06..ecaf66b30f9 100644
--- a/chromium/fuchsia/cipd/BUILD.gn
+++ b/chromium/fuchsia/cipd/BUILD.gn
@@ -57,6 +57,7 @@ process_version("build_id") {
# cipd_path: The path where the package will be located inside the CIPD
# repository.
# cipd_description: Sets the "description" field in CIPD metadata.
+# install_mode: String, should be either "symlink" or "copy".
# deps: A list of targets to build prior to copying files.
# sources: A list of files to copy into the staging root.
template("cipd_archive") {
@@ -65,15 +66,21 @@ template("cipd_archive") {
"cipd_manifest_name",
"cipd_path",
"cipd_description",
+ "install_mode",
"deps",
"sources",
])
archive_staging_dir = "${target_gen_dir}/${target_name}"
-
+ if (!defined(invoker.install_mode)) {
+ install_mode = "symlink"
+ }
+ assert(install_mode == "copy" || install_mode == "symlink",
+ "\"install_mode\" arg should be either \"copy\" or \"symlink\".")
yaml_contents = [
"package: ${cipd_path}",
"description: ${cipd_description}",
"root: \${outdir}/" + rebase_path(archive_staging_dir, root_build_dir),
+ "install_mode: ${install_mode}",
"data:",
" - file: LICENSE",
]
@@ -145,6 +152,49 @@ cipd_archive("http") {
]
}
+_stripped_chromedriver_file = "${root_out_dir}/clang_x64/stripped/chromedriver"
+
+action("strip_chromedriver_binary") {
+ testonly = true
+
+ prog_name = "${root_out_dir}/clang_x64/chromedriver"
+
+ deps = [
+ "//chrome/test/chromedriver:chromedriver($host_toolchain)",
+ ]
+ script = "//build/gn_run_binary.py"
+ sources = [
+ "//buildtools/third_party/eu-strip/bin/eu-strip",
+ prog_name,
+ ]
+ outputs = [
+ _stripped_chromedriver_file,
+ ]
+ args = [
+ rebase_path("//buildtools/third_party/eu-strip/bin/eu-strip",
+ root_build_dir),
+ "-o",
+ rebase_path(_stripped_chromedriver_file, root_build_dir),
+ rebase_path(prog_name, root_build_dir),
+ ]
+
+ visibility = [ ":*" ]
+}
+
+cipd_archive("chromedriver") {
+ cipd_manifest_name = "chromedriver.yaml"
+ cipd_path = "chromium/fuchsia/chromedriver/\${os}-\${arch}"
+ cipd_description = "Prebuilt Chromedriver binary for Fuchsia host."
+ install_mode = "copy"
+ deps = [
+ ":strip_chromedriver_binary",
+ ]
+
+ sources = [
+ _stripped_chromedriver_file,
+ ]
+}
+
cipd_archive("tests") {
_manifest_path = "${target_gen_dir}/test_manifest.json"
cipd_manifest_name = "tests.yaml"
@@ -216,10 +266,26 @@ cipd_archive("debug_symbols") {
sources = [ _symbol_manifest ] + _symbol_tarballs
}
+cipd_archive("clear_key_cdm") {
+ cipd_manifest_name = "clear_key_cdm.yaml"
+ cipd_path = "chromium/fuchsia/libclearkeycdm-\${targetarch}"
+ cipd_description = "Prebuilt libclearkeycdm.so binary for Fuchsia."
+
+ deps = [
+ "//media/cdm/library_cdm/clear_key_cdm:clear_key_cdm",
+ ]
+
+ sources = [
+ "${root_out_dir}/lib/libclearkeycdm.so",
+ ]
+}
+
group("cipd") {
testonly = true
deps = [
":castrunner",
+ ":chromedriver",
+ ":clear_key_cdm",
":debug_symbols",
":http",
":tests",
diff --git a/chromium/fuchsia/engine/BUILD.gn b/chromium/fuchsia/engine/BUILD.gn
index c999193fd0c..881fa15ec20 100644
--- a/chromium/fuchsia/engine/BUILD.gn
+++ b/chromium/fuchsia/engine/BUILD.gn
@@ -10,12 +10,6 @@ import("//mojo/public/tools/bindings/mojom.gni")
import("//testing/test.gni")
import("//tools/grit/repack.gni")
-declare_args() {
- # Enables Vulkan in WebEngine (has effect only for context instances that have
- # Vulkan loader service in the service directory).
- web_engine_enable_vulkan = false
-}
-
config("web_engine_implementation") {
defines = [ "WEB_ENGINE_IMPLEMENTATION" ]
}
@@ -54,6 +48,7 @@ repack("web_engine_pak") {
"//content/app/resources",
"//content/app/strings",
"//content/browser/tracing:resources",
+ "//gpu/command_buffer/service",
"//mojo/public/js:resources",
"//net:net_resources",
"//third_party/blink/public:resources",
@@ -71,6 +66,7 @@ component("web_engine_core") {
":mojom",
":web_engine_pak",
"//base",
+ "//base:base_static",
"//components/version_info",
"//content/public/app:both",
"//content/public/browser",
@@ -80,13 +76,23 @@ component("web_engine_core") {
"//fuchsia/base",
"//fuchsia/base:message_port",
"//fuchsia/base:modular",
+ "//gpu/command_buffer/service",
+ "//media/fuchsia/cdm/service",
+ "//media/fuchsia/mojom",
"//mojo/public/cpp/bindings",
"//services/network/public/cpp",
+ "//services/network/public/mojom",
"//services/service_manager/sandbox",
- "//skia/public/interfaces",
+ "//skia/public/mojom",
"//third_party/blink/public/common",
+ "//third_party/fuchsia-sdk/sdk:accessibility_semantics",
+ "//third_party/fuchsia-sdk/sdk:math",
+ "//third_party/fuchsia-sdk/sdk:scenic_cpp",
+ "//third_party/fuchsia-sdk/sdk:sys_cpp",
"//third_party/fuchsia-sdk/sdk:web",
+ "//third_party/widevine/cdm:headers",
"//ui/aura",
+ "//ui/base",
"//ui/base/ime",
"//ui/display",
"//ui/ozone",
@@ -105,8 +111,14 @@ component("web_engine_core") {
]
configs += [ ":web_engine_implementation" ]
sources = [
+ "browser/accessibility_bridge.cc",
+ "browser/accessibility_bridge.h",
+ "browser/content_directory_loader_factory.cc",
+ "browser/content_directory_loader_factory.h",
"browser/context_impl.cc",
"browser/context_impl.h",
+ "browser/cookie_manager_impl.cc",
+ "browser/cookie_manager_impl.h",
"browser/discarding_event_filter.cc",
"browser/discarding_event_filter.h",
"browser/frame_impl.cc",
@@ -119,6 +131,8 @@ component("web_engine_core") {
"browser/web_engine_browser_main.h",
"browser/web_engine_browser_main_parts.cc",
"browser/web_engine_browser_main_parts.h",
+ "browser/web_engine_cdm_service.cc",
+ "browser/web_engine_cdm_service.h",
"browser/web_engine_content_browser_client.cc",
"browser/web_engine_content_browser_client.h",
"browser/web_engine_devtools_manager_delegate.cc",
@@ -131,8 +145,6 @@ component("web_engine_core") {
"browser/web_engine_remote_debugging.h",
"browser/web_engine_screen.cc",
"browser/web_engine_screen.h",
- "browser/web_engine_url_request_context_getter.cc",
- "browser/web_engine_url_request_context_getter.h",
"common.cc",
"common.h",
"context_provider_impl.cc",
@@ -153,9 +165,6 @@ component("web_engine_core") {
":*",
"//fuchsia/runners:cast_runner_browsertests__exec",
]
- if (web_engine_enable_vulkan) {
- defines = [ "WEB_ENGINE_ENABLE_VULKAN" ]
- }
}
executable("web_engine_exe") {
@@ -210,6 +219,7 @@ source_set("browsertest_core") {
test("web_engine_browsertests") {
sources = [
+ "browser/content_directory_browsertest.cc",
"browser/context_impl_browsertest.cc",
"browser/frame_impl_browsertest.cc",
]
@@ -234,17 +244,24 @@ test("web_engine_browsertests") {
test("web_engine_unittests") {
sources = [
+ "browser/accessibility_bridge_unittest.cc",
+ "browser/cookie_manager_impl_unittest.cc",
"browser/frame_impl_unittest.cc",
"context_provider_impl_unittest.cc",
"fake_context.cc",
"fake_context.h",
+ "test/run_all_unittests.cc",
]
deps = [
":web_engine_core",
- "//base/test:run_all_unittests",
"//base/test:test_support",
+ "//fuchsia/base:test_support",
+ "//mojo/core/embedder",
+ "//services/network:network_service",
+ "//services/network/public/mojom",
"//testing/gmock",
"//testing/gtest",
+ "//third_party/fuchsia-sdk/sdk:scenic_cpp",
"//third_party/fuchsia-sdk/sdk:web",
]
}
@@ -254,8 +271,6 @@ test("web_engine_integration_tests") {
sources = [
"test_debug_listener.cc",
"test_debug_listener.h",
- "test_devtools_list_fetcher.cc",
- "test_devtools_list_fetcher.h",
"web_engine_debug_integration_test.cc",
"web_engine_integration_test.cc",
]
@@ -267,8 +282,6 @@ test("web_engine_integration_tests") {
"//base/test:run_all_unittests",
"//fuchsia/base",
"//fuchsia/base:test_support",
- "//net",
- "//net:test_support",
"//third_party/fuchsia-sdk/sdk:web",
]
package_deps = [ [
diff --git a/chromium/fuchsia/engine/DEPS b/chromium/fuchsia/engine/DEPS
index a86f48cf2b7..eb2adde5782 100644
--- a/chromium/fuchsia/engine/DEPS
+++ b/chromium/fuchsia/engine/DEPS
@@ -1,5 +1,8 @@
include_rules = [
+ "+components/viz/common",
"+content/public/app",
+ "+gpu/command_buffer/service",
"+services/service_manager",
"+ui/base",
+ "+ui/gl/gl_switches.h",
]
diff --git a/chromium/fuchsia/engine/browser/DEPS b/chromium/fuchsia/engine/browser/DEPS
index 77a16fce5c5..70b09f16e2d 100644
--- a/chromium/fuchsia/engine/browser/DEPS
+++ b/chromium/fuchsia/engine/browser/DEPS
@@ -3,13 +3,17 @@ include_rules = [
"+components/version_info",
"+content/public/common",
"+content/public/browser",
- "+content/public/test",
+ "+media/base",
+ "+media/fuchsia/cdm/service",
+ "+media/fuchsia/mojom",
"+mojo/public/cpp/bindings",
"+mojo/public/cpp/system",
+ "+services/network/public/mojom",
"+third_party/blink/public/common/associated_interfaces",
"+third_party/blink/public/common/logging",
"+third_party/blink/public/common/messaging",
"+third_party/blink/public/mojom/messaging",
+ "+third_party/widevine/cdm",
"+ui/aura",
"+ui/base/ime",
"+ui/display",
@@ -18,3 +22,10 @@ include_rules = [
"+ui/platform_window",
"+ui/wm/core",
]
+
+specific_include_rules = {
+ ".*_(unit|browser|api)test\.cc": [
+ "+content/public/test",
+ "+services/network",
+ ],
+}
diff --git a/chromium/fuchsia/engine/browser/accessibility_bridge.cc b/chromium/fuchsia/engine/browser/accessibility_bridge.cc
new file mode 100644
index 00000000000..b2f521c0dde
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/accessibility_bridge.cc
@@ -0,0 +1,35 @@
+// Copyright 2019 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 "fuchsia/engine/browser/accessibility_bridge.h"
+
+#include "base/logging.h"
+
+AccessibilityBridge::AccessibilityBridge(
+ fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager,
+ fuchsia::ui::views::ViewRef view_ref)
+ : binding_(this) {
+ semantics_manager->RegisterViewForSemantics(
+ std::move(view_ref), binding_.NewBinding(), tree_ptr_.NewRequest());
+}
+
+AccessibilityBridge::~AccessibilityBridge() = default;
+
+void AccessibilityBridge::OnAccessibilityActionRequested(
+ uint32_t node_id,
+ fuchsia::accessibility::semantics::Action action,
+ OnAccessibilityActionRequestedCallback callback) {
+ NOTIMPLEMENTED();
+}
+
+void AccessibilityBridge::HitTest(fuchsia::math::PointF local_point,
+ HitTestCallback callback) {
+ NOTIMPLEMENTED();
+}
+
+void AccessibilityBridge::OnSemanticsModeChanged(
+ bool updates_enabled,
+ OnSemanticsModeChangedCallback callback) {
+ NOTIMPLEMENTED();
+}
diff --git a/chromium/fuchsia/engine/browser/accessibility_bridge.h b/chromium/fuchsia/engine/browser/accessibility_bridge.h
new file mode 100644
index 00000000000..9a95027c332
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/accessibility_bridge.h
@@ -0,0 +1,47 @@
+// Copyright 2019 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 FUCHSIA_ENGINE_BROWSER_ACCESSIBILITY_BRIDGE_H_
+#define FUCHSIA_ENGINE_BROWSER_ACCESSIBILITY_BRIDGE_H_
+
+#include <fuchsia/accessibility/semantics/cpp/fidl.h>
+#include <fuchsia/math/cpp/fidl.h>
+#include <fuchsia/ui/views/cpp/fidl.h>
+#include <lib/fidl/cpp/binding.h>
+
+#include "base/macros.h"
+
+// This class is the intermediate for accessibility between Chrome and Fuchsia.
+// It handles registration to the Fuchsia Semantics Manager, translating events
+// and data structures between the two services, and forwarding actions and
+// events.
+// The lifetime of an instance of AccessibilityBridge is the same as that of a
+// View created by FrameImpl. This class refers to the View via the
+// caller-supplied ViewRef.
+class AccessibilityBridge
+ : public fuchsia::accessibility::semantics::SemanticListener {
+ public:
+ AccessibilityBridge(
+ fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager,
+ fuchsia::ui::views::ViewRef view_ref);
+ ~AccessibilityBridge() final;
+
+ private:
+ // fuchsia::accessibility::semantics::SemanticListener implementation.
+ void OnAccessibilityActionRequested(
+ uint32_t node_id,
+ fuchsia::accessibility::semantics::Action action,
+ OnAccessibilityActionRequestedCallback callback) final;
+ void HitTest(fuchsia::math::PointF local_point,
+ HitTestCallback callback) final;
+ void OnSemanticsModeChanged(bool updates_enabled,
+ OnSemanticsModeChangedCallback callback) final;
+
+ fuchsia::accessibility::semantics::SemanticTreePtr tree_ptr_;
+ fidl::Binding<fuchsia::accessibility::semantics::SemanticListener> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(AccessibilityBridge);
+};
+
+#endif // FUCHSIA_ENGINE_BROWSER_ACCESSIBILITY_BRIDGE_H_
diff --git a/chromium/fuchsia/engine/browser/accessibility_bridge_unittest.cc b/chromium/fuchsia/engine/browser/accessibility_bridge_unittest.cc
new file mode 100644
index 00000000000..49a4f1ad813
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/accessibility_bridge_unittest.cc
@@ -0,0 +1,102 @@
+// Copyright 2019 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 "fuchsia/engine/browser/accessibility_bridge.h"
+
+#include <fuchsia/accessibility/semantics/cpp/fidl.h>
+#include <fuchsia/accessibility/semantics/cpp/fidl_test_base.h>
+#include <lib/sys/cpp/component_context.h>
+#include <lib/ui/scenic/cpp/view_ref_pair.h>
+#include <zircon/types.h>
+
+#include "base/fuchsia/default_context.h"
+#include "base/fuchsia/scoped_service_binding.h"
+#include "base/fuchsia/service_directory_client.h"
+#include "base/logging.h"
+#include "base/test/task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using fuchsia::accessibility::semantics::SemanticListener;
+using fuchsia::accessibility::semantics::SemanticsManager;
+
+namespace {
+
+class FakeSemanticsManager : public fuchsia::accessibility::semantics::testing::
+ SemanticsManager_TestBase {
+ public:
+ explicit FakeSemanticsManager() = default;
+ ~FakeSemanticsManager() override = default;
+
+ // fuchsia::accessibility::semantics::SemanticsManager implementation.
+ void RegisterViewForSemantics(
+ fuchsia::ui::views::ViewRef view_ref,
+ fidl::InterfaceHandle<SemanticListener> listener,
+ fidl::InterfaceRequest<fuchsia::accessibility::semantics::SemanticTree>
+ semantic_tree) final {
+ view_ref_ = std::move(view_ref);
+ listener_ = std::move(listener);
+ semantic_tree_ = std::move(semantic_tree);
+ }
+
+ bool is_view_registered() const { return view_ref_.reference.is_valid(); }
+
+ bool is_listener_handle_valid() const { return listener_.is_valid(); }
+
+ bool is_semantic_tree_handle_valid() const {
+ return semantic_tree_.is_valid();
+ }
+
+ void NotImplemented_(const std::string& name) final {
+ NOTIMPLEMENTED() << name;
+ }
+
+ private:
+ fuchsia::ui::views::ViewRef view_ref_;
+ fidl::InterfaceHandle<SemanticListener> listener_;
+ fidl::InterfaceRequest<fuchsia::accessibility::semantics::SemanticTree>
+ semantic_tree_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeSemanticsManager);
+};
+
+} // namespace
+
+class AccessibilityBridgeTest : public testing::Test {
+ public:
+ AccessibilityBridgeTest()
+ : task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO),
+ semantics_manager_binding_(&semantics_manager_) {}
+ ~AccessibilityBridgeTest() override = default;
+
+ void CreateAccessibilityBridge() {
+ auto view_ref_pair = scenic::ViewRefPair::New();
+ control_ref_ = std::move(view_ref_pair.control_ref);
+ fuchsia::accessibility::semantics::SemanticsManagerPtr
+ semantics_manager_ptr;
+ semantics_manager_binding_.Bind(semantics_manager_ptr.NewRequest());
+ accessibility_bridge_ = std::make_unique<AccessibilityBridge>(
+ std::move(semantics_manager_ptr), std::move(view_ref_pair.view_ref));
+ }
+
+ protected:
+ base::test::SingleThreadTaskEnvironment task_environment_;
+ std::unique_ptr<AccessibilityBridge> accessibility_bridge_;
+ FakeSemanticsManager semantics_manager_;
+ fidl::Binding<fuchsia::accessibility::semantics::SemanticsManager>
+ semantics_manager_binding_;
+ fuchsia::ui::views::ViewRefControl control_ref_;
+
+ DISALLOW_COPY_AND_ASSIGN(AccessibilityBridgeTest);
+};
+
+// Test registration to the SemanticsManager.
+TEST_F(AccessibilityBridgeTest, RegisterViewRef) {
+ CreateAccessibilityBridge();
+ // Run loop so FIDL registration requests are processed.
+ task_environment_.RunUntilIdle();
+ EXPECT_TRUE(semantics_manager_.is_view_registered());
+ EXPECT_TRUE(semantics_manager_.is_listener_handle_valid());
+ EXPECT_TRUE(semantics_manager_.is_semantic_tree_handle_valid());
+}
diff --git a/chromium/fuchsia/engine/browser/content_directory_browsertest.cc b/chromium/fuchsia/engine/browser/content_directory_browsertest.cc
new file mode 100644
index 00000000000..54f7f787cfa
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/content_directory_browsertest.cc
@@ -0,0 +1,208 @@
+// Copyright 2019 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 <lib/fdio/directory.h>
+
+#include "fuchsia/engine/test/web_engine_browser_test.h"
+
+#include "base/files/file_path.h"
+#include "base/fuchsia/fuchsia_logging.h"
+#include "base/path_service.h"
+#include "base/test/bind_test_util.h"
+#include "base/test/test_timeouts.h"
+#include "fuchsia/base/frame_test_util.h"
+#include "fuchsia/base/test_navigation_listener.h"
+#include "fuchsia/engine/browser/content_directory_loader_factory.h"
+#include "fuchsia/engine/common.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class ContentDirectoryTest : public cr_fuchsia::WebEngineBrowserTest {
+ public:
+ ContentDirectoryTest()
+ : run_timeout_(TestTimeouts::action_timeout(),
+ base::MakeExpectedNotRunClosure(FROM_HERE)) {}
+ ~ContentDirectoryTest() override = default;
+
+ void SetUp() override {
+ // Set this flag early so that the fuchsia-dir:// scheme will be
+ // registered at browser startup.
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(kContentDirectories);
+
+ cr_fuchsia::WebEngineBrowserTest::SetUp();
+ }
+
+ void SetUpOnMainThread() override {
+ std::vector<fuchsia::web::ContentDirectoryProvider> providers;
+
+ fuchsia::web::ContentDirectoryProvider provider;
+ provider.set_name("testdata");
+ base::FilePath pkg_path;
+ base::PathService::Get(base::DIR_ASSETS, &pkg_path);
+ provider.set_directory(
+ OpenDirectoryHandle(pkg_path.AppendASCII("fuchsia/engine/test/data")));
+ providers.emplace_back(std::move(provider));
+
+ provider = {};
+ provider.set_name("alternate");
+ provider.set_directory(
+ OpenDirectoryHandle(pkg_path.AppendASCII("fuchsia/engine/test/data")));
+ providers.emplace_back(std::move(provider));
+
+ ContentDirectoryLoaderFactory::SetContentDirectoriesForTest(
+ std::move(providers));
+
+ cr_fuchsia::WebEngineBrowserTest::SetUpOnMainThread();
+ }
+
+ void TearDown() override {
+ ContentDirectoryLoaderFactory::SetContentDirectoriesForTest({});
+ }
+
+ fidl::InterfaceHandle<fuchsia::io::Directory> OpenDirectoryHandle(
+ const base::FilePath& path) {
+ zx::channel directory_channel;
+ zx::channel remote_directory_channel;
+ zx_status_t status =
+ zx::channel::create(0, &directory_channel, &remote_directory_channel);
+ ZX_DCHECK(status == ZX_OK, status) << "zx_channel_create";
+
+ status = fdio_open(
+ path.value().c_str(),
+ fuchsia::io::OPEN_FLAG_DIRECTORY | fuchsia::io::OPEN_RIGHT_READABLE,
+ remote_directory_channel.release());
+ ZX_DCHECK(status == ZX_OK, status) << "fdio_open";
+
+ return fidl::InterfaceHandle<fuchsia::io::Directory>(
+ std::move(directory_channel));
+ }
+
+ protected:
+ // Creates a Frame with |navigation_listener_| attached.
+ fuchsia::web::FramePtr CreateFrame() {
+ return WebEngineBrowserTest::CreateFrame(&navigation_listener_);
+ }
+
+ cr_fuchsia::TestNavigationListener navigation_listener_;
+
+ private:
+ const base::RunLoop::ScopedRunTimeoutForTest run_timeout_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentDirectoryTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, Navigate) {
+ const GURL kUrl("fuchsia-dir://testdata/title1.html");
+
+ fuchsia::web::FramePtr frame = CreateFrame();
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
+ navigation_listener_.RunUntilUrlEquals(kUrl);
+}
+
+// Navigate to a resource stored under a secondary provider.
+IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, NavigateAlternate) {
+ const GURL kUrl("fuchsia-dir://alternate/title1.html");
+
+ fuchsia::web::FramePtr frame = CreateFrame();
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
+ navigation_listener_.RunUntilUrlEquals(kUrl);
+}
+
+IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, ScriptSubresource) {
+ const GURL kUrl("fuchsia-dir://testdata/include_script.html");
+
+ fuchsia::web::FramePtr frame = CreateFrame();
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
+ navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "title set by script");
+}
+
+IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, ImgSubresource) {
+ const GURL kUrl("fuchsia-dir://testdata/include_image.html");
+
+ fuchsia::web::FramePtr frame = CreateFrame();
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
+ navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "image fetched");
+}
+
+// Verify that resource providers are origin-isolated.
+IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, ScriptSrcCrossOriginBlocked) {
+ const GURL kUrl("fuchsia-dir://testdata/cross_origin_include_script.html");
+
+ fuchsia::web::FramePtr frame = CreateFrame();
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ // If the cross-origin script succeeded, then we should see "title set by
+ // script". If "not clobbered" remains set, then we know that CROS enforcement
+ // is working.
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
+ navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "same origin ftw");
+}
+
+IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, CrossOriginImgBlocked) {
+ const GURL kUrl("fuchsia-dir://testdata/cross_origin_include_image.html");
+
+ fuchsia::web::FramePtr frame = CreateFrame();
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
+
+ navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "image rejected");
+}
+
+IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, MetadataFileParsed) {
+ const GURL kUrl("fuchsia-dir://testdata/mime_override.html");
+
+ fuchsia::web::FramePtr frame = CreateFrame();
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
+ navigation_listener_.RunUntilUrlAndTitleEquals(
+ kUrl, "content-type: text/bleep; charset=US-ASCII");
+}
+
+IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, BadMetadataFile) {
+ const GURL kUrl("fuchsia-dir://testdata/mime_override_invalid.html");
+
+ fuchsia::web::FramePtr frame = CreateFrame();
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
+ navigation_listener_.RunUntilUrlAndTitleEquals(kUrl,
+ "content-type: text/html");
+}
+
+} // namespace
diff --git a/chromium/fuchsia/engine/browser/content_directory_loader_factory.cc b/chromium/fuchsia/engine/browser/content_directory_loader_factory.cc
new file mode 100644
index 00000000000..5ca9821d7d0
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/content_directory_loader_factory.cc
@@ -0,0 +1,382 @@
+// Copyright 2019 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 "fuchsia/engine/browser/content_directory_loader_factory.h"
+
+#include <lib/fdio/directory.h>
+#include <lib/fdio/fdio.h>
+
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "base/files/memory_mapped_file.h"
+#include "base/fuchsia/fuchsia_logging.h"
+#include "base/json/json_reader.h"
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/no_destructor.h"
+#include "base/strings/strcat.h"
+#include "base/strings/string_split.h"
+#include "base/task/post_task.h"
+#include "base/task/task_traits.h"
+#include "fuchsia/engine/common.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/system/data_pipe_producer.h"
+#include "mojo/public/cpp/system/string_data_source.h"
+#include "net/base/filename_util.h"
+#include "net/base/mime_sniffer.h"
+#include "net/base/parse_number.h"
+#include "services/network/public/cpp/resource_response.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
+
+namespace {
+
+using ContentDirectoriesMap =
+ std::map<std::string, fidl::InterfaceHandle<fuchsia::io::Directory>>;
+
+ContentDirectoriesMap ParseContentDirectoriesFromCommandLine() {
+ ContentDirectoriesMap directories;
+
+ // Parse the list of content directories from the command line.
+ std::string content_directories_unsplit =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ kContentDirectories);
+ if (content_directories_unsplit.empty())
+ return {};
+
+ base::StringPairs named_handle_ids;
+ if (!base::SplitStringIntoKeyValuePairs(content_directories_unsplit, '=', ',',
+ &named_handle_ids)) {
+ LOG(WARNING) << "Couldn't parse --" << kContentDirectories
+ << " into KV pairs: " << content_directories_unsplit;
+ return {};
+ }
+
+ for (const auto& named_handle_id : named_handle_ids) {
+ uint32_t handle_id = 0;
+ if (!net::ParseUint32(named_handle_id.second, &handle_id)) {
+ DLOG(FATAL) << "Couldn't parse handle ID as uint32: "
+ << named_handle_id.second;
+ continue;
+ }
+
+ auto directory_channel = zx::channel(zx_take_startup_handle(handle_id));
+ if (directory_channel == ZX_HANDLE_INVALID) {
+ DLOG(FATAL) << "Couldn't take startup handle: " << handle_id;
+ continue;
+ }
+
+ directories.emplace(named_handle_id.first,
+ fidl::InterfaceHandle<fuchsia::io::Directory>(
+ std::move(directory_channel)));
+ }
+ return directories;
+}
+
+// Gets the process-global list of content directory channels.
+ContentDirectoriesMap* GetContentDirectories() {
+ static base::NoDestructor<ContentDirectoriesMap> directories(
+ ParseContentDirectoriesFromCommandLine());
+
+ return directories.get();
+}
+
+// Returns a list of populated response HTTP headers.
+// |mime_type|: The MIME type of the resource.
+// |charset|: The resource's character set. Optional. If omitted, the browser
+// will assume the charset to be "text/plain" by default.
+scoped_refptr<net::HttpResponseHeaders> CreateHeaders(
+ base::StringPiece mime_type,
+ const base::Optional<std::string>& charset) {
+ constexpr char kXFrameOptionsHeader[] = "X-Frame-Options: DENY";
+ constexpr char kCacheHeader[] = "Cache-Control: no-cache";
+ constexpr char kContentTypePrefix[] = "Content-Type: ";
+ constexpr char kCharsetSeparator[] = "; charset=";
+
+ auto headers =
+ base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK\r\n");
+ headers->AddHeader(kXFrameOptionsHeader);
+ headers->AddHeader(kCacheHeader);
+
+ if (charset) {
+ headers->AddHeader(base::StrCat(
+ {kContentTypePrefix, mime_type, kCharsetSeparator, *charset}));
+ } else {
+ headers->AddHeader(base::StrCat({kContentTypePrefix, mime_type}));
+ }
+
+ return headers;
+}
+
+// Copies data from a fuchsia.io.Node file into a URL response stream.
+class ContentDirectoryURLLoader : public network::mojom::URLLoader {
+ public:
+ ContentDirectoryURLLoader() = default;
+ ~ContentDirectoryURLLoader() final = default;
+
+ // Creates a read-only MemoryMappedFile view to |file|.
+ bool MapFile(fidl::InterfaceHandle<fuchsia::io::Node> file,
+ base::MemoryMappedFile* mmap) {
+ // Bind the file channel to a FDIO entry and then a file descriptor so that
+ // we can use it for reading.
+ fdio_t* fdio = nullptr;
+ zx_status_t status = fdio_create(file.TakeChannel().release(), &fdio);
+ if (status == ZX_ERR_PEER_CLOSED) {
+ // File-not-found errors are expected in some cases, so handle this result
+ // w/o logging error text.
+ return false;
+ } else if (status != ZX_OK) {
+ ZX_DLOG_IF(WARNING, status != ZX_OK, status) << "fdio_create";
+ return false;
+ }
+
+ base::ScopedFD fd(fdio_bind_to_fd(fdio, -1, 0));
+ if (!fd.is_valid()) {
+ LOG(ERROR) << "fdio_bind_to_fd returned an invalid FD.";
+ return false;
+ }
+
+ // Map the file into memory.
+ if (!mmap->Initialize(base::File(fd.release()),
+ base::MemoryMappedFile::READ_ONLY)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ // Initiates data transfer from |file_channel| to |client_info|.
+ // |metadata_channel|, if it is connected to a file, is accessed to get the
+ // MIME type and charset of the file.
+ static void CreateAndStart(
+ network::mojom::URLLoaderRequest url_loader_request,
+ const network::ResourceRequest& request,
+ network::mojom::URLLoaderClientPtrInfo client_info,
+ fidl::InterfaceHandle<fuchsia::io::Node> file_channel,
+ fidl::InterfaceHandle<fuchsia::io::Node> metadata_channel) {
+ std::unique_ptr<ContentDirectoryURLLoader> loader =
+ std::make_unique<ContentDirectoryURLLoader>();
+ loader->Start(request, std::move(client_info), std::move(file_channel),
+ std::move(metadata_channel));
+
+ // |loader|'s lifetime is bound to the lifetime of the URLLoader Mojo
+ // client endpoint.
+ mojo::MakeStrongBinding(std::move(loader), std::move(url_loader_request));
+ }
+
+ void Start(const network::ResourceRequest& request,
+ network::mojom::URLLoaderClientPtrInfo client_info,
+ fidl::InterfaceHandle<fuchsia::io::Node> file_channel,
+ fidl::InterfaceHandle<fuchsia::io::Node> metadata_channel) {
+ client_.Bind(std::move(client_info));
+
+ if (!MapFile(std::move(file_channel), &mmap_)) {
+ client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ return;
+ }
+
+ // Construct and deliver the HTTP response header.
+ network::ResourceResponseHead response;
+
+ // Read the charset and MIME type from the optional _metadata file.
+ base::Optional<std::string> charset;
+ base::Optional<std::string> mime_type;
+ base::MemoryMappedFile metadata_mmap;
+ if (MapFile(std::move(metadata_channel), &metadata_mmap)) {
+ base::Optional<base::Value> metadata_parsed = base::JSONReader::Read(
+ base::StringPiece(reinterpret_cast<char*>(metadata_mmap.data()),
+ metadata_mmap.length()));
+
+ if (metadata_parsed && metadata_parsed->is_dict()) {
+ if (metadata_parsed->FindStringKey("charset"))
+ charset = *metadata_parsed->FindStringKey("charset");
+
+ if (metadata_parsed->FindStringKey("mime"))
+ mime_type = *metadata_parsed->FindStringKey("mime");
+ }
+ }
+
+ // If a MIME type wasn't specified, then fall back on inferring the type
+ // from the file's contents.
+ if (!mime_type) {
+ mime_type.emplace();
+ net::SniffMimeType(
+ reinterpret_cast<char*>(mmap_.data()), mmap_.length(), request.url,
+ "", net::ForceSniffFileUrlsForHtml::kDisabled, &*mime_type);
+ }
+ response.mime_type = *mime_type;
+ response.headers = CreateHeaders(response.mime_type, charset);
+ response.content_length = mmap_.length();
+ client_->OnReceiveResponse(response);
+
+ // Set up the Mojo DataPipe used for streaming the response payload to the
+ // client.
+ mojo::ScopedDataPipeProducerHandle producer_handle;
+ mojo::ScopedDataPipeConsumerHandle consumer_handle;
+ MojoResult rv = mojo::CreateDataPipe(0, &producer_handle, &consumer_handle);
+ if (rv != MOJO_RESULT_OK) {
+ client_->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_INSUFFICIENT_RESOURCES));
+ return;
+ }
+
+ client_->OnStartLoadingResponseBody(std::move(consumer_handle));
+
+ // Start reading the contents of |mmap_| into the response DataPipe.
+ body_writer_ =
+ std::make_unique<mojo::DataPipeProducer>(std::move(producer_handle));
+ body_writer_->Write(
+ std::make_unique<mojo::StringDataSource>(
+ base::StringPiece(reinterpret_cast<char*>(mmap_.data()),
+ mmap_.length()),
+ mojo::StringDataSource::AsyncWritingMode::
+ STRING_STAYS_VALID_UNTIL_COMPLETION),
+ base::BindOnce(&ContentDirectoryURLLoader::OnWriteComplete,
+ base::Unretained(this)));
+ }
+
+ // network::mojom::URLLoader implementation:
+ void FollowRedirect(const std::vector<std::string>& removed_headers,
+ const net::HttpRequestHeaders& modified_request_headers,
+ const base::Optional<GURL>& new_url) override {}
+ void SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) override {}
+ void PauseReadingBodyFromNet() override {}
+ void ResumeReadingBodyFromNet() override {}
+
+ private:
+ // Called when body_writer_->Write() has completed asynchronously.
+ void OnWriteComplete(MojoResult result) {
+ // Signal stream EOF to the client.
+ body_writer_.reset();
+
+ if (result != MOJO_RESULT_OK) {
+ client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ return;
+ }
+
+ network::URLLoaderCompletionStatus status(net::OK);
+ status.encoded_data_length = mmap_.length();
+ status.encoded_body_length = mmap_.length();
+ status.decoded_body_length = mmap_.length();
+ client_->OnComplete(std::move(status));
+ }
+
+ // Used for sending status codes and response payloads to the client.
+ network::mojom::URLLoaderClientPtr client_;
+
+ // A read-only, memory mapped view of the file being loaded.
+ base::MemoryMappedFile mmap_;
+
+ // Manages chunked data transfer over the response DataPipe.
+ std::unique_ptr<mojo::DataPipeProducer> body_writer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentDirectoryURLLoader);
+};
+
+} // namespace
+
+ContentDirectoryLoaderFactory::ContentDirectoryLoaderFactory()
+ : task_runner_(base::CreateSequencedTaskRunner(
+ {base::ThreadPool(), base::MayBlock(),
+ base::TaskPriority::USER_VISIBLE,
+ base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})) {}
+
+ContentDirectoryLoaderFactory::~ContentDirectoryLoaderFactory() {}
+
+net::Error ContentDirectoryLoaderFactory::OpenFileFromDirectory(
+ const std::string& directory_name,
+ base::FilePath path,
+ fidl::InterfaceRequest<fuchsia::io::Node> file_request) {
+ DCHECK(file_request);
+
+ ContentDirectoriesMap* content_directories = GetContentDirectories();
+ if (content_directories->find(directory_name) == content_directories->end())
+ return net::ERR_FILE_NOT_FOUND;
+
+ const fidl::InterfaceHandle<fuchsia::io::Directory>& directory =
+ content_directories->at(directory_name);
+ if (!directory)
+ return net::ERR_INVALID_HANDLE;
+
+ zx_status_t status = fdio_open_at(
+ directory.channel().get(), path.value().c_str(),
+ fuchsia::io::OPEN_RIGHT_READABLE, file_request.TakeChannel().release());
+ if (status != ZX_OK) {
+ ZX_DLOG(WARNING, status) << "fdio_open_at";
+ return net::ERR_FILE_NOT_FOUND;
+ }
+
+ return net::OK;
+}
+
+void ContentDirectoryLoaderFactory::CreateLoaderAndStart(
+ network::mojom::URLLoaderRequest loader,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest& request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
+ if (!request.url.SchemeIs(kFuchsiaContentDirectoryScheme) ||
+ !request.url.is_valid()) {
+ client->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_INVALID_URL));
+ return;
+ }
+
+ if (request.method != "GET") {
+ client->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_METHOD_NOT_SUPPORTED));
+ return;
+ }
+
+ fidl::InterfaceHandle<fuchsia::io::Node> file_handle;
+ net::Error open_result = OpenFileFromDirectory(
+ request.url.GetOrigin().host(), base::FilePath(request.url.path()),
+ file_handle.NewRequest());
+ if (open_result != net::OK) {
+ client->OnComplete(network::URLLoaderCompletionStatus(open_result));
+ return;
+ }
+ DCHECK(file_handle);
+
+ // Metadata files are optional. In the event that the file is absent,
+ // |metadata_channel| will produce a ZX_CHANNEL_PEER_CLOSED status inside
+ // ContentDirectoryURLLoader::Start().
+ fidl::InterfaceHandle<fuchsia::io::Node> metadata_handle;
+ open_result =
+ OpenFileFromDirectory(request.url.GetOrigin().host(),
+ base::FilePath(request.url.path() + "._metadata"),
+ metadata_handle.NewRequest());
+ if (open_result != net::OK) {
+ client->OnComplete(network::URLLoaderCompletionStatus(open_result));
+ return;
+ }
+
+ // Load the resource on a blocking-capable TaskRunner.
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&ContentDirectoryURLLoader::CreateAndStart,
+ base::Passed(std::move(loader)), request,
+ base::Passed(client.PassInterface()),
+ base::Passed(std::move(file_handle)),
+ base::Passed(std::move(metadata_handle))));
+}
+
+void ContentDirectoryLoaderFactory::Clone(
+ network::mojom::URLLoaderFactoryRequest loader) {
+ bindings_.AddBinding(this, std::move(loader));
+}
+
+void ContentDirectoryLoaderFactory::SetContentDirectoriesForTest(
+ std::vector<fuchsia::web::ContentDirectoryProvider> directories) {
+ ContentDirectoriesMap* current_process_directories = GetContentDirectories();
+
+ current_process_directories->clear();
+ for (fuchsia::web::ContentDirectoryProvider& directory : directories) {
+ current_process_directories->emplace(directory.name(),
+ directory.mutable_directory()->Bind());
+ }
+}
diff --git a/chromium/fuchsia/engine/browser/content_directory_loader_factory.h b/chromium/fuchsia/engine/browser/content_directory_loader_factory.h
new file mode 100644
index 00000000000..c5257c29df5
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/content_directory_loader_factory.h
@@ -0,0 +1,57 @@
+// Copyright 2019 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 FUCHSIA_ENGINE_BROWSER_CONTENT_DIRECTORY_LOADER_FACTORY_H_
+#define FUCHSIA_ENGINE_BROWSER_CONTENT_DIRECTORY_LOADER_FACTORY_H_
+
+#include <fuchsia/io/cpp/fidl.h>
+#include <fuchsia/web/cpp/fidl.h>
+#include <lib/fidl/cpp/interface_handle.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "fuchsia/engine/web_engine_export.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+
+// Creates a URLLoaderFactory which services requests for resources stored
+// under named directories. The directories are accessed using the
+// fuchsia-dir:// scheme.
+class ContentDirectoryLoaderFactory : public network::mojom::URLLoaderFactory {
+ public:
+ ContentDirectoryLoaderFactory();
+ ~ContentDirectoryLoaderFactory() override;
+
+ // Sets the list of content directories for the duration of the process.
+ // Can be called multiple times for clearing or replacing the list.
+ static WEB_ENGINE_EXPORT void SetContentDirectoriesForTest(
+ std::vector<fuchsia::web::ContentDirectoryProvider> directories);
+
+ // network::mojom::URLLoaderFactory:
+ void CreateLoaderAndStart(
+ network::mojom::URLLoaderRequest loader,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest& request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) final;
+ void Clone(network::mojom::URLLoaderFactoryRequest loader) final;
+
+ private:
+ net::Error OpenFileFromDirectory(
+ const std::string& directory_name,
+ base::FilePath path,
+ fidl::InterfaceRequest<fuchsia::io::Node> file_request);
+
+ // Used for executing blocking URLLoader routines.
+ const scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
+ mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentDirectoryLoaderFactory);
+};
+
+#endif // FUCHSIA_ENGINE_BROWSER_CONTENT_DIRECTORY_LOADER_FACTORY_H_
diff --git a/chromium/fuchsia/engine/browser/context_impl.cc b/chromium/fuchsia/engine/browser/context_impl.cc
index b87a396433a..b154c9739bd 100644
--- a/chromium/fuchsia/engine/browser/context_impl.cc
+++ b/chromium/fuchsia/engine/browser/context_impl.cc
@@ -4,21 +4,36 @@
#include "fuchsia/engine/browser/context_impl.h"
-#include <lib/zx/object.h>
+#include <lib/zx/channel.h>
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/fuchsia/fuchsia_logging.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "fuchsia/engine/browser/frame_impl.h"
-#include "fuchsia/engine/browser/web_engine_browser_context.h"
#include "fuchsia/engine/common.h"
ContextImpl::ContextImpl(content::BrowserContext* browser_context)
- : browser_context_(browser_context) {}
+ : browser_context_(browser_context),
+ cookie_manager_(base::BindRepeating(
+ &content::StoragePartition::GetNetworkContext,
+ base::Unretained(content::BrowserContext::GetDefaultStoragePartition(
+ browser_context_)))) {}
ContextImpl::~ContextImpl() = default;
+fidl::InterfaceHandle<fuchsia::web::Frame>
+ContextImpl::CreateFrameForPopupWebContents(
+ std::unique_ptr<content::WebContents> web_contents) {
+ fidl::InterfaceHandle<fuchsia::web::Frame> frame_handle;
+ frames_.insert(std::make_unique<FrameImpl>(std::move(web_contents), this,
+ frame_handle.NewRequest()));
+ return frame_handle;
+}
+
void ContextImpl::DestroyFrame(FrameImpl* frame) {
DCHECK(frames_.find(frame) != frames_.end());
frames_.erase(frames_.find(frame));
@@ -42,6 +57,11 @@ void ContextImpl::CreateFrame(
std::move(frame)));
}
+void ContextImpl::GetCookieManager(
+ fidl::InterfaceRequest<fuchsia::web::CookieManager> request) {
+ cookie_manager_bindings_.AddBinding(&cookie_manager_, std::move(request));
+}
+
void ContextImpl::GetRemoteDebuggingPort(
GetRemoteDebuggingPortCallback callback) {
web_engine_remote_debugging_.GetRemoteDebuggingPort(std::move(callback));
diff --git a/chromium/fuchsia/engine/browser/context_impl.h b/chromium/fuchsia/engine/browser/context_impl.h
index cd406106feb..6a53ae185ca 100644
--- a/chromium/fuchsia/engine/browser/context_impl.h
+++ b/chromium/fuchsia/engine/browser/context_impl.h
@@ -6,16 +6,19 @@
#define FUCHSIA_ENGINE_BROWSER_CONTEXT_IMPL_H_
#include <fuchsia/web/cpp/fidl.h>
+#include <lib/fidl/cpp/binding_set.h>
#include <memory>
#include <set>
#include "base/containers/unique_ptr_adapters.h"
#include "base/macros.h"
+#include "fuchsia/engine/browser/cookie_manager_impl.h"
#include "fuchsia/engine/browser/web_engine_remote_debugging.h"
#include "fuchsia/engine/web_engine_export.h"
namespace content {
class BrowserContext;
+class WebContents;
} // namespace content
class FrameImpl;
@@ -29,7 +32,7 @@ class WEB_ENGINE_EXPORT ContextImpl : public fuchsia::web::Context {
explicit ContextImpl(content::BrowserContext* browser_context);
// Tears down the Context, destroying any active Frames in the process.
- ~ContextImpl() override;
+ ~ContextImpl() final;
content::BrowserContext* browser_context_for_test() {
return browser_context_;
@@ -41,13 +44,19 @@ class WEB_ENGINE_EXPORT ContextImpl : public fuchsia::web::Context {
// Returns |true| if JS injection was enabled for this Context.
bool IsJavaScriptInjectionAllowed();
+ // Registers a Frame originating from web content (i.e. a popup).
+ fidl::InterfaceHandle<fuchsia::web::Frame> CreateFrameForPopupWebContents(
+ std::unique_ptr<content::WebContents> web_contents);
+
// Called by Frames to signal a document has been loaded and signal to the
// debug listeners in |web_engine_remote_debugging_| that they can now
// successfully connect ChromeDriver.
void OnDebugDevToolsPortReady();
// fuchsia::web::Context implementation.
- void CreateFrame(fidl::InterfaceRequest<fuchsia::web::Frame> frame) override;
+ void CreateFrame(fidl::InterfaceRequest<fuchsia::web::Frame> frame) final;
+ void GetCookieManager(
+ fidl::InterfaceRequest<fuchsia::web::CookieManager> manager) final;
void GetRemoteDebuggingPort(GetRemoteDebuggingPortCallback callback) override;
// Gets the underlying FrameImpl service object associated with a connected
@@ -57,6 +66,9 @@ class WEB_ENGINE_EXPORT ContextImpl : public fuchsia::web::Context {
private:
content::BrowserContext* const browser_context_;
+ CookieManagerImpl cookie_manager_;
+ fidl::BindingSet<fuchsia::web::CookieManager> cookie_manager_bindings_;
+
// TODO(crbug.com/893236): Make this false by default, and allow it to be
// initialized at Context creation time.
bool allow_javascript_injection_ = true;
diff --git a/chromium/fuchsia/engine/browser/context_impl_browsertest.cc b/chromium/fuchsia/engine/browser/context_impl_browsertest.cc
index d536330d572..ff6403870af 100644
--- a/chromium/fuchsia/engine/browser/context_impl_browsertest.cc
+++ b/chromium/fuchsia/engine/browser/context_impl_browsertest.cc
@@ -20,23 +20,11 @@
#include "fuchsia/engine/test/web_engine_browser_test.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
-#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/url_constants.h"
-using testing::_;
-using testing::Field;
-using testing::InvokeWithoutArgs;
-
namespace {
-void OnCookiesReceived(net::CookieList* output,
- base::OnceClosure on_received_cb,
- const net::CookieList& cookies) {
- *output = cookies;
- std::move(on_received_cb).Run();
-}
-
// Defines a suite of tests that exercise browser-level configuration and
// functionality.
class ContextImplTest : public cr_fuchsia::WebEngineBrowserTest {
@@ -50,19 +38,39 @@ class ContextImplTest : public cr_fuchsia::WebEngineBrowserTest {
return WebEngineBrowserTest::CreateFrame(&navigation_listener_);
}
- // Synchronously gets a list of cookies for this BrowserContext.
- net::CookieList GetCookies() {
- base::RunLoop run_loop;
- net::CookieList cookies;
- network::mojom::CookieManagerPtr cookie_manager;
- content::BrowserContext::GetDefaultStoragePartition(
- context_impl()->browser_context_for_test())
- ->GetNetworkContext()
- ->GetCookieManager(mojo::MakeRequest(&cookie_manager));
- cookie_manager->GetAllCookies(base::BindOnce(&OnCookiesReceived,
- base::Unretained(&cookies),
- run_loop.QuitClosure()));
- run_loop.Run();
+ // Synchronously gets the list of all cookies from the fuchsia.web.Context.
+ std::vector<fuchsia::web::Cookie> GetCookies() {
+ base::RunLoop get_cookies_loop;
+
+ // Connect to the Context's CookieManager and request all the cookies.
+ fuchsia::web::CookieManagerPtr cookie_manager;
+ context()->GetCookieManager(cookie_manager.NewRequest());
+ fuchsia::web::CookiesIteratorPtr cookies_iterator;
+ cookie_manager->GetCookieList(nullptr, nullptr,
+ cookies_iterator.NewRequest());
+
+ // |cookies_iterator| will disconnect once after the last cookies have been
+ // returned by GetNext().
+ cookies_iterator.set_error_handler([&](zx_status_t status) {
+ EXPECT_EQ(ZX_ERR_PEER_CLOSED, status);
+ get_cookies_loop.Quit();
+ });
+ std::vector<fuchsia::web::Cookie> cookies;
+
+ // std::function<> must be used here because fit::function<> is move-only
+ // and this callback will be used both for the initial GetNext() call, and
+ // for the follow-up calls made each time GetNext() results are received.
+ std::function<void(std::vector<fuchsia::web::Cookie>)> get_next_callback =
+ [&](std::vector<fuchsia::web::Cookie> new_cookies) {
+ cookies.insert(cookies.end(),
+ std::make_move_iterator(new_cookies.begin()),
+ std::make_move_iterator(new_cookies.end()));
+ cookies_iterator->GetNext(get_next_callback);
+ };
+ cookies_iterator->GetNext(get_next_callback);
+
+ get_cookies_loop.Run();
+
return cookies;
}
@@ -74,44 +82,41 @@ class ContextImplTest : public cr_fuchsia::WebEngineBrowserTest {
} // namespace
-// Verifies that the BrowserContext has a working cookie store by setting
-// cookies in the content layer and then querying the CookieStore afterward.
-IN_PROC_BROWSER_TEST_F(ContextImplTest, VerifyPersistentCookieStore) {
+// BrowserContext with persistent storage stores cookies such that they can
+// be retrieved via the CookieManager API.
+IN_PROC_BROWSER_TEST_F(ContextImplTest, PersistentCookieStore) {
ASSERT_TRUE(embedded_test_server()->Start());
- GURL cookie_url(embedded_test_server()->GetURL("/set-cookie?foo=bar"));
fuchsia::web::FramePtr frame = CreateFrame();
- fuchsia::web::NavigationControllerPtr navigation_controller;
- frame->GetNavigationController(navigation_controller.NewRequest());
-
- cr_fuchsia::LoadUrlAndExpectResponse(navigation_controller.get(),
- fuchsia::web::LoadUrlParams(),
- cookie_url.spec());
- navigation_listener_.RunUntilUrlEquals(cookie_url);
-
- auto cookies = GetCookies();
- bool found = false;
- for (auto c : cookies) {
- if (c.Name() == "foo" && c.Value() == "bar") {
- found = true;
- break;
- }
- }
- EXPECT_TRUE(found);
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ const GURL kSetCookieUrl(
+ embedded_test_server()->GetURL("/set-cookie?foo=bar"));
+ cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kSetCookieUrl.spec());
+ navigation_listener_.RunUntilUrlEquals(kSetCookieUrl);
+
+ std::vector<fuchsia::web::Cookie> cookies = GetCookies();
+ ASSERT_EQ(cookies.size(), 1u);
+ ASSERT_TRUE(cookies[0].has_id());
+ ASSERT_TRUE(cookies[0].id().has_name());
+ ASSERT_TRUE(cookies[0].has_value());
+ EXPECT_EQ(cookies[0].id().name(), "foo");
+ EXPECT_EQ(cookies[0].value(), "bar");
// Check that the cookie persists beyond the lifetime of the Frame by
// releasing the Frame and re-querying the CookieStore.
frame.Unbind();
base::RunLoop().RunUntilIdle();
- found = false;
- for (auto c : cookies) {
- if (c.Name() == "foo" && c.Value() == "bar") {
- found = true;
- break;
- }
- }
- EXPECT_TRUE(found);
+ cookies = GetCookies();
+ ASSERT_EQ(cookies.size(), 1u);
+ ASSERT_TRUE(cookies[0].has_id());
+ ASSERT_TRUE(cookies[0].id().has_name());
+ ASSERT_TRUE(cookies[0].has_value());
+ EXPECT_EQ(cookies[0].id().name(), "foo");
+ EXPECT_EQ(cookies[0].value(), "bar");
}
// Suite for tests which run the BrowserContext in incognito mode (no data
@@ -145,25 +150,25 @@ IN_PROC_BROWSER_TEST_F(IncognitoContextImplTest, NavigateFrame) {
frame.Unbind();
}
-IN_PROC_BROWSER_TEST_F(IncognitoContextImplTest, VerifyInMemoryCookieStore) {
+// In-memory cookie store stores cookies, and is accessible via CookieManager.
+IN_PROC_BROWSER_TEST_F(IncognitoContextImplTest, InMemoryCookieStore) {
ASSERT_TRUE(embedded_test_server()->Start());
- GURL cookie_url(embedded_test_server()->GetURL("/set-cookie?foo=bar"));
fuchsia::web::FramePtr frame = CreateFrame();
fuchsia::web::NavigationControllerPtr controller;
frame->GetNavigationController(controller.NewRequest());
- EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
- controller.get(), fuchsia::web::LoadUrlParams(), cookie_url.spec()));
- navigation_listener_.RunUntilUrlEquals(cookie_url);
-
- auto cookies = GetCookies();
- bool found = false;
- for (auto c : cookies) {
- if (c.Name() == "foo" && c.Value() == "bar") {
- found = true;
- break;
- }
- }
- EXPECT_TRUE(found);
+ const GURL kSetCookieUrl(
+ embedded_test_server()->GetURL("/set-cookie?foo=bar"));
+ cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kSetCookieUrl.spec());
+ navigation_listener_.RunUntilUrlEquals(kSetCookieUrl);
+
+ std::vector<fuchsia::web::Cookie> cookies = GetCookies();
+ ASSERT_EQ(cookies.size(), 1u);
+ ASSERT_TRUE(cookies[0].has_id());
+ ASSERT_TRUE(cookies[0].id().has_name());
+ ASSERT_TRUE(cookies[0].has_value());
+ EXPECT_EQ(cookies[0].id().name(), "foo");
+ EXPECT_EQ(cookies[0].value(), "bar");
}
diff --git a/chromium/fuchsia/engine/browser/cookie_manager_impl.cc b/chromium/fuchsia/engine/browser/cookie_manager_impl.cc
new file mode 100644
index 00000000000..ad875621fc5
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/cookie_manager_impl.cc
@@ -0,0 +1,237 @@
+// Copyright 2019 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 "fuchsia/engine/browser/cookie_manager_impl.h"
+
+#include <lib/fidl/cpp/binding.h>
+
+#include "base/fuchsia/fuchsia_logging.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "net/cookies/canonical_cookie.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+#include "url/gurl.h"
+
+namespace {
+
+fuchsia::web::Cookie ConvertCanonicalCookie(
+ const net::CanonicalCookie& canonical_cookie,
+ network::mojom::CookieChangeCause cause) {
+ fuchsia::web::CookieId id;
+ id.set_name(canonical_cookie.Name());
+ id.set_domain(canonical_cookie.Domain());
+ id.set_path(canonical_cookie.Path());
+
+ fuchsia::web::Cookie cookie;
+ cookie.set_id(std::move(id));
+ switch (cause) {
+ case network::mojom::CookieChangeCause::INSERTED:
+ cookie.set_value(canonical_cookie.Value());
+ break;
+ case network::mojom::CookieChangeCause::EXPLICIT:
+ case network::mojom::CookieChangeCause::UNKNOWN_DELETION:
+ case network::mojom::CookieChangeCause::OVERWRITE:
+ case network::mojom::CookieChangeCause::EXPIRED:
+ case network::mojom::CookieChangeCause::EVICTED:
+ case network::mojom::CookieChangeCause::EXPIRED_OVERWRITE:
+ break;
+ };
+
+ return cookie;
+}
+
+class CookiesIteratorImpl : public fuchsia::web::CookiesIterator,
+ public network::mojom::CookieChangeListener {
+ public:
+ // |this| will delete itself when |mojo_request| or |changes| disconnect.
+ CookiesIteratorImpl(
+ mojo::PendingReceiver<network::mojom::CookieChangeListener> mojo_receiver,
+ fidl::InterfaceRequest<fuchsia::web::CookiesIterator> changes)
+ : CookiesIteratorImpl(std::move(changes)) {
+ mojo_receiver_.Bind(std::move(mojo_receiver));
+ mojo_receiver_.set_disconnect_handler(base::BindOnce(
+ &CookiesIteratorImpl::OnMojoError, base::Unretained(this)));
+ }
+ // |this| will delete itself when |iterator| disconnects, or if a GetNext()
+ // leaves |queued_cookies_| empty.
+ CookiesIteratorImpl(
+ const std::vector<net::CanonicalCookie>& cookies,
+ fidl::InterfaceRequest<fuchsia::web::CookiesIterator> iterator)
+ : CookiesIteratorImpl(std::move(iterator)) {
+ for (const auto& cookie : cookies) {
+ queued_cookies_[cookie.UniqueKey()] = ConvertCanonicalCookie(
+ cookie, network::mojom::CookieChangeCause::INSERTED);
+ }
+ }
+ // Same as above except it takes CookieStatusList instead of just CookieList.
+ CookiesIteratorImpl(
+ const std::vector<net::CookieWithStatus>& cookies_with_statuses,
+ fidl::InterfaceRequest<fuchsia::web::CookiesIterator> iterator)
+ : CookiesIteratorImpl(std::move(iterator)) {
+ for (const auto& cookie_with_status : cookies_with_statuses) {
+ queued_cookies_[cookie_with_status.cookie.UniqueKey()] =
+ ConvertCanonicalCookie(cookie_with_status.cookie,
+ network::mojom::CookieChangeCause::INSERTED);
+ }
+ }
+ ~CookiesIteratorImpl() final = default;
+
+ // fuchsia::web::CookiesIterator implementation:
+ void GetNext(GetNextCallback callback) final {
+ DCHECK(!get_next_callback_);
+ get_next_callback_ = std::move(callback);
+ MaybeSendQueuedCookies();
+ }
+
+ private:
+ explicit CookiesIteratorImpl(
+ fidl::InterfaceRequest<fuchsia::web::CookiesIterator> iterator)
+ : mojo_receiver_(this), fidl_binding_(this) {
+ fidl_binding_.Bind(std::move(iterator));
+ fidl_binding_.set_error_handler([this](zx_status_t status) {
+ ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status)
+ << "CookieChangeListener disconnected.";
+ delete this;
+ });
+ }
+
+ void OnMojoError() {
+ LOG(ERROR) << "NetworkService disconnected CookiesIterator.";
+ fidl_binding_.Close(ZX_ERR_UNAVAILABLE);
+ delete this;
+ }
+
+ void MaybeSendQueuedCookies() {
+ // Assuming cookies values never exceed 4KB in size, plus some overhead for
+ // the name, domain and path, and that Zircon messages can be up to 64KB.
+ constexpr int kMaxCookiesPerMessage = 8;
+
+ if (!get_next_callback_)
+ return;
+ if (mojo_receiver_.is_bound() && queued_cookies_.empty())
+ return;
+
+ // Build a vector of Cookies to return to the caller.
+ fuchsia::web::CookiesIterator::GetNextCallback callback(
+ std::move(get_next_callback_));
+ std::vector<fuchsia::web::Cookie> cookies;
+ while (!queued_cookies_.empty() && cookies.size() < kMaxCookiesPerMessage) {
+ auto cookie = queued_cookies_.begin();
+ cookies.emplace_back(std::move(cookie->second));
+ queued_cookies_.erase(cookie);
+ }
+ callback(std::move(cookies));
+
+ // If this is a one-off CookieIterator then tear down once |queued_cookies_|
+ // is empty.
+ if (queued_cookies_.empty() && !mojo_receiver_.is_bound())
+ delete this;
+ }
+
+ // network::mojom::CookieChangeListener implementation:
+ void OnCookieChange(const net::CanonicalCookie& cookie,
+ network::mojom::CookieChangeCause cause) final {
+ queued_cookies_[cookie.UniqueKey()] = ConvertCanonicalCookie(cookie, cause);
+ MaybeSendQueuedCookies();
+ }
+
+ mojo::Receiver<network::mojom::CookieChangeListener> mojo_receiver_;
+ fidl::Binding<fuchsia::web::CookiesIterator> fidl_binding_;
+
+ GetNextCallback get_next_callback_;
+
+ // Map from "unique key"s (see net::CanonicalCookie::UniqueKey()) to the
+ // corresponding fuchsia::web::Cookie.
+ std::map<std::tuple<std::string, std::string, std::string>,
+ fuchsia::web::Cookie>
+ queued_cookies_;
+
+ DISALLOW_COPY_AND_ASSIGN(CookiesIteratorImpl);
+};
+
+void OnAllCookiesReceived(
+ fidl::InterfaceRequest<fuchsia::web::CookiesIterator> iterator,
+ const std::vector<net::CanonicalCookie>& cookies) {
+ new CookiesIteratorImpl(cookies, std::move(iterator));
+}
+
+void OnCookiesAndExcludedReceived(
+ fidl::InterfaceRequest<fuchsia::web::CookiesIterator> iterator,
+ const std::vector<net::CookieWithStatus>& cookies_with_statuses,
+ const std::vector<net::CookieWithStatus>& excluded_cookies) {
+ // Since CookieOptions::set_return_excluded_cookies() is not used when calling
+ // the Mojo GetCookieList() API, |excluded_cookies| should be empty.
+ DCHECK(excluded_cookies.empty());
+ new CookiesIteratorImpl(cookies_with_statuses, std::move(iterator));
+}
+
+} // namespace
+
+CookieManagerImpl::CookieManagerImpl(
+ GetNetworkContextCallback get_network_context)
+ : get_network_context_(std::move(get_network_context)) {}
+
+CookieManagerImpl::~CookieManagerImpl() = default;
+
+void CookieManagerImpl::ObserveCookieChanges(
+ fidl::StringPtr url,
+ fidl::StringPtr name,
+ fidl::InterfaceRequest<fuchsia::web::CookiesIterator> changes) {
+ EnsureCookieManager();
+
+ mojo::PendingRemote<network::mojom::CookieChangeListener> mojo_listener;
+ new CookiesIteratorImpl(mojo_listener.InitWithNewPipeAndPassReceiver(),
+ std::move(changes));
+
+ if (url) {
+ base::Optional<std::string> maybe_name;
+ if (name)
+ maybe_name = *name;
+ cookie_manager_->AddCookieChangeListener(GURL(*url), maybe_name,
+ std::move(mojo_listener));
+ } else {
+ cookie_manager_->AddGlobalChangeListener(std::move(mojo_listener));
+ }
+}
+
+void CookieManagerImpl::GetCookieList(
+ fidl::StringPtr url,
+ fidl::StringPtr name,
+ fidl::InterfaceRequest<fuchsia::web::CookiesIterator> iterator) {
+ EnsureCookieManager();
+
+ if (!url && !name) {
+ cookie_manager_->GetAllCookies(
+ base::BindOnce(&OnAllCookiesReceived, std::move(iterator)));
+ } else {
+ if (!name) {
+ // Include HTTP and 1st-party-only cookies in those returned.
+ net::CookieOptions options;
+ options.set_include_httponly();
+ options.set_same_site_cookie_context(
+ net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
+
+ cookie_manager_->GetCookieList(
+ GURL(*url), options,
+ base::BindOnce(&OnCookiesAndExcludedReceived, std::move(iterator)));
+ } else {
+ // TODO(858853): Support filtering by name.
+ iterator.Close(ZX_ERR_NOT_SUPPORTED);
+ }
+ }
+}
+
+void CookieManagerImpl::EnsureCookieManager() {
+ if (cookie_manager_.is_bound())
+ return;
+ get_network_context_.Run()->GetCookieManager(
+ cookie_manager_.BindNewPipeAndPassReceiver());
+ cookie_manager_.set_disconnect_handler(base::BindOnce(
+ &CookieManagerImpl::OnMojoDisconnect, base::Unretained(this)));
+}
+
+void CookieManagerImpl::OnMojoDisconnect() {
+ LOG(ERROR) << "NetworkService disconnected CookieManager.";
+ cookie_manager_.reset();
+}
diff --git a/chromium/fuchsia/engine/browser/cookie_manager_impl.h b/chromium/fuchsia/engine/browser/cookie_manager_impl.h
new file mode 100644
index 00000000000..dac1098fb9b
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/cookie_manager_impl.h
@@ -0,0 +1,58 @@
+// Copyright 2019 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 FUCHSIA_ENGINE_BROWSER_COOKIE_MANAGER_IMPL_H_
+#define FUCHSIA_ENGINE_BROWSER_COOKIE_MANAGER_IMPL_H_
+
+#include <fuchsia/web/cpp/fidl.h>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "fuchsia/engine/web_engine_export.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/network/public/mojom/cookie_manager.mojom.h"
+
+namespace network {
+namespace mojom {
+class NetworkContext;
+} // namespace mojom
+} // namespace network
+
+class WEB_ENGINE_EXPORT CookieManagerImpl : public fuchsia::web::CookieManager {
+ public:
+ // Used to request the BrowserContext's CookieManager. Since the
+ // NetworkContext may change, e.g. if the NetworkService crashes, the returned
+ // pointer will be used immediately, and not cached by the CookieManagerImpl.
+ using GetNetworkContextCallback =
+ base::RepeatingCallback<network::mojom::NetworkContext*()>;
+
+ // |get_network_context| will be called to (re)connect to CookieManager,
+ // on-demand, in response to query/observation requests.
+ explicit CookieManagerImpl(GetNetworkContextCallback get_network_context);
+ ~CookieManagerImpl() final;
+
+ // fuchsia::web::CookieManager implementation:
+ void ObserveCookieChanges(
+ fidl::StringPtr url,
+ fidl::StringPtr name,
+ fidl::InterfaceRequest<fuchsia::web::CookiesIterator> changes) final;
+ void GetCookieList(
+ fidl::StringPtr url,
+ fidl::StringPtr name,
+ fidl::InterfaceRequest<fuchsia::web::CookiesIterator> cookies) final;
+
+ private:
+ // (Re)connects |cookie_manager_| if not currently connected.
+ void EnsureCookieManager();
+
+ // Handles errors on the |cookie_manager_| Mojo channel.
+ void OnMojoDisconnect();
+
+ const GetNetworkContextCallback get_network_context_;
+ mojo::Remote<network::mojom::CookieManager> cookie_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(CookieManagerImpl);
+};
+
+#endif // FUCHSIA_ENGINE_BROWSER_COOKIE_MANAGER_IMPL_H_
diff --git a/chromium/fuchsia/engine/browser/cookie_manager_impl_unittest.cc b/chromium/fuchsia/engine/browser/cookie_manager_impl_unittest.cc
new file mode 100644
index 00000000000..1794c0f3a12
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/cookie_manager_impl_unittest.cc
@@ -0,0 +1,377 @@
+// Copyright 2019 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 <lib/fidl/cpp/binding.h>
+
+#include <map>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/macros.h"
+#include "base/optional.h"
+#include "base/run_loop.h"
+#include "base/test/bind_test_util.h"
+#include "base/test/task_environment.h"
+#include "fuchsia/base/fit_adapter.h"
+#include "fuchsia/base/result_receiver.h"
+#include "fuchsia/engine/browser/cookie_manager_impl.h"
+#include "services/network/network_service.h"
+#include "services/network/public/mojom/cookie_manager.mojom.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char kTestCookieUrl[] = "https://www.testing.com/";
+const char kTestOtherUrl[] = "https://www.other.com/";
+const char kCookieName1[] = "Cookie";
+const char kCookieName2[] = "Monster";
+const char kCookieValue1[] = "Eats";
+const char kCookieValue2[] = "Cookies";
+const char kCookieValue3[] = "Nyom nyom nyom";
+
+// Creates a CanonicalCookie with |name| and |value|, for kTestCookieUrlHost.
+std::unique_ptr<net::CanonicalCookie> CreateCookie(base::StringPiece name,
+ base::StringPiece value) {
+ return net::CanonicalCookie::CreateSanitizedCookie(
+ GURL(kTestCookieUrl), name.as_string(), value.as_string(), /*domain=*/"",
+ /*path=*/"", /*creation_time=*/base::Time(),
+ /*expiration_time=*/base::Time(), /*last_access_time=*/base::Time(),
+ /*secure=*/false,
+ /*httponly*/ false, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_MEDIUM);
+}
+
+class CookieManagerImplTest : public testing::Test {
+ public:
+ CookieManagerImplTest()
+ : task_environment_(
+ base::test::TaskEnvironment::MainThreadType::IO),
+ network_service_(network::NetworkService::CreateForTesting()),
+ cookie_manager_(
+ base::BindRepeating(&CookieManagerImplTest::GetNetworkContext,
+ base::Unretained(this))) {}
+ ~CookieManagerImplTest() override = default;
+
+ protected:
+ network::mojom::NetworkContext* GetNetworkContext() {
+ if (!network_context_.is_bound()) {
+ network_service_->CreateNetworkContext(
+ mojo::MakeRequest(&network_context_),
+ network::mojom::NetworkContextParams::New());
+ network_context_.set_connection_error_handler(
+ base::BindLambdaForTesting([&]() { network_context_.reset(); }));
+ }
+ return network_context_.get();
+ }
+
+ // Adds the specified cookie under kTestCookieUrlHost.
+ void CreateAndSetCookieAsync(base::StringPiece name,
+ base::StringPiece value) {
+ EnsureMojoCookieManager();
+
+ net::CookieOptions options;
+ mojo_cookie_manager_->SetCanonicalCookie(
+ *CreateCookie(name, value), "https", options,
+ base::Bind([](net::CanonicalCookie::CookieInclusionStatus status) {
+ EXPECT_TRUE(status.IsInclude());
+ }));
+ }
+
+ // Removes the specified cookie from under kTestCookieUrlHost.
+ void DeleteCookieAsync(base::StringPiece name, base::StringPiece value) {
+ EnsureMojoCookieManager();
+
+ mojo_cookie_manager_->DeleteCanonicalCookie(
+ *CreateCookie(name, value),
+ base::Bind([](bool success) { EXPECT_TRUE(success); }));
+ }
+
+ // Synchronously fetches all cookies via the |cookie_manager_|.
+ // Returns a base::nullopt if the iterator closes before a GetNext() returns.
+ base::Optional<std::vector<fuchsia::web::Cookie>> GetAllCookies() {
+ base::RunLoop get_cookies_loop;
+ fuchsia::web::CookiesIteratorPtr cookies_iterator;
+ cookies_iterator.set_error_handler([&](zx_status_t status) {
+ EXPECT_EQ(ZX_ERR_PEER_CLOSED, status);
+ get_cookies_loop.Quit();
+ });
+ cookie_manager_.GetCookieList(nullptr, nullptr,
+ cookies_iterator.NewRequest());
+ base::Optional<std::vector<fuchsia::web::Cookie>> cookies;
+ std::function<void(std::vector<fuchsia::web::Cookie>)> get_next_callback =
+ [&](std::vector<fuchsia::web::Cookie> new_cookies) {
+ if (!cookies.has_value()) {
+ cookies.emplace(std::move(new_cookies));
+ } else {
+ cookies->insert(cookies->end(),
+ std::make_move_iterator(new_cookies.begin()),
+ std::make_move_iterator(new_cookies.end()));
+ }
+ cookies_iterator->GetNext(get_next_callback);
+ };
+ cookies_iterator->GetNext(get_next_callback);
+ get_cookies_loop.Run();
+ return cookies;
+ }
+
+ void EnsureMojoCookieManager() {
+ if (mojo_cookie_manager_.is_bound())
+ return;
+ network_context_->GetCookieManager(
+ mojo_cookie_manager_.BindNewPipeAndPassReceiver());
+ }
+
+ base::test::TaskEnvironment task_environment_;
+
+ std::unique_ptr<network::NetworkService> network_service_;
+ network::mojom::NetworkContextPtr network_context_;
+ mojo::Remote<network::mojom::CookieManager> mojo_cookie_manager_;
+
+ CookieManagerImpl cookie_manager_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CookieManagerImplTest);
+};
+
+// Calls GetNext() on the supplied |iterator| and lets the caller express
+// expectations on the results.
+class GetNextCookiesIteratorResult {
+ public:
+ explicit GetNextCookiesIteratorResult(fuchsia::web::CookiesIterator* iterator)
+ : result_(loop_.QuitClosure()) {
+ iterator->GetNext(
+ cr_fuchsia::CallbackToFitFunction(result_.GetReceiveCallback()));
+ }
+
+ ~GetNextCookiesIteratorResult() = default;
+
+ void ExpectSingleCookie(base::StringPiece name,
+ base::Optional<base::StringPiece> value) {
+ ExpectCookieUpdates({{name, value}});
+ }
+
+ void ExpectDeleteSingleCookie(base::StringPiece name) {
+ ExpectCookieUpdates({{name, base::nullopt}});
+ }
+
+ // Specifies the cookie name/value pairs expected in the GetNext() results.
+ // Deletions expectations are specified by using base::nullopt as the value.
+ void ExpectCookieUpdates(
+ std::map<base::StringPiece, base::Optional<base::StringPiece>> expected) {
+ loop_.Run();
+ ASSERT_TRUE(result_.has_value());
+ ASSERT_EQ(result_->size(), expected.size());
+ std::map<base::StringPiece, base::StringPiece> result_updates;
+ for (auto& cookie_update : *result_) {
+ ASSERT_TRUE(cookie_update.has_id());
+ ASSERT_TRUE(cookie_update.id().has_name());
+ auto it = expected.find(cookie_update.id().name());
+ ASSERT_TRUE(it != expected.end());
+ ASSERT_EQ(cookie_update.has_value(), it->second.has_value());
+ if (it->second.has_value())
+ EXPECT_EQ(*it->second, cookie_update.value());
+ expected.erase(it);
+ }
+ EXPECT_TRUE(expected.empty());
+ }
+
+ void ExpectReceivedNoUpdates() {
+ // If we ran |loop_| then this would hang, so just ensure any pending work
+ // has been processed.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(result_.has_value());
+ }
+
+ protected:
+ base::RunLoop loop_;
+ cr_fuchsia::ResultReceiver<std::vector<fuchsia::web::Cookie>> result_;
+
+ DISALLOW_COPY_AND_ASSIGN(GetNextCookiesIteratorResult);
+};
+
+} // namespace
+
+TEST_F(CookieManagerImplTest, GetAndObserveAddModifyDelete) {
+ // Add global, URL-filtered and URL+name-filtered observers.
+ fuchsia::web::CookiesIteratorPtr global_changes;
+ global_changes.set_error_handler([](zx_status_t) { ADD_FAILURE(); });
+ cookie_manager_.ObserveCookieChanges(nullptr, nullptr,
+ global_changes.NewRequest());
+
+ fuchsia::web::CookiesIteratorPtr url_changes;
+ url_changes.set_error_handler([](zx_status_t) { ADD_FAILURE(); });
+ cookie_manager_.ObserveCookieChanges(kTestCookieUrl, nullptr,
+ url_changes.NewRequest());
+
+ fuchsia::web::CookiesIteratorPtr name_changes;
+ name_changes.set_error_handler([](zx_status_t) { ADD_FAILURE(); });
+ cookie_manager_.ObserveCookieChanges(kTestCookieUrl, kCookieName1,
+ name_changes.NewRequest());
+
+ // Register interest in updates for another URL, so we can verify none are
+ // received.
+ fuchsia::web::CookiesIteratorPtr other_changes;
+ name_changes.set_error_handler([](zx_status_t) { ADD_FAILURE(); });
+ cookie_manager_.ObserveCookieChanges(kTestOtherUrl, nullptr,
+ other_changes.NewRequest());
+ GetNextCookiesIteratorResult other_updates(other_changes.get());
+
+ // Ensure that all ObserveCookieChanges() were processed before modifying
+ // cookies.
+ EXPECT_EQ(GetAllCookies()->size(), 0u);
+
+ // Set cookie kCookieName1, which should trigger notifications to all
+ // observers.
+ {
+ GetNextCookiesIteratorResult global_update(global_changes.get());
+ GetNextCookiesIteratorResult url_update(url_changes.get());
+ GetNextCookiesIteratorResult name_update(name_changes.get());
+
+ CreateAndSetCookieAsync(kCookieName1, kCookieValue1);
+
+ global_update.ExpectSingleCookie(kCookieName1, kCookieValue1);
+ url_update.ExpectSingleCookie(kCookieName1, kCookieValue1);
+ name_update.ExpectSingleCookie(kCookieName1, kCookieValue1);
+ }
+
+ // Expect an add notification for kCookieName2, except on the with-name
+ // observer. If the with-name observer does get notified then the remove &
+ // re-add check below will observe kCookieName2 rather than kCookieName1, and
+ // fail.
+ {
+ GetNextCookiesIteratorResult global_update(global_changes.get());
+ GetNextCookiesIteratorResult url_update(url_changes.get());
+
+ CreateAndSetCookieAsync(kCookieName2, kCookieValue2);
+
+ global_update.ExpectSingleCookie(kCookieName2, kCookieValue2);
+ url_update.ExpectSingleCookie(kCookieName2, kCookieValue2);
+ }
+
+ // Set kCookieName1 to a new value, which will trigger deletion notifications,
+ // followed by an addition with the new value.
+ {
+ GetNextCookiesIteratorResult global_update(global_changes.get());
+ GetNextCookiesIteratorResult url_update(url_changes.get());
+ GetNextCookiesIteratorResult name_update(name_changes.get());
+
+ // Updating the cookie will generate a deletion, following by an insertion.
+ // CookiesIterator will batch updates into a single response, so we may get
+ // two separate updates, or a single update, depending on timing. Eliminate
+ // the non-determinism by ensuring that the GetNext() calls have been
+ // received before updating the cookie.
+ base::RunLoop().RunUntilIdle();
+
+ CreateAndSetCookieAsync(kCookieName1, kCookieValue3);
+
+ global_update.ExpectDeleteSingleCookie(kCookieName1);
+ url_update.ExpectDeleteSingleCookie(kCookieName1);
+ name_update.ExpectDeleteSingleCookie(kCookieName1);
+ }
+ {
+ GetNextCookiesIteratorResult global_update(global_changes.get());
+ GetNextCookiesIteratorResult url_update(url_changes.get());
+ GetNextCookiesIteratorResult name_update(name_changes.get());
+
+ global_update.ExpectSingleCookie(kCookieName1, kCookieValue3);
+ url_update.ExpectSingleCookie(kCookieName1, kCookieValue3);
+ name_update.ExpectSingleCookie(kCookieName1, kCookieValue3);
+ }
+
+ // Set kCookieName2 empty, which will notify only the global and URL
+ // observers. If the name observer is mis-notified then the next step, below,
+ // will fail.
+ {
+ GetNextCookiesIteratorResult global_update(global_changes.get());
+ GetNextCookiesIteratorResult url_update(url_changes.get());
+
+ DeleteCookieAsync(kCookieName2, kCookieValue2);
+
+ global_update.ExpectDeleteSingleCookie(kCookieName2);
+ url_update.ExpectDeleteSingleCookie(kCookieName2);
+ }
+
+ // Set kCookieName1 empty, which will notify all the observers that it was
+ // removed.
+ {
+ GetNextCookiesIteratorResult global_update(global_changes.get());
+ GetNextCookiesIteratorResult url_update(url_changes.get());
+ GetNextCookiesIteratorResult name_update(name_changes.get());
+
+ DeleteCookieAsync(kCookieName1, kCookieValue3);
+
+ global_update.ExpectDeleteSingleCookie(kCookieName1);
+ url_update.ExpectDeleteSingleCookie(kCookieName1);
+ name_update.ExpectDeleteSingleCookie(kCookieName1);
+ }
+
+ // Verify that no updates were received for the "other" URL (since we did not
+ // set any cookies for it). It is possible that this could pass due to the
+ // CookiesIterator not having been scheduled, but that is very unlikely.
+ other_updates.ExpectReceivedNoUpdates();
+}
+
+TEST_F(CookieManagerImplTest, UpdateBatching) {
+ fuchsia::web::CookiesIteratorPtr global_changes;
+ global_changes.set_error_handler([](zx_status_t) { ADD_FAILURE(); });
+ cookie_manager_.ObserveCookieChanges(nullptr, nullptr,
+ global_changes.NewRequest());
+
+ // Ensure that all ObserveCookieChanges() were processed before modifying
+ // cookies.
+ EXPECT_EQ(GetAllCookies()->size(), 0u);
+
+ {
+ // Verify that some insertions are batched into a single GetNext() result.
+ CreateAndSetCookieAsync(kCookieName1, kCookieValue1);
+ CreateAndSetCookieAsync(kCookieName2, kCookieValue2);
+ CreateAndSetCookieAsync(kCookieName1, kCookieValue3);
+ mojo_cookie_manager_.FlushForTesting();
+
+ GetNextCookiesIteratorResult global_updates(global_changes.get());
+ global_updates.ExpectCookieUpdates(
+ {{kCookieName1, kCookieValue3}, {kCookieName2, kCookieValue2}});
+ }
+
+ {
+ // Verify that some deletions are batched into a single GetNext() result.
+ DeleteCookieAsync(kCookieName2, kCookieValue2);
+ DeleteCookieAsync(kCookieName1, kCookieValue3);
+ mojo_cookie_manager_.FlushForTesting();
+
+ GetNextCookiesIteratorResult global_updates(global_changes.get());
+ global_updates.ExpectCookieUpdates(
+ {{kCookieName1, base::nullopt}, {kCookieName2, base::nullopt}});
+ }
+}
+
+TEST_F(CookieManagerImplTest, ReconnectToNetworkContext) {
+ // Attach a cookie observer, which we expect should become disconnected with
+ // an appropriate error if the NetworkService goes away.
+ base::RunLoop global_changes_disconnect_loop;
+ fuchsia::web::CookiesIteratorPtr global_changes;
+ global_changes.set_error_handler([&](zx_status_t status) {
+ EXPECT_EQ(ZX_ERR_UNAVAILABLE, status);
+ global_changes_disconnect_loop.Quit();
+ });
+ cookie_manager_.ObserveCookieChanges(nullptr, nullptr,
+ global_changes.NewRequest());
+
+ // Verify that GetAllCookies() returns a valid list of cookies (as opposed to
+ // not returning a list at all) initially.
+ EXPECT_TRUE(GetAllCookies().has_value());
+
+ // Tear-down and re-create the NetworkService, causing the CookieManager's
+ // connection to it to be dropped.
+ network_service_.reset();
+ network_service_ = network::NetworkService::CreateForTesting();
+
+ // Expect that |global_changes| is disconnected at this point.
+ global_changes_disconnect_loop.Run();
+
+ // If the CookieManager fails to re-connect then GetAllCookies() will receive
+ // no data (as opposed to receiving an empty list of cookies).
+ EXPECT_TRUE(GetAllCookies().has_value());
+}
diff --git a/chromium/fuchsia/engine/browser/frame_impl.cc b/chromium/fuchsia/engine/browser/frame_impl.cc
index 0793e4dcf77..7a871690cb9 100644
--- a/chromium/fuchsia/engine/browser/frame_impl.cc
+++ b/chromium/fuchsia/engine/browser/frame_impl.cc
@@ -4,6 +4,7 @@
#include "fuchsia/engine/browser/frame_impl.h"
+#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include <limits>
#include "base/bind_helpers.h"
@@ -11,14 +12,16 @@
#include "base/json/json_writer.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/message_port_provider.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/renderer_preferences_util.h"
#include "content/public/browser/web_contents.h"
-#include "content/public/common/was_activated_option.h"
+#include "content/public/common/was_activated_option.mojom.h"
#include "fuchsia/base/mem_buffer_util.h"
#include "fuchsia/base/message_port.h"
#include "fuchsia/engine/browser/context_impl.h"
@@ -40,6 +43,13 @@ namespace {
const logging::LogSeverity kLogSeverityNone =
std::numeric_limits<logging::LogSeverity>::min();
+// Used for attaching popup-related metadata to a WebContents.
+constexpr char kPopupCreationInfo[] = "popup-creation-info";
+class PopupFrameCreationInfoUserData : public base::SupportsUserData::Data {
+ public:
+ fuchsia::web::PopupFrameCreationInfo info;
+};
+
// Layout manager that allows only one child window and stretches it to fill the
// parent.
class LayoutManagerImpl : public aura::LayoutManager {
@@ -266,8 +276,8 @@ void FrameImpl::ExecuteJavaScriptInternal(std::vector<std::string> origins,
}
fuchsia::web::Frame_ExecuteJavaScript_Response response;
- response.result =
- cr_fuchsia::MemBufferFromString(std::move(result_json));
+ response.result = cr_fuchsia::MemBufferFromString(
+ std::move(result_json), "cr-execute-js-response");
result.set_response(std::move(response));
callback(std::move(result));
},
@@ -285,12 +295,130 @@ void FrameImpl::ExecuteJavaScriptInternal(std::vector<std::string> origins,
}
}
+bool FrameImpl::ShouldCreateWebContents(
+ content::WebContents* web_contents,
+ content::RenderFrameHost* opener,
+ content::SiteInstance* source_site_instance,
+ int32_t route_id,
+ int32_t main_frame_route_id,
+ int32_t main_frame_widget_route_id,
+ content::mojom::WindowContainerType window_container_type,
+ const GURL& opener_url,
+ const std::string& frame_name,
+ const GURL& target_url,
+ const std::string& partition_id,
+ content::SessionStorageNamespace* session_storage_namespace) {
+ // Specify a generous upper bound for unacknowledged popup windows, so that we
+ // can catch bad client behavior while not interfering with normal operation.
+ constexpr size_t kMaxPendingWebContentsCount = 10;
+
+ DCHECK_EQ(web_contents, web_contents_.get());
+
+ if (!popup_listener_)
+ return false;
+
+ if (pending_popups_.size() >= kMaxPendingWebContentsCount) {
+ // The content is producing popups faster than the embedder can process
+ // them. Drop the popups so as to prevent resource exhaustion.
+ LOG(WARNING) << "Too many pending popups, ignoring request.";
+
+ // Don't produce a WebContents for this popup.
+ return false;
+ }
+
+ return true;
+}
+
+void FrameImpl::AddNewContents(
+ content::WebContents* source,
+ std::unique_ptr<content::WebContents> new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_rect,
+ bool user_gesture,
+ bool* was_blocked) {
+ DCHECK_EQ(source, web_contents_.get());
+
+ // TODO(crbug.com/995395): Add window disposition to the FIDL interface.
+ switch (disposition) {
+ case WindowOpenDisposition::NEW_FOREGROUND_TAB:
+ case WindowOpenDisposition::NEW_BACKGROUND_TAB:
+ case WindowOpenDisposition::NEW_POPUP:
+ case WindowOpenDisposition::NEW_WINDOW: {
+ PopupFrameCreationInfoUserData* popup_creation_info =
+ reinterpret_cast<PopupFrameCreationInfoUserData*>(
+ new_contents->GetUserData(kPopupCreationInfo));
+ popup_creation_info->info.set_initiated_by_user(user_gesture);
+ pending_popups_.emplace_back(std::move(new_contents));
+ MaybeSendPopup();
+ return;
+ }
+
+ // These kinds of windows don't produce Frames.
+ case WindowOpenDisposition::CURRENT_TAB:
+ case WindowOpenDisposition::SINGLETON_TAB:
+ case WindowOpenDisposition::SAVE_TO_DISK:
+ case WindowOpenDisposition::OFF_THE_RECORD:
+ case WindowOpenDisposition::IGNORE_ACTION:
+ case WindowOpenDisposition::SWITCH_TO_TAB:
+ case WindowOpenDisposition::UNKNOWN:
+ NOTIMPLEMENTED() << "Dropped new web contents (disposition: "
+ << static_cast<int>(disposition) << ")";
+ return;
+ }
+}
+
+void FrameImpl::WebContentsCreated(content::WebContents* source_contents,
+ int opener_render_process_id,
+ int opener_render_frame_id,
+ const std::string& frame_name,
+ const GURL& target_url,
+ content::WebContents* new_contents) {
+ auto creation_info = std::make_unique<PopupFrameCreationInfoUserData>();
+ creation_info->info.set_initial_url(target_url.spec());
+ new_contents->SetUserData(kPopupCreationInfo, std::move(creation_info));
+}
+
+void FrameImpl::MaybeSendPopup() {
+ if (!popup_listener_)
+ return;
+
+ if (popup_ack_outstanding_ || pending_popups_.empty())
+ return;
+
+ std::unique_ptr<content::WebContents> popup =
+ std::move(pending_popups_.front());
+ pending_popups_.pop_front();
+
+ fuchsia::web::PopupFrameCreationInfo creation_info =
+ std::move(reinterpret_cast<PopupFrameCreationInfoUserData*>(
+ popup->GetUserData(kPopupCreationInfo))
+ ->info);
+
+ // The PopupFrameCreationInfo won't be needed anymore, so clear it out.
+ popup->SetUserData(kPopupCreationInfo, nullptr);
+
+ popup_listener_->OnPopupFrameCreated(
+ context_->CreateFrameForPopupWebContents(std::move(popup)),
+ std::move(creation_info), [this] {
+ popup_ack_outstanding_ = false;
+ MaybeSendPopup();
+ });
+ popup_ack_outstanding_ = true;
+}
+
+void FrameImpl::OnPopupListenerDisconnected(zx_status_t status) {
+ ZX_LOG_IF(WARNING, status != ZX_ERR_PEER_CLOSED, status)
+ << "Popup listener disconnected.";
+ pending_popups_.clear();
+}
+
void FrameImpl::CreateView(fuchsia::ui::views::ViewToken view_token) {
// If a View to this Frame is already active then disconnect it.
TearDownView();
ui::PlatformWindowInitProperties properties;
properties.view_token = std::move(view_token);
+ properties.view_ref_pair = scenic::ViewRefPair::New();
window_tree_host_ =
std::make_unique<ScenicWindowTreeHost>(std::move(properties));
@@ -372,7 +500,7 @@ void FrameImpl::AddBeforeLoadJavaScript(
// Create a read-only VMO from |script|.
fuchsia::mem::Buffer script_buffer =
- cr_fuchsia::MemBufferFromString16(script_utf16);
+ cr_fuchsia::MemBufferFromString16(script_utf16, "cr-before-load-js");
// Wrap the VMO into a read-only shared-memory container that Mojo can work
// with.
@@ -485,6 +613,13 @@ void FrameImpl::SetEnableInput(bool enable_input) {
discarding_event_filter_.set_discard_events(!enable_input);
}
+void FrameImpl::SetPopupFrameCreationListener(
+ fidl::InterfaceHandle<fuchsia::web::PopupFrameCreationListener> listener) {
+ popup_listener_ = listener.Bind();
+ popup_listener_.set_error_handler(
+ fit::bind_member(this, &FrameImpl::OnPopupListenerDisconnected));
+}
+
void FrameImpl::CloseContents(content::WebContents* source) {
DCHECK_EQ(source, web_contents_.get());
context_->DestroyFrame(this);
@@ -529,29 +664,6 @@ bool FrameImpl::DidAddMessageToConsole(
return true;
}
-bool FrameImpl::ShouldCreateWebContents(
- content::WebContents* web_contents,
- content::RenderFrameHost* opener,
- content::SiteInstance* source_site_instance,
- int32_t route_id,
- int32_t main_frame_route_id,
- int32_t main_frame_widget_route_id,
- content::mojom::WindowContainerType window_container_type,
- const GURL& opener_url,
- const std::string& frame_name,
- const GURL& target_url,
- const std::string& partition_id,
- content::SessionStorageNamespace* session_storage_namespace) {
- DCHECK_EQ(web_contents, web_contents_.get());
-
- // Prevent any child WebContents (popup windows, tabs, etc.) from spawning.
- // TODO(crbug.com/888131): Implement support for popup windows.
- NOTIMPLEMENTED() << "Ignored popup window request for URL: "
- << target_url.spec();
-
- return false;
-}
-
void FrameImpl::ReadyToCommitNavigation(
content::NavigationHandle* navigation_handle) {
if (before_load_scripts_.empty())
diff --git a/chromium/fuchsia/engine/browser/frame_impl.h b/chromium/fuchsia/engine/browser/frame_impl.h
index 74415513da5..dbd85f680d5 100644
--- a/chromium/fuchsia/engine/browser/frame_impl.h
+++ b/chromium/fuchsia/engine/browser/frame_impl.h
@@ -92,6 +92,11 @@ class FrameImpl : public fuchsia::web::Frame,
ExecuteJavaScriptCallback callback,
bool need_result);
+ // Sends the next entry in |pending_popups_| to |popup_listener_|.
+ void MaybeSendPopup();
+
+ void OnPopupListenerDisconnected(zx_status_t status);
+
// fuchsia::web::Frame implementation.
void CreateView(fuchsia::ui::views::ViewToken view_token) override;
void GetNavigationController(
@@ -118,6 +123,9 @@ class FrameImpl : public fuchsia::web::Frame,
override;
void SetJavaScriptLogLevel(fuchsia::web::ConsoleLogLevel level) override;
void SetEnableInput(bool enable_input) override;
+ void SetPopupFrameCreationListener(
+ fidl::InterfaceHandle<fuchsia::web::PopupFrameCreationListener> listener)
+ override;
// content::WebContentsDelegate implementation.
void CloseContents(content::WebContents* source) override;
@@ -139,6 +147,18 @@ class FrameImpl : public fuchsia::web::Frame,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) override;
+ void WebContentsCreated(content::WebContents* source_contents,
+ int opener_render_process_id,
+ int opener_render_frame_id,
+ const std::string& frame_name,
+ const GURL& target_url,
+ content::WebContents* new_contents) override;
+ void AddNewContents(content::WebContents* source,
+ std::unique_ptr<content::WebContents> new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_rect,
+ bool user_gesture,
+ bool* was_blocked) override;
// content::WebContentsObserver implementation.
void ReadyToCommitNavigation(
@@ -158,6 +178,11 @@ class FrameImpl : public fuchsia::web::Frame,
std::vector<uint64_t> before_load_scripts_order_;
base::RepeatingCallback<void(base::StringPiece)> console_log_message_hook_;
+ // Used for receiving and dispatching popup created by this Frame.
+ fuchsia::web::PopupFrameCreationListenerPtr popup_listener_;
+ std::list<std::unique_ptr<content::WebContents>> pending_popups_;
+ bool popup_ack_outstanding_ = false;
+
fidl::Binding<fuchsia::web::Frame> binding_;
DISALLOW_COPY_AND_ASSIGN(FrameImpl);
diff --git a/chromium/fuchsia/engine/browser/frame_impl_browsertest.cc b/chromium/fuchsia/engine/browser/frame_impl_browsertest.cc
index 67a73935570..50bd2538ed8 100644
--- a/chromium/fuchsia/engine/browser/frame_impl_browsertest.cc
+++ b/chromium/fuchsia/engine/browser/frame_impl_browsertest.cc
@@ -5,8 +5,6 @@
#include <lib/fidl/cpp/binding.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
-#include "base/containers/span.h"
-
#include "base/bind.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/macros.h"
@@ -21,6 +19,7 @@
#include "fuchsia/base/frame_test_util.h"
#include "fuchsia/base/mem_buffer_util.h"
#include "fuchsia/base/result_receiver.h"
+#include "fuchsia/base/string_util.h"
#include "fuchsia/base/test_navigation_listener.h"
#include "fuchsia/engine/browser/frame_impl.h"
#include "fuchsia/engine/common.h"
@@ -52,6 +51,9 @@ const char kPage1Path[] = "/title1.html";
const char kPage2Path[] = "/title2.html";
const char kPage3Path[] = "/websql.html";
const char kDynamicTitlePath[] = "/dynamic_title.html";
+const char kPopupPath[] = "/popup_parent.html";
+const char kPopupRedirectPath[] = "/popup_child.html";
+const char kPopupMultiplePath[] = "/popup_multiple.html";
const char kPage1Title[] = "title 1";
const char kPage2Title[] = "title 2";
const char kPage3Title[] = "websql not available";
@@ -80,11 +82,6 @@ class MockWebContentsObserver : public content::WebContentsObserver {
void(content::RenderViewHost* render_view_host));
};
-std::vector<uint8_t> StringToUnsignedVector(base::StringPiece str) {
- const uint8_t* raw_data = reinterpret_cast<const uint8_t*>(str.data());
- return std::vector<uint8_t>(raw_data, raw_data + str.length());
-}
-
std::string StringFromMemBufferOrDie(const fuchsia::mem::Buffer& buffer) {
std::string output;
CHECK(cr_fuchsia::StringFromMemBuffer(buffer, &output));
@@ -612,7 +609,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, BeforeLoadScript) {
frame->AddBeforeLoadJavaScript(
kBindingsId, {url.GetOrigin().spec()},
- cr_fuchsia::MemBufferFromString("stashed_title = 'hello';"),
+ cr_fuchsia::MemBufferFromString("stashed_title = 'hello';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -634,7 +631,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, BeforeLoadScriptUpdated) {
frame->AddBeforeLoadJavaScript(
kBindingsId, {url.GetOrigin().spec()},
- cr_fuchsia::MemBufferFromString("stashed_title = 'hello';"),
+ cr_fuchsia::MemBufferFromString("stashed_title = 'hello';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -645,7 +642,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, BeforeLoadScriptUpdated) {
frame->AddBeforeLoadJavaScript(
kBindingsId, {url.GetOrigin().spec()},
cr_fuchsia::MemBufferFromString(
- "stashed_title = document.title + 'clobber';"),
+ "stashed_title = document.title + 'clobber';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -670,13 +667,13 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, BeforeLoadScriptOrdered) {
frame->AddBeforeLoadJavaScript(
kBindingsId1, {url.GetOrigin().spec()},
- cr_fuchsia::MemBufferFromString("stashed_title = 'hello';"),
+ cr_fuchsia::MemBufferFromString("stashed_title = 'hello';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
frame->AddBeforeLoadJavaScript(
kBindingsId2, {url.GetOrigin().spec()},
- cr_fuchsia::MemBufferFromString("stashed_title += ' there';"),
+ cr_fuchsia::MemBufferFromString("stashed_title += ' there';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -699,7 +696,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, BeforeLoadScriptRemoved) {
frame->AddBeforeLoadJavaScript(
kBindingsId1, {url.GetOrigin().spec()},
- cr_fuchsia::MemBufferFromString("stashed_title = 'foo';"),
+ cr_fuchsia::MemBufferFromString("stashed_title = 'foo';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -707,7 +704,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, BeforeLoadScriptRemoved) {
// Add a script which clobbers "foo".
frame->AddBeforeLoadJavaScript(
kBindingsId2, {url.GetOrigin().spec()},
- cr_fuchsia::MemBufferFromString("stashed_title = 'bar';"),
+ cr_fuchsia::MemBufferFromString("stashed_title = 'bar';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -759,7 +756,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, ExecuteJavaScript) {
frame->ExecuteJavaScriptNoResult(
{kUrl.GetOrigin().spec()},
cr_fuchsia::MemBufferFromString(
- base::StringPrintf("my_variable = %s;", kJsonStringLiteral)),
+ base::StringPrintf("my_variable = %s;", kJsonStringLiteral), "test"),
[](fuchsia::web::Frame_ExecuteJavaScriptNoResult_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -768,7 +765,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, ExecuteJavaScript) {
base::RunLoop loop;
frame->ExecuteJavaScript(
{kUrl.GetOrigin().spec()},
- cr_fuchsia::MemBufferFromString("my_variable;"),
+ cr_fuchsia::MemBufferFromString("my_variable;", "test"),
[&](fuchsia::web::Frame_ExecuteJavaScript_Result result) {
ASSERT_TRUE(result.is_response());
std::string result_json =
@@ -786,7 +783,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, BeforeLoadScriptVmoDestroyed) {
frame->AddBeforeLoadJavaScript(
kOnLoadScriptId, {url.GetOrigin().spec()},
- cr_fuchsia::MemBufferFromString("stashed_title = 'hello';"),
+ cr_fuchsia::MemBufferFromString("stashed_title = 'hello';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -806,7 +803,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, BeforeLoadScriptWrongOrigin) {
frame->AddBeforeLoadJavaScript(
kOnLoadScriptId, {"http://example.com"},
- cr_fuchsia::MemBufferFromString("stashed_title = 'hello';"),
+ cr_fuchsia::MemBufferFromString("stashed_title = 'hello';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -829,7 +826,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, BeforeLoadScriptWildcardOrigin) {
frame->AddBeforeLoadJavaScript(
kOnLoadScriptId, {"*"},
- cr_fuchsia::MemBufferFromString("stashed_title = 'hello';"),
+ cr_fuchsia::MemBufferFromString("stashed_title = 'hello';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -865,7 +862,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest,
frame->AddBeforeLoadJavaScript(
kOnLoadScriptId, {url.GetOrigin().spec()},
- cr_fuchsia::MemBufferFromString("stashed_title = 'hello';"),
+ cr_fuchsia::MemBufferFromString("stashed_title = 'hello';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -879,7 +876,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest,
frame->AddBeforeLoadJavaScript(
kOnLoadScriptId2, {url.GetOrigin().spec()},
- cr_fuchsia::MemBufferFromString("stashed_title += ' there';"),
+ cr_fuchsia::MemBufferFromString("stashed_title += ' there';", "test"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
EXPECT_TRUE(result.is_response());
});
@@ -912,7 +909,8 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, ExecuteJavaScriptBadEncoding) {
// 0xFE is an illegal UTF-8 byte; it should cause UTF-8 conversion to fail.
frame->ExecuteJavaScriptNoResult(
- {url.GetOrigin().spec()}, cr_fuchsia::MemBufferFromString("true;\xfe"),
+ {url.GetOrigin().spec()},
+ cr_fuchsia::MemBufferFromString("true;\xfe", "test"),
[&run_loop](fuchsia::web::Frame_ExecuteJavaScriptNoResult_Result result) {
EXPECT_TRUE(result.is_err());
EXPECT_EQ(result.err(), fuchsia::web::FrameError::BUFFER_NOT_UTF8);
@@ -1084,7 +1082,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, PostMessage) {
"postmessage");
fuchsia::web::WebMessage message;
- message.set_data(cr_fuchsia::MemBufferFromString(kPage1Path));
+ message.set_data(cr_fuchsia::MemBufferFromString(kPage1Path, "test"));
cr_fuchsia::ResultReceiver<fuchsia::web::Frame_PostMessage_Result>
post_result;
frame->PostMessage(
@@ -1122,7 +1120,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, PostMessagePassMessagePort) {
std::vector<fuchsia::web::OutgoingTransferable> outgoing_vector;
outgoing_vector.push_back(std::move(outgoing));
msg.set_outgoing_transfer(std::move(outgoing_vector));
- msg.set_data(cr_fuchsia::MemBufferFromString("hi"));
+ msg.set_data(cr_fuchsia::MemBufferFromString("hi", "test"));
cr_fuchsia::ResultReceiver<fuchsia::web::Frame_PostMessage_Result>
post_result;
frame->PostMessage(
@@ -1140,7 +1138,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, PostMessagePassMessagePort) {
}
{
- msg.set_data(cr_fuchsia::MemBufferFromString("ping"));
+ msg.set_data(cr_fuchsia::MemBufferFromString("ping", "test"));
cr_fuchsia::ResultReceiver<fuchsia::web::MessagePort_PostMessage_Result>
post_result;
message_port->PostMessage(
@@ -1183,7 +1181,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, PostMessageMessagePortDisconnected) {
std::vector<fuchsia::web::OutgoingTransferable> outgoing_vector;
outgoing_vector.push_back(std::move(outgoing));
msg.set_outgoing_transfer(std::move(outgoing_vector));
- msg.set_data(cr_fuchsia::MemBufferFromString("hi"));
+ msg.set_data(cr_fuchsia::MemBufferFromString("hi", "test"));
cr_fuchsia::ResultReceiver<fuchsia::web::Frame_PostMessage_Result>
post_result;
frame->PostMessage(
@@ -1240,7 +1238,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, PostMessageUseContentProvidedPort) {
std::vector<fuchsia::web::OutgoingTransferable> outgoing_vector;
outgoing_vector.push_back(std::move(outgoing));
msg.set_outgoing_transfer(std::move(outgoing_vector));
- msg.set_data(cr_fuchsia::MemBufferFromString("hi"));
+ msg.set_data(cr_fuchsia::MemBufferFromString("hi", "test"));
cr_fuchsia::ResultReceiver<fuchsia::web::Frame_PostMessage_Result>
post_result;
frame->PostMessage(
@@ -1268,7 +1266,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, PostMessageUseContentProvidedPort) {
base::RunLoop run_loop;
cr_fuchsia::ResultReceiver<fuchsia::web::MessagePort_PostMessage_Result>
post_result(run_loop.QuitClosure());
- msg.set_data(cr_fuchsia::MemBufferFromString("ping"));
+ msg.set_data(cr_fuchsia::MemBufferFromString("ping", "test"));
incoming_message_port->PostMessage(
std::move(msg),
cr_fuchsia::CallbackToFitFunction(post_result.GetReceiveCallback()));
@@ -1286,7 +1284,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, PostMessageUseContentProvidedPort) {
std::vector<fuchsia::web::OutgoingTransferable> outgoing_vector;
outgoing_vector.push_back(std::move(outgoing));
msg.set_outgoing_transfer(std::move(outgoing_vector));
- msg.set_data(cr_fuchsia::MemBufferFromString("hi"));
+ msg.set_data(cr_fuchsia::MemBufferFromString("hi", "test"));
// Quit the runloop only after we've received a WebMessage AND a PostMessage
// result.
@@ -1345,7 +1343,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, PostMessageBadOriginDropped) {
std::vector<fuchsia::web::OutgoingTransferable> unused_outgoing_vector;
unused_outgoing_vector.push_back(std::move(unused_outgoing));
msg.set_outgoing_transfer(std::move(unused_outgoing_vector));
- msg.set_data(cr_fuchsia::MemBufferFromString("bad origin, bad!"));
+ msg.set_data(cr_fuchsia::MemBufferFromString("bad origin, bad!", "test"));
cr_fuchsia::ResultReceiver<fuchsia::web::Frame_PostMessage_Result>
unused_post_result;
@@ -1369,7 +1367,7 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, PostMessageBadOriginDropped) {
std::vector<fuchsia::web::OutgoingTransferable> outgoing_vector;
outgoing_vector.push_back(std::move(outgoing));
msg.set_outgoing_transfer(std::move(outgoing_vector));
- msg.set_data(cr_fuchsia::MemBufferFromString("good origin"));
+ msg.set_data(cr_fuchsia::MemBufferFromString("good origin", "test"));
cr_fuchsia::ResultReceiver<fuchsia::web::Frame_PostMessage_Result>
post_result;
@@ -1444,6 +1442,114 @@ IN_PROC_BROWSER_TEST_F(FrameImplTest, RecreateView) {
navigation_listener_.RunUntilUrlAndTitleEquals(page1_url, kPage1Title);
}
+// Tests SetNavigationEventListener() immediately returns a NavigationEvent,
+// even in the absence of a new navigation.
+IN_PROC_BROWSER_TEST_F(FrameImplTest, ImmediateNavigationEvent) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL page_url(embedded_test_server()->GetURL(kPage1Path));
+
+ // The first NavigationState received should be empty.
+ base::RunLoop run_loop;
+ navigation_listener_.SetBeforeAckHook(base::BindRepeating(
+ [](base::RunLoop* run_loop, const fuchsia::web::NavigationState& change,
+ OnNavigationStateChangedCallback callback) {
+ EXPECT_TRUE(change.IsEmpty());
+ run_loop->Quit();
+ callback();
+ },
+ base::Unretained(&run_loop)));
+ fuchsia::web::FramePtr frame = CreateFrame();
+ run_loop.Run();
+ navigation_listener_.SetBeforeAckHook({});
+
+ // Navigate to a page and wait for the navigation to complete.
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), page_url.spec()));
+ navigation_listener_.RunUntilUrlEquals(page_url);
+
+ // Attach a new navigation listener, we should get the new page state, even if
+ // no new navigation occurred.
+ cr_fuchsia::TestNavigationListener navigation_listener2;
+ fidl::Binding<fuchsia::web::NavigationEventListener>
+ navigation_listener_binding(&navigation_listener2);
+ frame->SetNavigationEventListener(navigation_listener_binding.NewBinding());
+ navigation_listener2.RunUntilUrlAndTitleEquals(page_url, kPage1Title);
+}
+
+// Check loading an invalid URL in NavigationController.LoadUrl() sets the right
+// error.
+IN_PROC_BROWSER_TEST_F(FrameImplTest, InvalidUrl) {
+ fuchsia::web::FramePtr frame = CreateFrame();
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ base::RunLoop run_loop;
+ cr_fuchsia::ResultReceiver<fuchsia::web::NavigationController_LoadUrl_Result>
+ result(run_loop.QuitClosure());
+ controller->LoadUrl(
+ "http:google.com:foo", fuchsia::web::LoadUrlParams(),
+ cr_fuchsia::CallbackToFitFunction(result.GetReceiveCallback()));
+ run_loop.Run();
+
+ ASSERT_TRUE(result->is_err());
+ EXPECT_EQ(result->err(),
+ fuchsia::web::NavigationControllerError::INVALID_URL);
+}
+
+// Check setting invalid headers in NavigationController.LoadUrl() sets the
+// right error.
+IN_PROC_BROWSER_TEST_F(FrameImplTest, InvalidHeader) {
+ fuchsia::web::FramePtr frame = CreateFrame();
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+
+ {
+ // Set an invalid header name.
+ fuchsia::web::LoadUrlParams load_url_params;
+ fuchsia::net::http::Header header;
+ header.name = cr_fuchsia::StringToBytes("Invalid:Header");
+ header.value = cr_fuchsia::StringToBytes("1");
+ load_url_params.set_headers({header});
+
+ base::RunLoop run_loop;
+ cr_fuchsia::ResultReceiver<
+ fuchsia::web::NavigationController_LoadUrl_Result>
+ result(run_loop.QuitClosure());
+ controller->LoadUrl(
+ "http://site.ext/", std::move(load_url_params),
+ cr_fuchsia::CallbackToFitFunction(result.GetReceiveCallback()));
+ run_loop.Run();
+
+ ASSERT_TRUE(result->is_err());
+ EXPECT_EQ(result->err(),
+ fuchsia::web::NavigationControllerError::INVALID_HEADER);
+ }
+
+ {
+ // Set an invalid header value.
+ fuchsia::web::LoadUrlParams load_url_params;
+ fuchsia::net::http::Header header;
+ header.name = cr_fuchsia::StringToBytes("Header");
+ header.value = cr_fuchsia::StringToBytes("Invalid\rValue");
+ load_url_params.set_headers({header});
+
+ base::RunLoop run_loop;
+ cr_fuchsia::ResultReceiver<
+ fuchsia::web::NavigationController_LoadUrl_Result>
+ result(run_loop.QuitClosure());
+ controller->LoadUrl(
+ "http://site.ext/", std::move(load_url_params),
+ cr_fuchsia::CallbackToFitFunction(result.GetReceiveCallback()));
+ run_loop.Run();
+
+ ASSERT_TRUE(result->is_err());
+ EXPECT_EQ(result->err(),
+ fuchsia::web::NavigationControllerError::INVALID_HEADER);
+ }
+}
+
class RequestMonitoringFrameImplBrowserTest : public FrameImplTest {
public:
RequestMonitoringFrameImplBrowserTest() = default;
@@ -1493,11 +1599,11 @@ IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest, ExtraHeaders) {
const GURL page_url(embedded_test_server()->GetURL(kPage1Path));
fuchsia::web::LoadUrlParams load_url_params;
fuchsia::net::http::Header header1;
- header1.name = StringToUnsignedVector("X-ExtraHeaders");
- header1.value = StringToUnsignedVector("1");
+ header1.name = cr_fuchsia::StringToBytes("X-ExtraHeaders");
+ header1.value = cr_fuchsia::StringToBytes("1");
fuchsia::net::http::Header header2;
- header2.name = StringToUnsignedVector("X-2ExtraHeaders");
- header2.value = StringToUnsignedVector("2");
+ header2.name = cr_fuchsia::StringToBytes("X-2ExtraHeaders");
+ header2.value = cr_fuchsia::StringToBytes("2");
load_url_params.set_headers({header1, header2});
EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
@@ -1513,3 +1619,100 @@ IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest, ExtraHeaders) {
EXPECT_THAT(iter->second.headers,
testing::Contains(testing::Key("X-2ExtraHeaders")));
}
+
+class TestPopupListener : public fuchsia::web::PopupFrameCreationListener {
+ public:
+ TestPopupListener() = default;
+ ~TestPopupListener() override = default;
+
+ void GetAndAckNextPopup(fuchsia::web::FramePtr* frame,
+ fuchsia::web::PopupFrameCreationInfo* creation_info) {
+ if (!frame_) {
+ base::RunLoop run_loop;
+ received_popup_callback_ = run_loop.QuitClosure();
+ run_loop.Run();
+ }
+
+ *frame = frame_.Bind();
+ *creation_info = std::move(creation_info_);
+
+ popup_ack_callback_();
+ popup_ack_callback_ = {};
+ }
+
+ private:
+ void OnPopupFrameCreated(fidl::InterfaceHandle<fuchsia::web::Frame> frame,
+ fuchsia::web::PopupFrameCreationInfo creation_info,
+ OnPopupFrameCreatedCallback callback) override {
+ creation_info_ = std::move(creation_info);
+ frame_ = std::move(frame);
+
+ popup_ack_callback_ = std::move(callback);
+
+ if (received_popup_callback_)
+ std::move(received_popup_callback_).Run();
+ }
+
+ fidl::InterfaceHandle<fuchsia::web::Frame> frame_;
+ fuchsia::web::PopupFrameCreationInfo creation_info_;
+ base::OnceClosure received_popup_callback_;
+ OnPopupFrameCreatedCallback popup_ack_callback_;
+};
+
+IN_PROC_BROWSER_TEST_F(FrameImplTest, PopupWindow) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL popup_url(embedded_test_server()->GetURL(kPopupPath));
+ GURL popup_child_url(embedded_test_server()->GetURL(kPopupRedirectPath));
+ GURL title1_url(embedded_test_server()->GetURL(kPage1Path));
+ fuchsia::web::FramePtr frame = CreateFrame();
+
+ TestPopupListener popup_listener;
+ fidl::Binding<fuchsia::web::PopupFrameCreationListener>
+ popup_listener_binding(&popup_listener);
+ frame->SetPopupFrameCreationListener(popup_listener_binding.NewBinding());
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(controller.get(), {},
+ popup_url.spec()));
+
+ // Verify the popup's initial URL, "popup_child.html".
+ fuchsia::web::FramePtr popup_frame;
+ fuchsia::web::PopupFrameCreationInfo popup_info;
+ popup_listener.GetAndAckNextPopup(&popup_frame, &popup_info);
+ EXPECT_EQ(popup_info.initial_url(), popup_child_url);
+
+ // Verify that the popup eventually redirects to "title1.html".
+ cr_fuchsia::TestNavigationListener popup_nav_listener;
+ fidl::Binding<fuchsia::web::NavigationEventListener>
+ popup_nav_listener_binding(&popup_nav_listener);
+ popup_frame->SetNavigationEventListener(
+ popup_nav_listener_binding.NewBinding());
+ popup_nav_listener.RunUntilUrlAndTitleEquals(title1_url, kPage1Title);
+}
+
+IN_PROC_BROWSER_TEST_F(FrameImplTest, MultiplePopups) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL popup_url(embedded_test_server()->GetURL(kPopupMultiplePath));
+ GURL title1_url(embedded_test_server()->GetURL(kPage1Path));
+ GURL title2_url(embedded_test_server()->GetURL(kPage2Path));
+ fuchsia::web::FramePtr frame = CreateFrame();
+
+ TestPopupListener popup_listener;
+ fidl::Binding<fuchsia::web::PopupFrameCreationListener>
+ popup_listener_binding(&popup_listener);
+ frame->SetPopupFrameCreationListener(popup_listener_binding.NewBinding());
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame->GetNavigationController(controller.NewRequest());
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(controller.get(), {},
+ popup_url.spec()));
+
+ fuchsia::web::FramePtr popup_frame;
+ fuchsia::web::PopupFrameCreationInfo popup_info;
+ popup_listener.GetAndAckNextPopup(&popup_frame, &popup_info);
+ EXPECT_EQ(popup_info.initial_url(), title1_url);
+
+ popup_listener.GetAndAckNextPopup(&popup_frame, &popup_info);
+ EXPECT_EQ(popup_info.initial_url(), title2_url);
+}
diff --git a/chromium/fuchsia/engine/browser/navigation_controller_impl.cc b/chromium/fuchsia/engine/browser/navigation_controller_impl.cc
index cf0eb7e2435..5f5257b42a9 100644
--- a/chromium/fuchsia/engine/browser/navigation_controller_impl.cc
+++ b/chromium/fuchsia/engine/browser/navigation_controller_impl.cc
@@ -9,7 +9,9 @@
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
-#include "content/public/common/was_activated_option.h"
+#include "content/public/common/was_activated_option.mojom.h"
+#include "fuchsia/base/string_util.h"
+#include "net/http/http_util.h"
#include "ui/base/page_transition_types.h"
namespace {
@@ -62,12 +64,26 @@ void NavigationControllerImpl::SetEventListener(
previous_navigation_state_ = {};
pending_navigation_event_ = {};
- if (listener) {
- navigation_listener_.Bind(std::move(listener));
- navigation_listener_.set_error_handler(
- [this](zx_status_t status) { SetEventListener(nullptr); });
- } else {
+ // Simply unbind if no new listener was set.
+ if (!listener) {
navigation_listener_.Unbind();
+ return;
+ }
+
+ navigation_listener_.Bind(std::move(listener));
+ navigation_listener_.set_error_handler(
+ [this](zx_status_t status) { SetEventListener(nullptr); });
+
+ // Immediately send the current navigation state, even if it is empty.
+ if (web_contents_->GetController().GetVisibleEntry() == nullptr) {
+ waiting_for_navigation_event_ack_ = true;
+ navigation_listener_->OnNavigationStateChanged(
+ fuchsia::web::NavigationState(), [this]() {
+ waiting_for_navigation_event_ack_ = false;
+ MaybeSendNavigationEvent();
+ });
+ } else {
+ OnNavigationEntryChanged();
}
}
@@ -126,13 +142,15 @@ void NavigationControllerImpl::LoadUrl(std::string url,
std::vector<std::string> extra_headers;
extra_headers.reserve(params.headers().size());
for (const auto& header : params.headers()) {
- // TODO(crbug.com/964732): Check there is no colon in |header_name|.
- base::StringPiece header_name(
- reinterpret_cast<const char*>(header.name.data()),
- header.name.size());
- base::StringPiece header_value(
- reinterpret_cast<const char*>(header.value.data()),
- header.value.size());
+ base::StringPiece header_name = cr_fuchsia::BytesAsString(header.name);
+ base::StringPiece header_value = cr_fuchsia::BytesAsString(header.value);
+ if (!net::HttpUtil::IsValidHeaderName(header_name) ||
+ !net::HttpUtil::IsValidHeaderValue(header_value)) {
+ result.set_err(fuchsia::web::NavigationControllerError::INVALID_HEADER);
+ callback(std::move(result));
+ return;
+ }
+
extra_headers.emplace_back(
base::StrCat({header_name, ": ", header_value}));
}
@@ -145,9 +163,9 @@ void NavigationControllerImpl::LoadUrl(std::string url,
params_converted.transition_type = ui::PageTransitionFromInt(
ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
if (params.has_was_user_activated() && params.was_user_activated()) {
- params_converted.was_activated = content::WasActivatedOption::kYes;
+ params_converted.was_activated = content::mojom::WasActivatedOption::kYes;
} else {
- params_converted.was_activated = content::WasActivatedOption::kNo;
+ params_converted.was_activated = content::mojom::WasActivatedOption::kNo;
}
web_contents_->GetController().LoadURLWithParams(params_converted);
diff --git a/chromium/fuchsia/engine/browser/web_engine_browser_context.cc b/chromium/fuchsia/engine/browser/web_engine_browser_context.cc
index df15f6cc017..c381d9c7b6d 100644
--- a/chromium/fuchsia/engine/browser/web_engine_browser_context.cc
+++ b/chromium/fuchsia/engine/browser/web_engine_browser_context.cc
@@ -19,9 +19,7 @@
#include "content/public/browser/resource_context.h"
#include "fuchsia/engine/browser/web_engine_net_log.h"
#include "fuchsia/engine/browser/web_engine_permission_manager.h"
-#include "fuchsia/engine/browser/web_engine_url_request_context_getter.h"
#include "fuchsia/engine/common.h"
-#include "net/url_request/url_request_context.h"
#include "services/network/public/cpp/network_switches.h"
class WebEngineBrowserContext::ResourceContext
@@ -144,21 +142,3 @@ content::BrowsingDataRemoverDelegate*
WebEngineBrowserContext::GetBrowsingDataRemoverDelegate() {
return nullptr;
}
-
-net::URLRequestContextGetter* WebEngineBrowserContext::CreateRequestContext(
- content::ProtocolHandlerMap* protocol_handlers,
- content::URLRequestInterceptorScopedVector request_interceptors) {
- DCHECK(!url_request_getter_);
- url_request_getter_ = new WebEngineURLRequestContextGetter(
- base::CreateSingleThreadTaskRunnerWithTraits(
- {content::BrowserThread::IO}),
- net_log_.get(), std::move(*protocol_handlers),
- std::move(request_interceptors), data_dir_path_);
- return url_request_getter_.get();
-}
-
-net::URLRequestContextGetter*
-WebEngineBrowserContext::CreateMediaRequestContext() {
- DCHECK(url_request_getter_.get());
- return url_request_getter_.get();
-}
diff --git a/chromium/fuchsia/engine/browser/web_engine_browser_context.h b/chromium/fuchsia/engine/browser/web_engine_browser_context.h
index 914f7de2306..c508858c24d 100644
--- a/chromium/fuchsia/engine/browser/web_engine_browser_context.h
+++ b/chromium/fuchsia/engine/browser/web_engine_browser_context.h
@@ -14,7 +14,6 @@
class WebEngineNetLog;
class WebEnginePermissionManager;
-class WebEngineURLRequestContextGetter;
class WebEngineBrowserContext : public content::BrowserContext {
public:
@@ -42,10 +41,6 @@ class WebEngineBrowserContext : public content::BrowserContext {
content::BackgroundSyncController* GetBackgroundSyncController() override;
content::BrowsingDataRemoverDelegate* GetBrowsingDataRemoverDelegate()
override;
- net::URLRequestContextGetter* CreateRequestContext(
- content::ProtocolHandlerMap* protocol_handlers,
- content::URLRequestInterceptorScopedVector request_interceptors) override;
- net::URLRequestContextGetter* CreateMediaRequestContext() override;
private:
// Contains URLRequestContextGetter required for resource loading.
@@ -54,7 +49,6 @@ class WebEngineBrowserContext : public content::BrowserContext {
base::FilePath data_dir_path_;
std::unique_ptr<WebEngineNetLog> net_log_;
- scoped_refptr<WebEngineURLRequestContextGetter> url_request_getter_;
std::unique_ptr<SimpleFactoryKey> simple_factory_key_;
std::unique_ptr<ResourceContext> resource_context_;
std::unique_ptr<WebEnginePermissionManager> permission_manager_;
diff --git a/chromium/fuchsia/engine/browser/web_engine_browser_main_parts.cc b/chromium/fuchsia/engine/browser/web_engine_browser_main_parts.cc
index ae98822ff45..a8ac93a91eb 100644
--- a/chromium/fuchsia/engine/browser/web_engine_browser_main_parts.cc
+++ b/chromium/fuchsia/engine/browser/web_engine_browser_main_parts.cc
@@ -10,12 +10,14 @@
#include "base/command_line.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/logging.h"
+#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/main_function_params.h"
#include "fuchsia/engine/browser/context_impl.h"
#include "fuchsia/engine/browser/web_engine_browser_context.h"
#include "fuchsia/engine/browser/web_engine_screen.h"
#include "fuchsia/engine/common.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
#include "ui/aura/screen_ozone.h"
#include "ui/ozone/public/ozone_platform.h"
@@ -31,17 +33,20 @@ WebEngineBrowserMainParts::~WebEngineBrowserMainParts() {
void WebEngineBrowserMainParts::PreMainMessageLoopRun() {
DCHECK(!screen_);
- auto platform_screen = ui::OzonePlatform::GetInstance()->CreateScreen();
- if (platform_screen) {
- screen_ = std::make_unique<aura::ScreenOzone>(std::move(platform_screen));
- } else {
- // Use dummy display::Screen for Ozone platforms that don't provide
- // PlatformScreen.
- screen_ = std::make_unique<WebEngineScreen>();
- }
-
+ screen_ = std::make_unique<aura::ScreenOzone>();
display::Screen::SetScreenInstance(screen_.get());
+ // If Vulkan is not enabled then disable hardware acceleration. Otherwise gpu
+ // process will be restarted several times trying to initialize GL before
+ // falling back to software compositing.
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseVulkan)) {
+ content::GpuDataManager* gpu_data_manager =
+ content::GpuDataManager::GetInstance();
+ DCHECK(gpu_data_manager);
+ gpu_data_manager->DisableHardwareAcceleration();
+ }
+
DCHECK(!browser_context_);
browser_context_ = std::make_unique<WebEngineBrowserContext>(
base::CommandLine::ForCurrentProcess()->HasSwitch(kIncognitoSwitch));
diff --git a/chromium/fuchsia/engine/browser/web_engine_cdm_service.cc b/chromium/fuchsia/engine/browser/web_engine_cdm_service.cc
new file mode 100644
index 00000000000..968b02884e9
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/web_engine_cdm_service.cc
@@ -0,0 +1,131 @@
+// Copyright 2019 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 "fuchsia/engine/browser/web_engine_cdm_service.h"
+
+#include <fuchsia/media/drm/cpp/fidl.h>
+#include <lib/sys/cpp/component_context.h>
+#include <string>
+
+#include "base/bind.h"
+#include "base/fuchsia/default_context.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/frame_service_base.h"
+#include "content/public/browser/provision_fetcher_factory.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/storage_partition.h"
+#include "media/base/provision_fetcher.h"
+#include "media/fuchsia/cdm/service/fuchsia_cdm_manager.h"
+#include "media/fuchsia/mojom/fuchsia_cdm_provider.mojom.h"
+#include "third_party/widevine/cdm/widevine_cdm_common.h"
+
+namespace {
+class FuchsiaCdmProviderImpl
+ : public content::FrameServiceBase<media::mojom::FuchsiaCdmProvider> {
+ public:
+ FuchsiaCdmProviderImpl(media::FuchsiaCdmManager* cdm_manager,
+ media::CreateFetcherCB create_fetcher_cb,
+ content::RenderFrameHost* render_frame_host,
+ media::mojom::FuchsiaCdmProviderRequest request);
+ ~FuchsiaCdmProviderImpl() final;
+
+ // media::mojom::FuchsiaCdmProvider implementation.
+ void CreateCdmInterface(
+ const std::string& key_system,
+ fidl::InterfaceRequest<fuchsia::media::drm::ContentDecryptionModule>
+ request) final;
+
+ private:
+ media::FuchsiaCdmManager* const cdm_manager_;
+ const media::CreateFetcherCB create_fetcher_cb_;
+
+ DISALLOW_COPY_AND_ASSIGN(FuchsiaCdmProviderImpl);
+};
+
+FuchsiaCdmProviderImpl::FuchsiaCdmProviderImpl(
+ media::FuchsiaCdmManager* cdm_manager,
+ media::CreateFetcherCB create_fetcher_cb,
+ content::RenderFrameHost* render_frame_host,
+ media::mojom::FuchsiaCdmProviderRequest request)
+ : FrameServiceBase(render_frame_host, std::move(request)),
+ cdm_manager_(cdm_manager),
+ create_fetcher_cb_(std::move(create_fetcher_cb)) {
+ DCHECK(cdm_manager_);
+}
+
+FuchsiaCdmProviderImpl::~FuchsiaCdmProviderImpl() = default;
+
+void FuchsiaCdmProviderImpl::CreateCdmInterface(
+ const std::string& key_system,
+ fidl::InterfaceRequest<fuchsia::media::drm::ContentDecryptionModule>
+ request) {
+ cdm_manager_->CreateAndProvision(key_system, origin(), create_fetcher_cb_,
+ std::move(request));
+}
+
+void BindFuchsiaCdmProvider(media::FuchsiaCdmManager* cdm_manager,
+ media::mojom::FuchsiaCdmProviderRequest request,
+ content::RenderFrameHost* const frame_host) {
+ scoped_refptr<network::SharedURLLoaderFactory> loader_factory =
+ content::BrowserContext::GetDefaultStoragePartition(
+ frame_host->GetProcess()->GetBrowserContext())
+ ->GetURLLoaderFactoryForBrowserProcess();
+
+ // The object will delete itself when connection to the frame is broken.
+ new FuchsiaCdmProviderImpl(
+ cdm_manager,
+ base::BindRepeating(&content::CreateProvisionFetcher,
+ std::move(loader_factory)),
+ frame_host, std::move(request));
+}
+
+class WidevineHandler : public media::FuchsiaCdmManager::KeySystemHandler {
+ public:
+ WidevineHandler() = default;
+ ~WidevineHandler() override = default;
+
+ void CreateCdm(
+ fidl::InterfaceRequest<fuchsia::media::drm::ContentDecryptionModule>
+ request) override {
+ auto widevine = base::fuchsia::ComponentContextForCurrentProcess()
+ ->svc()
+ ->Connect<fuchsia::media::drm::Widevine>();
+ widevine->CreateContentDecryptionModule(std::move(request));
+ }
+
+ fuchsia::media::drm::ProvisionerPtr CreateProvisioner() override {
+ fuchsia::media::drm::ProvisionerPtr provisioner;
+
+ auto widevine = base::fuchsia::ComponentContextForCurrentProcess()
+ ->svc()
+ ->Connect<fuchsia::media::drm::Widevine>();
+ widevine->CreateProvisioner(provisioner.NewRequest());
+
+ return provisioner;
+ }
+};
+
+// Supported key systems:
+std::unique_ptr<media::FuchsiaCdmManager> CreateCdmManager() {
+ media::FuchsiaCdmManager::KeySystemHandlerMap handlers;
+ handlers.emplace(kWidevineKeySystem, std::make_unique<WidevineHandler>());
+
+ return std::make_unique<media::FuchsiaCdmManager>(std::move(handlers));
+}
+} // namespace
+
+WebEngineCdmService::WebEngineCdmService(
+ service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>*
+ registry)
+ : cdm_manager_(CreateCdmManager()), registry_(registry) {
+ DCHECK(cdm_manager_);
+ DCHECK(registry_);
+ registry_->AddInterface(
+ base::BindRepeating(&BindFuchsiaCdmProvider, cdm_manager_.get()));
+}
+
+WebEngineCdmService::~WebEngineCdmService() {
+ registry_->RemoveInterface<media::mojom::FuchsiaCdmProvider>();
+}
diff --git a/chromium/fuchsia/engine/browser/web_engine_cdm_service.h b/chromium/fuchsia/engine/browser/web_engine_cdm_service.h
new file mode 100644
index 00000000000..d35882fe354
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/web_engine_cdm_service.h
@@ -0,0 +1,37 @@
+// Copyright 2019 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 FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_CDM_SERVICE_H_
+#define FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_CDM_SERVICE_H_
+
+#include <memory>
+
+#include "services/service_manager/public/cpp/binder_registry.h"
+
+namespace content {
+class RenderFrameHost;
+}
+
+namespace media {
+class FuchsiaCdmManager;
+}
+
+class WebEngineCdmService {
+ public:
+ explicit WebEngineCdmService(
+ service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>*
+ registry);
+ ~WebEngineCdmService();
+
+ private:
+ std::unique_ptr<media::FuchsiaCdmManager> cdm_manager_;
+
+ // Not owned pointer. |registry_| must outlive |this|.
+ service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>* const
+ registry_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebEngineCdmService);
+};
+
+#endif // FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_CDM_SERVICE_H_
diff --git a/chromium/fuchsia/engine/browser/web_engine_content_browser_client.cc b/chromium/fuchsia/engine/browser/web_engine_content_browser_client.cc
index f6621b54b96..a16f17ddb88 100644
--- a/chromium/fuchsia/engine/browser/web_engine_content_browser_client.cc
+++ b/chromium/fuchsia/engine/browser/web_engine_content_browser_client.cc
@@ -4,6 +4,8 @@
#include "fuchsia/engine/browser/web_engine_content_browser_client.h"
+#include <fuchsia/web/cpp/fidl.h>
+#include <string>
#include <utility>
#include "components/version_info/version_info.h"
@@ -16,7 +18,7 @@
WebEngineContentBrowserClient::WebEngineContentBrowserClient(
fidl::InterfaceRequest<fuchsia::web::Context> request)
- : request_(std::move(request)) {}
+ : request_(std::move(request)), cdm_service_(&mojo_service_registry_) {}
WebEngineContentBrowserClient::~WebEngineContentBrowserClient() = default;
@@ -60,3 +62,39 @@ void WebEngineContentBrowserClient::OverrideWebkitPrefs(
// Disable WebSQL support since it's being removed from the web platform.
web_prefs->databases_enabled = false;
}
+
+void WebEngineContentBrowserClient::BindInterfaceRequestFromFrame(
+ content::RenderFrameHost* render_frame_host,
+ const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) {
+ mojo_service_registry_.BindInterface(
+ interface_name, std::move(interface_pipe), render_frame_host);
+}
+
+void WebEngineContentBrowserClient::
+ RegisterNonNetworkNavigationURLLoaderFactories(
+ int frame_tree_node_id,
+ NonNetworkURLLoaderFactoryMap* factories) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(kContentDirectories)) {
+ (*factories)[kFuchsiaContentDirectoryScheme] =
+ std::make_unique<ContentDirectoryLoaderFactory>();
+ }
+}
+
+void WebEngineContentBrowserClient::
+ RegisterNonNetworkSubresourceURLLoaderFactories(
+ int render_process_id,
+ int render_frame_id,
+ NonNetworkURLLoaderFactoryMap* factories) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(kContentDirectories)) {
+ (*factories)[kFuchsiaContentDirectoryScheme] =
+ std::make_unique<ContentDirectoryLoaderFactory>();
+ }
+}
+
+void WebEngineContentBrowserClient::AppendExtraCommandLineSwitches(
+ base::CommandLine* command_line,
+ int child_process_id) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(kContentDirectories))
+ command_line->AppendSwitch(kContentDirectories);
+}
diff --git a/chromium/fuchsia/engine/browser/web_engine_content_browser_client.h b/chromium/fuchsia/engine/browser/web_engine_content_browser_client.h
index 73092827e29..560ed6c7546 100644
--- a/chromium/fuchsia/engine/browser/web_engine_content_browser_client.h
+++ b/chromium/fuchsia/engine/browser/web_engine_content_browser_client.h
@@ -5,13 +5,17 @@
#ifndef FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_CONTENT_BROWSER_CLIENT_H_
#define FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_CONTENT_BROWSER_CLIENT_H_
-#include <memory>
+#include <lib/zx/channel.h>
#include <fuchsia/web/cpp/fidl.h>
-#include <lib/zx/channel.h>
+#include <memory>
+#include <string>
#include "base/macros.h"
#include "content/public/browser/content_browser_client.h"
+#include "fuchsia/engine/browser/content_directory_loader_factory.h"
+#include "fuchsia/engine/browser/web_engine_cdm_service.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
class WebEngineBrowserMainParts;
@@ -19,18 +23,31 @@ class WebEngineContentBrowserClient : public content::ContentBrowserClient {
public:
explicit WebEngineContentBrowserClient(
fidl::InterfaceRequest<fuchsia::web::Context> request);
- ~WebEngineContentBrowserClient() override;
+ ~WebEngineContentBrowserClient() final;
WebEngineBrowserMainParts* main_parts_for_test() const { return main_parts_; }
// ContentBrowserClient overrides.
std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(
- const content::MainFunctionParams& parameters) override;
- content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override;
- std::string GetProduct() override;
- std::string GetUserAgent() override;
+ const content::MainFunctionParams& parameters) final;
+ content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() final;
+ std::string GetProduct() final;
+ std::string GetUserAgent() final;
void OverrideWebkitPrefs(content::RenderViewHost* rvh,
- content::WebPreferences* web_prefs) override;
+ content::WebPreferences* web_prefs) final;
+ void BindInterfaceRequestFromFrame(
+ content::RenderFrameHost* render_frame_host,
+ const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) final;
+ void RegisterNonNetworkNavigationURLLoaderFactories(
+ int frame_tree_node_id,
+ NonNetworkURLLoaderFactoryMap* factories) final;
+ void RegisterNonNetworkSubresourceURLLoaderFactories(
+ int render_process_id,
+ int render_frame_id,
+ NonNetworkURLLoaderFactoryMap* factories) final;
+ void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
+ int child_process_id) final;
private:
fidl::InterfaceRequest<fuchsia::web::Context> request_;
@@ -38,6 +55,10 @@ class WebEngineContentBrowserClient : public content::ContentBrowserClient {
// Owned by content::BrowserMainLoop.
WebEngineBrowserMainParts* main_parts_;
+ service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>
+ mojo_service_registry_;
+ WebEngineCdmService cdm_service_;
+
DISALLOW_COPY_AND_ASSIGN(WebEngineContentBrowserClient);
};
diff --git a/chromium/fuchsia/engine/browser/web_engine_url_request_context_getter.cc b/chromium/fuchsia/engine/browser/web_engine_url_request_context_getter.cc
deleted file mode 100644
index 91a97a60498..00000000000
--- a/chromium/fuchsia/engine/browser/web_engine_url_request_context_getter.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018 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 "fuchsia/engine/browser/web_engine_url_request_context_getter.h"
-
-#include <utility>
-
-#include "base/single_thread_task_runner.h"
-#include "content/public/browser/cookie_store_factory.h"
-#include "net/cookies/cookie_store.h"
-#include "net/proxy_resolution/proxy_config_service.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_builder.h"
-
-WebEngineURLRequestContextGetter::WebEngineURLRequestContextGetter(
- scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
- net::NetLog* net_log,
- content::ProtocolHandlerMap protocol_handlers,
- content::URLRequestInterceptorScopedVector request_interceptors,
- base::FilePath data_dir_path)
- : network_task_runner_(std::move(network_task_runner)),
- net_log_(net_log),
- protocol_handlers_(std::move(protocol_handlers)),
- request_interceptors_(std::move(request_interceptors)),
- data_dir_path_(data_dir_path) {}
-
-WebEngineURLRequestContextGetter::~WebEngineURLRequestContextGetter() = default;
-
-net::URLRequestContext*
-WebEngineURLRequestContextGetter::GetURLRequestContext() {
- if (!url_request_context_) {
- net::URLRequestContextBuilder builder;
- builder.set_net_log(net_log_);
- builder.set_data_enabled(true);
-
- for (auto& protocol_handler : protocol_handlers_) {
- builder.SetProtocolHandler(protocol_handler.first,
- std::move(protocol_handler.second));
- }
- protocol_handlers_.clear();
-
- builder.SetInterceptors(std::move(request_interceptors_));
-
- if (data_dir_path_.empty()) {
- // Set up an in-memory (ephemeral) CookieStore.
- builder.SetCookieStore(
- content::CreateCookieStore(content::CookieStoreConfig(), nullptr));
- } else {
- // Set up a persistent CookieStore under |data_dir_path|.
- content::CookieStoreConfig cookie_config(
- data_dir_path_.Append(FILE_PATH_LITERAL("Cookies")), false, false,
- NULL);
-
- // Fuchsia protects the local data at rest so there is no need to encrypt
- // cookie store.
- builder.SetCookieStore(
- content::CreateCookieStore(cookie_config, nullptr));
- }
-
- url_request_context_ = builder.Build();
- }
- return url_request_context_.get();
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-WebEngineURLRequestContextGetter::GetNetworkTaskRunner() const {
- return network_task_runner_;
-}
diff --git a/chromium/fuchsia/engine/browser/web_engine_url_request_context_getter.h b/chromium/fuchsia/engine/browser/web_engine_url_request_context_getter.h
deleted file mode 100644
index 9d501cdc692..00000000000
--- a/chromium/fuchsia/engine/browser/web_engine_url_request_context_getter.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2018 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 FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_URL_REQUEST_CONTEXT_GETTER_H_
-#define FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_URL_REQUEST_CONTEXT_GETTER_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "content/public/browser/browser_context.h"
-#include "net/url_request/url_request_context_getter.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-} // namespace base
-
-namespace net {
-class NetLog;
-class ProxyConfigService;
-} // namespace net
-
-class WebEngineURLRequestContextGetter : public net::URLRequestContextGetter {
- public:
- WebEngineURLRequestContextGetter(
- scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
- net::NetLog* net_log,
- content::ProtocolHandlerMap protocol_handlers,
- content::URLRequestInterceptorScopedVector request_interceptors,
- base::FilePath data_dir_path);
-
- // net::URLRequestContextGetter overrides.
- net::URLRequestContext* GetURLRequestContext() override;
- scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
- const override;
-
- protected:
- ~WebEngineURLRequestContextGetter() override;
-
- private:
- scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
- net::NetLog* net_log_;
- std::unique_ptr<net::ProxyConfigService> proxy_config_service_;
- std::unique_ptr<net::URLRequestContext> url_request_context_;
-
- content::ProtocolHandlerMap protocol_handlers_;
- content::URLRequestInterceptorScopedVector request_interceptors_;
- base::FilePath data_dir_path_;
-
- DISALLOW_COPY_AND_ASSIGN(WebEngineURLRequestContextGetter);
-};
-
-#endif // FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_URL_REQUEST_CONTEXT_GETTER_H_
diff --git a/chromium/fuchsia/engine/common.cc b/chromium/fuchsia/engine/common.cc
index 22db116c1fb..55207757550 100644
--- a/chromium/fuchsia/engine/common.cc
+++ b/chromium/fuchsia/engine/common.cc
@@ -7,3 +7,5 @@
constexpr char kIncognitoSwitch[] = "incognito";
constexpr char kRemoteDebuggerHandles[] = "remote-debugger-handles";
constexpr char kUserAgentProductAndVersion[] = "user-agent-product";
+constexpr char kContentDirectories[] = "content-directories";
+constexpr char kFuchsiaContentDirectoryScheme[] = "fuchsia-dir";
diff --git a/chromium/fuchsia/engine/common.h b/chromium/fuchsia/engine/common.h
index f0664e0e6a3..7a478794281 100644
--- a/chromium/fuchsia/engine/common.h
+++ b/chromium/fuchsia/engine/common.h
@@ -27,4 +27,17 @@ WEB_ENGINE_EXPORT extern const char kUserAgentProductAndVersion[];
// Context process.
constexpr uint32_t kContextRequestHandleId = PA_HND(PA_USER0, 0);
+// The URL scheme used to access content directories.
+WEB_ENGINE_EXPORT extern const char
+ kFuchsiaContentDirectoryScheme[]; // "fuchsia-dir"
+
+// The command line switch used to register custom schemes with a process.
+// The contents are structured as a list of key-value pairs which map the scheme
+// name to the handle of a Fuchsia::io::Directory channel.
+// e.g. foo=1234,bar=5678
+// The switch can be used to send names by themselves, by pairing the names with
+// zeroed handles.
+WEB_ENGINE_EXPORT extern const char
+ kContentDirectories[]; // "content-directories";
+
#endif // FUCHSIA_ENGINE_COMMON_H_
diff --git a/chromium/fuchsia/engine/context_provider_impl.cc b/chromium/fuchsia/engine/context_provider_impl.cc
index b9a39ba03d5..5d8d9b279dd 100644
--- a/chromium/fuchsia/engine/context_provider_impl.cc
+++ b/chromium/fuchsia/engine/context_provider_impl.cc
@@ -16,10 +16,12 @@
#include <unistd.h>
#include <zircon/processargs.h>
+#include <string>
#include <utility>
#include <vector>
#include "base/base_paths_fuchsia.h"
+#include "base/base_switches.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/scoped_file.h"
@@ -28,12 +30,16 @@
#include "base/logging.h"
#include "base/path_service.h"
#include "base/process/launch.h"
+#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
+#include "components/viz/common/features.h"
#include "content/public/common/content_switches.h"
#include "fuchsia/engine/common.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
#include "net/http/http_util.h"
#include "services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.h"
+#include "ui/gl/gl_switches.h"
namespace {
@@ -55,27 +61,41 @@ zx::channel ValidateDirectoryAndTakeChannel(
return zx::channel();
}
-// Verifies that Vulkan loader service is provided by the specified service
-// directory.
-bool CheckVulkanSupport(
- const fidl::InterfaceHandle<::fuchsia::io::Directory>& directory_handle,
- bool* vulkan_supported) {
- zx::channel dir_channel(fdio_service_clone(directory_handle.channel().get()));
- if (!dir_channel)
- return false;
-
- base::ScopedFD dir_fd;
- zx_status_t status = fdio_fd_create(dir_channel.release(),
- base::ScopedFD::Receiver(dir_fd).get());
- if (status != ZX_OK) {
- ZX_DLOG(ERROR, status) << "fdio_fd_create()";
- return false;
+// Populates a CommandLine with content directory name/handle pairs.
+bool SetContentDirectoriesInCommandLine(
+ std::vector<fuchsia::web::ContentDirectoryProvider> directories,
+ base::CommandLine* command_line,
+ base::LaunchOptions* launch_options) {
+ DCHECK(command_line);
+ DCHECK(launch_options);
+
+ std::vector<std::string> directory_pairs;
+ for (size_t i = 0; i < directories.size(); ++i) {
+ fuchsia::web::ContentDirectoryProvider& directory = directories[i];
+
+ if (directory.name().find('=') != std::string::npos ||
+ directory.name().find(',') != std::string::npos) {
+ DLOG(ERROR) << "Invalid character in directory name: "
+ << directory.name();
+ return false;
+ }
+
+ if (!directory.directory().is_valid()) {
+ DLOG(ERROR) << "Service directory handle not valid for directory: "
+ << directory.name();
+ return false;
+ }
+
+ uint32_t directory_handle_id = base::LaunchOptions::AddHandleToTransfer(
+ &launch_options->handles_to_transfer,
+ directory.mutable_directory()->TakeChannel().release());
+ directory_pairs.emplace_back(
+ base::StrCat({directory.name().c_str(), "=",
+ base::NumberToString(directory_handle_id)}));
}
- struct stat statbuf;
- int result =
- fstatat(dir_fd.get(), "fuchsia.vulkan.loader.Loader", &statbuf, 0);
- *vulkan_supported = result == 0;
+ command_line->AppendSwitchASCII(kContentDirectories,
+ base::JoinString(directory_pairs, ","));
return true;
}
@@ -102,17 +122,15 @@ void ContextProviderImpl::Create(
fidl::InterfaceHandle<::fuchsia::io::Directory> service_directory =
std::move(*params.mutable_service_directory());
-
- // Enable Vulkan if the Vulkan loader service is present in the service
- // directory.
- bool vulkan_supported = false;
- if (!CheckVulkanSupport(service_directory, &vulkan_supported)) {
- // TODO(crbug.com/934539): Add type epitaph.
+ if (!service_directory) {
DLOG(WARNING) << "Invalid |service_directory| in CreateContextParams.";
+ context_request.Close(ZX_ERR_INVALID_ARGS);
return;
}
base::LaunchOptions launch_options;
+ launch_options.process_name_suffix = ":context";
+
service_manager::SandboxPolicyFuchsia sandbox_policy;
sandbox_policy.Initialize(service_manager::SANDBOX_TYPE_WEB_CONTEXT);
sandbox_policy.SetServiceDirectory(std::move(service_directory));
@@ -178,18 +196,21 @@ void ContextProviderImpl::Create(
base::JoinString(handles_ids, ","));
}
-#if defined(WEB_ENGINE_ENABLE_VULKAN)
- // Enable Vulkan when the Vulkan loader service is included in the service
- // directory.
- // TODO(https://crbug.com/962617): Enable Vulkan by default and remove this
- // hack.
- if (vulkan_supported) {
- launch_command.AppendSwitchASCII(
- "--enable-features", "DefaultEnableOopRasterization,UseSkiaRenderer");
- launch_command.AppendSwitch("--use-vulkan");
- launch_command.AppendSwitchASCII("--use-gl", "stub");
+ fuchsia::web::ContextFeatureFlags features = {};
+ if (params.has_features())
+ features = params.features();
+
+ bool enable_vulkan = (features & fuchsia::web::ContextFeatureFlags::VULKAN) ==
+ fuchsia::web::ContextFeatureFlags::VULKAN;
+
+ if (enable_vulkan) {
+ launch_command.AppendSwitch(switches::kUseVulkan);
+ launch_command.AppendSwitchASCII(switches::kEnableFeatures,
+ features::kUseSkiaRenderer.name);
+ launch_command.AppendSwitch(switches::kEnableOopRasterization);
+ launch_command.AppendSwitchASCII(switches::kUseGL,
+ gl::kGLImplementationStubName);
}
-#endif // WEB_ENGINE_ENABLE_VULKAN
// Validate embedder-supplied product, and optional version, and pass it to
// the Context to include in the UserAgent.
@@ -216,6 +237,14 @@ void ContextProviderImpl::Create(
return;
}
+ if (params.has_content_directories() &&
+ !SetContentDirectoriesInCommandLine(
+ std::move(*params.mutable_content_directories()), &launch_command,
+ &launch_options)) {
+ context_request.Close(ZX_ERR_INVALID_ARGS);
+ return;
+ }
+
if (launch_for_test_)
launch_for_test_.Run(launch_command, launch_options);
else
diff --git a/chromium/fuchsia/engine/context_provider_impl_unittest.cc b/chromium/fuchsia/engine/context_provider_impl_unittest.cc
index 078e765b4e2..6f30b4174d6 100644
--- a/chromium/fuchsia/engine/context_provider_impl_unittest.cc
+++ b/chromium/fuchsia/engine/context_provider_impl_unittest.cc
@@ -29,9 +29,9 @@
#include "base/fuchsia/file_utils.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/service_directory.h"
-#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/test/multiprocess_test.h"
+#include "base/test/task_environment.h"
#include "base/test/test_timeouts.h"
#include "fuchsia/engine/common.h"
#include "fuchsia/engine/fake_context.h"
@@ -46,7 +46,9 @@ constexpr char kUrl[] = "chrome://:emorhc";
constexpr char kTitle[] = "Palindrome";
MULTIPROCESS_TEST_MAIN(SpawnContextServer) {
- base::MessageLoopForIO message_loop;
+ base::test::TaskEnvironment task_environment(
+ base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
+ base::test::TaskEnvironment::MainThreadType::IO);
base::FilePath data_dir;
CHECK(base::PathService::Get(base::DIR_APP_DATA, &data_dir));
@@ -177,7 +179,9 @@ class ContextProviderImplTest : public base::MultiProcessTest {
}
protected:
- base::MessageLoopForIO message_loop_;
+ base::test::TaskEnvironment task_environment_{
+ base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
+ base::test::TaskEnvironment::MainThreadType::IO};
std::unique_ptr<ContextProviderImpl> provider_;
fuchsia::web::ContextProviderPtr provider_ptr_;
fidl::BindingSet<fuchsia::web::ContextProvider> bindings_;
@@ -326,8 +330,7 @@ static bool WaitUntilJobIsEmpty(zx::unowned_job job, zx::duration timeout) {
TEST_F(ContextProviderImplTest, CleansUpContextJobs) {
// Replace the default job with one that is guaranteed to be empty.
zx::job job;
- ASSERT_EQ(base::GetDefaultJob()->duplicate(ZX_RIGHT_SAME_RIGHTS, &job),
- ZX_OK);
+ ASSERT_EQ(zx::job::create(*base::GetDefaultJob(), 0, &job), ZX_OK);
base::ScopedDefaultJobForTest empty_default_job(std::move(job));
// Bind to the ContextProvider.
diff --git a/chromium/fuchsia/engine/context_provider_main.cc b/chromium/fuchsia/engine/context_provider_main.cc
index 5355a817da5..b080857221b 100644
--- a/chromium/fuchsia/engine/context_provider_main.cc
+++ b/chromium/fuchsia/engine/context_provider_main.cc
@@ -4,26 +4,30 @@
#include "fuchsia/engine/context_provider_main.h"
+#include <lib/sys/cpp/component_context.h>
+#include <lib/sys/cpp/outgoing_directory.h>
+
+#include "base/fuchsia/default_context.h"
#include "base/fuchsia/scoped_service_binding.h"
-#include "base/fuchsia/service_directory.h"
#include "base/logging.h"
+#include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h"
#include "fuchsia/base/lifecycle_impl.h"
#include "fuchsia/engine/context_provider_impl.h"
int ContextProviderMain() {
- base::SingleThreadTaskExecutor main_task_executor(
- base::MessagePump::Type::UI);
- base::fuchsia::ServiceDirectory* const directory =
- base::fuchsia::ServiceDirectory::GetDefault();
+ base::SingleThreadTaskExecutor main_task_executor(base::MessagePumpType::UI);
+ sys::OutgoingDirectory* directory =
+ base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get();
ContextProviderImpl context_provider;
base::fuchsia::ScopedServiceBinding<fuchsia::web::ContextProvider> binding(
directory, &context_provider);
+ directory->ServeFromStartupInfo();
base::fuchsia::ScopedServiceBinding<fuchsia::web::Debug> debug_binding(
- directory->outgoing_directory()->debug_dir(), &context_provider);
+ directory->debug_dir(), &context_provider);
base::RunLoop run_loop;
cr_fuchsia::LifecycleImpl lifecycle(directory, run_loop.QuitClosure());
diff --git a/chromium/fuchsia/engine/web_engine_content_client.cc b/chromium/fuchsia/engine/web_engine_content_client.cc
index f8caada0a34..41993815873 100644
--- a/chromium/fuchsia/engine/web_engine_content_client.cc
+++ b/chromium/fuchsia/engine/web_engine_content_client.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "fuchsia/engine/web_engine_content_client.h"
+#include "base/command_line.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
@@ -35,3 +36,8 @@ blink::OriginTrialPolicy* WebEngineContentClient::GetOriginTrialPolicy() {
NOTIMPLEMENTED_LOG_ONCE();
return nullptr;
}
+
+void WebEngineContentClient::AddAdditionalSchemes(Schemes* schemes) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(kContentDirectories))
+ schemes->standard_schemes.push_back(kFuchsiaContentDirectoryScheme);
+}
diff --git a/chromium/fuchsia/engine/web_engine_content_client.h b/chromium/fuchsia/engine/web_engine_content_client.h
index 820d2ce606b..c2e9b4085a5 100644
--- a/chromium/fuchsia/engine/web_engine_content_client.h
+++ b/chromium/fuchsia/engine/web_engine_content_client.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "content/public/common/content_client.h"
+#include "fuchsia/engine/common.h"
class WebEngineContentClient : public content::ContentClient {
public:
@@ -20,6 +21,7 @@ class WebEngineContentClient : public content::ContentClient {
base::RefCountedMemory* GetDataResourceBytes(int resource_id) override;
gfx::Image& GetNativeImageNamed(int resource_id) override;
blink::OriginTrialPolicy* GetOriginTrialPolicy() override;
+ void AddAdditionalSchemes(Schemes* schemes) override;
private:
DISALLOW_COPY_AND_ASSIGN(WebEngineContentClient);
diff --git a/chromium/fuchsia/engine/web_engine_debug_integration_test.cc b/chromium/fuchsia/engine/web_engine_debug_integration_test.cc
index e70c05bb4c5..2168aebefd7 100644
--- a/chromium/fuchsia/engine/web_engine_debug_integration_test.cc
+++ b/chromium/fuchsia/engine/web_engine_debug_integration_test.cc
@@ -5,17 +5,20 @@
#include <fuchsia/web/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/binding_set.h>
+#include <lib/sys/cpp/component_context.h>
#include "base/files/file_enumerator.h"
+#include "base/fuchsia/default_context.h"
#include "base/fuchsia/file_utils.h"
#include "base/fuchsia/service_directory_client.h"
#include "base/macros.h"
+#include "base/test/task_environment.h"
#include "fuchsia/base/fit_adapter.h"
#include "fuchsia/base/frame_test_util.h"
#include "fuchsia/base/result_receiver.h"
+#include "fuchsia/base/test_devtools_list_fetcher.h"
#include "fuchsia/base/test_navigation_listener.h"
#include "fuchsia/engine/test_debug_listener.h"
-#include "fuchsia/engine/test_devtools_list_fetcher.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -33,9 +36,9 @@ class WebEngineDebugIntegrationTest : public testing::Test {
~WebEngineDebugIntegrationTest() override = default;
void SetUp() override {
- web_context_provider_ =
- base::fuchsia::ServiceDirectoryClient::ForCurrentProcess()
- ->ConnectToService<fuchsia::web::ContextProvider>();
+ web_context_provider_ = base::fuchsia::ComponentContextForCurrentProcess()
+ ->svc()
+ ->Connect<fuchsia::web::ContextProvider>();
web_context_provider_.set_error_handler(
[](zx_status_t status) { ADD_FAILURE(); });
@@ -93,7 +96,9 @@ class WebEngineDebugIntegrationTest : public testing::Test {
fuchsia::web::ContextError::REMOTE_DEBUGGING_PORT_NOT_OPENED);
}
- base::MessageLoopForIO message_loop_;
+ base::test::TaskEnvironment task_environment_{
+ base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
+ base::test::TaskEnvironment::MainThreadType::IO};
TestDebugListener dev_tools_listener_;
fidl::Binding<fuchsia::web::DevToolsListener> dev_tools_listener_binding_;
@@ -151,8 +156,8 @@ TEST_F(WebEngineDebugIntegrationTest, DebugService) {
// Test the debug information is correct.
dev_tools_listener_.RunUntilNumberOfPortsIs(1u);
- base::Value devtools_list =
- GetDevToolsListFromPort(*dev_tools_listener_.debug_ports().begin());
+ base::Value devtools_list = cr_fuchsia::GetDevToolsListFromPort(
+ *dev_tools_listener_.debug_ports().begin());
ASSERT_TRUE(devtools_list.is_list());
EXPECT_EQ(devtools_list.GetList().size(), 1u);
@@ -179,7 +184,7 @@ TEST_F(WebEngineDebugIntegrationTest, MultipleDebugClients) {
dev_tools_listener_.RunUntilNumberOfPortsIs(1u);
uint16_t port1 = *dev_tools_listener_.debug_ports().begin();
- base::Value devtools_list1 = GetDevToolsListFromPort(port1);
+ base::Value devtools_list1 = cr_fuchsia::GetDevToolsListFromPort(port1);
ASSERT_TRUE(devtools_list1.is_list());
EXPECT_EQ(devtools_list1.GetList().size(), 1u);
@@ -213,7 +218,7 @@ TEST_F(WebEngineDebugIntegrationTest, MultipleDebugClients) {
ASSERT_NE(dev_tools_listener_.debug_ports().find(port2),
dev_tools_listener_.debug_ports().end());
- base::Value devtools_list2 = GetDevToolsListFromPort(port2);
+ base::Value devtools_list2 = cr_fuchsia::GetDevToolsListFromPort(port2);
ASSERT_TRUE(devtools_list2.is_list());
EXPECT_EQ(devtools_list2.GetList().size(), 1u);
diff --git a/chromium/fuchsia/engine/web_engine_integration_test.cc b/chromium/fuchsia/engine/web_engine_integration_test.cc
index d2aa6b10f89..a1ad9b41374 100644
--- a/chromium/fuchsia/engine/web_engine_integration_test.cc
+++ b/chromium/fuchsia/engine/web_engine_integration_test.cc
@@ -3,18 +3,22 @@
// found in the LICENSE file.
#include <fuchsia/web/cpp/fidl.h>
+#include <lib/fdio/directory.h>
#include <lib/fidl/cpp/binding.h>
+#include <lib/sys/cpp/component_context.h>
+#include "base/fuchsia/default_context.h"
#include "base/fuchsia/file_utils.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/service_directory_client.h"
#include "base/macros.h"
-#include "base/test/scoped_task_environment.h"
+#include "base/path_service.h"
+#include "base/test/task_environment.h"
#include "fuchsia/base/fit_adapter.h"
#include "fuchsia/base/frame_test_util.h"
#include "fuchsia/base/result_receiver.h"
+#include "fuchsia/base/test_devtools_list_fetcher.h"
#include "fuchsia/base/test_navigation_listener.h"
-#include "fuchsia/engine/test_devtools_list_fetcher.h"
#include "net/http/http_request_headers.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
@@ -33,14 +37,13 @@ constexpr char kInvalidUserAgentVersion[] = "dev/12345";
class WebEngineIntegrationTest : public testing::Test {
public:
WebEngineIntegrationTest()
- : task_environment_(
- base::test::ScopedTaskEnvironment::MainThreadType::IO) {}
+ : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
~WebEngineIntegrationTest() override = default;
void SetUp() override {
- web_context_provider_ =
- base::fuchsia::ServiceDirectoryClient::ForCurrentProcess()
- ->ConnectToService<fuchsia::web::ContextProvider>();
+ web_context_provider_ = base::fuchsia::ComponentContextForCurrentProcess()
+ ->svc()
+ ->Connect<fuchsia::web::ContextProvider>();
web_context_provider_.set_error_handler(
[](zx_status_t status) { ADD_FAILURE(); });
@@ -105,8 +108,19 @@ class WebEngineIntegrationTest : public testing::Test {
return value ? value->GetString() : std::string();
}
+ fidl::InterfaceHandle<fuchsia::io::Directory> OpenDirectoryHandle(
+ const base::FilePath& path) {
+ fidl::InterfaceHandle<fuchsia::io::Directory> directory_channel;
+ zx_status_t status = fdio_open(
+ path.value().c_str(),
+ fuchsia::io::OPEN_FLAG_DIRECTORY | fuchsia::io::OPEN_RIGHT_READABLE,
+ directory_channel.NewRequest().TakeChannel().release());
+ ZX_DCHECK(status == ZX_OK, status) << "fdio_open";
+ return directory_channel;
+ }
+
protected:
- const base::test::ScopedTaskEnvironment task_environment_;
+ const base::test::TaskEnvironment task_environment_;
fuchsia::web::ContextProviderPtr web_context_provider_;
@@ -240,7 +254,8 @@ TEST_F(WebEngineIntegrationTest, RemoteDebuggingPort) {
nav_controller.get(), fuchsia::web::LoadUrlParams(), url.spec()));
navigation_listener.RunUntilUrlEquals(url);
- base::Value devtools_list = GetDevToolsListFromPort(remote_debugging_port);
+ base::Value devtools_list =
+ cr_fuchsia::GetDevToolsListFromPort(remote_debugging_port);
ASSERT_TRUE(devtools_list.is_list());
EXPECT_EQ(devtools_list.GetList().size(), 1u);
@@ -248,3 +263,37 @@ TEST_F(WebEngineIntegrationTest, RemoteDebuggingPort) {
ASSERT_TRUE(devtools_url->is_string());
EXPECT_EQ(devtools_url->GetString(), url);
}
+
+// Navigates to a resource served under the "testdata" ContentDirectory.
+TEST_F(WebEngineIntegrationTest, ContentDirectoryProvider) {
+ const GURL kUrl("fuchsia-dir://testdata/title1.html");
+ constexpr char kTitle[] = "title 1";
+
+ fuchsia::web::CreateContextParams create_params = DefaultContextParams();
+
+ fuchsia::web::ContentDirectoryProvider provider;
+ provider.set_name("testdata");
+ base::FilePath pkg_path;
+ CHECK(base::PathService::Get(base::DIR_ASSETS, &pkg_path));
+ provider.set_directory(
+ OpenDirectoryHandle(pkg_path.AppendASCII("fuchsia/engine/test/data")));
+
+ create_params.mutable_content_directories()->emplace_back(
+ std::move(provider));
+
+ CreateContextAndFrame(std::move(create_params));
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame_->GetNavigationController(controller.NewRequest());
+ controller.set_error_handler([](zx_status_t status) { ADD_FAILURE(); });
+
+ // Navigate to test1.html and verify that the resource was correctly
+ // downloaded and interpreted by inspecting the document title.
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
+ cr_fuchsia::TestNavigationListener navigation_listener;
+ fidl::Binding<fuchsia::web::NavigationEventListener> listener_binding(
+ &navigation_listener);
+ frame_->SetNavigationEventListener(listener_binding.NewBinding());
+ navigation_listener.RunUntilUrlAndTitleEquals(kUrl, kTitle);
+}
diff --git a/chromium/fuchsia/engine/web_engine_integration_tests.cmx b/chromium/fuchsia/engine/web_engine_integration_tests.cmx
index 3c0c9ca6645..21096856cf8 100644
--- a/chromium/fuchsia/engine/web_engine_integration_tests.cmx
+++ b/chromium/fuchsia/engine/web_engine_integration_tests.cmx
@@ -1,10 +1,10 @@
{
"sandbox": {
"features": [
- "isolated-persistent-storage",
"deprecated-shell",
- "system-temp",
- "deprecated-ambient-replace-as-executable"
+ "deprecated-ambient-replace-as-executable",
+ "isolated-persistent-storage",
+ "isolated-temp"
],
"services": [
"fuchsia.deprecatedtimezone.Timezone",
@@ -12,7 +12,6 @@
"fuchsia.fonts.Provider",
"fuchsia.logger.LogSink",
"fuchsia.net.NameLookup",
- "fuchsia.net.SocketProvider",
"fuchsia.netstack.Netstack",
"fuchsia.posix.socket.Provider",
"fuchsia.process.Launcher",
diff --git a/chromium/fuchsia/engine/web_engine_main_delegate.cc b/chromium/fuchsia/engine/web_engine_main_delegate.cc
index e88300dc302..c796b92beff 100644
--- a/chromium/fuchsia/engine/web_engine_main_delegate.cc
+++ b/chromium/fuchsia/engine/web_engine_main_delegate.cc
@@ -24,10 +24,14 @@ WebEngineMainDelegate* g_current_web_engine_main_delegate = nullptr;
void InitLoggingFromCommandLine(const base::CommandLine& command_line) {
logging::LoggingSettings settings;
- settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
+ if (command_line.GetSwitchValueASCII(switches::kEnableLogging) == "stderr") {
+ settings.logging_dest = logging::LOG_TO_STDERR;
+ } else {
+ settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
+ }
if (command_line.HasSwitch(switches::kLogFile)) {
settings.logging_dest |= logging::LOG_TO_FILE;
- settings.log_file =
+ settings.log_file_path =
command_line.GetSwitchValueASCII(switches::kLogFile).c_str();
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
}
diff --git a/chromium/fuchsia/fidl/cast/application_config.fidl b/chromium/fuchsia/fidl/cast/application_config.fidl
index 070bb9577a3..6e7505b8ca2 100644
--- a/chromium/fuchsia/fidl/cast/application_config.fidl
+++ b/chromium/fuchsia/fidl/cast/application_config.fidl
@@ -21,6 +21,10 @@ table ApplicationConfig {
/// If false, then touch input is disabled.
/// If unset, then the caller is allowed to enable or disable input.
4: bool touch_enabled_policy;
+
+ // If true, enable remote debugging for this application.
+ // if false or unset, remote debugging is disabled for this application.
+ 5: bool enable_remote_debugging;
};
/// Service interface for working with application configurations.
diff --git a/chromium/fuchsia/fidl/cast/application_controller.fidl b/chromium/fuchsia/fidl/cast/application_controller.fidl
new file mode 100644
index 00000000000..17bf0313c00
--- /dev/null
+++ b/chromium/fuchsia/fidl/cast/application_controller.fidl
@@ -0,0 +1,19 @@
+// Copyright 2019 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.
+
+library chromium.cast;
+
+[Discoverable]
+protocol ApplicationControllerReceiver {
+ /// Used by the Agent to receive a controller from the Cast Runner.
+ /// Can only be called at most one time for the lifetime of the Component.
+ SetApplicationController(ApplicationController controller);
+};
+
+/// Allows clients to access and modify certain aspects of the Cast receiver
+/// application runtime.
+protocol ApplicationController {
+ /// Enables or disables touch event processing.
+ SetTouchInputEnabled(bool enable);
+};
diff --git a/chromium/fuchsia/fidl/cast/queryable_data.fidl b/chromium/fuchsia/fidl/cast/queryable_data.fidl
deleted file mode 100644
index c7148a13965..00000000000
--- a/chromium/fuchsia/fidl/cast/queryable_data.fidl
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2019 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.
-
-library chromium.cast;
-
-struct QueryableDataEntry {
- string key;
- string json_value;
-};
-
-/// Interface for serving configuration- and environmental-related values
-/// to CastRunner instances.
-[Discoverable]
-protocol QueryableData {
- /// Gets a list of changed entries since the last call to GetChangedEntries,
- /// delaying execution of the the pending callback until a change becomes
- /// available. The initial call will return all entries managed by the
- /// QueryableData service.
- GetChangedEntries() -> (vector<QueryableDataEntry> values);
-};
-
diff --git a/chromium/fuchsia/fidl/cast/url_request_rewriter.fidl b/chromium/fuchsia/fidl/cast/url_request_rewriter.fidl
new file mode 100644
index 00000000000..45fd69e15ef
--- /dev/null
+++ b/chromium/fuchsia/fidl/cast/url_request_rewriter.fidl
@@ -0,0 +1,17 @@
+// Copyright 2019 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.
+
+library chromium.cast;
+
+using fuchsia.web;
+
+/// Provides URL request rewriting rules from the Agent.
+[Discoverable]
+protocol UrlRequestRewriteRulesProvider {
+ /// Returns a set of URL request rewriting rules. The first call must always
+ /// return immediately with a potentially empty set of rules. On subsequent
+ /// calls, the callback will only be invoked when the rules have changed.
+ GetUrlRequestRewriteRules() ->
+ (vector<fuchsia.web.UrlRequestRewriteRule> rules);
+};
diff --git a/chromium/fuchsia/http/BUILD.gn b/chromium/fuchsia/http/BUILD.gn
index 624ff0ad7a3..27ec91039bf 100644
--- a/chromium/fuchsia/http/BUILD.gn
+++ b/chromium/fuchsia/http/BUILD.gn
@@ -20,9 +20,11 @@ source_set("core") {
]
public_deps = [
"//base:base",
+ "//fuchsia/base",
"//net:net",
"//third_party/fuchsia-sdk/sdk:net_oldhttp",
"//third_party/fuchsia-sdk/sdk:sys",
+ "//third_party/fuchsia-sdk/sdk:sys_cpp",
]
visibility = [ ":*" ]
}
diff --git a/chromium/fuchsia/http/http.cmx b/chromium/fuchsia/http/http.cmx
index b4cde0cf4b4..389f2b56a08 100644
--- a/chromium/fuchsia/http/http.cmx
+++ b/chromium/fuchsia/http/http.cmx
@@ -9,7 +9,6 @@
"fuchsia.device.NameProvider",
"fuchsia.logger.LogSink",
"fuchsia.net.NameLookup",
- "fuchsia.net.SocketProvider",
"fuchsia.netstack.Netstack",
"fuchsia.posix.socket.Provider"
]
diff --git a/chromium/fuchsia/http/http_service_main.cc b/chromium/fuchsia/http/http_service_main.cc
index 81fbfc742d3..359a15bb84e 100644
--- a/chromium/fuchsia/http/http_service_main.cc
+++ b/chromium/fuchsia/http/http_service_main.cc
@@ -2,30 +2,33 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <lib/sys/cpp/component_context.h>
+
#include "base/at_exit.h"
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/fuchsia/default_context.h"
#include "base/fuchsia/scoped_service_binding.h"
-#include "base/fuchsia/service_directory.h"
+#include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h"
-#include "base/task/thread_pool/thread_pool.h"
+#include "base/task/thread_pool/thread_pool_instance.h"
#include "fuchsia/http/http_service_impl.h"
int main(int argc, char** argv) {
// Instantiate various global structures.
base::ThreadPoolInstance::CreateAndStartWithDefaultParams("HTTP Service");
base::CommandLine::Init(argc, argv);
- base::SingleThreadTaskExecutor io_task_executor(base::MessagePump::Type::IO);
+ base::SingleThreadTaskExecutor io_task_executor(base::MessagePumpType::IO);
base::AtExitManager exit_manager;
- // Bind the parent-supplied ServiceDirectory-request to a directory and
+ // Bind the parent-supplied OutgoingDirectory-request to a directory and
// publish the HTTP service into it.
- base::fuchsia::ServiceDirectory* directory =
- base::fuchsia::ServiceDirectory::GetDefault();
+ sys::OutgoingDirectory* outgoing_directory =
+ base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get();
HttpServiceImpl http_service;
base::fuchsia::ScopedServiceBinding<::fuchsia::net::oldhttp::HttpService>
- binding(directory, &http_service);
+ binding(outgoing_directory, &http_service);
base::RunLoop run_loop;
diff --git a/chromium/fuchsia/http/http_service_unittest.cc b/chromium/fuchsia/http/http_service_unittest.cc
index c1b52fc66a9..628e2ef5f2d 100644
--- a/chromium/fuchsia/http/http_service_unittest.cc
+++ b/chromium/fuchsia/http/http_service_unittest.cc
@@ -8,7 +8,7 @@
#include "base/fuchsia/scoped_service_binding.h"
#include "base/fuchsia/service_directory.h"
#include "base/run_loop.h"
-#include "base/test/scoped_task_environment.h"
+#include "base/test/task_environment.h"
#include "fuchsia/http/http_service_impl.h"
#include "fuchsia/http/url_loader_impl.h"
#include "net/base/net_errors.h"
@@ -31,8 +31,7 @@ using ResponseHeaders = std::multimap<std::string, std::string>;
class HttpServiceTest : public ::testing::Test {
public:
HttpServiceTest()
- : task_environment_(
- base::test::ScopedTaskEnvironment::MainThreadType::IO),
+ : task_environment_(base::test::TaskEnvironment::MainThreadType::IO),
binding_(&http_service_server_) {
// Initialize the test server.
test_server_.AddDefaultHandlers(
@@ -41,7 +40,7 @@ class HttpServiceTest : public ::testing::Test {
}
protected:
- base::test::ScopedTaskEnvironment task_environment_;
+ base::test::TaskEnvironment task_environment_;
void SetUp() override {
ASSERT_TRUE(test_server_.Start());
@@ -203,7 +202,8 @@ void CheckResponseBuffer(const oldhttp::URLResponse& response,
void CheckResponseHeaders(const oldhttp::URLResponse& response,
ResponseHeaders* expected_headers) {
- for (auto& header : response.headers.get()) {
+ ASSERT_TRUE(response.headers.has_value());
+ for (auto& header : response.headers.value()) {
const std::string header_name = header.name.data();
const std::string header_value = header.value.data();
auto iter = std::find_if(expected_headers->begin(), expected_headers->end(),
diff --git a/chromium/fuchsia/http/url_loader_impl.cc b/chromium/fuchsia/http/url_loader_impl.cc
index f745b9c240e..fdcdf92aa93 100644
--- a/chromium/fuchsia/http/url_loader_impl.cc
+++ b/chromium/fuchsia/http/url_loader_impl.cc
@@ -7,6 +7,7 @@
#include "base/fuchsia/fuchsia_logging.h"
#include "base/message_loop/message_loop_current.h"
#include "base/task/post_task.h"
+#include "fuchsia/base/mem_buffer_util.h"
#include "net/base/chunked_upload_data_stream.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
@@ -30,20 +31,9 @@ oldhttp::URLBodyPtr CreateURLBodyFromBuffer(net::GrowableIOBuffer* buffer) {
// The response buffer size is exactly the offset.
size_t total_size = buffer->offset();
- ::fuchsia::mem::Buffer mem_buffer;
- mem_buffer.size = total_size;
- zx_status_t result = zx::vmo::create(total_size, 0, &mem_buffer.vmo);
- if (result != ZX_OK) {
- ZX_DLOG(WARNING, result) << "zx_vmo_create";
- return nullptr;
- }
-
- result = mem_buffer.vmo.write(buffer->StartOfBuffer(), 0, total_size);
- if (result != ZX_OK) {
- ZX_DLOG(WARNING, result) << "zx_vmo_write";
- return nullptr;
- }
- body->set_buffer(std::move(mem_buffer));
+ body->set_buffer(cr_fuchsia::MemBufferFromString(
+ base::StringPiece(buffer->StartOfBuffer(), total_size),
+ "cr-http-url-body"));
return body;
}
@@ -420,12 +410,13 @@ oldhttp::URLResponse URLLoaderImpl::BuildResponse(int net_error) {
size_t iter = 0;
std::string header_name;
std::string header_value;
+ response.headers.emplace();
while (response_headers->EnumerateHeaderLines(&iter, &header_name,
&header_value)) {
oldhttp::HttpHeader header;
header.name = header_name;
header.value = header_value;
- response.headers.push_back(header);
+ response.headers->push_back(header);
}
}
diff --git a/chromium/fuchsia/mojo/example.typemap b/chromium/fuchsia/mojo/example.typemap
deleted file mode 100644
index b1d15125e4c..00000000000
--- a/chromium/fuchsia/mojo/example.typemap
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2019 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.
-
-mojom = "//fuchsia/mojo/example.mojom"
-os_whitelist = [ "fuchsia" ]
-public_headers = [ "base/fuchsia/testfidl/cpp/fidl.h" ]
-traits_headers = [ "//fuchsia/mojo/test_interface_request_mojom_traits.h" ]
-sources = [
- "//fuchsia/mojo/test_interface_request_mojom_traits.h",
-]
-public_deps = [
- "//base:testfidl",
- "//fuchsia/mojo:traits",
-]
-type_mappings = [ "fuchsia.test.mojom.TestInterfaceRequest=fidl::InterfaceRequest<base::fuchsia::testfidl::TestInterface>[move_only]" ]
diff --git a/chromium/fuchsia/mojo/BUILD.gn b/chromium/fuchsia/mojom/BUILD.gn
index c79710377c7..e8c4919e507 100644
--- a/chromium/fuchsia/mojo/BUILD.gn
+++ b/chromium/fuchsia/mojom/BUILD.gn
@@ -34,6 +34,7 @@ test("fuchsia_mojo_unittests") {
deps = [
":example_interfaces",
"//base:testfidl",
+ "//base/test:test_support",
"//mojo/core/test:run_all_unittests",
"//mojo/public/cpp/test_support:test_utils",
"//testing/gtest",
diff --git a/chromium/fuchsia/mojo/DEPS b/chromium/fuchsia/mojom/DEPS
index ef8ad28d9d4..ef8ad28d9d4 100644
--- a/chromium/fuchsia/mojo/DEPS
+++ b/chromium/fuchsia/mojom/DEPS
diff --git a/chromium/fuchsia/mojo/OWNERS b/chromium/fuchsia/mojom/OWNERS
index ae29a36aac8..ae29a36aac8 100644
--- a/chromium/fuchsia/mojo/OWNERS
+++ b/chromium/fuchsia/mojom/OWNERS
diff --git a/chromium/fuchsia/mojo/example.mojom b/chromium/fuchsia/mojom/example.mojom
index a27c956182e..a27c956182e 100644
--- a/chromium/fuchsia/mojo/example.mojom
+++ b/chromium/fuchsia/mojom/example.mojom
diff --git a/chromium/fuchsia/mojom/example.typemap b/chromium/fuchsia/mojom/example.typemap
new file mode 100644
index 00000000000..7e2aaac3df0
--- /dev/null
+++ b/chromium/fuchsia/mojom/example.typemap
@@ -0,0 +1,16 @@
+# Copyright 2019 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.
+
+mojom = "//fuchsia/mojom/example.mojom"
+os_whitelist = [ "fuchsia" ]
+public_headers = [ "base/fuchsia/testfidl/cpp/fidl.h" ]
+traits_headers = [ "//fuchsia/mojom/test_interface_request_mojom_traits.h" ]
+sources = [
+ "//fuchsia/mojom/test_interface_request_mojom_traits.h",
+]
+public_deps = [
+ "//base:testfidl",
+ "//fuchsia/mojom:traits",
+]
+type_mappings = [ "fuchsia.test.mojom.TestInterfaceRequest=::fidl::InterfaceRequest<::base::fuchsia::testfidl::TestInterface>[move_only]" ]
diff --git a/chromium/fuchsia/mojo/fidl_interface_request_mojom_traits.h b/chromium/fuchsia/mojom/fidl_interface_request_mojom_traits.h
index 2c38438aaeb..d40f369930a 100644
--- a/chromium/fuchsia/mojo/fidl_interface_request_mojom_traits.h
+++ b/chromium/fuchsia/mojom/fidl_interface_request_mojom_traits.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef FUCHSIA_MOJO_FIDL_INTERFACE_REQUEST_MOJOM_TRAITS_H_
-#define FUCHSIA_MOJO_FIDL_INTERFACE_REQUEST_MOJOM_TRAITS_H_
+#ifndef FUCHSIA_MOJOM_FIDL_INTERFACE_REQUEST_MOJOM_TRAITS_H_
+#define FUCHSIA_MOJOM_FIDL_INTERFACE_REQUEST_MOJOM_TRAITS_H_
#include <lib/fidl/cpp/interface_request.h>
@@ -40,4 +40,4 @@ struct FidlInterfaceRequestStructTraits {
} // namespace mojo
-#endif // FUCHSIA_MOJO_FIDL_INTERFACE_REQUEST_MOJOM_TRAITS_H_
+#endif // FUCHSIA_MOJOM_FIDL_INTERFACE_REQUEST_MOJOM_TRAITS_H_
diff --git a/chromium/fuchsia/mojo/fidl_interface_request_mojom_traits_unittest.cc b/chromium/fuchsia/mojom/fidl_interface_request_mojom_traits_unittest.cc
index 8e34582c25e..a9d5772de15 100644
--- a/chromium/fuchsia/mojo/fidl_interface_request_mojom_traits_unittest.cc
+++ b/chromium/fuchsia/mojom/fidl_interface_request_mojom_traits_unittest.cc
@@ -3,9 +3,9 @@
// found in the LICENSE file.
#include "base/fuchsia/testfidl/cpp/fidl.h"
-#include "base/message_loop/message_loop.h"
-#include "fuchsia/mojo/example.mojom.h"
-#include "fuchsia/mojo/test_interface_request_mojom_traits.h"
+#include "base/test/task_environment.h"
+#include "fuchsia/mojom/example.mojom.h"
+#include "fuchsia/mojom/test_interface_request_mojom_traits.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -15,7 +15,9 @@ using base::fuchsia::testfidl::TestInterface;
using base::fuchsia::testfidl::TestInterfacePtr;
TEST(InterfaceRequestStructTraitsTest, Serialization) {
- base::MessageLoopForIO message_loop;
+ base::test::TaskEnvironment task_environment(
+ base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
+ base::test::TaskEnvironment::MainThreadType::IO);
TestInterfacePtr test_ptr;
fidl::InterfaceRequest<TestInterface> input_request = test_ptr.NewRequest();
fidl::InterfaceRequest<TestInterface> output_request;
diff --git a/chromium/fuchsia/mojo/test_interface_request_mojom_traits.h b/chromium/fuchsia/mojom/test_interface_request_mojom_traits.h
index 0f0aeb66858..f9be179d816 100644
--- a/chromium/fuchsia/mojo/test_interface_request_mojom_traits.h
+++ b/chromium/fuchsia/mojom/test_interface_request_mojom_traits.h
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef FUCHSIA_MOJO_TEST_INTERFACE_REQUEST_MOJOM_TRAITS_H_
-#define FUCHSIA_MOJO_TEST_INTERFACE_REQUEST_MOJOM_TRAITS_H_
+#ifndef FUCHSIA_MOJOM_TEST_INTERFACE_REQUEST_MOJOM_TRAITS_H_
+#define FUCHSIA_MOJOM_TEST_INTERFACE_REQUEST_MOJOM_TRAITS_H_
-#include "fuchsia/mojo/fidl_interface_request_mojom_traits.h"
+#include "fuchsia/mojom/fidl_interface_request_mojom_traits.h"
namespace mojo {
@@ -19,4 +19,4 @@ struct StructTraits<
} // namespace mojo
-#endif // FUCHSIA_MOJO_TEST_INTERFACE_REQUEST_MOJOM_TRAITS_H_
+#endif // FUCHSIA_MOJOM_TEST_INTERFACE_REQUEST_MOJOM_TRAITS_H_
diff --git a/chromium/fuchsia/mojo/test_typemaps.gni b/chromium/fuchsia/mojom/test_typemaps.gni
index 0fb662f47d8..521c8d4f8fb 100644
--- a/chromium/fuchsia/mojo/test_typemaps.gni
+++ b/chromium/fuchsia/mojom/test_typemaps.gni
@@ -2,4 +2,4 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-typemaps = [ "//fuchsia/mojo/example.typemap" ]
+typemaps = [ "//fuchsia/mojom/example.typemap" ]
diff --git a/chromium/fuchsia/runners/BUILD.gn b/chromium/fuchsia/runners/BUILD.gn
index e8916eeafde..ed8fb9e209f 100644
--- a/chromium/fuchsia/runners/BUILD.gn
+++ b/chromium/fuchsia/runners/BUILD.gn
@@ -39,6 +39,7 @@ source_set("common") {
]
public_deps = [
"//third_party/fuchsia-sdk/sdk:sys",
+ "//third_party/fuchsia-sdk/sdk:sys_cpp",
"//third_party/fuchsia-sdk/sdk:web",
]
visibility = [ ":*" ]
@@ -48,6 +49,8 @@ source_set("cast_runner_core") {
sources = [
"cast/api_bindings_client.cc",
"cast/api_bindings_client.h",
+ "cast/application_controller_impl.cc",
+ "cast/application_controller_impl.h",
"cast/cast_component.cc",
"cast/cast_component.h",
"cast/cast_platform_bindings_ids.h",
@@ -70,6 +73,7 @@ source_set("cast_runner_core") {
"//fuchsia/base",
"//fuchsia/base:modular",
"//third_party/fuchsia-sdk/sdk:modular",
+ "//third_party/fuchsia-sdk/sdk:sys_cpp",
"//url",
]
public_deps = [
@@ -128,6 +132,24 @@ source_set("cast_runner_test_core") {
visibility = [ ":*" ]
}
+test("cast_runner_unittests") {
+ sources = [
+ "cast/application_controller_impl_unittest.cc",
+ ]
+ deps = [
+ ":cast_runner_core",
+ ":cast_runner_test_core",
+ "//base",
+ "//base/test:run_all_unittests",
+ "//base/test:test_support",
+ "//fuchsia/base:test_support",
+ "//net:test_support",
+ "//testing/gmock",
+ "//testing/gtest",
+ "//third_party/fuchsia-sdk/sdk:web",
+ ]
+}
+
test("cast_runner_integration_tests") {
sources = [
"cast/cast_runner_integration_test.cc",
@@ -143,6 +165,7 @@ test("cast_runner_integration_tests") {
"//fuchsia/base:test_support",
"//net:test_support",
"//testing/gtest",
+ "//third_party/fuchsia-sdk/sdk:modular",
]
package_deps = [ [
"//fuchsia/engine:web_engine",
diff --git a/chromium/fuchsia/runners/cast/api_bindings_client_browsertest.cc b/chromium/fuchsia/runners/cast/api_bindings_client_browsertest.cc
index 947886f1ca6..3cbb79573ac 100644
--- a/chromium/fuchsia/runners/cast/api_bindings_client_browsertest.cc
+++ b/chromium/fuchsia/runners/cast/api_bindings_client_browsertest.cc
@@ -77,7 +77,8 @@ IN_PROC_BROWSER_TEST_F(ApiBindingsClientTest, EndToEnd) {
std::vector<chromium::cast::ApiBinding> binding_list;
chromium::cast::ApiBinding echo_binding;
echo_binding.set_before_load_script(cr_fuchsia::MemBufferFromString(
- "window.echo = cast.__platform__.PortConnector.bind('echoService');"));
+ "window.echo = cast.__platform__.PortConnector.bind('echoService');",
+ "test"));
binding_list.emplace_back(std::move(echo_binding));
api_service_.set_bindings(std::move(binding_list));
StartClient();
@@ -92,7 +93,7 @@ IN_PROC_BROWSER_TEST_F(ApiBindingsClientTest, EndToEnd) {
api_service_.RunUntilMessagePortReceived("echoService").Bind();
fuchsia::web::WebMessage message;
- message.set_data(cr_fuchsia::MemBufferFromString("ping"));
+ message.set_data(cr_fuchsia::MemBufferFromString("ping", "ping-msg"));
port->PostMessage(std::move(message),
[](fuchsia::web::MessagePort_PostMessage_Result result) {
EXPECT_TRUE(result.is_response());
diff --git a/chromium/fuchsia/runners/cast/application_controller_impl.cc b/chromium/fuchsia/runners/cast/application_controller_impl.cc
new file mode 100644
index 00000000000..d613247be1e
--- /dev/null
+++ b/chromium/fuchsia/runners/cast/application_controller_impl.cc
@@ -0,0 +1,31 @@
+// Copyright 2019 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 "fuchsia/runners/cast/application_controller_impl.h"
+
+#include "base/fuchsia/fuchsia_logging.h"
+#include "base/logging.h"
+
+ApplicationControllerImpl::ApplicationControllerImpl(
+ fuchsia::web::Frame* frame,
+ fidl::InterfaceHandle<chromium::cast::ApplicationControllerReceiver>
+ receiver)
+ : binding_(this), frame_(frame) {
+ DCHECK(receiver);
+ DCHECK(frame_);
+
+ receiver.Bind()->SetApplicationController(binding_.NewBinding());
+
+ binding_.set_error_handler([](zx_status_t status) {
+ if (status != ZX_ERR_PEER_CLOSED && status != ZX_ERR_CANCELED) {
+ ZX_LOG(WARNING, status) << "Application bindings connection dropped.";
+ }
+ });
+}
+
+ApplicationControllerImpl::~ApplicationControllerImpl() = default;
+
+void ApplicationControllerImpl::SetTouchInputEnabled(bool enable) {
+ frame_->SetEnableInput(enable);
+}
diff --git a/chromium/fuchsia/runners/cast/application_controller_impl.h b/chromium/fuchsia/runners/cast/application_controller_impl.h
new file mode 100644
index 00000000000..766e274a075
--- /dev/null
+++ b/chromium/fuchsia/runners/cast/application_controller_impl.h
@@ -0,0 +1,32 @@
+// Copyright 2019 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 FUCHSIA_RUNNERS_CAST_APPLICATION_CONTROLLER_IMPL_H_
+#define FUCHSIA_RUNNERS_CAST_APPLICATION_CONTROLLER_IMPL_H_
+
+#include <fuchsia/web/cpp/fidl.h>
+#include <lib/fidl/cpp/binding.h>
+
+#include "base/macros.h"
+#include "fuchsia/fidl/chromium/cast/cpp/fidl.h"
+
+class ApplicationControllerImpl : public chromium::cast::ApplicationController {
+ public:
+ ApplicationControllerImpl(
+ fuchsia::web::Frame* frame,
+ fidl::InterfaceHandle<chromium::cast::ApplicationControllerReceiver>
+ receiver);
+ ~ApplicationControllerImpl() final;
+
+ protected:
+ void SetTouchInputEnabled(bool enable) override;
+
+ private:
+ fidl::Binding<chromium::cast::ApplicationController> binding_;
+ fuchsia::web::Frame* const frame_;
+
+ DISALLOW_COPY_AND_ASSIGN(ApplicationControllerImpl);
+};
+
+#endif // FUCHSIA_RUNNERS_CAST_APPLICATION_CONTROLLER_IMPL_H_
diff --git a/chromium/fuchsia/runners/cast/application_controller_impl_unittest.cc b/chromium/fuchsia/runners/cast/application_controller_impl_unittest.cc
new file mode 100644
index 00000000000..8569fc616a8
--- /dev/null
+++ b/chromium/fuchsia/runners/cast/application_controller_impl_unittest.cc
@@ -0,0 +1,91 @@
+// Copyright 2019 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 <fuchsia/web/cpp/fidl.h>
+#include <fuchsia/web/cpp/fidl_test_base.h>
+#include <lib/fidl/cpp/binding.h>
+#include <string>
+#include <utility>
+
+#include "base/logging.h"
+#include "base/test/bind_test_util.h"
+#include "base/test/task_environment.h"
+#include "base/test/test_timeouts.h"
+#include "fuchsia/base/fit_adapter.h"
+#include "fuchsia/fidl/chromium/cast/cpp/fidl.h"
+#include "fuchsia/runners/cast/application_controller_impl.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::InvokeWithoutArgs;
+
+namespace {
+
+class MockFrame : public fuchsia::web::testing::Frame_TestBase {
+ public:
+ void NotImplemented_(const std::string& name) final {
+ LOG(FATAL) << "No mock defined for " << name;
+ }
+
+ MOCK_METHOD1(SetEnableInput, void(bool));
+};
+
+class ApplicationControllerImplTest
+ : public chromium::cast::ApplicationControllerReceiver,
+ public testing::Test {
+ public:
+ ApplicationControllerImplTest()
+ : run_timeout_(TestTimeouts::action_timeout(),
+ base::MakeExpectedNotRunClosure(FROM_HERE)),
+ application_receiver_binding_(this),
+ application_(&frame_, application_receiver_binding_.NewBinding()) {
+ base::RunLoop run_loop;
+ wait_for_controller_callback_ = run_loop.QuitClosure();
+ run_loop.Run();
+ }
+
+ ~ApplicationControllerImplTest() override = default;
+
+ protected:
+ // chromium::cast::ApplicationReceiver implementation.
+ void SetApplicationController(
+ fidl::InterfaceHandle<chromium::cast::ApplicationController> application)
+ final {
+ DCHECK(wait_for_controller_callback_);
+
+ application_ptr_ = application.Bind();
+ std::move(wait_for_controller_callback_).Run();
+ }
+
+ const base::RunLoop::ScopedRunTimeoutForTest run_timeout_;
+ base::test::SingleThreadTaskEnvironment task_environment_{
+ base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
+
+ MockFrame frame_;
+ fidl::Binding<chromium::cast::ApplicationControllerReceiver>
+ application_receiver_binding_;
+
+ chromium::cast::ApplicationControllerPtr application_ptr_;
+ ApplicationControllerImpl application_;
+ base::OnceClosure wait_for_controller_callback_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ApplicationControllerImplTest);
+};
+
+// Verifies that SetTouchInputEnabled() calls the Frame API correctly.
+TEST_F(ApplicationControllerImplTest, SetEnableInput) {
+ base::RunLoop run_loop;
+
+ EXPECT_CALL(frame_, SetEnableInput(true)).Times(2);
+ EXPECT_CALL(frame_, SetEnableInput(false))
+ .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
+
+ application_ptr_->SetTouchInputEnabled(true);
+ application_ptr_->SetTouchInputEnabled(true);
+ application_ptr_->SetTouchInputEnabled(false);
+ run_loop.Run();
+}
+
+} // namespace
diff --git a/chromium/fuchsia/runners/cast/cast_component.cc b/chromium/fuchsia/runners/cast/cast_component.cc
index 03a0067dbd7..9aed46f6045 100644
--- a/chromium/fuchsia/runners/cast/cast_component.cc
+++ b/chromium/fuchsia/runners/cast/cast_component.cc
@@ -38,21 +38,22 @@ TouchInputPolicy TouchInputPolicyFromApplicationConfig(
} // namespace
-CastComponent::CastComponent(
- CastRunner* runner,
- chromium::cast::ApplicationConfig application_config,
- std::unique_ptr<ApiBindingsClient> api_bindings_client,
- std::unique_ptr<base::fuchsia::StartupContext> context,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController>
- controller_request,
- std::unique_ptr<cr_fuchsia::AgentManager> agent_manager)
- : WebComponent(runner, std::move(context), std::move(controller_request)),
- agent_manager_(std::move(agent_manager)),
- application_config_(std::move(application_config)),
+CastComponent::CastComponentParams::CastComponentParams() = default;
+CastComponent::CastComponentParams::CastComponentParams(CastComponentParams&&) =
+ default;
+CastComponent::CastComponentParams::~CastComponentParams() = default;
+
+CastComponent::CastComponent(CastRunner* runner,
+ CastComponent::CastComponentParams params)
+ : WebComponent(runner,
+ std::move(params.startup_context),
+ std::move(params.controller_request)),
+ agent_manager_(std::move(params.agent_manager)),
+ application_config_(std::move(params.app_config)),
touch_input_policy_(
TouchInputPolicyFromApplicationConfig(application_config_)),
connector_(frame()),
- api_bindings_client_(std::move(api_bindings_client)),
+ api_bindings_client_(std::move(params.api_bindings_client)),
navigation_listener_binding_(this) {
base::AutoReset<bool> constructor_active_reset(&constructor_active_, true);
@@ -65,6 +66,11 @@ CastComponent::CastComponent(
kBindingsFailureExitCode,
fuchsia::sys::TerminationReason::INTERNAL_ERROR));
+ application_controller_ = std::make_unique<ApplicationControllerImpl>(
+ frame(), agent_manager_->ConnectToAgentService<
+ chromium::cast::ApplicationControllerReceiver>(
+ CastRunner::kAgentComponentUrl));
+
InitializeCastPlatformBindings();
}
diff --git a/chromium/fuchsia/runners/cast/cast_component.h b/chromium/fuchsia/runners/cast/cast_component.h
index a65f3b8d2d8..9b1fe7d597a 100644
--- a/chromium/fuchsia/runners/cast/cast_component.h
+++ b/chromium/fuchsia/runners/cast/cast_component.h
@@ -9,8 +9,11 @@
#include <memory>
#include "base/fuchsia/service_directory.h"
+#include "base/fuchsia/startup_context.h"
+#include "base/optional.h"
#include "fuchsia/base/agent_manager.h"
#include "fuchsia/runners/cast/api_bindings_client.h"
+#include "fuchsia/runners/cast/application_controller_impl.h"
#include "fuchsia/runners/cast/named_message_port_connector.h"
#include "fuchsia/runners/cast/touch_input_bindings.h"
#include "fuchsia/runners/common/web_component.h"
@@ -21,13 +24,23 @@ class CastRunner;
class CastComponent : public WebComponent,
public fuchsia::web::NavigationEventListener {
public:
- CastComponent(CastRunner* runner,
- chromium::cast::ApplicationConfig application_config,
- std::unique_ptr<ApiBindingsClient> bindings_manager,
- std::unique_ptr<base::fuchsia::StartupContext> startup_context,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController>
- controller_request,
- std::unique_ptr<cr_fuchsia::AgentManager> agent_manager);
+ struct CastComponentParams {
+ CastComponentParams();
+ CastComponentParams(CastComponentParams&&);
+ ~CastComponentParams();
+
+ chromium::cast::ApplicationConfigManagerPtr app_config_manager;
+ std::unique_ptr<base::fuchsia::StartupContext> startup_context;
+ std::unique_ptr<cr_fuchsia::AgentManager> agent_manager;
+ std::unique_ptr<ApiBindingsClient> api_bindings_client;
+ fidl::InterfaceRequest<fuchsia::sys::ComponentController>
+ controller_request;
+ chromium::cast::ApplicationConfig app_config;
+ fuchsia::web::AdditionalHeadersProviderPtr headers_provider;
+ base::Optional<std::vector<fuchsia::net::http::Header>> headers;
+ };
+
+ CastComponent(CastRunner* runner, CastComponentParams params);
~CastComponent() override;
private:
@@ -52,6 +65,7 @@ class CastComponent : public WebComponent,
NamedMessagePortConnector connector_;
std::unique_ptr<TouchInputBindings> touch_input_;
std::unique_ptr<ApiBindingsClient> api_bindings_client_;
+ std::unique_ptr<ApplicationControllerImpl> application_controller_;
fidl::Binding<fuchsia::web::NavigationEventListener>
navigation_listener_binding_;
diff --git a/chromium/fuchsia/runners/cast/cast_runner.cc b/chromium/fuchsia/runners/cast/cast_runner.cc
index 6f53482ebcd..a6d9368b023 100644
--- a/chromium/fuchsia/runners/cast/cast_runner.cc
+++ b/chromium/fuchsia/runners/cast/cast_runner.cc
@@ -10,29 +10,15 @@
#include <utility>
#include "base/fuchsia/fuchsia_logging.h"
-#include "base/fuchsia/startup_context.h"
#include "base/logging.h"
-#include "fuchsia/base/agent_manager.h"
-#include "fuchsia/runners/cast/cast_component.h"
#include "url/gurl.h"
-CastRunner::CastRunner(base::fuchsia::ServiceDirectory* service_directory,
+CastRunner::CastRunner(sys::OutgoingDirectory* outgoing_directory,
fuchsia::web::ContextPtr context)
- : WebContentRunner(service_directory, std::move(context)) {}
+ : WebContentRunner(outgoing_directory, std::move(context)) {}
CastRunner::~CastRunner() = default;
-struct CastRunner::PendingComponent {
- chromium::cast::ApplicationConfigManagerPtr app_config_manager;
- std::unique_ptr<base::fuchsia::StartupContext> startup_context;
- std::unique_ptr<cr_fuchsia::AgentManager> agent_manager;
- std::unique_ptr<ApiBindingsClient> bindings_manager;
- fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller_request;
- chromium::cast::ApplicationConfig app_config;
- fuchsia::web::AdditionalHeadersProviderPtr headers_provider;
- base::Optional<std::vector<fuchsia::net::http::Header>> headers;
-};
-
void CastRunner::StartComponent(
fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info,
@@ -54,7 +40,8 @@ void CastRunner::StartComponent(
// The application configuration asynchronously via the per-component
// ApplicationConfigManager, the pointer to that service must be kept live
// until the request completes, or CastRunner is deleted.
- auto pending_component = std::make_unique<PendingComponent>();
+ auto pending_component =
+ std::make_unique<CastComponent::CastComponentParams>();
pending_component->startup_context =
std::make_unique<base::fuchsia::StartupContext>(std::move(startup_info));
pending_component->agent_manager = std::make_unique<cr_fuchsia::AgentManager>(
@@ -75,7 +62,7 @@ void CastRunner::StartComponent(
fidl::InterfaceHandle<chromium::cast::ApiBindings> api_bindings_client;
pending_component->agent_manager->ConnectToAgentService(
kAgentComponentUrl, api_bindings_client.NewRequest());
- pending_component->bindings_manager = std::make_unique<ApiBindingsClient>(
+ pending_component->api_bindings_client = std::make_unique<ApiBindingsClient>(
std::move(api_bindings_client),
base::BindOnce(&CastRunner::MaybeStartComponent, base::Unretained(this),
base::Unretained(pending_component.get())));
@@ -116,12 +103,8 @@ const char CastRunner::kAgentComponentUrl[] =
"fuchsia-pkg://fuchsia.com/cast_agent#meta/cast_agent.cmx";
void CastRunner::GetConfigCallback(
- PendingComponent* pending_component,
+ CastComponent::CastComponentParams* pending_component,
chromium::cast::ApplicationConfig app_config) {
- // Ideally the PendingComponent would be move()d out of |pending_components_|
- // here, but that requires extract(), which isn't available until C++17.
- // Instead find |pending_component| and move() the individual fields out
- // before erase()ing it.
auto it = pending_components_.find(pending_component);
DCHECK(it != pending_components_.end());
@@ -137,25 +120,23 @@ void CastRunner::GetConfigCallback(
MaybeStartComponent(pending_component);
}
-void CastRunner::MaybeStartComponent(PendingComponent* pending_component) {
+void CastRunner::MaybeStartComponent(
+ CastComponent::CastComponentParams* pending_component) {
if (pending_component->app_config.IsEmpty())
return;
- if (!pending_component->bindings_manager->HasBindings())
+ if (!pending_component->api_bindings_client->HasBindings())
return;
if (!pending_component->headers.has_value())
return;
// Create a component based on the returned configuration, and pass it the
- // fields stashed in PendingComponent.
- GURL cast_app_url(pending_component->app_config.web_url());
- auto component = std::make_unique<CastComponent>(
- this, std::move(pending_component->app_config),
- std::move(pending_component->bindings_manager),
- std::move(pending_component->startup_context),
- std::move(pending_component->controller_request),
- std::move(pending_component->agent_manager));
+ // |pending_component|.
std::vector<fuchsia::net::http::Header> additional_headers =
pending_component->headers.value();
+
+ GURL cast_app_url(pending_component->app_config.web_url());
+ auto component =
+ std::make_unique<CastComponent>(this, std::move(*pending_component));
pending_components_.erase(pending_component);
component->LoadUrl(std::move(cast_app_url), std::move(additional_headers));
diff --git a/chromium/fuchsia/runners/cast/cast_runner.cmx b/chromium/fuchsia/runners/cast/cast_runner.cmx
index cdb498dd370..ddd13673854 100644
--- a/chromium/fuchsia/runners/cast/cast_runner.cmx
+++ b/chromium/fuchsia/runners/cast/cast_runner.cmx
@@ -10,10 +10,9 @@
"fuchsia.fonts.Provider",
"fuchsia.logger.LogSink",
"fuchsia.media.Audio",
- "fuchsia.media.drm.WidevineContentDecryptionModule",
+ "fuchsia.media.drm.Widevine",
"fuchsia.mediacodec.CodecFactory",
"fuchsia.net.NameLookup",
- "fuchsia.net.SocketProvider",
"fuchsia.netstack.Netstack",
"fuchsia.posix.socket.Provider",
"fuchsia.process.Launcher",
@@ -21,6 +20,7 @@
"fuchsia.ui.input.ImeService",
"fuchsia.ui.input.ImeVisibilityService",
"fuchsia.ui.scenic.Scenic",
+ "fuchsia.vulkan.loader.Loader",
"fuchsia.web.ContextProvider"
]
}
diff --git a/chromium/fuchsia/runners/cast/cast_runner.h b/chromium/fuchsia/runners/cast/cast_runner.h
index fe44c2de7e3..afbcaae63a7 100644
--- a/chromium/fuchsia/runners/cast/cast_runner.h
+++ b/chromium/fuchsia/runners/cast/cast_runner.h
@@ -14,12 +14,13 @@
#include "base/containers/unique_ptr_adapters.h"
#include "base/macros.h"
#include "fuchsia/fidl/chromium/cast/cpp/fidl.h"
+#include "fuchsia/runners/cast/cast_component.h"
#include "fuchsia/runners/common/web_content_runner.h"
// sys::Runner which instantiates Cast activities specified via cast/casts URIs.
class CastRunner : public WebContentRunner {
public:
- CastRunner(base::fuchsia::ServiceDirectory* service_directory,
+ CastRunner(sys::OutgoingDirectory* outgoing_directory,
fuchsia::web::ContextPtr context);
~CastRunner() override;
@@ -34,19 +35,20 @@ class CastRunner : public WebContentRunner {
static const char kAgentComponentUrl[];
private:
- struct PendingComponent;
-
- void GetConfigCallback(PendingComponent* pending_component,
+ void GetConfigCallback(CastComponent::CastComponentParams* pending_component,
chromium::cast::ApplicationConfig app_config);
- void GetBindingsCallback(PendingComponent* pending_component,
- std::vector<chromium::cast::ApiBinding> bindings);
+ void GetBindingsCallback(
+ CastComponent::CastComponentParams* pending_component,
+ std::vector<chromium::cast::ApiBinding> bindings);
// Starts a component once all configuration data is available.
- void MaybeStartComponent(PendingComponent* pending_component);
+ void MaybeStartComponent(
+ CastComponent::CastComponentParams* pending_component);
// Holds StartComponent() requests while the ApplicationConfig is being
// fetched from the ApplicationConfigManager.
- base::flat_set<std::unique_ptr<PendingComponent>, base::UniquePtrComparator>
+ base::flat_set<std::unique_ptr<CastComponent::CastComponentParams>,
+ base::UniquePtrComparator>
pending_components_;
DISALLOW_COPY_AND_ASSIGN(CastRunner);
diff --git a/chromium/fuchsia/runners/cast/cast_runner_integration_test.cc b/chromium/fuchsia/runners/cast/cast_runner_integration_test.cc
index ed8e8f2cb65..88a63ead670 100644
--- a/chromium/fuchsia/runners/cast/cast_runner_integration_test.cc
+++ b/chromium/fuchsia/runners/cast/cast_runner_integration_test.cc
@@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <fuchsia/modular/cpp/fidl.h>
+#include <lib/fdio/directory.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/zx/channel.h>
#include "base/fuchsia/file_utils.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/scoped_service_binding.h"
-#include "base/fuchsia/service_directory.h"
-#include "base/fuchsia/service_directory_client.h"
-#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind_test_util.h"
+#include "base/test/task_environment.h"
#include "base/test/test_timeouts.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "fuchsia/base/agent_impl.h"
@@ -21,6 +21,7 @@
#include "fuchsia/base/frame_test_util.h"
#include "fuchsia/base/mem_buffer_util.h"
#include "fuchsia/base/result_receiver.h"
+#include "fuchsia/base/string_util.h"
#include "fuchsia/base/test_navigation_listener.h"
#include "fuchsia/runners/cast/cast_runner.h"
#include "fuchsia/runners/cast/fake_application_config_manager.h"
@@ -44,15 +45,10 @@ void ComponentErrorHandler(zx_status_t status) {
ADD_FAILURE();
}
-std::vector<uint8_t> StringToUnsignedVector(base::StringPiece str) {
- const uint8_t* raw_data = reinterpret_cast<const uint8_t*>(str.data());
- return std::vector<uint8_t>(raw_data, raw_data + str.length());
-}
-
class FakeAdditionalHeadersProvider
: public fuchsia::web::AdditionalHeadersProvider {
public:
- FakeAdditionalHeadersProvider(base::fuchsia::ServiceDirectory* directory)
+ explicit FakeAdditionalHeadersProvider(sys::OutgoingDirectory* directory)
: binding_(directory, this) {}
~FakeAdditionalHeadersProvider() override = default;
@@ -60,8 +56,8 @@ class FakeAdditionalHeadersProvider
void GetHeaders(GetHeadersCallback callback) override {
std::vector<fuchsia::net::http::Header> headers;
fuchsia::net::http::Header header;
- header.name = StringToUnsignedVector("Test");
- header.value = StringToUnsignedVector("Value");
+ header.name = cr_fuchsia::StringToBytes("Test");
+ header.value = cr_fuchsia::StringToBytes("Value");
headers.push_back(std::move(header));
callback(std::move(headers), 0);
}
@@ -73,21 +69,53 @@ class FakeAdditionalHeadersProvider
DISALLOW_COPY_AND_ASSIGN(FakeAdditionalHeadersProvider);
};
+class FakeApplicationControllerReceiver
+ : public chromium::cast::ApplicationControllerReceiver {
+ public:
+ FakeApplicationControllerReceiver() = default;
+ ~FakeApplicationControllerReceiver() final = default;
+
+ chromium::cast::ApplicationController* controller() {
+ if (!controller_)
+ return nullptr;
+
+ return controller_.get();
+ }
+
+ private:
+ // chromium::cast::ApplicationControllerReceiver implementation.
+ void SetApplicationController(
+ fidl::InterfaceHandle<chromium::cast::ApplicationController> controller)
+ final {
+ controller_ = controller.Bind();
+ }
+
+ chromium::cast::ApplicationControllerPtr controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeApplicationControllerReceiver);
+};
+
class FakeComponentState : public cr_fuchsia::AgentImpl::ComponentStateBase {
public:
FakeComponentState(
base::StringPiece component_url,
chromium::cast::ApplicationConfigManager* app_config_manager,
- chromium::cast::ApiBindings* bindings_manager)
+ chromium::cast::ApiBindings* bindings_manager,
+ bool provide_controller_receiver)
: ComponentStateBase(component_url),
- app_config_binding_(service_directory(), app_config_manager),
+ app_config_binding_(outgoing_directory(), app_config_manager),
additional_headers_provider_(
std::make_unique<FakeAdditionalHeadersProvider>(
- service_directory())) {
+ outgoing_directory())) {
if (bindings_manager) {
bindings_manager_binding_ = std::make_unique<
base::fuchsia::ScopedServiceBinding<chromium::cast::ApiBindings>>(
- service_directory(), bindings_manager);
+ outgoing_directory(), bindings_manager);
+ }
+
+ if (provide_controller_receiver) {
+ controller_receiver_binding_.emplace(outgoing_directory(),
+ &controller_receiver_);
}
}
~FakeComponentState() override {
@@ -95,6 +123,10 @@ class FakeComponentState : public cr_fuchsia::AgentImpl::ComponentStateBase {
std::move(on_delete_).Run();
}
+ FakeApplicationControllerReceiver* controller_receiver() {
+ return &controller_receiver_;
+ }
+
void set_on_delete(base::OnceClosure on_delete) {
on_delete_ = std::move(on_delete);
}
@@ -107,6 +139,10 @@ class FakeComponentState : public cr_fuchsia::AgentImpl::ComponentStateBase {
base::fuchsia::ScopedServiceBinding<chromium::cast::ApiBindings>>
bindings_manager_binding_;
std::unique_ptr<FakeAdditionalHeadersProvider> additional_headers_provider_;
+ FakeApplicationControllerReceiver controller_receiver_;
+ base::Optional<base::fuchsia::ScopedServiceBinding<
+ chromium::cast::ApplicationControllerReceiver>>
+ controller_receiver_binding_;
base::OnceClosure on_delete_;
DISALLOW_COPY_AND_ASSIGN(FakeComponentState);
@@ -120,21 +156,19 @@ class CastRunnerIntegrationTest : public testing::Test {
: run_timeout_(
TestTimeouts::action_timeout(),
base::MakeExpectedNotRunClosure(FROM_HERE, "Run() timed out.")) {
- // Create a new test ServiceDirectory, and ServiceDirectoryClient connected
- // to it, for tests to use to drive the CastRunner.
- fidl::InterfaceHandle<fuchsia::io::Directory> directory;
- public_services_ = std::make_unique<base::fuchsia::ServiceDirectory>(
- directory.NewRequest());
-
// Create the CastRunner, published into |test_services_|.
+ constexpr fuchsia::web::ContextFeatureFlags kFeatures = {};
cast_runner_ = std::make_unique<CastRunner>(
- public_services_.get(), WebContentRunner::CreateIncognitoWebContext());
+ &outgoing_directory_,
+ WebContentRunner::CreateIncognitoWebContext(kFeatures));
// Connect to the CastRunner's fuchsia.sys.Runner interface.
- base::fuchsia::ServiceDirectoryClient public_directory_client(
- std::move(directory));
- cast_runner_ptr_ =
- public_directory_client.ConnectToService<fuchsia::sys::Runner>();
+ fidl::InterfaceHandle<fuchsia::io::Directory> directory;
+ outgoing_directory_.GetOrCreateDirectory("svc")->Serve(
+ fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
+ directory.NewRequest().TakeChannel());
+ sys::ServiceDirectory public_directory_client(std::move(directory));
+ cast_runner_ptr_ = public_directory_client.Connect<fuchsia::sys::Runner>();
cast_runner_ptr_.set_error_handler([](zx_status_t status) {
ZX_LOG(ERROR, status) << "CastRunner closed channel.";
ADD_FAILURE();
@@ -157,20 +191,35 @@ class CastRunnerIntegrationTest : public testing::Test {
base::StringPiece component_url) {
DCHECK(!component_state_);
- // Create a ServiceDirectory and publish the ComponentContext into it.
- fidl::InterfaceHandle<fuchsia::io::Directory> directory;
- component_services_ = std::make_unique<base::fuchsia::ServiceDirectory>(
- directory.NewRequest());
+ // Create an OutgoingDirectory and publish the ComponentContext into it.
component_context_ = std::make_unique<cr_fuchsia::FakeComponentContext>(
base::BindRepeating(&CastRunnerIntegrationTest::OnComponentConnect,
base::Unretained(this)),
- component_services_.get(), component_url);
+ &component_services_, component_url);
// Configure the Runner, including a service directory channel to publish
// services to.
+ fidl::InterfaceHandle<fuchsia::io::Directory> directory;
+ component_services_.GetOrCreateDirectory("svc")->Serve(
+ fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
+ directory.NewRequest().TakeChannel());
fuchsia::sys::StartupInfo startup_info;
startup_info.launch_info.url = component_url.as_string();
+ fidl::InterfaceHandle<fuchsia::io::Directory> outgoing_directory;
+ startup_info.launch_info.directory_request =
+ outgoing_directory.NewRequest().TakeChannel();
+
+ fidl::InterfaceHandle<::fuchsia::io::Directory> svc_directory;
+ CHECK_EQ(fdio_service_connect_at(
+ outgoing_directory.channel().get(), "svc",
+ svc_directory.NewRequest().TakeChannel().release()),
+ ZX_OK);
+
+ component_services_client_ =
+ std::make_unique<base::fuchsia::ServiceDirectoryClient>(
+ std::move(svc_directory));
+
// Place the ServiceDirectory in the |flat_namespace|.
startup_info.flat_namespace.paths.emplace_back(
base::fuchsia::kServiceDirectoryPath);
@@ -194,13 +243,16 @@ class CastRunnerIntegrationTest : public testing::Test {
base::StringPiece component_url) {
auto component_state = std::make_unique<FakeComponentState>(
component_url, &app_config_manager_,
- (provide_api_bindings_ ? &api_bindings_ : nullptr));
+ (provide_api_bindings_ ? &api_bindings_ : nullptr),
+ provide_controller_receiver_);
component_state_ = component_state.get();
return component_state;
}
const base::RunLoop::ScopedRunTimeoutForTest run_timeout_;
- base::MessageLoopForIO message_loop_;
+ base::test::TaskEnvironment task_environment_{
+ base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
+ base::test::TaskEnvironment::MainThreadType::IO};
net::EmbeddedTestServer test_server_;
// Returns fake Cast application information to the CastRunner.
@@ -208,16 +260,23 @@ class CastRunnerIntegrationTest : public testing::Test {
TestApiBindings api_bindings_;
+ // If set, publishes a ApplicationControllerReceiver service from the agent.
+ // TODO(crbug.com/953958): Remove this flag and make provisioning of the
+ // receiver service mandatory once CastAgent supports it.
+ bool provide_controller_receiver_ = true;
+
// If set, publishes an ApiBindings service from the Agent.
bool provide_api_bindings_ = true;
// Incoming service directory, ComponentContext and per-component state.
- std::unique_ptr<base::fuchsia::ServiceDirectory> component_services_;
+ sys::OutgoingDirectory component_services_;
std::unique_ptr<cr_fuchsia::FakeComponentContext> component_context_;
+ std::unique_ptr<base::fuchsia::ServiceDirectoryClient>
+ component_services_client_;
FakeComponentState* component_state_ = nullptr;
// ServiceDirectory into which the CastRunner will publish itself.
- std::unique_ptr<base::fuchsia::ServiceDirectory> public_services_;
+ sys::OutgoingDirectory outgoing_directory_;
std::unique_ptr<CastRunner> cast_runner_;
fuchsia::sys::RunnerPtr cast_runner_ptr_;
@@ -283,7 +342,8 @@ TEST_F(CastRunnerIntegrationTest, ApiBindings) {
std::vector<chromium::cast::ApiBinding> binding_list;
chromium::cast::ApiBinding echo_binding;
echo_binding.set_before_load_script(cr_fuchsia::MemBufferFromString(
- "window.echo = cast.__platform__.PortConnector.bind('echoService');"));
+ "window.echo = cast.__platform__.PortConnector.bind('echoService');",
+ "test"));
binding_list.emplace_back(std::move(echo_binding));
api_bindings_.set_bindings(std::move(binding_list));
@@ -296,7 +356,7 @@ TEST_F(CastRunnerIntegrationTest, ApiBindings) {
api_bindings_.RunUntilMessagePortReceived("echoService").Bind();
fuchsia::web::WebMessage message;
- message.set_data(cr_fuchsia::MemBufferFromString("ping"));
+ message.set_data(cr_fuchsia::MemBufferFromString("ping", "ping-msg"));
port->PostMessage(std::move(message),
[](fuchsia::web::MessagePort_PostMessage_Result result) {
EXPECT_TRUE(result.is_response());
@@ -374,4 +434,69 @@ TEST_F(CastRunnerIntegrationTest, AdditionalHeadersProvider) {
EXPECT_EQ(result->GetString(), "Value");
}
+TEST_F(CastRunnerIntegrationTest, ApplicationControllerBound) {
+ const char kCastChannelAppId[] = "00000001";
+ const char kCastChannelAppPath[] = "/defaultresponse";
+ app_config_manager_.AddAppMapping(kCastChannelAppId,
+ test_server_.GetURL(kCastChannelAppPath));
+
+ fuchsia::sys::ComponentControllerPtr component_controller =
+ StartCastComponent(base::StringPrintf("cast:%s", kCastChannelAppId));
+
+ // Spin the message loop to handle creation of the component state.
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(component_state_);
+ EXPECT_TRUE(component_state_->controller_receiver()->controller());
+}
+
+// Verify that we gracefully handle the interim case where the Agent doesn't
+// publish the ApplicationController service.
+// TODO(crbug.com/953958): Remove this test case once CastAgent provides the
+// service.
+TEST_F(CastRunnerIntegrationTest, ApplicationControllerNotSupported) {
+ const char kCastChannelAppId[] = "00000001";
+ const char kCastChannelAppPath[] = "/defaultresponse";
+
+ provide_controller_receiver_ = false;
+
+ app_config_manager_.AddAppMapping(kCastChannelAppId,
+ test_server_.GetURL(kCastChannelAppPath));
+
+ fuchsia::sys::ComponentControllerPtr component_controller =
+ StartCastComponent(base::StringPrintf("cast:%s", kCastChannelAppId));
+
+ // Spin the message loop to handle creation of the component state.
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(component_state_);
+ EXPECT_FALSE(component_state_->controller_receiver()->controller());
+}
+
+// Verify that we can connect to the Lifecycle interface and terminate the
+// component. Service connection is sent immediately after the component start
+// request, so this test also verifies that the component doesn't start handling
+// incoming service requests before the service has been published.
+TEST_F(CastRunnerIntegrationTest, Lifecycle) {
+ const char kCastChannelAppId[] = "00000001";
+ const char kCastChannelAppPath[] = "/defaultresponse";
+
+ provide_controller_receiver_ = false;
+
+ app_config_manager_.AddAppMapping(kCastChannelAppId,
+ test_server_.GetURL(kCastChannelAppPath));
+
+ fuchsia::sys::ComponentControllerPtr component_controller =
+ StartCastComponent(base::StringPrintf("cast:%s", kCastChannelAppId));
+
+ fuchsia::modular::LifecyclePtr lifecycle;
+ component_services_client_->ConnectToService(lifecycle.NewRequest());
+ lifecycle->Terminate();
+
+ base::RunLoop run_loop;
+ component_controller.set_error_handler([&run_loop](zx_status_t status) {
+ EXPECT_EQ(status, ZX_ERR_PEER_CLOSED);
+ run_loop.Quit();
+ });
+ run_loop.Run();
+}
+
} // namespace castrunner
diff --git a/chromium/fuchsia/runners/cast/fake_queryable_data.cc b/chromium/fuchsia/runners/cast/fake_queryable_data.cc
deleted file mode 100644
index 4f3758dea5a..00000000000
--- a/chromium/fuchsia/runners/cast/fake_queryable_data.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 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 "fuchsia/runners/cast/fake_queryable_data.h"
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/json/json_writer.h"
-
-FakeQueryableData::FakeQueryableData() = default;
-
-FakeQueryableData::~FakeQueryableData() = default;
-
-void FakeQueryableData::SendChanges(
- std::vector<std::pair<base::StringPiece, base::Value&&>> changes) {
- for (const auto& change : changes) {
- std::string value_json;
- CHECK(base::JSONWriter::Write(change.second, &value_json));
- changes_.push_back({change.first.as_string(), value_json});
- }
-
- if (get_changed_callback_)
- DeliverChanges();
-}
-
-void FakeQueryableData::GetChangedEntries(GetChangedEntriesCallback callback) {
- DCHECK(!get_changed_callback_);
- get_changed_callback_ = std::move(callback);
-
- if (!changes_.empty())
- DeliverChanges();
-}
-
-void FakeQueryableData::DeliverChanges() {
- (*get_changed_callback_)(std::move(changes_));
- get_changed_callback_ = base::nullopt;
-}
diff --git a/chromium/fuchsia/runners/cast/fake_queryable_data.h b/chromium/fuchsia/runners/cast/fake_queryable_data.h
deleted file mode 100644
index 1c3f14d3afa..00000000000
--- a/chromium/fuchsia/runners/cast/fake_queryable_data.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2019 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 FUCHSIA_RUNNERS_CAST_FAKE_QUERYABLE_DATA_H_
-#define FUCHSIA_RUNNERS_CAST_FAKE_QUERYABLE_DATA_H_
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/optional.h"
-#include "base/strings/string_piece.h"
-#include "base/values.h"
-#include "fuchsia/fidl/chromium/cast/cpp/fidl.h"
-
-// A simple STL map-backed implementation of QueryableData, for testing
-// purposes.
-class FakeQueryableData : public chromium::cast::QueryableData {
- public:
- FakeQueryableData();
- ~FakeQueryableData() override;
-
- // Sends, or prepares to send, a set of changed values to the page.
- void SendChanges(
- std::vector<std::pair<base::StringPiece, base::Value&&>> changes);
-
- private:
- void DeliverChanges();
-
- // chromium::cast::QueryableData implementation.
- void GetChangedEntries(GetChangedEntriesCallback callback) override;
-
- base::Optional<GetChangedEntriesCallback> get_changed_callback_;
- std::vector<chromium::cast::QueryableDataEntry> changes_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeQueryableData);
-};
-
-#endif // FUCHSIA_RUNNERS_CAST_FAKE_QUERYABLE_DATA_H_
diff --git a/chromium/fuchsia/runners/cast/main.cc b/chromium/fuchsia/runners/cast/main.cc
index a4b791e7202..65c55ddc350 100644
--- a/chromium/fuchsia/runners/cast/main.cc
+++ b/chromium/fuchsia/runners/cast/main.cc
@@ -2,18 +2,31 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/fuchsia/service_directory.h"
-#include "base/fuchsia/service_directory_client.h"
+#include <lib/sys/cpp/component_context.h>
+
+#include "base/fuchsia/default_context.h"
+#include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h"
#include "fuchsia/runners/cast/cast_runner.h"
int main(int argc, char** argv) {
- base::SingleThreadTaskExecutor io_task_executor(base::MessagePump::Type::IO);
+ base::SingleThreadTaskExecutor io_task_executor(base::MessagePumpType::IO);
base::RunLoop run_loop;
- CastRunner runner(base::fuchsia::ServiceDirectory::GetDefault(),
- WebContentRunner::CreateIncognitoWebContext());
+ constexpr fuchsia::web::ContextFeatureFlags kCastRunnerFeatures =
+ fuchsia::web::ContextFeatureFlags::NETWORK |
+ fuchsia::web::ContextFeatureFlags::AUDIO |
+ fuchsia::web::ContextFeatureFlags::VULKAN |
+ fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER;
+
+ CastRunner runner(
+ base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get(),
+ WebContentRunner::CreateIncognitoWebContext(kCastRunnerFeatures));
+
+ base::fuchsia::ComponentContextForCurrentProcess()
+ ->outgoing()
+ ->ServeFromStartupInfo();
// Run until there are no Components, or the last service client channel is
// closed.
diff --git a/chromium/fuchsia/runners/cast/named_message_port_connector.cc b/chromium/fuchsia/runners/cast/named_message_port_connector.cc
index 23e106125c9..a9c5306330c 100644
--- a/chromium/fuchsia/runners/cast/named_message_port_connector.cc
+++ b/chromium/fuchsia/runners/cast/named_message_port_connector.cc
@@ -20,8 +20,8 @@
namespace {
-const char kBindingsJsPath[] =
- FILE_PATH_LITERAL("chromecast/bindings/named_message_port_connector.js");
+const char kBindingsJsPath[] = FILE_PATH_LITERAL(
+ "chromecast/bindings/resources/named_message_port_connector.js");
const char kControlPortConnectMessage[] = "cast.master.connect";
} // namespace
@@ -43,7 +43,8 @@ NamedMessagePortConnector::NamedMessagePortConnector(fuchsia::web::Frame* frame)
frame_->AddBeforeLoadJavaScript(
static_cast<uint64_t>(
CastPlatformBindingsId::NAMED_MESSAGE_PORT_CONNECTOR),
- std::move(origins), cr_fuchsia::CloneBuffer(bindings_script_),
+ std::move(origins),
+ cr_fuchsia::CloneBuffer(bindings_script_, "cast-bindings-js"),
[](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
CHECK(result.is_response()) << "Couldn't inject bindings.";
});
@@ -81,7 +82,8 @@ void NamedMessagePortConnector::OnPageLoad() {
control_port_.Unbind();
fuchsia::web::WebMessage message;
- message.set_data(cr_fuchsia::MemBufferFromString(kControlPortConnectMessage));
+ message.set_data(cr_fuchsia::MemBufferFromString(kControlPortConnectMessage,
+ "cast-connect-message"));
std::vector<fuchsia::web::OutgoingTransferable> outgoing_vector(1);
outgoing_vector[0].set_message_port(control_port_.NewRequest());
message.set_outgoing_transfer(std::move(outgoing_vector));
diff --git a/chromium/fuchsia/runners/cast/named_message_port_connector_browsertest.cc b/chromium/fuchsia/runners/cast/named_message_port_connector_browsertest.cc
index 30e702d2b41..01c9e76ef12 100644
--- a/chromium/fuchsia/runners/cast/named_message_port_connector_browsertest.cc
+++ b/chromium/fuchsia/runners/cast/named_message_port_connector_browsertest.cc
@@ -97,7 +97,7 @@ IN_PROC_BROWSER_TEST_F(NamedMessagePortConnectorTest, EndToEnd) {
fuchsia::web::MessagePortPtr message_port = message_port_receiver->Bind();
fuchsia::web::WebMessage msg;
- msg.set_data(cr_fuchsia::MemBufferFromString("ping"));
+ msg.set_data(cr_fuchsia::MemBufferFromString("ping", "test"));
cr_fuchsia::ResultReceiver<fuchsia::web::MessagePort_PostMessage_Result>
post_result;
message_port->PostMessage(
@@ -175,7 +175,7 @@ IN_PROC_BROWSER_TEST_F(NamedMessagePortConnectorTest, MultiplePorts) {
for (fuchsia::web::MessagePortPtr* port : {&port_1, &port_2}) {
fuchsia::web::WebMessage msg;
- msg.set_data(cr_fuchsia::MemBufferFromString("ping"));
+ msg.set_data(cr_fuchsia::MemBufferFromString("ping", "test"));
cr_fuchsia::ResultReceiver<fuchsia::web::MessagePort_PostMessage_Result>
post_result;
(*port)->PostMessage(std::move(msg), cr_fuchsia::CallbackToFitFunction(
diff --git a/chromium/fuchsia/runners/cast/not_implemented_api_bindings.js b/chromium/fuchsia/runners/cast/not_implemented_api_bindings.js
index debe43a23d8..c131e9b3257 100644
--- a/chromium/fuchsia/runners/cast/not_implemented_api_bindings.js
+++ b/chromium/fuchsia/runners/cast/not_implemented_api_bindings.js
@@ -58,33 +58,33 @@ if (!cast.__platform__._notImplemented) {
}
};
-
+ // TODO(b/139230885)
if (!cast.__platform__.canDisplayType) {
cast.__platform__.canDisplayType =
cast.__platform__._notImplemented('canDisplayType', true);
}
+ // TODO(b/139229713)
if (!cast.__platform__.setAssistantMessageHandler) {
cast.__platform__.setAssistantMessageHandler =
cast.__platform__._notImplemented('setAssistantMessageHandler');
}
-
if (!cast.__platform__.sendAssistantRequest) {
cast.__platform__.sendAssistantRequest =
cast.__platform__._notImplemented('sendAssistantRequest');
}
+ // TODO(b/139228475)
if (!cast.__platform__.setWindowRequestHandler) {
cast.__platform__.setWindowRequestHandler =
cast.__platform__._notImplemented('setWindowRequestHandler');
}
-
if (!cast.__platform__.takeScreenshot) {
cast.__platform__.takeScreenshot =
cast.__platform__._notImplemented('takeScreenshot');
}
-
+ // TODO(b/139232520)
if (!cast.__platform__.crypto) {
cast.__platform__.crypto = {};
@@ -124,8 +124,6 @@ if (!cast.__platform__._notImplemented) {
undefined,
cast.__platform__.ReturnType.PROMISE_REJECTED);
}
-
-
if (!cast.__platform__.cryptokeys) {
cast.__platform__.cryptokeys = {};
@@ -136,7 +134,7 @@ if (!cast.__platform__._notImplemented) {
cast.__platform__.ReturnType.PROMISE_REJECTED);
}
-
+ // TODO(b/139232101)
if (!cast.__platform__.display) {
cast.__platform__.display = {};
@@ -153,7 +151,7 @@ if (!cast.__platform__._notImplemented) {
cast.__platform__.ReturnType.PROMISE_RESOLVED);
}
-
+ // TODO(b/139232160)
if (!cast.__platform__.accessibility) {
cast.__platform__.accessibility = {};
@@ -172,7 +170,7 @@ if (!cast.__platform__._notImplemented) {
'accessibility.setMagnificationGesture');
}
-
+ // TODO(b/139229752)
if (!cast.__platform__.windowManager) {
cast.__platform__.windowManager = {};
diff --git a/chromium/fuchsia/runners/cast/not_implemented_api_bindings_browsertest.cc b/chromium/fuchsia/runners/cast/not_implemented_api_bindings_browsertest.cc
index 6d019e02a0e..d0867c56960 100644
--- a/chromium/fuchsia/runners/cast/not_implemented_api_bindings_browsertest.cc
+++ b/chromium/fuchsia/runners/cast/not_implemented_api_bindings_browsertest.cc
@@ -178,7 +178,8 @@ IN_PROC_BROWSER_TEST_F(StubBindingsTest, ApiCoverage) {
{"*"},
cr_fuchsia::MemBufferFromString(
base::StringPrintf("try { cast.__platform__.%s(); } catch {}",
- expectation.function_name.c_str())),
+ expectation.function_name.c_str()),
+ "test"),
[](fuchsia::web::Frame_ExecuteJavaScriptNoResult_Result result) {
ASSERT_TRUE(result.is_response());
});
@@ -194,7 +195,7 @@ IN_PROC_BROWSER_TEST_F(StubBindingsTest, FunctionArgumentsInLogMessage) {
frame_->ExecuteJavaScriptNoResult(
{"*"},
cr_fuchsia::MemBufferFromString(
- "cast.__platform__.sendAssistantRequest(1,2,'foo');"),
+ "cast.__platform__.sendAssistantRequest(1,2,'foo');", "test"),
[](fuchsia::web::Frame_ExecuteJavaScriptNoResult_Result result) {
ASSERT_TRUE(result.is_response());
});
diff --git a/chromium/fuchsia/runners/cast/touch_input_bindings.cc b/chromium/fuchsia/runners/cast/touch_input_bindings.cc
index ea27f6d5705..3138586401c 100644
--- a/chromium/fuchsia/runners/cast/touch_input_bindings.cc
+++ b/chromium/fuchsia/runners/cast/touch_input_bindings.cc
@@ -140,7 +140,8 @@ void TouchInputBindings::OnControlMessageReceived(
std::string response_json;
CHECK(base::JSONWriter::Write(response, &response_json));
fuchsia::web::WebMessage response_message = {};
- response_message.set_data(cr_fuchsia::MemBufferFromString(response_json));
+ response_message.set_data(cr_fuchsia::MemBufferFromString(
+ response_json, "cast-touch-message-response"));
port_->PostMessage(std::move(response_message),
[](fuchsia::web::MessagePort_PostMessage_Result result) {
LOG_IF(ERROR, result.is_err())
diff --git a/chromium/fuchsia/runners/cast/touch_input_bindings.js b/chromium/fuchsia/runners/cast/touch_input_bindings.js
index 6ab7c2d16dc..9ecd9c9f37d 100644
--- a/chromium/fuchsia/runners/cast/touch_input_bindings.js
+++ b/chromium/fuchsia/runners/cast/touch_input_bindings.js
@@ -4,70 +4,73 @@
'use strict';
-cast.__platform__.__touchInput__ = new class {
- constructor() {
- this.port_ = cast.__platform__.PortConnector.bind(
- 'cast.__platform__.__touchInput__');
+// Don't supercede an Agent-provided API function.
+if (!cast.__platform__.setTouchInputSupport) {
+ cast.__platform__.__touchInput__ = new class {
+ constructor() {
+ this.port_ = cast.__platform__.PortConnector.bind(
+ 'cast.__platform__.__touchInput__');
- this.port_.onmessage = function(message) {
- var responseParsed = JSON.parse(message.data);
- if (responseParsed) {
- this.onAck(responseParsed.requestId,
- responseParsed.displayControls);
- }
- }.bind(this);
- }
-
- // Receives an acknowledgement from the native bindings layer and relays the
- // result to the Promise.
- onAck(requestId, displayControls) {
- if (!this.pendingRequests_.hasOwnProperty(requestId)) {
- console.error('Received ack for unknown request ID: ' + requestId);
- return;
+ this.port_.onmessage = function(message) {
+ var responseParsed = JSON.parse(message.data);
+ if (responseParsed) {
+ this.onAck(responseParsed.requestId,
+ responseParsed.displayControls);
+ }
+ }.bind(this);
}
- var request = this.pendingRequests_[requestId];
- delete this.pendingRequests_[requestId];
+ // Receives an acknowledgement from the native bindings layer and relays the
+ // result to the Promise.
+ onAck(requestId, displayControls) {
+ if (!this.pendingRequests_.hasOwnProperty(requestId)) {
+ console.error('Received ack for unknown request ID: ' + requestId);
+ return;
+ }
+
+ var request = this.pendingRequests_[requestId];
+ delete this.pendingRequests_[requestId];
- if (displayControls === undefined) {
- request.reject();
- } else {
- request.resolve({'displayControls': displayControls});
+ if (displayControls === undefined) {
+ request.reject();
+ } else {
+ request.resolve({'displayControls': displayControls});
+ }
}
- }
- // Requests touch input support from the native bindings layer and returns a
- // Promise with the result.
- // If the request was successful, the Promise will be resolved with a
- // dictionary indicating whether onscreen controls should be shown for the
- // application.
- // If the request was rejected, then the Promise will be rejected.
- setTouchInputSupport(touchEnabled) {
- return new Promise((resolve, reject) => {
- var requestId = this.currentRequestId_++;
- this.pendingRequests_[requestId] = {
- 'resolve': resolve,
- 'reject': reject,
- };
- this.port_.postMessage(JSON.stringify({
- 'requestId': requestId,
- 'touchEnabled': touchEnabled,
- }));
- });
- }
+ // Requests touch input support from the native bindings layer and returns a
+ // Promise with the result.
+ // If the request was successful, the Promise will be resolved with a
+ // dictionary indicating whether onscreen controls should be shown for the
+ // application.
+ // If the request was rejected, then the Promise will be rejected.
+ setTouchInputSupport(touchEnabled) {
+ return new Promise((resolve, reject) => {
+ var requestId = this.currentRequestId_++;
+ this.pendingRequests_[requestId] = {
+ 'resolve': resolve,
+ 'reject': reject,
+ };
+ this.port_.postMessage(JSON.stringify({
+ 'requestId': requestId,
+ 'touchEnabled': touchEnabled,
+ }));
+ });
+ }
- // Port for sending requests and receiving acknowledgements with the native
- // bindings layer.
- port_ = null;
+ // Port for sending requests and receiving acknowledgements with the native
+ // bindings layer.
+ port_ = null;
- // A dictionary relating inflight request IDs to their Promise resolve/reject
- // functions.
- pendingRequests_ = {};
+ // A dictionary relating inflight request IDs to their Promise
+ // resolve/reject functions.
+ pendingRequests_ = {};
- // Unique ID of the next request.
- currentRequestId_ = 0;
-};
+ // Unique ID of the next request.
+ currentRequestId_ = 0;
+ };
-cast.__platform__.setTouchInputSupport =
- cast.__platform__.__touchInput__.setTouchInputSupport.bind(
- cast.__platform__.__touchInput__);
+ cast.__platform__.setTouchInputSupport =
+ cast.__platform__.__touchInput__.setTouchInputSupport.bind(
+ cast.__platform__.__touchInput__);
+}
diff --git a/chromium/fuchsia/runners/common/web_component.cc b/chromium/fuchsia/runners/common/web_component.cc
index b700f04768b..8cdcab7f528 100644
--- a/chromium/fuchsia/runners/common/web_component.cc
+++ b/chromium/fuchsia/runners/common/web_component.cc
@@ -8,8 +8,10 @@
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fit/function.h>
+#include <lib/sys/cpp/component_context.h>
#include <utility>
+#include "base/fuchsia/default_context.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/logging.h"
#include "fuchsia/runners/common/web_content_runner.h"
@@ -51,16 +53,16 @@ WebComponent::WebComponent(
DestroyComponent(0, fuchsia::sys::TerminationReason::EXITED);
});
- if (startup_context()->public_services()) {
- // Publish services before returning control to the message-loop, to ensure
- // that it is available before the ServiceDirectory starts processing
- // requests.
+ if (startup_context()->has_outgoing_directory_request()) {
+ // Publish outgoing services and start serving component's outgoing
+ // directory.
view_provider_binding_ = std::make_unique<
base::fuchsia::ScopedServiceBinding<fuchsia::ui::app::ViewProvider>>(
- startup_context()->public_services(), this);
+ startup_context()->component_context()->outgoing().get(), this);
lifecycle_ = std::make_unique<cr_fuchsia::LifecycleImpl>(
- startup_context_->public_services(),
+ startup_context()->component_context()->outgoing().get(),
base::BindOnce(&WebComponent::Kill, base::Unretained(this)));
+ startup_context()->ServeOutgoingDirectory();
}
}
diff --git a/chromium/fuchsia/runners/common/web_content_runner.cc b/chromium/fuchsia/runners/common/web_content_runner.cc
index 2ffe589cd95..2469821b610 100644
--- a/chromium/fuchsia/runners/common/web_content_runner.cc
+++ b/chromium/fuchsia/runners/common/web_content_runner.cc
@@ -6,16 +6,16 @@
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
+#include <lib/sys/cpp/component_context.h>
#include <utility>
#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
+#include "base/fuchsia/default_context.h"
#include "base/fuchsia/file_utils.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/scoped_service_binding.h"
-#include "base/fuchsia/service_directory.h"
-#include "base/fuchsia/service_directory_client.h"
#include "base/fuchsia/startup_context.h"
#include "base/logging.h"
#include "fuchsia/runners/buildflags.h"
@@ -32,10 +32,11 @@ fidl::InterfaceHandle<fuchsia::io::Directory> OpenDirectoryOrFail(
}
fuchsia::web::ContextPtr CreateWebContextWithDataDirectory(
- fidl::InterfaceHandle<fuchsia::io::Directory> data_directory) {
- auto web_context_provider =
- base::fuchsia::ServiceDirectoryClient::ForCurrentProcess()
- ->ConnectToService<fuchsia::web::ContextProvider>();
+ fidl::InterfaceHandle<fuchsia::io::Directory> data_directory,
+ fuchsia::web::ContextFeatureFlags features) {
+ auto web_context_provider = base::fuchsia::ComponentContextForCurrentProcess()
+ ->svc()
+ ->Connect<fuchsia::web::ContextProvider>();
fuchsia::web::CreateContextParams create_params;
@@ -45,6 +46,8 @@ fuchsia::web::ContextPtr CreateWebContextWithDataDirectory(
if (data_directory)
create_params.set_data_directory(std::move(data_directory));
+ create_params.set_features(features);
+
// Set |remote_debugging_port| on the context, if set.
if (BUILDFLAG(ENABLE_REMOTE_DEBUGGING_ON_PORT) != 0) {
create_params.set_remote_debugging_port(
@@ -66,21 +69,24 @@ fuchsia::web::ContextPtr CreateWebContextWithDataDirectory(
} // namespace
// static
-fuchsia::web::ContextPtr WebContentRunner::CreateDefaultWebContext() {
- return CreateWebContextWithDataDirectory(OpenDirectoryOrFail(
- base::FilePath(base::fuchsia::kPersistedDataDirectoryPath)));
+fuchsia::web::ContextPtr WebContentRunner::CreateDefaultWebContext(
+ fuchsia::web::ContextFeatureFlags features) {
+ return CreateWebContextWithDataDirectory(
+ OpenDirectoryOrFail(
+ base::FilePath(base::fuchsia::kPersistedDataDirectoryPath)),
+ features);
}
// static
-fuchsia::web::ContextPtr WebContentRunner::CreateIncognitoWebContext() {
+fuchsia::web::ContextPtr WebContentRunner::CreateIncognitoWebContext(
+ fuchsia::web::ContextFeatureFlags features) {
return CreateWebContextWithDataDirectory(
- fidl::InterfaceHandle<fuchsia::io::Directory>());
+ fidl::InterfaceHandle<fuchsia::io::Directory>(), features);
}
-WebContentRunner::WebContentRunner(
- base::fuchsia::ServiceDirectory* service_directory,
- fuchsia::web::ContextPtr context)
- : context_(std::move(context)), service_binding_(service_directory, this) {
+WebContentRunner::WebContentRunner(sys::OutgoingDirectory* outgoing_directory,
+ fuchsia::web::ContextPtr context)
+ : context_(std::move(context)), service_binding_(outgoing_directory, this) {
DCHECK(context_);
}
diff --git a/chromium/fuchsia/runners/common/web_content_runner.h b/chromium/fuchsia/runners/common/web_content_runner.h
index f8add75b44b..b1c6323e93e 100644
--- a/chromium/fuchsia/runners/common/web_content_runner.h
+++ b/chromium/fuchsia/runners/common/web_content_runner.h
@@ -13,7 +13,6 @@
#include "base/callback.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/fuchsia/scoped_service_binding.h"
-#include "base/fuchsia/service_directory.h"
#include "base/macros.h"
class WebComponent;
@@ -24,20 +23,22 @@ class WebContentRunner : public fuchsia::sys::Runner {
// Creates and returns a web.Context with a default path and parameters,
// and with access to the same services as this Runner. The returned binding
// is configured to exit this process on error.
- static fuchsia::web::ContextPtr CreateDefaultWebContext();
+ static fuchsia::web::ContextPtr CreateDefaultWebContext(
+ fuchsia::web::ContextFeatureFlags features);
// Creates and returns an incognito web.Context with access to the same
// services as this Runner. The returned binding is configured to exit this
// process on error.
- static fuchsia::web::ContextPtr CreateIncognitoWebContext();
+ static fuchsia::web::ContextPtr CreateIncognitoWebContext(
+ fuchsia::web::ContextFeatureFlags features);
- // |service_directory|: ServiceDirectory into which this Runner will be
+ // |outgoing_directory|: OutgoingDirectory into which this Runner will be
// published. |on_idle_closure| will be invoked when the final client of the
// published service disconnects, even if one or more Components are still
// active.
- // |content|: Context (e.g. persisted profile storage) under which all web
+ // |context|: Context (e.g. persisted profile storage) under which all web
// content launched through this Runner instance will be run.
- WebContentRunner(base::fuchsia::ServiceDirectory* service_directory,
+ WebContentRunner(sys::OutgoingDirectory* outgoing_directory,
fuchsia::web::ContextPtr context);
~WebContentRunner() override;
diff --git a/chromium/fuchsia/runners/web/main.cc b/chromium/fuchsia/runners/web/main.cc
index dd9ad4a76b3..ed0d1f75c27 100644
--- a/chromium/fuchsia/runners/web/main.cc
+++ b/chromium/fuchsia/runners/web/main.cc
@@ -2,17 +2,31 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/fuchsia/service_directory.h"
+#include <lib/sys/cpp/component_context.h>
+
+#include "base/fuchsia/default_context.h"
+#include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h"
#include "fuchsia/runners/common/web_content_runner.h"
int main(int argc, char** argv) {
- base::SingleThreadTaskExecutor io_task_executor(base::MessagePump::Type::IO);
+ base::SingleThreadTaskExecutor io_task_executor(base::MessagePumpType::IO);
base::RunLoop run_loop;
- WebContentRunner runner(base::fuchsia::ServiceDirectory::GetDefault(),
- WebContentRunner::CreateDefaultWebContext());
+ constexpr fuchsia::web::ContextFeatureFlags kWebRunnerFeatures =
+ fuchsia::web::ContextFeatureFlags::NETWORK |
+ fuchsia::web::ContextFeatureFlags::AUDIO |
+ fuchsia::web::ContextFeatureFlags::VULKAN |
+ fuchsia::web::ContextFeatureFlags::HARDWARE_VIDEO_DECODER;
+
+ WebContentRunner runner(
+ base::fuchsia::ComponentContextForCurrentProcess()->outgoing().get(),
+ WebContentRunner::CreateDefaultWebContext(kWebRunnerFeatures));
+
+ base::fuchsia::ComponentContextForCurrentProcess()
+ ->outgoing()
+ ->ServeFromStartupInfo();
// Run until there are no Components, or the last service client channel is
// closed.
diff --git a/chromium/fuchsia/runners/web/web_runner.cmx b/chromium/fuchsia/runners/web/web_runner.cmx
index 83648b53840..8acaf9a0c83 100644
--- a/chromium/fuchsia/runners/web/web_runner.cmx
+++ b/chromium/fuchsia/runners/web/web_runner.cmx
@@ -10,10 +10,9 @@
"fuchsia.fonts.Provider",
"fuchsia.logger.LogSink",
"fuchsia.media.Audio",
- "fuchsia.media.drm.WidevineContentDecryptionModule",
+ "fuchsia.media.drm.Widevine",
"fuchsia.mediacodec.CodecFactory",
"fuchsia.net.NameLookup",
- "fuchsia.net.SocketProvider",
"fuchsia.netstack.Netstack",
"fuchsia.posix.socket.Provider",
"fuchsia.process.Launcher",
@@ -21,6 +20,7 @@
"fuchsia.ui.input.ImeService",
"fuchsia.ui.input.ImeVisibilityService",
"fuchsia.ui.scenic.Scenic",
+ "fuchsia.vulkan.loader.Loader",
"fuchsia.web.ContextProvider"
]
}
diff --git a/chromium/fuchsia/runners/web/web_runner_smoke_test.cc b/chromium/fuchsia/runners/web/web_runner_smoke_test.cc
index 03d804e8da7..dadc81f3a1c 100644
--- a/chromium/fuchsia/runners/web/web_runner_smoke_test.cc
+++ b/chromium/fuchsia/runners/web/web_runner_smoke_test.cc
@@ -5,13 +5,14 @@
#include <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/modular/cpp/fidl_test_base.h>
#include <fuchsia/sys/cpp/fidl.h>
+#include <lib/sys/cpp/component_context.h>
#include "base/bind.h"
+#include "base/fuchsia/default_context.h"
#include "base/fuchsia/scoped_service_binding.h"
-#include "base/fuchsia/service_directory.h"
-#include "base/fuchsia/service_directory_client.h"
#include "base/fuchsia/service_provider_impl.h"
#include "base/test/bind_test_util.h"
+#include "base/test/task_environment.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
@@ -36,8 +37,10 @@ class WebRunnerSmokeTest : public testing::Test {
ASSERT_TRUE(test_server_.Start());
fidl::InterfaceHandle<fuchsia::io::Directory> directory;
- service_directory_ = std::make_unique<base::fuchsia::ServiceDirectory>(
- directory.NewRequest());
+ outgoing_directory_.GetOrCreateDirectory("svc")->Serve(
+ fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
+ directory.NewRequest().TakeChannel());
+
service_provider_ = std::make_unique<base::fuchsia::ServiceProviderImpl>(
std::move(directory));
}
@@ -84,9 +87,11 @@ class WebRunnerSmokeTest : public testing::Test {
bool test_html_requested_ = false;
bool test_image_requested_ = false;
- base::MessageLoopForIO message_loop_;
+ base::test::TaskEnvironment task_environment_{
+ base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
+ base::test::TaskEnvironment::MainThreadType::IO};
- std::unique_ptr<base::fuchsia::ServiceDirectory> service_directory_;
+ sys::OutgoingDirectory outgoing_directory_;
std::unique_ptr<base::fuchsia::ServiceProviderImpl> service_provider_;
net::EmbeddedTestServer test_server_;
@@ -101,8 +106,9 @@ TEST_F(WebRunnerSmokeTest, RequestHtmlAndImage) {
fuchsia::sys::LaunchInfo launch_info = LaunchInfoWithServices();
launch_info.url = test_server_.GetURL("/test.html").spec();
- auto launcher = base::fuchsia::ServiceDirectoryClient::ForCurrentProcess()
- ->ConnectToServiceSync<fuchsia::sys::Launcher>();
+ auto launcher = base::fuchsia::ComponentContextForCurrentProcess()
+ ->svc()
+ ->Connect<fuchsia::sys::Launcher>();
fuchsia::sys::ComponentControllerSyncPtr controller;
launcher->CreateComponent(std::move(launch_info), controller.NewRequest());
@@ -121,8 +127,9 @@ TEST_F(WebRunnerSmokeTest, LifecycleTerminate) {
launch_info.url = test_server_.GetURL("/test.html").spec();
launch_info.directory_request = directory.NewRequest().TakeChannel();
- auto launcher = base::fuchsia::ServiceDirectoryClient::ForCurrentProcess()
- ->ConnectToServiceSync<fuchsia::sys::Launcher>();
+ auto launcher = base::fuchsia::ComponentContextForCurrentProcess()
+ ->svc()
+ ->Connect<fuchsia::sys::Launcher>();
fuchsia::sys::ComponentControllerPtr controller;
launcher->CreateComponent(std::move(launch_info), controller.NewRequest());
@@ -151,8 +158,9 @@ TEST_F(WebRunnerSmokeTest, ComponentExitOnFrameClose) {
fuchsia::sys::LaunchInfo launch_info = LaunchInfoWithServices();
launch_info.url = test_server_.GetURL("/window_close.html").spec();
- auto launcher = base::fuchsia::ServiceDirectoryClient::ForCurrentProcess()
- ->ConnectToService<fuchsia::sys::Launcher>();
+ auto launcher = base::fuchsia::ComponentContextForCurrentProcess()
+ ->svc()
+ ->Connect<fuchsia::sys::Launcher>();
fuchsia::sys::ComponentControllerPtr controller;
launcher->CreateComponent(std::move(launch_info), controller.NewRequest());
@@ -193,12 +201,13 @@ TEST_F(WebRunnerSmokeTest, RemoveSelfFromStoryOnFrameClose) {
MockModuleContext module_context;
EXPECT_CALL(module_context, RemoveSelfFromStory);
base::fuchsia::ScopedServiceBinding<fuchsia::modular::ModuleContext> binding(
- service_directory_.get(), &module_context);
+ &outgoing_directory_, &module_context);
launch_info.additional_services->names.emplace_back(
fuchsia::modular::ModuleContext::Name_);
- auto launcher = base::fuchsia::ServiceDirectoryClient::ForCurrentProcess()
- ->ConnectToService<fuchsia::sys::Launcher>();
+ auto launcher = base::fuchsia::ComponentContextForCurrentProcess()
+ ->svc()
+ ->Connect<fuchsia::sys::Launcher>();
fuchsia::sys::ComponentControllerPtr controller;
launcher->CreateComponent(std::move(launch_info), controller.NewRequest());