summaryrefslogtreecommitdiff
path: root/chromium/fuchsia
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-09-01 11:08:40 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-01 12:16:21 +0000
commit03c549e0392f92c02536d3f86d5e1d8dfa3435ac (patch)
treefe49d170a929b34ba82cd10db1a0bd8e3760fa4b /chromium/fuchsia
parent5d013f5804a0d91fcf6c626b2d6fb6eca5c845b0 (diff)
downloadqtwebengine-chromium-03c549e0392f92c02536d3f86d5e1d8dfa3435ac.tar.gz
BASELINE: Update Chromium to 91.0.4472.160
Change-Id: I0def1f08a2412aeed79a9ab95dd50eb5c3f65f31 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/fuchsia')
-rw-r--r--chromium/fuchsia/BUILD.gn3
-rw-r--r--chromium/fuchsia/base/fake_component_context.cc3
-rw-r--r--chromium/fuchsia/base/fake_component_context.h3
-rw-r--r--chromium/fuchsia/base/init_logging.cc13
-rw-r--r--chromium/fuchsia/base/init_logging.h9
-rw-r--r--chromium/fuchsia/base/legacymetrics_client.cc116
-rw-r--r--chromium/fuchsia/base/legacymetrics_client.h25
-rw-r--r--chromium/fuchsia/base/legacymetrics_client_unittest.cc191
-rw-r--r--chromium/fuchsia/base/mem_buffer_util.cc4
-rw-r--r--chromium/fuchsia/base/mem_buffer_util.h2
-rw-r--r--chromium/fuchsia/base/message_port.cc4
-rw-r--r--chromium/fuchsia/base/test_devtools_list_fetcher.cc1
-rw-r--r--chromium/fuchsia/base/test_navigation_listener.cc63
-rw-r--r--chromium/fuchsia/base/test_navigation_listener.h19
-rw-r--r--chromium/fuchsia/engine/BUILD.gn128
-rw-r--r--chromium/fuchsia/engine/browser/accessibility_bridge.cc99
-rw-r--r--chromium/fuchsia/engine/browser/accessibility_bridge.h32
-rw-r--r--chromium/fuchsia/engine/browser/accessibility_bridge_browsertest.cc451
-rw-r--r--chromium/fuchsia/engine/browser/ax_tree_converter.cc15
-rw-r--r--chromium/fuchsia/engine/browser/ax_tree_converter.h5
-rw-r--r--chromium/fuchsia/engine/browser/ax_tree_converter_unittest.cc172
-rw-r--r--chromium/fuchsia/engine/browser/content_directory_loader_factory.cc10
-rw-r--r--chromium/fuchsia/engine/browser/content_directory_loader_factory.h1
-rw-r--r--chromium/fuchsia/engine/browser/context_impl.cc19
-rw-r--r--chromium/fuchsia/engine/browser/context_impl.h10
-rw-r--r--chromium/fuchsia/engine/browser/explicit_sites_filter_browsertest.cc2
-rw-r--r--chromium/fuchsia/engine/browser/fake_semantic_tree.cc15
-rw-r--r--chromium/fuchsia/engine/browser/fake_semantic_tree.h1
-rw-r--r--chromium/fuchsia/engine/browser/frame_impl.cc13
-rw-r--r--chromium/fuchsia/engine/browser/frame_impl.h7
-rw-r--r--chromium/fuchsia/engine/browser/frame_impl_browsertest.cc1
-rw-r--r--chromium/fuchsia/engine/browser/frame_window_tree_host.cc10
-rw-r--r--chromium/fuchsia/engine/browser/frame_window_tree_host.h1
-rw-r--r--chromium/fuchsia/engine/browser/media_player_impl.cc6
-rw-r--r--chromium/fuchsia/engine/browser/media_player_impl_unittest.cc3
-rw-r--r--chromium/fuchsia/engine/browser/navigation_controller_impl.cc8
-rw-r--r--chromium/fuchsia/engine/browser/navigation_controller_impl.h3
-rw-r--r--chromium/fuchsia/engine/browser/permissions_browsertest.cc144
-rw-r--r--chromium/fuchsia/engine/browser/theme_manager.cc1
-rw-r--r--chromium/fuchsia/engine/browser/virtual_keyboard_browsertest.cc376
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_browser_context.cc44
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_browser_context.h11
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_browser_main_parts.cc95
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_browser_main_parts.h24
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_content_browser_client.cc50
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_content_browser_client.h12
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_devtools_controller.cc99
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_permission_delegate.cc12
-rw-r--r--chromium/fuchsia/engine/browser/web_engine_permission_delegate.h15
-rw-r--r--chromium/fuchsia/engine/common/web_engine_content_client.cc2
-rw-r--r--chromium/fuchsia/engine/common/web_engine_content_client.h2
-rw-r--r--chromium/fuchsia/engine/context_provider_impl.cc1
-rw-r--r--chromium/fuchsia/engine/renderer/DEPS2
-rw-r--r--chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.cc56
-rw-r--r--chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.h4
-rw-r--r--chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.cc6
-rw-r--r--chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.h10
-rw-r--r--chromium/fuchsia/engine/web_engine_integration_test.cc33
-rw-r--r--chromium/fuchsia/engine/web_engine_integration_test_base.cc7
-rw-r--r--chromium/fuchsia/engine/web_engine_integration_tests.cmx28
-rw-r--r--chromium/fuchsia/http/BUILD.gn2
-rw-r--r--chromium/fuchsia/release/size_tests/fyi_sizes.json7
-rw-r--r--chromium/fuchsia/release/size_tests/fyi_sizes_smoketest.json12
-rw-r--r--chromium/fuchsia/release/size_tests/fyi_sizes_warning.json10
-rw-r--r--chromium/fuchsia/runners/BUILD.gn17
-rw-r--r--chromium/fuchsia/runners/cast/cast_component.cc32
-rw-r--r--chromium/fuchsia/runners/cast/cast_component.h23
-rw-r--r--chromium/fuchsia/runners/cast/cast_runner.cc98
-rw-r--r--chromium/fuchsia/runners/cast/cast_runner.cmx4
-rw-r--r--chromium/fuchsia/runners/cast/cast_runner_integration_test.cc370
-rw-r--r--chromium/fuchsia/runners/common/web_component.h2
-rw-r--r--chromium/fuchsia/runners/runners_integration_tests.test-cmx37
-rw-r--r--chromium/fuchsia/runners/web/web_runner.cmx4
73 files changed, 2201 insertions, 919 deletions
diff --git a/chromium/fuchsia/BUILD.gn b/chromium/fuchsia/BUILD.gn
index eed02881545..47057485af4 100644
--- a/chromium/fuchsia/BUILD.gn
+++ b/chromium/fuchsia/BUILD.gn
@@ -44,6 +44,9 @@ group("gn_all") {
"runners:cast_runner_unittests",
"runners:web_runner",
"//chromecast/bindings:bindings_manager_fuchsia",
+
+ # Ensure this target, which is used by cipd, is built in all configurations.
+ "//media/cdm/library_cdm/clear_key_cdm:clear_key_cdm",
]
if (is_official_build) {
diff --git a/chromium/fuchsia/base/fake_component_context.cc b/chromium/fuchsia/base/fake_component_context.cc
index 1120748dee8..3e523fc7b7f 100644
--- a/chromium/fuchsia/base/fake_component_context.cc
+++ b/chromium/fuchsia/base/fake_component_context.cc
@@ -4,8 +4,6 @@
#include "fuchsia/base/fake_component_context.h"
-#include <fuchsia/base/agent_impl.h>
-
#include <memory>
#include <string>
#include <utility>
@@ -13,6 +11,7 @@
#include "base/check.h"
#include "base/notreached.h"
#include "base/run_loop.h"
+#include "fuchsia/base/agent_impl.h"
namespace cr_fuchsia {
diff --git a/chromium/fuchsia/base/fake_component_context.h b/chromium/fuchsia/base/fake_component_context.h
index b7af7311606..35168ce126e 100644
--- a/chromium/fuchsia/base/fake_component_context.h
+++ b/chromium/fuchsia/base/fake_component_context.h
@@ -5,14 +5,15 @@
#ifndef FUCHSIA_BASE_FAKE_COMPONENT_CONTEXT_H_
#define FUCHSIA_BASE_FAKE_COMPONENT_CONTEXT_H_
-#include <fuchsia/base/agent_impl.h>
#include <fuchsia/modular/cpp/fidl_test_base.h>
+
#include <map>
#include <memory>
#include <string>
#include <utility>
#include "base/strings/string_piece.h"
+#include "fuchsia/base/agent_impl.h"
namespace cr_fuchsia {
diff --git a/chromium/fuchsia/base/init_logging.cc b/chromium/fuchsia/base/init_logging.cc
index ed0a60a099c..920cfb03add 100644
--- a/chromium/fuchsia/base/init_logging.cc
+++ b/chromium/fuchsia/base/init_logging.cc
@@ -9,6 +9,9 @@
namespace cr_fuchsia {
+// These values must match content/public/common/content_switches.cc so that
+// the values will be passed to child processes in projects that Chromium's
+// Content layer.
constexpr char kEnableLogging[] = "enable-logging";
constexpr char kLogFile[] = "log-file";
@@ -29,4 +32,14 @@ bool InitLoggingFromCommandLine(const base::CommandLine& command_line) {
return logging::InitLogging(settings);
}
+bool InitLoggingFromCommandLineDefaultingToStderrForTest(
+ base::CommandLine* command_line) {
+ // Set logging to stderr if not specified.
+ if (!command_line->HasSwitch(cr_fuchsia::kEnableLogging)) {
+ command_line->AppendSwitchNative(cr_fuchsia::kEnableLogging, "stderr");
+ }
+
+ return InitLoggingFromCommandLine(*command_line);
+}
+
} // namespace cr_fuchsia
diff --git a/chromium/fuchsia/base/init_logging.h b/chromium/fuchsia/base/init_logging.h
index c08ff6e1cdc..0eac356d653 100644
--- a/chromium/fuchsia/base/init_logging.h
+++ b/chromium/fuchsia/base/init_logging.h
@@ -11,15 +11,16 @@ class CommandLine;
namespace cr_fuchsia {
-// These are intended to match those in content_switches.cc.
-extern const char kEnableLogging[];
-extern const char kLogFile[];
-
// Configures logging for the current process based on the supplied
// |command_line|. Returns false if a logging output stream could not
// be created.
bool InitLoggingFromCommandLine(const base::CommandLine& command_line);
+// Same as InitLoggingFromCommandLine but defaults to "stderr" if the logging
+// target is not specified.
+bool InitLoggingFromCommandLineDefaultingToStderrForTest(
+ base::CommandLine* command_line);
+
} // namespace cr_fuchsia
#endif // FUCHSIA_BASE_INIT_LOGGING_H_
diff --git a/chromium/fuchsia/base/legacymetrics_client.cc b/chromium/fuchsia/base/legacymetrics_client.cc
index 431c2f73cf2..f79d4af2c33 100644
--- a/chromium/fuchsia/base/legacymetrics_client.cc
+++ b/chromium/fuchsia/base/legacymetrics_client.cc
@@ -13,6 +13,7 @@
#include <utility>
#include <vector>
+#include "base/callback_helpers.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/process_context.h"
#include "base/logging.h"
@@ -34,6 +35,35 @@ LegacyMetricsClient::~LegacyMetricsClient() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
+void LegacyMetricsClient::DisableAutoConnect() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(auto_connect_);
+ DCHECK_EQ(report_interval_, base::TimeDelta())
+ << "DisableAutoConnect() must be called before Start().";
+
+ auto_connect_ = false;
+}
+
+void LegacyMetricsClient::SetMetricsRecorder(
+ fidl::InterfaceHandle<fuchsia::legacymetrics::MetricsRecorder>
+ metrics_recorder) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(!auto_connect_);
+
+ auto weak_this = weak_factory_.GetWeakPtr();
+ ResetMetricsRecorderState();
+
+ // ResetMetricsRecorderState() may call |on_flush_complete_closures_|, which
+ // may destroy LegacyMetricsClient.
+ if (!weak_this)
+ return;
+
+ SetMetricsRecorderInternal(std::move(metrics_recorder));
+
+ if (report_interval_ > base::TimeDelta())
+ ScheduleNextReport();
+}
+
void LegacyMetricsClient::Start(base::TimeDelta report_interval) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_GT(report_interval, base::TimeDelta::FromSeconds(0));
@@ -42,7 +72,12 @@ void LegacyMetricsClient::Start(base::TimeDelta report_interval) {
user_events_recorder_ = std::make_unique<LegacyMetricsUserActionRecorder>();
report_interval_ = report_interval;
- ConnectAndStartReporting();
+
+ if (auto_connect_)
+ ConnectFromComponentContext();
+
+ if (metrics_recorder_)
+ ScheduleNextReport();
}
void LegacyMetricsClient::SetReportAdditionalMetricsCallback(
@@ -65,22 +100,36 @@ void LegacyMetricsClient::SetNotifyFlushCallback(NotifyFlushCallback callback) {
notify_flush_callback_ = std::move(callback);
}
-void LegacyMetricsClient::ConnectAndStartReporting() {
+void LegacyMetricsClient::ConnectFromComponentContext() {
DCHECK(!metrics_recorder_) << "Trying to connect when already connected.";
DVLOG(1) << "Trying to connect to MetricsRecorder service.";
- metrics_recorder_ = base::ComponentContextForProcess()
- ->svc()
- ->Connect<fuchsia::legacymetrics::MetricsRecorder>();
+ DCHECK(auto_connect_);
+
+ fidl::InterfaceHandle<fuchsia::legacymetrics::MetricsRecorder>
+ metrics_recorder;
+ base::ComponentContextForProcess()->svc()->Connect(
+ metrics_recorder.NewRequest());
+ SetMetricsRecorderInternal(std::move(metrics_recorder));
+
+ ScheduleNextReport();
+}
+
+void LegacyMetricsClient::SetMetricsRecorderInternal(
+ fidl::InterfaceHandle<fuchsia::legacymetrics::MetricsRecorder>
+ metrics_recorder) {
+ metrics_recorder_.Bind(std::move(metrics_recorder));
metrics_recorder_.set_error_handler(fit::bind_member(
this, &LegacyMetricsClient::OnMetricsRecorderDisconnected));
metrics_recorder_.events().OnCloseSoon =
fit::bind_member(this, &LegacyMetricsClient::OnCloseSoon);
- ScheduleNextReport();
}
void LegacyMetricsClient::ScheduleNextReport() {
DCHECK(!is_flushing_);
+ if (report_timer_.IsRunning())
+ return;
+
DVLOG(1) << "Scheduling next report in " << report_interval_.InSeconds()
<< "seconds.";
report_timer_.Start(FROM_HERE, report_interval_, this,
@@ -141,11 +190,11 @@ void LegacyMetricsClient::DrainBuffer() {
if (is_flushing_) {
metrics_recorder_.Unbind();
- std::move(on_flush_complete_).Run();
- } else {
- ScheduleNextReport();
+ CompleteFlush();
+ return;
}
+ ScheduleNextReport();
return;
}
@@ -172,31 +221,40 @@ void LegacyMetricsClient::DrainBuffer() {
void LegacyMetricsClient::OnMetricsRecorderDisconnected(zx_status_t status) {
ZX_LOG(ERROR, status) << "MetricsRecorder connection lost.";
- // Stop reporting metric events.
- report_timer_.AbandonAndStop();
-
- if (status == ZX_ERR_PEER_CLOSED) {
+ if (auto_connect_ && status == ZX_ERR_PEER_CLOSED) {
DVLOG(1) << "Scheduling reconnect after " << reconnect_delay_;
// Try to reconnect with exponential backoff.
reconnect_timer_.Start(FROM_HERE, reconnect_delay_, this,
- &LegacyMetricsClient::ConnectAndStartReporting);
+ &LegacyMetricsClient::ReconnectMetricsRecorder);
// Increase delay exponentially. No random jittering since we don't expect
// many clients overloading the service with simultaneous reconnections.
reconnect_delay_ = std::min(reconnect_delay_ * kReconnectBackoffFactor,
kMaxReconnectDelay);
}
+
+ ResetMetricsRecorderState();
+}
+
+void LegacyMetricsClient::ReconnectMetricsRecorder() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DVLOG(1) << __func__ << " called.";
+
+ ConnectFromComponentContext();
+ ScheduleNextReport();
}
void LegacyMetricsClient::FlushAndDisconnect(
base::OnceClosure on_flush_complete) {
DVLOG(1) << __func__ << " called.";
- DCHECK(on_flush_complete);
+
+ if (on_flush_complete)
+ on_flush_complete_closures_.push_back(std::move(on_flush_complete));
+
if (is_flushing_)
return;
- on_flush_complete_ = std::move(on_flush_complete);
report_timer_.AbandonAndStop();
is_flushing_ = true;
@@ -211,7 +269,31 @@ void LegacyMetricsClient::FlushAndDisconnect(
}
void LegacyMetricsClient::OnCloseSoon() {
- FlushAndDisconnect(base::DoNothing::Once());
+ FlushAndDisconnect(base::OnceClosure());
+}
+
+void LegacyMetricsClient::CompleteFlush() {
+ DCHECK(is_flushing_);
+
+ is_flushing_ = false;
+
+ // One of the callbacks may destroy |this|, so move them all to the stack
+ // first.
+ std::vector<base::OnceClosure> on_flush_complete_closures;
+ on_flush_complete_closures.swap(on_flush_complete_closures_);
+ for (auto& closure : on_flush_complete_closures) {
+ std::move(closure).Run();
+ }
+}
+
+void LegacyMetricsClient::ResetMetricsRecorderState() {
+ // Stop reporting metric events.
+ report_timer_.AbandonAndStop();
+
+ record_ack_pending_ = false;
+
+ if (is_flushing_)
+ CompleteFlush();
}
} // namespace cr_fuchsia
diff --git a/chromium/fuchsia/base/legacymetrics_client.h b/chromium/fuchsia/base/legacymetrics_client.h
index ce59db86134..3ed2f2f15b6 100644
--- a/chromium/fuchsia/base/legacymetrics_client.h
+++ b/chromium/fuchsia/base/legacymetrics_client.h
@@ -48,6 +48,17 @@ class LegacyMetricsClient {
explicit LegacyMetricsClient(const LegacyMetricsClient&) = delete;
LegacyMetricsClient& operator=(const LegacyMetricsClient&) = delete;
+ // Disables automatic MetricsRecorder connection. Caller will have to supply
+ // MetricsRecorder by calling SetMetricsRecorder(). Must be called before
+ // Start().
+ void DisableAutoConnect();
+
+ // Sets |metrics_recorder| to use. Should be called only after
+ // DisableAutoConnect().
+ void SetMetricsRecorder(
+ fidl::InterfaceHandle<fuchsia::legacymetrics::MetricsRecorder>
+ metrics_recorder);
+
// Starts buffering data and schedules metric reporting after every
// |report_interval|.
void Start(base::TimeDelta report_interval);
@@ -71,12 +82,18 @@ class LegacyMetricsClient {
void FlushAndDisconnect(base::OnceClosure on_flush_complete);
private:
- void ConnectAndStartReporting();
+ void ConnectFromComponentContext();
+ void SetMetricsRecorderInternal(
+ fidl::InterfaceHandle<fuchsia::legacymetrics::MetricsRecorder>
+ metrics_recorder);
void ScheduleNextReport();
void StartReport();
void Report(std::vector<fuchsia::legacymetrics::Event> additional_metrics);
void OnMetricsRecorderDisconnected(zx_status_t status);
+ void ReconnectMetricsRecorder();
void OnCloseSoon();
+ void CompleteFlush();
+ void ResetMetricsRecorderState();
// Incrementally sends the contents of |to_send_| to |metrics_recorder_|.
void DrainBuffer();
@@ -90,12 +107,14 @@ class LegacyMetricsClient {
std::vector<fuchsia::legacymetrics::Event> to_send_;
std::unique_ptr<LegacyMetricsUserActionRecorder> user_events_recorder_;
- fuchsia::legacymetrics::MetricsRecorderPtr metrics_recorder_;
+ bool auto_connect_ = true;
base::RetainingOneShotTimer reconnect_timer_;
+
+ fuchsia::legacymetrics::MetricsRecorderPtr metrics_recorder_;
base::RetainingOneShotTimer report_timer_;
SEQUENCE_CHECKER(sequence_checker_);
- base::OnceClosure on_flush_complete_;
+ std::vector<base::OnceClosure> on_flush_complete_closures_;
// Prevents use-after-free if |report_additional_callback_| is invoked after
// |this| is destroyed.
diff --git a/chromium/fuchsia/base/legacymetrics_client_unittest.cc b/chromium/fuchsia/base/legacymetrics_client_unittest.cc
index 7f0978d97dd..59bb5cf6ebf 100644
--- a/chromium/fuchsia/base/legacymetrics_client_unittest.cc
+++ b/chromium/fuchsia/base/legacymetrics_client_unittest.cc
@@ -8,6 +8,7 @@
#include <string>
#include <utility>
+#include "base/callback_helpers.h"
#include "base/fuchsia/scoped_service_binding.h"
#include "base/fuchsia/test_component_context_for_process.h"
#include "base/metrics/histogram_macros.h"
@@ -38,6 +39,8 @@ class TestMetricsRecorder
bool IsRecordInFlight() const { return ack_callback_.has_value(); }
+ bool IsEmpty() const { return recorded_events_.empty(); }
+
std::vector<fuchsia::legacymetrics::Event> WaitForEvents() {
if (recorded_events_.empty()) {
base::RunLoop run_loop;
@@ -132,6 +135,13 @@ class LegacyMetricsClientTest : public testing::Test {
EXPECT_TRUE(service_binding_->has_clients()) << "Expected delay: " << delay;
}
+ void SetMetricsRecorder() {
+ fidl::InterfaceHandle<fuchsia::legacymetrics::MetricsRecorder>
+ metrics_recorder;
+ direct_binding_.Bind(metrics_recorder.NewRequest());
+ client_.SetMetricsRecorder(std::move(metrics_recorder));
+ }
+
protected:
base::test::TaskEnvironment task_environment_;
base::TestComponentContextForProcess test_context_;
@@ -139,6 +149,9 @@ class LegacyMetricsClientTest : public testing::Test {
std::unique_ptr<base::ScopedSingleClientServiceBinding<
fuchsia::legacymetrics::MetricsRecorder>>
service_binding_;
+ fidl::Binding<fuchsia::legacymetrics::MetricsRecorder> direct_binding_{
+ &test_recorder_};
+
LegacyMetricsClient client_;
};
@@ -264,6 +277,51 @@ TEST_F(LegacyMetricsClientTest, ReconnectAfterServiceDisconnect) {
EXPECT_FALSE(service_binding_->has_clients());
task_environment_.FastForwardBy(LegacyMetricsClient::kInitialReconnectDelay);
EXPECT_TRUE(service_binding_->has_clients());
+
+ base::RecordComputedAction("foo");
+ task_environment_.FastForwardBy(kReportInterval);
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+ test_recorder_.SendAck();
+ EXPECT_FALSE(test_recorder_.IsRecordInFlight());
+}
+
+TEST_F(LegacyMetricsClientTest, ServiceDisconnectWhileRecordPending) {
+ StartClientAndExpectConnection();
+
+ base::RecordComputedAction("foo");
+ task_environment_.FastForwardBy(kReportInterval);
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+
+ DisconnectAndRestartMetricsService();
+ EXPECT_FALSE(service_binding_->has_clients());
+ test_recorder_.DropAck();
+
+ task_environment_.FastForwardBy(LegacyMetricsClient::kInitialReconnectDelay);
+ EXPECT_TRUE(service_binding_->has_clients());
+
+ base::RecordComputedAction("foo");
+ task_environment_.FastForwardBy(kReportInterval);
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+}
+
+TEST_F(LegacyMetricsClientTest, ServiceDisconnectWhileFlushing) {
+ StartClientAndExpectConnection();
+
+ base::RecordComputedAction("foo");
+ client_.FlushAndDisconnect(base::OnceClosure());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+
+ DisconnectAndRestartMetricsService();
+ test_recorder_.DropAck();
+ EXPECT_FALSE(service_binding_->has_clients());
+
+ task_environment_.FastForwardBy(LegacyMetricsClient::kInitialReconnectDelay);
+ EXPECT_TRUE(service_binding_->has_clients());
+
+ base::RecordComputedAction("foo");
+ task_environment_.FastForwardBy(kReportInterval);
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
}
TEST_F(LegacyMetricsClientTest,
@@ -494,6 +552,33 @@ TEST_F(LegacyMetricsClientTest, ExplicitFlush) {
EXPECT_TRUE(called);
}
+TEST_F(LegacyMetricsClientTest, DoubleFlush) {
+ client_.Start(kReportInterval);
+
+ base::RecordComputedAction("bar");
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(test_recorder_.IsRecordInFlight());
+
+ bool called = false;
+ client_.FlushAndDisconnect(
+ base::BindLambdaForTesting([&called] { called = true; }));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+ EXPECT_FALSE(called);
+
+ bool called2 = false;
+ client_.FlushAndDisconnect(
+ base::BindLambdaForTesting([&called2] { called2 = true; }));
+
+ test_recorder_.WaitForEvents();
+ test_recorder_.SendAck();
+ base::RunLoop().RunUntilIdle();
+
+ // Verify that both FlushAndDisconnect() callbacks were called.
+ EXPECT_TRUE(called);
+ EXPECT_TRUE(called2);
+}
+
TEST_F(LegacyMetricsClientTest, ExplicitFlushMultipleBatches) {
const size_t kSizeForMultipleBatches = LegacyMetricsClient::kMaxBatchSize * 2;
client_.Start(kReportInterval);
@@ -512,5 +597,111 @@ TEST_F(LegacyMetricsClientTest, ExplicitFlushMultipleBatches) {
EXPECT_EQ("bar", events[i].user_action_event().name());
}
+TEST_F(LegacyMetricsClientTest, UseInjectedMetricsRecorder) {
+ client_.DisableAutoConnect();
+ SetMetricsRecorder();
+
+ client_.Start(kReportInterval);
+
+ base::RecordComputedAction("bar");
+
+ task_environment_.FastForwardBy(kReportInterval);
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+
+ auto events = test_recorder_.WaitForEvents();
+ EXPECT_EQ(1u, events.size());
+ EXPECT_EQ("bar", events[0].user_action_event().name());
+
+ // Verify that /svc wasn't used.
+ EXPECT_FALSE(service_binding_->has_clients());
+
+ // Verify that LegacyMetricsClient doesn't try to reconnect after
+ // MetricsRecorder has been disconnected.
+ direct_binding_.Unbind();
+ task_environment_.FastForwardBy(LegacyMetricsClient::kInitialReconnectDelay *
+ 2);
+ EXPECT_FALSE(service_binding_->has_clients());
+}
+
+TEST_F(LegacyMetricsClientTest, UseInjectedMetricsRecorderReconnect) {
+ client_.DisableAutoConnect();
+ SetMetricsRecorder();
+
+ client_.Start(kReportInterval);
+
+ bool flush_complete = false;
+ client_.FlushAndDisconnect(
+ base::BindLambdaForTesting([&flush_complete] { flush_complete = true; }));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(flush_complete);
+
+ EXPECT_TRUE(test_recorder_.IsEmpty());
+
+ // Set recorder again and verify that it receives metrics now.
+ SetMetricsRecorder();
+
+ base::RecordComputedAction("bar");
+
+ task_environment_.FastForwardBy(kReportInterval);
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+
+ auto events = test_recorder_.WaitForEvents();
+ EXPECT_EQ(1u, events.size());
+}
+
+TEST_F(LegacyMetricsClientTest, SetMetricsRecorderDuringRecord) {
+ client_.DisableAutoConnect();
+ SetMetricsRecorder();
+
+ client_.Start(kReportInterval);
+
+ base::RecordComputedAction("bar");
+
+ task_environment_.FastForwardBy(kReportInterval);
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+ test_recorder_.DropAck();
+
+ // Set recorder again and verify that it can receive metrics.
+ SetMetricsRecorder();
+
+ base::RecordComputedAction("bar");
+
+ task_environment_.FastForwardBy(kReportInterval);
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+
+ auto events = test_recorder_.WaitForEvents();
+ EXPECT_EQ(2u, events.size());
+}
+
+TEST_F(LegacyMetricsClientTest, SetMetricsRecorderDuringFlush) {
+ client_.DisableAutoConnect();
+ SetMetricsRecorder();
+
+ client_.Start(kReportInterval);
+
+ base::RecordComputedAction("bar");
+
+ bool flush_complete = false;
+ client_.FlushAndDisconnect(
+ base::BindLambdaForTesting([&flush_complete] { flush_complete = true; }));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+ test_recorder_.DropAck();
+ EXPECT_FALSE(flush_complete);
+
+ // Set recorder again. It's expected to complete the Flush().
+ SetMetricsRecorder();
+ EXPECT_TRUE(flush_complete);
+
+ // Verify that metrics are sent to the new MetricsRecorder instance.
+ base::RecordComputedAction("bar");
+
+ task_environment_.FastForwardBy(kReportInterval);
+ EXPECT_TRUE(test_recorder_.IsRecordInFlight());
+
+ auto events = test_recorder_.WaitForEvents();
+ EXPECT_EQ(2u, events.size());
+}
+
} // namespace
} // namespace cr_fuchsia
diff --git a/chromium/fuchsia/base/mem_buffer_util.cc b/chromium/fuchsia/base/mem_buffer_util.cc
index cc448f97725..2a84d0a7c53 100644
--- a/chromium/fuchsia/base/mem_buffer_util.cc
+++ b/chromium/fuchsia/base/mem_buffer_util.cc
@@ -20,7 +20,7 @@
namespace cr_fuchsia {
bool ReadUTF8FromVMOAsUTF16(const fuchsia::mem::Buffer& buffer,
- base::string16* output) {
+ std::u16string* output) {
std::string output_utf8;
if (!StringFromMemBuffer(buffer, &output_utf8))
return false;
@@ -48,7 +48,7 @@ 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(char16_t)),
name);
}
diff --git a/chromium/fuchsia/base/mem_buffer_util.h b/chromium/fuchsia/base/mem_buffer_util.h
index fe7129f5a25..9a2b4613e35 100644
--- a/chromium/fuchsia/base/mem_buffer_util.h
+++ b/chromium/fuchsia/base/mem_buffer_util.h
@@ -19,7 +19,7 @@ namespace cr_fuchsia {
// Reads the contents of |buffer|, encoded in UTF-8, to a UTF-16 string.
// Returns |false| if |buffer| is not valid UTF-8.
bool ReadUTF8FromVMOAsUTF16(const fuchsia::mem::Buffer& buffer,
- base::string16* output);
+ std::u16string* output);
// Creates a Fuchsia memory buffer from |data|.
fuchsia::mem::Buffer MemBufferFromString(base::StringPiece data,
diff --git a/chromium/fuchsia/base/message_port.cc b/chromium/fuchsia/base/message_port.cc
index 891ec699665..c20f1378858 100644
--- a/chromium/fuchsia/base/message_port.cc
+++ b/chromium/fuchsia/base/message_port.cc
@@ -35,7 +35,7 @@ base::Optional<fuchsia::web::FrameError> BlinkMessageFromFidl(
return fuchsia::web::FrameError::NO_DATA_IN_MESSAGE;
}
- base::string16 data_utf16;
+ std::u16string data_utf16;
if (!cr_fuchsia::ReadUTF8FromVMOAsUTF16(fidl_message.data(), &data_utf16)) {
return fuchsia::web::FrameError::BUFFER_NOT_UTF8;
}
@@ -359,7 +359,7 @@ base::Optional<fuchsia::web::WebMessage> FidlWebMessageFromBlink(
blink_message.ports.clear();
}
- base::string16 data_utf16 = std::move(blink_message.data);
+ std::u16string data_utf16 = std::move(blink_message.data);
std::string data_utf8;
if (!base::UTF16ToUTF8(data_utf16.data(), data_utf16.size(), &data_utf8))
return base::nullopt;
diff --git a/chromium/fuchsia/base/test_devtools_list_fetcher.cc b/chromium/fuchsia/base/test_devtools_list_fetcher.cc
index 1969f504765..79d5bbf8170 100644
--- a/chromium/fuchsia/base/test_devtools_list_fetcher.cc
+++ b/chromium/fuchsia/base/test_devtools_list_fetcher.cc
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
diff --git a/chromium/fuchsia/base/test_navigation_listener.cc b/chromium/fuchsia/base/test_navigation_listener.cc
index f45a65fcc3f..37a3655c1ea 100644
--- a/chromium/fuchsia/base/test_navigation_listener.cc
+++ b/chromium/fuchsia/base/test_navigation_listener.cc
@@ -15,19 +15,6 @@
#include "fuchsia/base/mem_buffer_util.h"
namespace cr_fuchsia {
-namespace {
-
-void QuitRunLoopAndRunCallback(
- base::OnceClosure quit_run_loop_closure,
- TestNavigationListener::BeforeAckCallback before_ack_callback,
- const fuchsia::web::NavigationState& change,
- fuchsia::web::NavigationEventListener::OnNavigationStateChangedCallback
- ack_callback) {
- std::move(quit_run_loop_closure).Run();
- before_ack_callback.Run(change, std::move(ack_callback));
-}
-
-} // namespace
TestNavigationListener::TestNavigationListener() {
// Set up the default acknowledgement handling behavior.
@@ -41,13 +28,17 @@ void TestNavigationListener::RunUntilNavigationStateMatches(
DCHECK(before_ack_);
// Spin the runloop until the expected conditions are met.
- while (!AllFieldsMatch(expected_state)) {
- base::RunLoop run_loop;
- base::AutoReset<BeforeAckCallback> callback_setter(
- &before_ack_, base::BindRepeating(&QuitRunLoopAndRunCallback,
- run_loop.QuitClosure(), before_ack_));
- run_loop.Run();
- }
+ if (AllFieldsMatch(expected_state))
+ return;
+
+ base::RunLoop run_loop;
+ base::AutoReset<BeforeAckCallback> callback_setter(
+ &before_ack_,
+ base::BindRepeating(&TestNavigationListener::QuitLoopIfAllFieldsMatch,
+ base::Unretained(this),
+ base::Unretained(&expected_state),
+ run_loop.QuitClosure(), before_ack_));
+ run_loop.Run();
}
void TestNavigationListener::RunUntilLoaded() {
@@ -106,6 +97,16 @@ void TestNavigationListener::RunUntilUrlTitleBackForwardEquals(
RunUntilNavigationStateMatches(state);
}
+void TestNavigationListener::SetBeforeAckHook(BeforeAckCallback send_ack_cb) {
+ if (send_ack_cb) {
+ before_ack_ = send_ack_cb;
+ } else {
+ before_ack_ = base::BindRepeating(
+ [](const fuchsia::web::NavigationState&,
+ OnNavigationStateChangedCallback callback) { callback(); });
+ }
+}
+
void TestNavigationListener::OnNavigationStateChanged(
fuchsia::web::NavigationState change,
OnNavigationStateChangedCallback callback) {
@@ -172,16 +173,6 @@ void TestNavigationListener::OnNavigationStateChanged(
before_ack_.Run(change, std::move(callback));
}
-void TestNavigationListener::SetBeforeAckHook(BeforeAckCallback send_ack_cb) {
- if (send_ack_cb) {
- before_ack_ = send_ack_cb;
- } else {
- before_ack_ = base::BindRepeating(
- [](const fuchsia::web::NavigationState&,
- OnNavigationStateChangedCallback callback) { callback(); });
- }
-}
-
bool TestNavigationListener::AllFieldsMatch(
const fuchsia::web::NavigationState& expected) {
if (expected.has_url() &&
@@ -222,4 +213,16 @@ bool TestNavigationListener::AllFieldsMatch(
return true;
}
+void TestNavigationListener::QuitLoopIfAllFieldsMatch(
+ const fuchsia::web::NavigationState* expected_state,
+ base::RepeatingClosure quit_run_loop_closure,
+ TestNavigationListener::BeforeAckCallback before_ack_callback,
+ const fuchsia::web::NavigationState& change,
+ fuchsia::web::NavigationEventListener::OnNavigationStateChangedCallback
+ ack_callback) {
+ if (AllFieldsMatch(*expected_state))
+ quit_run_loop_closure.Run();
+ before_ack_callback.Run(change, std::move(ack_callback));
+}
+
} // namespace cr_fuchsia
diff --git a/chromium/fuchsia/base/test_navigation_listener.h b/chromium/fuchsia/base/test_navigation_listener.h
index 6d94d5914b6..951a722a2fe 100644
--- a/chromium/fuchsia/base/test_navigation_listener.h
+++ b/chromium/fuchsia/base/test_navigation_listener.h
@@ -25,6 +25,9 @@ class TestNavigationListener : public fuchsia::web::NavigationEventListener {
TestNavigationListener();
~TestNavigationListener() final;
+ TestNavigationListener(const TestNavigationListener&) = delete;
+ TestNavigationListener& operator=(const TestNavigationListener&) = delete;
+
// Spins a RunLoop until the navigation state of the page matches the fields
// of |expected_state| that have been set.
void RunUntilNavigationStateMatches(
@@ -78,14 +81,20 @@ class TestNavigationListener : public fuchsia::web::NavigationEventListener {
fuchsia::web::NavigationState change,
OnNavigationStateChangedCallback callback) final;
- fuchsia::web::NavigationState current_state_;
-
- BeforeAckCallback before_ack_;
-
// Compare the current state with all fields of |expected| that have been set.
bool AllFieldsMatch(const fuchsia::web::NavigationState& expected);
- DISALLOW_COPY_AND_ASSIGN(TestNavigationListener);
+ void QuitLoopIfAllFieldsMatch(
+ const fuchsia::web::NavigationState* expected_state,
+ base::RepeatingClosure quit_run_loop_closure,
+ BeforeAckCallback before_ack_callback,
+ const fuchsia::web::NavigationState& change,
+ fuchsia::web::NavigationEventListener::OnNavigationStateChangedCallback
+ ack_callback);
+
+ fuchsia::web::NavigationState current_state_;
+
+ BeforeAckCallback before_ack_;
};
} // namespace cr_fuchsia
diff --git a/chromium/fuchsia/engine/BUILD.gn b/chromium/fuchsia/engine/BUILD.gn
index 20cd491b429..32c27392368 100644
--- a/chromium/fuchsia/engine/BUILD.gn
+++ b/chromium/fuchsia/engine/BUILD.gn
@@ -62,7 +62,7 @@ repack("web_engine_pak") {
visibility = [ ":*" ]
}
-foreach(locale, locales_with_fake_bidi) {
+foreach(locale, locales_with_pseudolocales) {
repack("web_engine_locale_${locale}_pak") {
# WebEngine requires the following locale-specific resources:
# 1. Locale settings (e.g. default encoding, accept-languages per locale).
@@ -153,7 +153,7 @@ component("web_engine_core") {
# package.
deps += [ ":web_engine_pak" ]
data = [ "$root_gen_dir/common_resources.pak" ]
- foreach(locale, locales_with_fake_bidi) {
+ foreach(locale, locales_with_pseudolocales) {
deps += [ ":web_engine_locale_${locale}_pak" ]
data += [ "$root_gen_dir/locales/${locale}.pak" ]
}
@@ -283,101 +283,6 @@ _web_engine_excluded_files = [
"lib/libswiftshader_libGLESv2.so",
]
-# TODO(crbug.com/1174013): Remove exclusions when DevTools discontinues the
-# use of "data".
-# Devtools' build configuration currently generates "data" entries that
-# are inert in production but still increase the size of the production
-# package.
-_devtools_excluded_files = [
- "common/App.js",
- "common/App.js.map",
- "common/AppProvider.js",
- "common/AppProvider.js.map",
- "common/Base64.js",
- "common/Base64.js.map",
- "common/CharacterIdMap.js",
- "common/CharacterIdMap.js.map",
- "common/Color.js",
- "common/Color.js.map",
- "common/ColorUtils.js",
- "common/ColorUtils.js.map",
- "common/common.js",
- "common/Console.js",
- "common/Console.js.map",
- "common/Debouncer.js",
- "common/Debouncer.js.map",
- "common/EventTarget.js",
- "common/EventTarget.js.map",
- "common/JavaScriptMetaData.js",
- "common/JavaScriptMetaData.js.map",
- "common/Lazy.js",
- "common/Lazy.js.map",
- "common/Linkifier.js",
- "common/Linkifier.js.map",
- "common/Object.js",
- "common/Object.js.map",
- "common/ParsedURL.js",
- "common/ParsedURL.js.map",
- "common/Progress.js",
- "common/Progress.js.map",
- "common/QueryParamHandler.js",
- "common/QueryParamHandler.js.map",
- "common/ResourceType.js",
- "common/ResourceType.js.map",
- "common/Revealer.js",
- "common/Revealer.js.map",
- "common/Runnable.js",
- "common/Runnable.js.map",
- "common/SegmentedRange.js",
- "common/SegmentedRange.js.map",
- "common/SettingRegistration.js",
- "common/SettingRegistration.js.map",
- "common/Settings.js",
- "common/Settings.js.map",
- "common/SimpleHistoryManager.js",
- "common/SimpleHistoryManager.js.map",
- "common/StringOutputStream.js",
- "common/StringOutputStream.js.map",
- "common/TextDictionary.js",
- "common/TextDictionary.js.map",
- "common/Throttler.js",
- "common/Throttler.js.map",
- "common/Trie.js",
- "common/Trie.js.map",
- "common/WasmDisassembly.js",
- "common/WasmDisassembly.js.map",
- "common/Worker.js",
- "common/Worker.js.map",
- "platform/array-utilities.js",
- "platform/array-utilities.js.map",
- "platform/date-utilities.js",
- "platform/date-utilities.js.map",
- "platform/keyboard-utilities.js",
- "platform/keyboard-utilities.js.map",
- "platform/map-utilities.js",
- "platform/map-utilities.js.map",
- "platform/number-utilities.js",
- "platform/number-utilities.js.map",
- "platform/platform.js",
- "platform/set-utilities.js",
- "platform/set-utilities.js.map",
- "platform/string-utilities.js",
- "platform/string-utilities.js.map",
- "platform/typescript-utilities.js",
- "platform/typescript-utilities.js.map",
- "platform/UIString.js",
- "platform/UIString.js.map",
- "platform/utilities.js",
- "platform/utilities.js.map",
- "root/root.js",
- "root/Runtime.js",
- "root/Runtime.js.map",
-]
-foreach(excluded, _devtools_excluded_files) {
- _web_engine_excluded_files +=
- [ "third_party/devtools-frontend/src/front_end/${excluded}" ]
-}
-
# Definitions for the main web_engine package. The package contains the
# context_provider component definition, and its dependencies. An installer
# script is declared for the package, for ease of development.
@@ -456,7 +361,9 @@ test("web_engine_browsertests") {
"browser/headless_browsertest.cc",
"browser/media_browsertest.cc",
"browser/navigation_policy_browsertest.cc",
+ "browser/permissions_browsertest.cc",
"browser/theme_manager_browsertest.cc",
+ "browser/virtual_keyboard_browsertest.cc",
]
# TODO(crbug.com/1157909): Move to the list above when the bug is fixed.
@@ -483,10 +390,18 @@ test("web_engine_browsertests") {
"//testing/gmock",
"//testing/gtest",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics",
+ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.input.virtualkeyboard",
"//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
"//ui/gfx",
"//ui/ozone",
]
+ additional_manifest_fragments = [
+ "//build/config/fuchsia/test/jit_capabilities.test-cmx",
+ "//build/config/fuchsia/test/network_capabilities.test-cmx",
+ "//build/config/fuchsia/test/present_view_capabilities.test-cmx",
+ "//build/config/fuchsia/test/vulkan_capabilities.test-cmx",
+ "//build/config/fuchsia/test/web_engine_required_capabilities.test-cmx",
+ ]
}
test("web_engine_unittests") {
@@ -524,10 +439,18 @@ test("web_engine_unittests") {
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.web",
"//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
]
+ additional_manifest_fragments = [
+ "//build/config/fuchsia/test/access_test_data_dir.test-cmx",
+
+ # TODO(crbug.com/1185811): Figure out why jit_capabilities is needed.
+ "//build/config/fuchsia/test/jit_capabilities.test-cmx",
+
+ "//build/config/fuchsia/test/network_capabilities.test-cmx",
+ "//build/config/fuchsia/test/vulkan_capabilities.test-cmx",
+ ]
}
test("web_engine_integration_tests") {
- manifest = "web_engine_integration_tests.cmx"
sources = [
"test_debug_listener.cc",
"test_debug_listener.h",
@@ -555,6 +478,12 @@ test("web_engine_integration_tests") {
":web_engine",
"web_engine",
] ]
+ additional_manifest_fragments = [
+ "//build/config/fuchsia/test/network_capabilities.test-cmx",
+ "//build/config/fuchsia/test/read_debug_data.test-cmx",
+ "//build/config/fuchsia/test/vulkan_capabilities.test-cmx",
+ "//build/config/fuchsia/test/web_engine_required_capabilities.test-cmx",
+ ]
}
cr_fuchsia_package("web_engine_shell_pkg") {
@@ -581,6 +510,7 @@ fuchsia_package_runner("web_engine_shell") {
}
executable("web_engine_shell_exec") {
+ testonly = true
sources = [ "test/web_engine_shell.cc" ]
data = [ "test/shell_data" ]
@@ -594,6 +524,8 @@ executable("web_engine_shell_exec") {
"//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
"//url",
]
+
+ visibility = [ ":*" ]
}
if (is_official_build) {
diff --git a/chromium/fuchsia/engine/browser/accessibility_bridge.cc b/chromium/fuchsia/engine/browser/accessibility_bridge.cc
index f69d6835760..4c7fb5ed3da 100644
--- a/chromium/fuchsia/engine/browser/accessibility_bridge.cc
+++ b/chromium/fuchsia/engine/browser/accessibility_bridge.cc
@@ -11,6 +11,7 @@
#include "base/fuchsia/fuchsia_logging.h"
#include "base/logging.h"
+#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/accessibility/ax_action_data.h"
#include "ui/gfx/geometry/rect_conversions.h"
@@ -24,6 +25,16 @@ constexpr size_t kMaxNodesPerUpdate = 16;
// Error allowed for each edge when converting from gfx::RectF to gfx::Rect.
constexpr float kRectConversionError = 0.5;
+// Returns the id of the offset container for |node|, or the root node id if
+// |node| does not specify an offset container.
+int32_t GetOffsetContainerId(const ui::AXTree* tree,
+ const ui::AXNodeData& node_data) {
+ int32_t offset_container_id = node_data.relative_bounds.offset_container_id;
+ if (offset_container_id == -1)
+ return tree->root()->id();
+ return offset_container_id;
+}
+
} // namespace
AccessibilityBridge::AccessibilityBridge(
@@ -50,6 +61,18 @@ AccessibilityBridge::~AccessibilityBridge() {
ax_trees_.clear();
}
+void AccessibilityBridge::RemoveNodeFromOffsetMapping(
+ ui::AXTree* tree,
+ const ui::AXNodeData& node_data) {
+ auto offset_container_children_it =
+ offset_container_children_.find(std::make_pair(
+ tree->GetAXTreeID(), GetOffsetContainerId(tree, node_data)));
+ if (offset_container_children_it != offset_container_children_.end()) {
+ offset_container_children_it->second.erase(
+ std::make_pair(tree->GetAXTreeID(), node_data.id));
+ }
+}
+
void AccessibilityBridge::TryCommit() {
if (commit_inflight_ || (to_delete_.empty() && to_update_.empty()) ||
ShouldHoldCommit())
@@ -242,11 +265,60 @@ void AccessibilityBridge::OnSemanticsModeChanged(
callback();
}
+void AccessibilityBridge::OnNodeWillBeDeleted(ui::AXTree* tree,
+ ui::AXNode* node) {
+ // Remove the node from its offset container's list of children.
+ RemoveNodeFromOffsetMapping(tree, node->data());
+
+ // Also remove the mapping from deleted node to its offset children.
+ offset_container_children_.erase(
+ std::make_pair(tree->GetAXTreeID(), node->data().id));
+}
+
void AccessibilityBridge::OnNodeDeleted(ui::AXTree* tree, int32_t node_id) {
to_delete_.push_back(
id_mapper_->ToFuchsiaNodeID(tree->GetAXTreeID(), node_id, false));
}
+void AccessibilityBridge::OnNodeDataChanged(
+ ui::AXTree* tree,
+ const ui::AXNodeData& old_node_data,
+ const ui::AXNodeData& new_node_data) {
+ if (!tree)
+ return;
+
+ // If this node's bounds have changed, then we should update its offset
+ // children's transforms to reflect the new bounds.
+ auto offset_container_children_it = offset_container_children_.find(
+ std::make_pair(tree->GetAXTreeID(), old_node_data.id));
+
+ // If any descendants have this node as their offset containers, and this
+ // node's bounds have changed, then we need to update those descendants'
+ // transforms to reflect the new bounds.
+ if (offset_container_children_it != offset_container_children_.end() &&
+ old_node_data.relative_bounds.bounds !=
+ new_node_data.relative_bounds.bounds) {
+ for (auto offset_child_id : offset_container_children_it->second) {
+ auto* child_node = tree->GetFromId(offset_child_id.second);
+ if (!child_node) {
+ continue;
+ }
+
+ auto child_node_data = child_node->data();
+ to_update_.push_back(AXNodeDataToSemanticNode(
+ child_node_data, new_node_data, tree->GetAXTreeID(), false,
+ id_mapper_.get()));
+ }
+ }
+
+ // If this node's offset container has changed, then we should remove it from
+ // its old offset container's offset children.
+ if (old_node_data.relative_bounds.offset_container_id !=
+ new_node_data.relative_bounds.offset_container_id) {
+ RemoveNodeFromOffsetMapping(tree, old_node_data);
+ }
+}
+
void AccessibilityBridge::OnAtomicUpdateFinished(
ui::AXTree* tree,
bool root_changed,
@@ -266,9 +338,20 @@ void AccessibilityBridge::OnAtomicUpdateFinished(
// |to_update_| are going to be executed after |to_delete_|.
for (const ui::AXTreeObserver::Change& change : changes) {
const auto& node = change.node->data();
+
+ int32_t offset_container_id =
+ GetOffsetContainerId(tree, change.node->data());
+ const auto* container = tree->GetFromId(offset_container_id);
+ DCHECK(container);
+
+ offset_container_children_[std::make_pair(tree->GetAXTreeID(),
+ offset_container_id)]
+ .insert(std::make_pair(tree->GetAXTreeID(), node.id));
+
const bool is_root = is_main_frame_tree ? node.id == root_id_ : false;
- to_update_.push_back(AXNodeDataToSemanticNode(node, tree->GetAXTreeID(),
- is_root, id_mapper_.get()));
+ to_update_.push_back(AXNodeDataToSemanticNode(node, container->data(),
+ tree->GetAXTreeID(), is_root,
+ id_mapper_.get()));
if (node.HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId)) {
const auto child_tree_id = ui::AXTreeID::FromString(
node.GetStringAttribute(ax::mojom::StringAttribute::kChildTreeId));
@@ -298,7 +381,7 @@ float AccessibilityBridge::GetDeviceScaleFactor() {
return web_contents_->GetRenderWidgetHostView()->GetDeviceScaleFactor();
}
-const ui::AXSerializableTree* AccessibilityBridge::ax_tree_for_test() {
+ui::AXSerializableTree* AccessibilityBridge::ax_tree_for_test() {
if (ax_trees_.empty())
return nullptr;
@@ -349,8 +432,14 @@ void AccessibilityBridge::UpdateTreeConnections() {
if (kv.second.is_connected)
continue; // No work to do, trees connected and present.
- auto fuchsia_node = AXNodeDataToSemanticNode(
- ax_node->data(), parent_ax_tree_id, false, id_mapper_.get());
+ int32_t offset_container_id =
+ GetOffsetContainerId(parent_tree, ax_node->data());
+ const auto* container = parent_tree->GetFromId(offset_container_id);
+ DCHECK(container);
+
+ auto fuchsia_node =
+ AXNodeDataToSemanticNode(ax_node->data(), container->data(),
+ parent_ax_tree_id, false, id_mapper_.get());
// Now, the connection really happens:
// This node, from the parent tree, will have a child that points to the
diff --git a/chromium/fuchsia/engine/browser/accessibility_bridge.h b/chromium/fuchsia/engine/browser/accessibility_bridge.h
index 7b6973049cb..f3ec2de6ba8 100644
--- a/chromium/fuchsia/engine/browser/accessibility_bridge.h
+++ b/chromium/fuchsia/engine/browser/accessibility_bridge.h
@@ -10,8 +10,9 @@
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
-#include <base/containers/flat_map.h>
#include "base/callback.h"
+#include "base/containers/flat_map.h"
+#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/optional.h"
#include "content/public/browser/ax_event_notification_details.h"
@@ -53,7 +54,7 @@ class WEB_ENGINE_EXPORT AccessibilityBridge
AccessibilityBridge(const AccessibilityBridge&) = delete;
AccessibilityBridge& operator=(const AccessibilityBridge&) = delete;
- const ui::AXSerializableTree* ax_tree_for_test();
+ ui::AXSerializableTree* ax_tree_for_test();
void set_event_received_callback_for_test(base::OnceClosure callback) {
event_received_callback_for_test_ = std::move(callback);
@@ -67,6 +68,14 @@ class WEB_ENGINE_EXPORT AccessibilityBridge
FRIEND_TEST_ALL_PREFIXES(AccessibilityBridgeTest, OnSemanticsModeChanged);
FRIEND_TEST_ALL_PREFIXES(AccessibilityBridgeTest,
TreeModificationsAreForwarded);
+ FRIEND_TEST_ALL_PREFIXES(AccessibilityBridgeTest,
+ TransformAccountsForOffsetContainerBounds);
+ FRIEND_TEST_ALL_PREFIXES(AccessibilityBridgeTest,
+ UpdateTransformWhenContainerBoundsChange);
+ FRIEND_TEST_ALL_PREFIXES(AccessibilityBridgeTest,
+ OffsetContainerBookkeepingIsUpdated);
+
+ using AXNodeID = std::pair<ui::AXTreeID, int32_t>;
// Represents a connection between two AXTrees that are in different frames.
struct TreeConnection {
@@ -110,6 +119,11 @@ class WEB_ENGINE_EXPORT AccessibilityBridge
// in tests.
float GetDeviceScaleFactor();
+ // Helper method to remove a node id from its offset container's offset
+ // children mapping.
+ void RemoveNodeFromOffsetMapping(ui::AXTree* tree,
+ const ui::AXNodeData& node_data);
+
// content::WebContentsObserver implementation.
void AccessibilityEventReceived(
const content::AXEventNotificationDetails& details) override;
@@ -126,11 +140,15 @@ class WEB_ENGINE_EXPORT AccessibilityBridge
OnSemanticsModeChangedCallback callback) final;
// ui::AXTreeObserver implementation.
+ void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
void OnNodeDeleted(ui::AXTree* tree, int32_t node_id) override;
void OnAtomicUpdateFinished(
ui::AXTree* tree,
bool root_changed,
const std::vector<ui::AXTreeObserver::Change>& changes) override;
+ void OnNodeDataChanged(ui::AXTree* tree,
+ const ui::AXNodeData& old_node_data,
+ const ui::AXNodeData& new_node_data) override;
fuchsia::accessibility::semantics::SemanticTreePtr semantic_tree_;
fidl::Binding<fuchsia::accessibility::semantics::SemanticListener> binding_;
@@ -149,6 +167,10 @@ class WEB_ENGINE_EXPORT AccessibilityBridge
// tree.
base::flat_map<ui::AXTreeID, TreeConnection> tree_connections_;
+ // Maintain a map of callbacks as multiple hit test events can happen at
+ // once. These are keyed by the request_id field of ui::AXActionData.
+ base::flat_map<int, HitTestCallback> pending_hit_test_callbacks_;
+
// Whether semantic updates are enabled.
bool enable_semantic_updates_ = false;
@@ -157,9 +179,9 @@ class WEB_ENGINE_EXPORT AccessibilityBridge
std::vector<fuchsia::accessibility::semantics::Node> to_update_;
bool commit_inflight_ = false;
- // Maintain a map of callbacks as multiple hit test events can happen at
- // once. These are keyed by the request_id field of ui::AXActionData.
- base::flat_map<int, HitTestCallback> pending_hit_test_callbacks_;
+ // Maintain a map from AXNode IDs to a list of the AXNode IDs of descendant
+ // nodes that have the key node ID as their offset containers.
+ std::map<AXNodeID, base::flat_set<AXNodeID>> offset_container_children_;
// Run in the case of an internal error that cannot be recovered from. This
// will cause the frame |this| is owned by to be torn down.
diff --git a/chromium/fuchsia/engine/browser/accessibility_bridge_browsertest.cc b/chromium/fuchsia/engine/browser/accessibility_bridge_browsertest.cc
index 778adc27323..704e90c5be7 100644
--- a/chromium/fuchsia/engine/browser/accessibility_bridge_browsertest.cc
+++ b/chromium/fuchsia/engine/browser/accessibility_bridge_browsertest.cc
@@ -17,6 +17,7 @@
#include "fuchsia/engine/test/web_engine_browser_test.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/accessibility/ax_tree_observer.h"
#include "ui/gfx/switches.h"
#include "ui/ozone/public/ozone_switches.h"
@@ -34,6 +35,14 @@ const char kButtonName3[] = "button 3";
const char kNodeName[] = "last node";
const char kParagraphName[] = "a third paragraph";
const char kOffscreenNodeName[] = "offscreen node";
+const char kUpdate1Name[] = "update1";
+const char kUpdate2Name[] = "update2";
+const char kUpdate3Name[] = "update3";
+const char kUpdate4Name[] = "update4";
+const char kUpdate5Name[] = "update5";
+const char kUpdate6Name[] = "update6";
+const char kUpdate7Name[] = "update7";
+const char kUpdate8Name[] = "update8";
const size_t kPage1NodeCount = 29;
const size_t kPage2NodeCount = 190;
const size_t kInitialRangeValue = 51;
@@ -145,17 +154,6 @@ class AccessibilityBridgeTest : public cr_fuchsia::WebEngineBrowserTest {
navigation_listener_.RunUntilUrlAndTitleEquals(page_url, page_title);
}
- // Helper function that checks if |num_deletes|, |num_updates| and
- // |num_commits| match the ones in the FakeSemanticTree.
- void CheckCallsToFakeSemanticTree(size_t num_deletes,
- size_t num_updates,
- size_t num_commits) {
- auto* tree = semantics_manager_.semantic_tree();
- EXPECT_EQ(tree->num_delete_calls(), num_deletes);
- EXPECT_EQ(tree->num_update_calls(), num_updates);
- EXPECT_EQ(tree->num_commit_calls(), num_commits);
- }
-
protected:
fuchsia::web::FramePtr frame_ptr_;
FrameImpl* frame_impl_;
@@ -182,9 +180,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, CorrectDataSent) {
// Batching is performed when the number of nodes to send or delete exceeds the
// maximum, as set on the Fuchsia side. Check that all nodes are received by the
// Semantic Tree when batching is performed.
-// TODO(1168126): Number of commit calls is not deterministic in general,
-// leading to flakiness.
-IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, DISABLED_DataSentWithBatching) {
+IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, DataSentWithBatching) {
LoadPage(kPage2Path, kPage2Title);
// Run until we expect more than a batch's worth of nodes to be present.
@@ -194,19 +190,17 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, DISABLED_DataSentWithBatching) {
// Checks if the actual batching happened.
EXPECT_GE(semantics_manager_.semantic_tree()->num_update_calls(), 18u);
- EXPECT_EQ(semantics_manager_.semantic_tree()->num_commit_calls(), 1u);
+
+ // Checks if one or more commit calls were made to send the data.
+ EXPECT_GE(semantics_manager_.semantic_tree()->num_commit_calls(), 1u);
}
// Check that semantics information is correctly sent when navigating from page
// to page.
-// TODO(1168126): Number of commit calls is not deterministic in general,
-// leading to flakiness.
-IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
- DISABLED_NavigateFromPageToPage) {
+IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, NavigateFromPageToPage) {
LoadPage(kPage1Path, kPage1Title);
semantics_manager_.semantic_tree()->RunUntilNodeCountAtLeast(kPage1NodeCount);
- EXPECT_EQ(semantics_manager_.semantic_tree()->num_commit_calls(), 1u);
EXPECT_TRUE(
semantics_manager_.semantic_tree()->GetNodeFromLabel(kPage1Title));
@@ -217,8 +211,8 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
LoadPage(kPage2Path, kPage2Title);
- semantics_manager_.semantic_tree()->RunUntilNodeCountAtLeast(kPage2NodeCount);
- EXPECT_EQ(semantics_manager_.semantic_tree()->num_commit_calls(), 2u);
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kPage2Title);
EXPECT_TRUE(
semantics_manager_.semantic_tree()->GetNodeFromLabel(kPage2Title));
@@ -413,15 +407,10 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, DISABLED_Slider) {
// This test makes sure that when semantic updates toggle on / off / on, the
// full semantic tree is sent in the first update when back on.
-// TODO(1168126): Number of commit calls is not deterministic in general,
-// leading to flakiness.
-IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
- DISABLED_TogglesSemanticsUpdates) {
+IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, TogglesSemanticsUpdates) {
LoadPage(kPage1Path, kPage1Title);
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(1);
semantics_manager_.semantic_tree()->RunUntilNodeCountAtLeast(kPage1NodeCount);
- EXPECT_EQ(semantics_manager_.semantic_tree()->num_commit_calls(), 1u);
semantics_manager_.SetSemanticsModeEnabled(false);
base::RunLoop().RunUntilIdle();
@@ -434,7 +423,6 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
semantics_manager_.SetSemanticsModeEnabled(true);
base::RunLoop().RunUntilIdle();
semantics_manager_.semantic_tree()->RunUntilNodeCountAtLeast(kPage1NodeCount);
- EXPECT_EQ(semantics_manager_.semantic_tree()->num_commit_calls(), 2u);
ASSERT_TRUE(frame_impl_->web_contents_for_test()
->IsWebContentsOnlyAccessibilityModeForTesting());
@@ -445,15 +433,12 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
// also forward the nodes in a way that leaves the tree in the Fuchsia side in a
// valid state. Note that every time that a new tree is sent to Fuchsia, the
// FakeSemantiTree checks if the tree is valid.
-// TODO(1168126): Number of commit calls is not deterministic in general,
-// leading to flakiness.
-IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
- DISABLED_TreeModificationsAreForwarded) {
+IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, TreeModificationsAreForwarded) {
// Loads a page, so a real frame is created for this test. Then, several tree
// operations are applied on top of it, using the AXTreeID that corresponds to
// that frame.
LoadPage(kPage1Path, kPage1Title);
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(1);
+ semantics_manager_.semantic_tree()->RunUntilNodeCountAtLeast(kPage1NodeCount);
// Fetch the AXTreeID of the main frame (the page just loaded). This ID will
// be used in the operations that follow to simulate new data coming in.
@@ -472,11 +457,15 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
tree_accessibility_event.updates[0].node_id_to_clear =
bridge->ax_tree_for_test()->root()->id();
+ // Set a name in a node so we can wait for this node to appear. This pattern
+ // is used throughout this test to ensure that the new data we are waiting for
+ // arrived.
+ tree_accessibility_event.updates[0].nodes[0].SetName(kUpdate1Name);
+
bridge->AccessibilityEventReceived(tree_accessibility_event);
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(2);
- CheckCallsToFakeSemanticTree(/*num_deletes=*/1, /*num_updates=*/3,
- /*num_commits=*/2);
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate1Name);
// Adds a new node with ID 6.
// (1 (2 (3 (4 (5 6)))))
@@ -488,12 +477,12 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
update.nodes[0].child_ids.push_back(5);
update.nodes[0].child_ids.push_back(6);
update.nodes[1].id = 6;
+ update.nodes[0].SetName(kUpdate2Name);
bridge->AccessibilityEventReceived(
CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(3);
- CheckCallsToFakeSemanticTree(/*num_deletes=*/1, /*num_updates=*/4,
- /*num_commits=*/3);
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate2Name);
}
// Removes the added node 6.
@@ -507,13 +496,13 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
update.nodes[0].child_ids.push_back(5);
update.nodes[1].id = 5;
+ update.nodes[0].SetName(kUpdate3Name);
bridge->AccessibilityEventReceived(
CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(4);
- CheckCallsToFakeSemanticTree(/*num_deletes=*/2, /*num_updates=*/5,
- /*num_commits=*/4);
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate3Name);
EXPECT_EQ(semantics_manager_.semantic_tree()->tree_size(), tree_size);
}
@@ -530,13 +519,13 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
update.nodes[1].id = 4;
update.nodes[2].id = 5;
+ update.nodes[0].SetName(kUpdate4Name);
bridge->AccessibilityEventReceived(
CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(5);
- CheckCallsToFakeSemanticTree(/*num_deletes=*/2, /*num_updates=*/6,
- /*num_commits=*/5);
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate4Name);
EXPECT_EQ(semantics_manager_.semantic_tree()->tree_size(), tree_size);
}
@@ -558,13 +547,13 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
update.nodes[3].id = 4;
update.nodes[4].id = 5;
+ update.nodes[0].SetName(kUpdate5Name);
bridge->AccessibilityEventReceived(
CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(6);
- CheckCallsToFakeSemanticTree(/*num_deletes=*/2, /*num_updates=*/7,
- /*num_commits=*/6);
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate5Name);
EXPECT_EQ(semantics_manager_.semantic_tree()->tree_size(), tree_size);
}
@@ -579,13 +568,13 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
update.nodes[0].child_ids.push_back(2);
update.nodes[1].id = 2;
+ update.nodes[0].SetName(kUpdate6Name);
bridge->AccessibilityEventReceived(
CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(7);
- CheckCallsToFakeSemanticTree(/*num_deletes=*/3, /*num_updates=*/8,
- /*num_commits=*/7);
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate6Name);
EXPECT_EQ(semantics_manager_.semantic_tree()->tree_size(), 2u);
}
@@ -600,13 +589,13 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
update.nodes[0].child_ids.push_back(2);
update.nodes[1].id = 2;
+ update.nodes[0].SetName(kUpdate7Name);
bridge->AccessibilityEventReceived(
CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(8);
- CheckCallsToFakeSemanticTree(/*num_deletes=*/4, /*num_updates=*/9,
- /*num_commits=*/8);
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate7Name);
EXPECT_EQ(semantics_manager_.semantic_tree()->tree_size(), 2u);
}
@@ -618,21 +607,335 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
update.node_id_to_clear = 7;
update.nodes.resize(1);
update.nodes[0].id = 1;
+ update.nodes[0].SetName(kUpdate8Name);
bridge->AccessibilityEventReceived(
CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(9);
- CheckCallsToFakeSemanticTree(/*num_deletes=*/5, /*num_updates=*/10,
- /*num_commits=*/9);
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate8Name);
EXPECT_EQ(semantics_manager_.semantic_tree()->tree_size(), 1u);
}
}
-// TODO(crbug.com/1167266): Number of commit calls is not deterministic in
-// general, leading to flakiness. Hard-wired wait for 200ms may also lead to
-// expectations failures if the system running tests is overloaded.
-IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, DISABLED_OutOfProcessIframe) {
+// Verifies that offset container bookkeeping is updated correctly.
+IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
+ OffsetContainerBookkeepingIsUpdated) {
+ // Loads a page, so a real frame is created for this test. Then, several tree
+ // operations are applied on top of it, using the AXTreeID that corresponds to
+ // that frame.
+ LoadPage(kPage1Path, kPage1Title);
+ semantics_manager_.semantic_tree()->RunUntilNodeCountAtLeast(kPage1NodeCount);
+
+ // Fetch the AXTreeID of the main frame (the page just loaded). This ID will
+ // be used in the operations that follow to simulate new data coming in.
+ auto tree_id =
+ frame_impl_->web_contents_for_test()->GetMainFrame()->GetAXTreeID();
+
+ AccessibilityBridge* bridge = frame_impl_->accessibility_bridge_for_test();
+ size_t tree_size = 5;
+
+ // The tree has the following form: (1 (2 (3 (4 (5)))))
+ auto tree_accessibility_event = CreateTreeAccessibilityEvent(tree_size);
+ tree_accessibility_event.ax_tree_id = tree_id;
+
+ // The root of this tree needs to be cleared (because it holds the page just
+ // loaded, and we are loading something completely new).
+ tree_accessibility_event.updates[0].node_id_to_clear =
+ bridge->ax_tree_for_test()->root()->id();
+
+ // Set a name in a node so we can wait for this node to appear. This pattern
+ // is used throughout this test to ensure that the new data we are waiting for
+ // arrived.
+ tree_accessibility_event.updates[0].nodes[0].SetName(kUpdate1Name);
+
+ bridge->AccessibilityEventReceived(tree_accessibility_event);
+
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate1Name);
+
+ // Adds a new node with ID 6.
+ // (1 (2 (3 (4 (5 6)))))
+ {
+ ui::AXTreeUpdate update;
+ update.root_id = 1;
+ update.nodes.resize(2);
+ update.nodes[0].id = 4;
+ update.nodes[0].child_ids.push_back(5);
+ update.nodes[0].child_ids.push_back(6);
+ update.nodes[1].id = 6;
+ update.nodes[1].relative_bounds.offset_container_id = 3;
+ update.nodes[1].SetName(kUpdate2Name);
+
+ bridge->AccessibilityEventReceived(
+ CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate2Name);
+ }
+
+ // Then, verify that offset container bookkeeping was updated.
+ {
+ auto* tree = bridge->ax_tree_for_test();
+ auto offset_container_children_it = bridge->offset_container_children_.find(
+ std::make_pair(tree->GetAXTreeID(), 3));
+ EXPECT_NE(offset_container_children_it,
+ bridge->offset_container_children_.end());
+ const auto& offset_children = offset_container_children_it->second;
+ EXPECT_EQ(offset_children.size(), 1u);
+ EXPECT_TRUE(offset_children.count(std::make_pair(tree->GetAXTreeID(), 6)));
+ }
+
+ // Now, change node 6's offset container to be node 4.
+ {
+ ui::AXTreeUpdate update;
+ update.root_id = 1;
+ update.nodes.resize(1);
+ update.nodes[0].id = 6;
+ update.nodes[0].relative_bounds.offset_container_id = 4;
+ update.nodes[0].SetName(kUpdate3Name);
+
+ bridge->AccessibilityEventReceived(
+ CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate3Name);
+ }
+
+ // Then, verify that offset container bookkeeping was updated.
+ {
+ // Check that node 6 was deleted from node 3's offset children.
+ auto* tree = bridge->ax_tree_for_test();
+ auto offset_container_children_it = bridge->offset_container_children_.find(
+ std::make_pair(tree->GetAXTreeID(), 3));
+ EXPECT_NE(offset_container_children_it,
+ bridge->offset_container_children_.end());
+ const auto& offset_children = offset_container_children_it->second;
+ EXPECT_TRUE(offset_children.empty());
+
+ // Check that node 6 was added to node 4's offset children.
+ auto new_offset_container_children_it =
+ bridge->offset_container_children_.find(
+ std::make_pair(tree->GetAXTreeID(), 4));
+ EXPECT_NE(offset_container_children_it,
+ bridge->offset_container_children_.end());
+ const auto& new_offset_children = new_offset_container_children_it->second;
+ EXPECT_EQ(new_offset_children.size(), 1u);
+ EXPECT_TRUE(
+ new_offset_children.count(std::make_pair(tree->GetAXTreeID(), 6)));
+ }
+
+ // Removes the added node 6.
+ // (1 (2 (3 (4 (5)))))
+ {
+ ui::AXTreeUpdate update;
+ update.root_id = 1;
+ update.node_id_to_clear = 4;
+ update.nodes.resize(2);
+ update.nodes[0].id = 4;
+ update.nodes[0].child_ids.push_back(5);
+
+ update.nodes[1].id = 5;
+ update.nodes[1].SetName(kUpdate4Name);
+
+ bridge->AccessibilityEventReceived(
+ CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate4Name);
+ }
+
+ // Verify that node 6 was removed as an offset child of node 4.
+ {
+ auto* tree = bridge->ax_tree_for_test();
+ auto offset_container_children_it = bridge->offset_container_children_.find(
+ std::make_pair(tree->GetAXTreeID(), 4));
+ EXPECT_NE(offset_container_children_it,
+ bridge->offset_container_children_.end());
+ const auto& offset_children = offset_container_children_it->second;
+ EXPECT_TRUE(offset_children.empty());
+ }
+
+ // Removes node 4.
+ // (1 (2 (3 )))
+ {
+ ui::AXTreeUpdate update;
+ update.root_id = 1;
+ update.node_id_to_clear = 3;
+ update.nodes.resize(1);
+ update.nodes[0].id = 3;
+ update.nodes[0].SetName(kUpdate5Name);
+
+ bridge->AccessibilityEventReceived(
+ CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate5Name);
+ }
+
+ // Verify that node 4 was cleared from the offset children map.
+ {
+ auto* tree = bridge->ax_tree_for_test();
+ EXPECT_FALSE(bridge->offset_container_children_.count(
+ std::make_pair(tree->GetAXTreeID(), 4)));
+ }
+}
+
+// This test verifies that a node's transform includes a translation for its
+// offset container's bounds.
+IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
+ TransformAccountsForOffsetContainerBounds) {
+ // Loads a page, so a real frame is created for this test. Then, several tree
+ // operations are applied on top of it, using the AXTreeID that corresponds to
+ // that frame.
+ LoadPage(kPage1Path, kPage1Title);
+ semantics_manager_.semantic_tree()->RunUntilNodeCountAtLeast(kPage1NodeCount);
+
+ // Fetch the AXTreeID of the main frame (the page just loaded). This ID will
+ // be used in the operations that follow to simulate new data coming in.
+ auto tree_id =
+ frame_impl_->web_contents_for_test()->GetMainFrame()->GetAXTreeID();
+
+ AccessibilityBridge* bridge = frame_impl_->accessibility_bridge_for_test();
+ size_t tree_size = 5;
+
+ // The tree has the following form: (1 (2 (3 (4 (5)))))
+ auto tree_accessibility_event = CreateTreeAccessibilityEvent(tree_size);
+ tree_accessibility_event.ax_tree_id = tree_id;
+
+ // The root of this tree needs to be cleared (because it holds the page just
+ // loaded, and we are loading something completely new).
+ tree_accessibility_event.updates[0].node_id_to_clear =
+ bridge->ax_tree_for_test()->root()->id();
+
+ // Set a name in a node so we can wait for this node to appear. This pattern
+ // is used throughout this test to ensure that the new data we are waiting for
+ // arrived.
+ tree_accessibility_event.updates[0].nodes[0].SetName(kUpdate1Name);
+
+ bridge->AccessibilityEventReceived(tree_accessibility_event);
+
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate1Name);
+
+ const char kNodeName[] = "transfrom should update";
+ // Changes the bounds of node 1.
+ // (1 (2 (3 (4 (5)))))
+ ui::AXTreeUpdate update;
+ update.root_id = 1;
+ update.nodes.resize(2);
+ update.nodes[0].id = 1;
+ // Update the relative bounds of node 1, which is node 2's offset container.
+ update.nodes[0].relative_bounds.bounds = gfx::RectF(2, 3, 4, 5);
+ update.nodes[0].child_ids = {2};
+ update.nodes[0].SetName(kUpdate2Name);
+ update.nodes[1].id = 2;
+ update.nodes[1].SetName(kNodeName);
+ update.nodes[1].relative_bounds.offset_container_id = 1;
+ // Node 2 should have non-trivial relative bounds to ensure that the
+ // accessibility bridge correctly composes node 2's transform and the
+ // translation for node 1's bounds.
+ update.nodes[1].relative_bounds.bounds = gfx::RectF(10, 11, 10, 11);
+ update.nodes[1].relative_bounds.transform = std::make_unique<gfx::Transform>(
+ 5, 0, 0, 100, 0, 5, 0, 200, 0, 0, 5, 0, 0, 0, 0, 1);
+ bridge->AccessibilityEventReceived(
+ CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate2Name);
+
+ auto* tree = bridge->ax_tree_for_test();
+ auto* updated_node = tree->GetFromId(2);
+ ASSERT_TRUE(updated_node);
+
+ // Verify that the transform for the Fuchsia semantic node corresponding to
+ // node 2 reflects the new bounds of node 1.
+ fuchsia::accessibility::semantics::Node* fuchsia_node =
+ semantics_manager_.semantic_tree()->GetNodeFromLabel(kNodeName);
+ ASSERT_TRUE(fuchsia_node);
+ // A Fuchsia node's semantic transform should include an offset for its parent
+ // node as a post-translation on top of its existing transform. Therefore, the
+ // x, y, and z scale (indices 0, 5, and 10, respectively) should remain
+ // unchanged, and the x and y bounds of the offset container should be added
+ // to the node's existing translation entries (indices 12 and 13).
+ EXPECT_EQ(fuchsia_node->transform().matrix[0], 5);
+ EXPECT_EQ(fuchsia_node->transform().matrix[5], 5);
+ EXPECT_EQ(fuchsia_node->transform().matrix[10], 5);
+ EXPECT_EQ(fuchsia_node->transform().matrix[12], 102);
+ EXPECT_EQ(fuchsia_node->transform().matrix[13], 203);
+}
+
+// This test verifies that a node's transform is updated correctly when its
+// container's relative bounds change.
+// NOTE: This test is distinct from the above test case.
+IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest,
+ UpdateTransformWhenContainerBoundsChange) {
+ // Loads a page, so a real frame is created for this test. Then, several tree
+ // operations are applied on top of it, using the AXTreeID that corresponds to
+ // that frame.
+ LoadPage(kPage1Path, kPage1Title);
+ semantics_manager_.semantic_tree()->RunUntilNodeCountAtLeast(kPage1NodeCount);
+
+ // Fetch the AXTreeID of the main frame (the page just loaded). This ID will
+ // be used in the operations that follow to simulate new data coming in.
+ auto tree_id =
+ frame_impl_->web_contents_for_test()->GetMainFrame()->GetAXTreeID();
+
+ AccessibilityBridge* bridge = frame_impl_->accessibility_bridge_for_test();
+ size_t tree_size = 5;
+
+ // The tree has the following form: (1 (2 (3 (4 (5)))))
+ auto tree_accessibility_event = CreateTreeAccessibilityEvent(tree_size);
+ tree_accessibility_event.ax_tree_id = tree_id;
+
+ // The root of this tree needs to be cleared (because it holds the page just
+ // loaded, and we are loading something completely new).
+ tree_accessibility_event.updates[0].node_id_to_clear =
+ bridge->ax_tree_for_test()->root()->id();
+
+ // Set a name in a node so we can wait for this node to appear. This pattern
+ // is used throughout this test to ensure that the new data we are waiting for
+ // arrived.
+ tree_accessibility_event.updates[0].nodes[0].SetName(kUpdate1Name);
+
+ bridge->AccessibilityEventReceived(tree_accessibility_event);
+
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate1Name);
+
+ // Ensure that the accessibility bridge's offset container bookkeeping is up
+ // to date.
+ bridge->offset_container_children_[std::make_pair(tree_id, 1)].insert(
+ std::make_pair(tree_id, 2));
+
+ const char kNodeName[] = "transfrom should update";
+ // Changes the bounds of node 1.
+ // (1 (2 (3 (4 (5)))))
+ ui::AXTreeUpdate update;
+ update.root_id = 1;
+ update.nodes.resize(2);
+ update.nodes[0].id = 1;
+ // Update the relative bounds of node 1, which is node 2's offset container.
+ update.nodes[0].relative_bounds.bounds = gfx::RectF(2, 3, 4, 5);
+ update.nodes[0].child_ids = {2};
+ update.nodes[0].SetName(kUpdate2Name);
+ update.nodes[1].id = 2;
+ update.nodes[1].SetName(kNodeName);
+ bridge->AccessibilityEventReceived(
+ CreateAccessibilityEventWithUpdate(std::move(update), tree_id));
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kUpdate2Name);
+
+ // Verify that the transform for the Fuchsia semantic node corresponding to
+ // node 2 reflects the new bounds of node 1.
+ fuchsia::accessibility::semantics::Node* fuchsia_node =
+ semantics_manager_.semantic_tree()->GetNodeFromLabel(kNodeName);
+
+ // A Fuchsia node's semantic transform should include an offset for its parent
+ // node as a post-translation on top of its existing transform. Therefore, the
+ // x, y, and z scale (indices 0, 5, and 10, respectively) should remain
+ // unchanged, and the x and y bounds of the offset container should be added
+ // to the node's existing translation entries (indices 12 and 13).
+ EXPECT_EQ(fuchsia_node->transform().matrix[12], 2);
+ EXPECT_EQ(fuchsia_node->transform().matrix[13], 3);
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, OutOfProcessIframe) {
constexpr int64_t kBindingsId = 1234;
// Start a different embedded test server, and load a page on it. The URL for
@@ -657,15 +960,11 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, DISABLED_OutOfProcessIframe) {
});
LoadPage(kPageIframePath, "iframe loaded");
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(1);
-
- // Run message loop for 200ms to ensure that all AX updates from the iframes
- // are processed.
- base::RunLoop run_loop;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, run_loop.QuitClosure(),
- base::TimeDelta::FromMilliseconds(200));
- run_loop.Run();
+ // Run until the title of the iframe page is in the semantic tree. Because
+ // the iframe's semantic tree is only sent when it is connected to the parent
+ // tree, it is guaranteed that both trees will be present.
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kPage1Title);
// Two frames should be present.
int num_frames = frame_impl_->web_contents_for_test()->GetAllFrames().size();
@@ -691,7 +990,8 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, DISABLED_OutOfProcessIframe) {
CHECK(result.is_response());
});
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(4);
+ semantics_manager_.semantic_tree()->RunUntilNodeWithLabelIsInTree(
+ kPage2Title);
// check that the iframe navigated to a different page.
EXPECT_TRUE(semantics_manager_.semantic_tree()->GetNodeFromLabel(kNodeName));
@@ -704,7 +1004,12 @@ IN_PROC_BROWSER_TEST_F(AccessibilityBridgeTest, DISABLED_OutOfProcessIframe) {
// away.
LoadPage(kPage2Path, kPage2Title);
- semantics_manager_.semantic_tree()->RunUntilCommitCountIs(5);
+ // Wait for the root to be updated, which means that we navigated to a new
+ // page.
+ base::RunLoop run_loop;
+ semantics_manager_.semantic_tree()->SetNodeUpdatedCallback(
+ 0u, run_loop.QuitClosure());
+ run_loop.Run();
// We've navigated to a different page that has no iframes. Only one frame
// should be present.
diff --git a/chromium/fuchsia/engine/browser/ax_tree_converter.cc b/chromium/fuchsia/engine/browser/ax_tree_converter.cc
index 5a73bcd06f5..f315544e941 100644
--- a/chromium/fuchsia/engine/browser/ax_tree_converter.cc
+++ b/chromium/fuchsia/engine/browser/ax_tree_converter.cc
@@ -213,6 +213,7 @@ fuchsia::ui::gfx::mat4 ConvertTransform(gfx::Transform* transform) {
fuchsia::accessibility::semantics::Node AXNodeDataToSemanticNode(
const ui::AXNodeData& node,
+ const ui::AXNodeData& container_node,
const ui::AXTreeID& tree_id,
bool is_root,
NodeIDMapper* id_mapper) {
@@ -226,9 +227,19 @@ fuchsia::accessibility::semantics::Node AXNodeDataToSemanticNode(
fuchsia_node.set_child_ids(
ConvertChildIds(node.child_ids, tree_id, id_mapper));
fuchsia_node.set_location(ConvertBoundingBox(node.relative_bounds.bounds));
+ fuchsia_node.set_container_id(
+ id_mapper->ToFuchsiaNodeID(tree_id, container_node.id, false));
+
+ // The transform field must be handled carefully to account for
+ // the offsetting implied by the offset container's relative bounds.
+ gfx::Transform transform;
if (node.relative_bounds.transform) {
- fuchsia_node.set_transform(
- ConvertTransform(node.relative_bounds.transform.get()));
+ transform = *node.relative_bounds.transform;
+ }
+ transform.PostTranslate(container_node.relative_bounds.bounds.x(),
+ container_node.relative_bounds.bounds.y());
+ if (!transform.IsIdentity()) {
+ fuchsia_node.set_transform(ConvertTransform(&transform));
}
return fuchsia_node;
diff --git a/chromium/fuchsia/engine/browser/ax_tree_converter.h b/chromium/fuchsia/engine/browser/ax_tree_converter.h
index bcef03e27d6..a7ec5340e26 100644
--- a/chromium/fuchsia/engine/browser/ax_tree_converter.h
+++ b/chromium/fuchsia/engine/browser/ax_tree_converter.h
@@ -5,12 +5,12 @@
#ifndef FUCHSIA_ENGINE_BROWSER_AX_TREE_CONVERTER_H_
#define FUCHSIA_ENGINE_BROWSER_AX_TREE_CONVERTER_H_
-#include <base/containers/flat_map.h>
-#include <base/optional.h>
#include <fuchsia/accessibility/semantics/cpp/fidl.h>
#include <unordered_map>
+#include "base/containers/flat_map.h"
+#include "base/optional.h"
#include "content/public/browser/ax_event_notification_details.h"
#include "fuchsia/engine/web_engine_export.h"
@@ -65,6 +65,7 @@ class WEB_ENGINE_EXPORT NodeIDMapper {
// accepts partial updates, so |node| does not require all fields to be set.
WEB_ENGINE_EXPORT fuchsia::accessibility::semantics::Node
AXNodeDataToSemanticNode(const ui::AXNodeData& node,
+ const ui::AXNodeData& container_node,
const ui::AXTreeID& tree_id,
bool is_root,
NodeIDMapper* id_mapper);
diff --git a/chromium/fuchsia/engine/browser/ax_tree_converter_unittest.cc b/chromium/fuchsia/engine/browser/ax_tree_converter_unittest.cc
index 6c50b85deb2..d6fd990d31c 100644
--- a/chromium/fuchsia/engine/browser/ax_tree_converter_unittest.cc
+++ b/chromium/fuchsia/engine/browser/ax_tree_converter_unittest.cc
@@ -23,6 +23,7 @@ const char kLabel1[] = "label nodes, not people";
const char kLabel2[] = "fancy stickers";
const char kDescription1[] = "this node does some stuff";
const char kValue1[] = "user entered value";
+const int32_t kRootId = 182;
const int32_t kChildId1 = 23901;
const int32_t kChildId2 = 484345;
const int32_t kChildId3 = 4156877;
@@ -30,8 +31,8 @@ const int32_t kRectX = 1;
const int32_t kRectY = 2;
const int32_t kRectWidth = 7;
const int32_t kRectHeight = 8;
-const std::array<float, 16> k4DIdentityMatrix = {1, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0, 0, 0, 1};
+const std::array<float, 16> k4DIdentityMatrixWithDefaultOffset = {
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 0, 1};
class MockNodeIDMapper : public NodeIDMapper {
public:
@@ -55,7 +56,10 @@ ui::AXNodeData CreateAXNodeData(ax::mojom::Role role,
ui::AXNodeData node;
node.id = 2;
node.role = role;
- node.AddAction(action);
+ if (action != ax::mojom::Action::kNone) {
+ node.AddAction(action);
+ }
+
node.AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
static_cast<int32_t>(checked_state));
node.child_ids = child_ids;
@@ -86,6 +90,7 @@ Node CreateSemanticNode(uint32_t id,
node.set_child_ids(child_ids);
node.set_location(location);
node.set_transform(transform);
+ node.set_container_id(kRootId);
return node;
}
@@ -96,6 +101,7 @@ std::pair<ui::AXNodeData, Node> CreateSemanticNodeAllFieldsSet() {
relative_bounds.transform =
std::make_unique<gfx::Transform>(gfx::Transform::kSkipInitialization);
relative_bounds.transform->MakeIdentity();
+ relative_bounds.offset_container_id = -1;
auto ax_node_data = CreateAXNodeData(
ax::mojom::Role::kButton, ax::mojom::Action::kFocus,
std::vector<int32_t>{kChildId1, kChildId2, kChildId3}, relative_bounds,
@@ -114,7 +120,7 @@ std::pair<ui::AXNodeData, Node> CreateSemanticNodeAllFieldsSet() {
box.max =
scenic::NewVector3({kRectX + kRectWidth, kRectY + kRectHeight, 0.0f});
fuchsia::ui::gfx::Matrix4Value mat =
- scenic::NewMatrix4Value(k4DIdentityMatrix);
+ scenic::NewMatrix4Value(k4DIdentityMatrixWithDefaultOffset);
States states;
states.set_checked_state(CheckedState::MIXED);
states.set_hidden(false);
@@ -133,10 +139,24 @@ std::pair<ui::AXNodeData, Node> CreateSemanticNodeAllFieldsSet() {
class AXTreeConverterTest : public testing::Test {
public:
- AXTreeConverterTest() = default;
+ AXTreeConverterTest() {
+ ui::AXRelativeBounds relative_bounds = ui::AXRelativeBounds();
+ relative_bounds.bounds =
+ gfx::RectF(kRectX, kRectY, kRectWidth, kRectHeight);
+ root_node_data_ =
+ CreateAXNodeData(ax::mojom::Role::kNone, ax::mojom::Action::kNone,
+ std::vector<int32_t>{}, relative_bounds, "", "",
+ ax::mojom::CheckedState::kNone);
+ root_node_data_.id = kRootId;
+ }
~AXTreeConverterTest() override = default;
+ ui::AXNodeData& root_node() { return root_node_data_; }
+
DISALLOW_COPY_AND_ASSIGN(AXTreeConverterTest);
+
+ private:
+ ui::AXNodeData root_node_data_;
};
TEST_F(AXTreeConverterTest, AllFieldsSetAndEqual) {
@@ -146,10 +166,40 @@ TEST_F(AXTreeConverterTest, AllFieldsSetAndEqual) {
MockNodeIDMapper mapper;
auto converted_node = AXNodeDataToSemanticNode(
- source_node_data, ui::AXTreeID::CreateNewAXTreeID(), false, &mapper);
+ source_node_data, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false,
+ &mapper);
EXPECT_TRUE(fidl::Equals(converted_node, expected_node));
}
+TEST_F(AXTreeConverterTest, TransformAccountsForContainerOffset) {
+ ui::AXNodeData container_node_data;
+ container_node_data.id = 0;
+ container_node_data.relative_bounds = ui::AXRelativeBounds();
+ container_node_data.relative_bounds.bounds =
+ gfx::RectF(100 /* x */, 200 /* y */, 10 /* width */, 20 /* height */);
+
+ ui::AXNodeData child_node_data;
+ child_node_data.id = 1;
+ child_node_data.relative_bounds.transform = std::make_unique<gfx::Transform>(
+ 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+ MockNodeIDMapper mapper;
+ auto converted_node = AXNodeDataToSemanticNode(
+ child_node_data, container_node_data, ui::AXTreeID::CreateNewAXTreeID(),
+ false, &mapper);
+
+ Node expected_node;
+ expected_node.set_node_id(1);
+ fuchsia::ui::gfx::BoundingBox box;
+ expected_node.set_location(std::move(box));
+ // The fuchsia node transform should include a post-translation for the
+ // container node's relative bounds.
+ auto expected_transform = scenic::NewMatrix4Value(
+ {2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 100, 200, 0, 1});
+ expected_node.set_transform(expected_transform.value);
+ EXPECT_EQ(converted_node.transform().matrix,
+ expected_node.transform().matrix);
+}
+
TEST_F(AXTreeConverterTest, SomeFieldsSetAndEqual) {
ui::AXNodeData source_node_data;
source_node_data.id = 0;
@@ -162,7 +212,8 @@ TEST_F(AXTreeConverterTest, SomeFieldsSetAndEqual) {
MockNodeIDMapper mapper;
auto converted_node = AXNodeDataToSemanticNode(
- source_node_data, ui::AXTreeID::CreateNewAXTreeID(), false, &mapper);
+ source_node_data, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false,
+ &mapper);
Node expected_node;
expected_node.set_node_id(0);
@@ -178,7 +229,10 @@ TEST_F(AXTreeConverterTest, SomeFieldsSetAndEqual) {
expected_node.set_attributes(std::move(attributes));
fuchsia::ui::gfx::BoundingBox box;
expected_node.set_location(std::move(box));
-
+ expected_node.set_container_id(kRootId);
+ fuchsia::ui::gfx::Matrix4Value mat =
+ scenic::NewMatrix4Value(k4DIdentityMatrixWithDefaultOffset);
+ expected_node.set_transform(mat.value);
EXPECT_TRUE(fidl::Equals(converted_node, expected_node));
}
@@ -195,7 +249,8 @@ TEST_F(AXTreeConverterTest, FieldMismatch) {
MockNodeIDMapper mapper;
auto converted_node = AXNodeDataToSemanticNode(
- source_node_data, ui::AXTreeID::CreateNewAXTreeID(), false, &mapper);
+ source_node_data, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false,
+ &mapper);
Attributes attributes;
attributes.set_label(kLabel1);
@@ -208,7 +263,7 @@ TEST_F(AXTreeConverterTest, FieldMismatch) {
box.max =
scenic::NewVector3({kRectX + kRectWidth, kRectY + kRectHeight, 0.0f});
fuchsia::ui::gfx::Matrix4Value mat =
- scenic::NewMatrix4Value(k4DIdentityMatrix);
+ scenic::NewMatrix4Value(k4DIdentityMatrixWithDefaultOffset);
auto expected_node = CreateSemanticNode(
source_node_data.id, Role::HEADER, std::move(attributes),
std::move(states), std::vector<Action>{Action::SET_VALUE},
@@ -223,15 +278,17 @@ TEST_F(AXTreeConverterTest, FieldMismatch) {
modified_node_data.AddStringAttribute(ax::mojom::StringAttribute::kName,
kLabel2);
- converted_node = AXNodeDataToSemanticNode(
- modified_node_data, ui::AXTreeID::CreateNewAXTreeID(), false, &mapper);
+ converted_node = AXNodeDataToSemanticNode(modified_node_data, root_node(),
+ ui::AXTreeID::CreateNewAXTreeID(),
+ false, &mapper);
EXPECT_FALSE(fidl::Equals(converted_node, expected_node));
// The same as above, this time changing |child_ids|.
modified_node_data = source_node_data;
modified_node_data.child_ids = std::vector<int32_t>{};
- converted_node = AXNodeDataToSemanticNode(
- modified_node_data, ui::AXTreeID::CreateNewAXTreeID(), false, &mapper);
+ converted_node = AXNodeDataToSemanticNode(modified_node_data, root_node(),
+ ui::AXTreeID::CreateNewAXTreeID(),
+ false, &mapper);
EXPECT_FALSE(fidl::Equals(converted_node, expected_node));
}
@@ -248,7 +305,8 @@ TEST_F(AXTreeConverterTest, LocationFieldRespectsTypeInvariants) {
MockNodeIDMapper mapper;
auto converted_node = AXNodeDataToSemanticNode(
- source_node_data, ui::AXTreeID::CreateNewAXTreeID(), false, &mapper);
+ source_node_data, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false,
+ &mapper);
// The type definition of the location field requires that in order to be
// interpreted as having non-zero length in a dimension, the min must be less
@@ -272,7 +330,8 @@ TEST_F(AXTreeConverterTest, DefaultAction) {
MockNodeIDMapper mapper;
auto converted_node = AXNodeDataToSemanticNode(
- source_node_data, ui::AXTreeID::CreateNewAXTreeID(), false, &mapper);
+ source_node_data, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false,
+ &mapper);
EXPECT_TRUE(fidl::Equals(converted_node, expected_node));
}
@@ -323,58 +382,67 @@ TEST_F(AXTreeConverterTest, ConvertRoles) {
ui::AXNodeData node;
node.id = 0;
node.role = ax::mojom::Role::kButton;
- EXPECT_EQ(fuchsia::accessibility::semantics::Role::BUTTON,
- AXNodeDataToSemanticNode(node, ui::AXTreeID::CreateNewAXTreeID(),
- false, &mapper)
- .role());
+ EXPECT_EQ(
+ fuchsia::accessibility::semantics::Role::BUTTON,
+ AXNodeDataToSemanticNode(
+ node, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false, &mapper)
+ .role());
node.role = ax::mojom::Role::kCheckBox;
- EXPECT_EQ(fuchsia::accessibility::semantics::Role::CHECK_BOX,
- AXNodeDataToSemanticNode(node, ui::AXTreeID::CreateNewAXTreeID(),
- false, &mapper)
- .role());
+ EXPECT_EQ(
+ fuchsia::accessibility::semantics::Role::CHECK_BOX,
+ AXNodeDataToSemanticNode(
+ node, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false, &mapper)
+ .role());
node.role = ax::mojom::Role::kHeader;
- EXPECT_EQ(fuchsia::accessibility::semantics::Role::HEADER,
- AXNodeDataToSemanticNode(node, ui::AXTreeID::CreateNewAXTreeID(),
- false, &mapper)
- .role());
+ EXPECT_EQ(
+ fuchsia::accessibility::semantics::Role::HEADER,
+ AXNodeDataToSemanticNode(
+ node, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false, &mapper)
+ .role());
node.role = ax::mojom::Role::kImage;
- EXPECT_EQ(fuchsia::accessibility::semantics::Role::IMAGE,
- AXNodeDataToSemanticNode(node, ui::AXTreeID::CreateNewAXTreeID(),
- false, &mapper)
- .role());
+ EXPECT_EQ(
+ fuchsia::accessibility::semantics::Role::IMAGE,
+ AXNodeDataToSemanticNode(
+ node, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false, &mapper)
+ .role());
node.role = ax::mojom::Role::kLink;
- EXPECT_EQ(fuchsia::accessibility::semantics::Role::LINK,
- AXNodeDataToSemanticNode(node, ui::AXTreeID::CreateNewAXTreeID(),
- false, &mapper)
- .role());
+ EXPECT_EQ(
+ fuchsia::accessibility::semantics::Role::LINK,
+ AXNodeDataToSemanticNode(
+ node, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false, &mapper)
+ .role());
node.role = ax::mojom::Role::kRadioButton;
- EXPECT_EQ(fuchsia::accessibility::semantics::Role::RADIO_BUTTON,
- AXNodeDataToSemanticNode(node, ui::AXTreeID::CreateNewAXTreeID(),
- false, &mapper)
- .role());
+ EXPECT_EQ(
+ fuchsia::accessibility::semantics::Role::RADIO_BUTTON,
+ AXNodeDataToSemanticNode(
+ node, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false, &mapper)
+ .role());
node.role = ax::mojom::Role::kSlider;
- EXPECT_EQ(fuchsia::accessibility::semantics::Role::SLIDER,
- AXNodeDataToSemanticNode(node, ui::AXTreeID::CreateNewAXTreeID(),
- false, &mapper)
- .role());
+ EXPECT_EQ(
+ fuchsia::accessibility::semantics::Role::SLIDER,
+ AXNodeDataToSemanticNode(
+ node, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false, &mapper)
+ .role());
node.role = ax::mojom::Role::kTextField;
- EXPECT_EQ(fuchsia::accessibility::semantics::Role::TEXT_FIELD,
- AXNodeDataToSemanticNode(node, ui::AXTreeID::CreateNewAXTreeID(),
- false, &mapper)
- .role());
+ EXPECT_EQ(
+ fuchsia::accessibility::semantics::Role::TEXT_FIELD,
+ AXNodeDataToSemanticNode(
+ node, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false, &mapper)
+ .role());
node.role = ax::mojom::Role::kStaticText;
- EXPECT_EQ(fuchsia::accessibility::semantics::Role::STATIC_TEXT,
- AXNodeDataToSemanticNode(node, ui::AXTreeID::CreateNewAXTreeID(),
- false, &mapper)
- .role());
+ EXPECT_EQ(
+ fuchsia::accessibility::semantics::Role::STATIC_TEXT,
+ AXNodeDataToSemanticNode(
+ node, root_node(), ui::AXTreeID::CreateNewAXTreeID(), false, &mapper)
+ .role());
}
} // namespace
diff --git a/chromium/fuchsia/engine/browser/content_directory_loader_factory.cc b/chromium/fuchsia/engine/browser/content_directory_loader_factory.cc
index 0a81d4ae30e..80ed7ccd8de 100644
--- a/chromium/fuchsia/engine/browser/content_directory_loader_factory.cc
+++ b/chromium/fuchsia/engine/browser/content_directory_loader_factory.cc
@@ -401,7 +401,6 @@ net::Error ContentDirectoryLoaderFactory::OpenFileFromDirectory(
void ContentDirectoryLoaderFactory::CreateLoaderAndStart(
mojo::PendingReceiver<network::mojom::URLLoader> loader,
- int32_t routing_id,
int32_t request_id,
uint32_t options,
const network::ResourceRequest& request,
@@ -454,11 +453,10 @@ void ContentDirectoryLoaderFactory::CreateLoaderAndStart(
// Load the resource on a blocking-capable TaskRunner.
task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&ContentDirectoryURLLoader::CreateAndStart,
- base::Passed(std::move(loader)), request,
- base::Passed(std::move(client)),
- base::Passed(std::move(file_handle)),
- base::Passed(std::move(metadata_handle))));
+ FROM_HERE,
+ base::BindOnce(&ContentDirectoryURLLoader::CreateAndStart,
+ std::move(loader), request, std::move(client),
+ std::move(file_handle), std::move(metadata_handle)));
}
void ContentDirectoryLoaderFactory::SetContentDirectoriesForTest(
diff --git a/chromium/fuchsia/engine/browser/content_directory_loader_factory.h b/chromium/fuchsia/engine/browser/content_directory_loader_factory.h
index 218b90eb35b..1fc4e8795a9 100644
--- a/chromium/fuchsia/engine/browser/content_directory_loader_factory.h
+++ b/chromium/fuchsia/engine/browser/content_directory_loader_factory.h
@@ -45,7 +45,6 @@ class ContentDirectoryLoaderFactory
// network::mojom::URLLoaderFactory:
void CreateLoaderAndStart(
mojo::PendingReceiver<network::mojom::URLLoader> loader,
- int32_t routing_id,
int32_t request_id,
uint32_t options,
const network::ResourceRequest& request,
diff --git a/chromium/fuchsia/engine/browser/context_impl.cc b/chromium/fuchsia/engine/browser/context_impl.cc
index 5aadde8d4aa..92ae702522f 100644
--- a/chromium/fuchsia/engine/browser/context_impl.cc
+++ b/chromium/fuchsia/engine/browser/context_impl.cc
@@ -22,14 +22,13 @@
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/mojom/webpreferences/web_preferences.mojom.h"
-ContextImpl::ContextImpl(content::BrowserContext* browser_context,
- WebEngineDevToolsController* devtools_controller)
- : browser_context_(browser_context),
+ContextImpl::ContextImpl(
+ std::unique_ptr<content::BrowserContext> browser_context,
+ WebEngineDevToolsController* devtools_controller)
+ : browser_context_(std::move(browser_context)),
devtools_controller_(devtools_controller),
- cookie_manager_(base::BindRepeating(
- &content::StoragePartition::GetNetworkContext,
- base::Unretained(content::BrowserContext::GetDefaultStoragePartition(
- browser_context_)))) {
+ cookie_manager_(base::BindRepeating(&ContextImpl::GetNetworkContext,
+ base::Unretained(this))) {
DCHECK(browser_context_);
DCHECK(devtools_controller_);
devtools_controller_->OnContextCreated();
@@ -73,7 +72,8 @@ void ContextImpl::CreateFrameWithParams(
}
// Create a WebContents to host the new Frame.
- content::WebContents::CreateParams create_params(browser_context_, nullptr);
+ content::WebContents::CreateParams create_params(browser_context_.get(),
+ nullptr);
create_params.initially_hidden = true;
auto web_contents = content::WebContents::Create(create_params);
@@ -211,6 +211,7 @@ FrameImpl* ContextImpl::GetFrameImplForTest(
network::mojom::NetworkContext* ContextImpl::GetNetworkContext() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- return content::BrowserContext::GetDefaultStoragePartition(browser_context_)
+ return content::BrowserContext::GetDefaultStoragePartition(
+ browser_context_.get())
->GetNetworkContext();
}
diff --git a/chromium/fuchsia/engine/browser/context_impl.h b/chromium/fuchsia/engine/browser/context_impl.h
index 1c314860f23..6d41ccaa850 100644
--- a/chromium/fuchsia/engine/browser/context_impl.h
+++ b/chromium/fuchsia/engine/browser/context_impl.h
@@ -34,8 +34,8 @@ class WebEngineDevToolsController;
// All created Frames are owned by this object.
class WEB_ENGINE_EXPORT ContextImpl : public fuchsia::web::Context {
public:
- // |browser_context| and |devtools_controller| must outlive ContextImpl.
- ContextImpl(content::BrowserContext* browser_context,
+ // |devtools_controller| must outlive ContextImpl.
+ ContextImpl(std::unique_ptr<content::BrowserContext> browser_context,
WebEngineDevToolsController* devtools_controller);
// Tears down the Context, destroying any active Frames in the process.
@@ -76,8 +76,8 @@ class WEB_ENGINE_EXPORT ContextImpl : public fuchsia::web::Context {
// |frame_ptr| client.
FrameImpl* GetFrameImplForTest(fuchsia::web::FramePtr* frame_ptr) const;
- content::BrowserContext* browser_context_for_test() const {
- return browser_context_;
+ content::BrowserContext* browser_context() const {
+ return browser_context_.get();
}
private:
@@ -85,7 +85,7 @@ class WEB_ENGINE_EXPORT ContextImpl : public fuchsia::web::Context {
network::mojom::NetworkContext* GetNetworkContext();
// Reference to the browser implementation for this Context.
- content::BrowserContext* const browser_context_;
+ std::unique_ptr<content::BrowserContext> const browser_context_;
// Reference to the class managing the DevTools remote debugging service.
WebEngineDevToolsController* const devtools_controller_;
diff --git a/chromium/fuchsia/engine/browser/explicit_sites_filter_browsertest.cc b/chromium/fuchsia/engine/browser/explicit_sites_filter_browsertest.cc
index 7c57d3a4fb3..2b03e18f17d 100644
--- a/chromium/fuchsia/engine/browser/explicit_sites_filter_browsertest.cc
+++ b/chromium/fuchsia/engine/browser/explicit_sites_filter_browsertest.cc
@@ -50,7 +50,7 @@ class ExplicitSitesFilterTest : public FrameImplTestBaseWithServer {
FrameImplTestBaseWithServer::SetUpOnMainThread();
SafeSearchFactory::GetInstance()
- ->GetForBrowserContext(context_impl()->browser_context_for_test())
+ ->GetForBrowserContext(context_impl()->browser_context())
->SetSafeSearchURLCheckerForTest(
stub_url_checker_.BuildURLChecker(kUrlCheckerCacheSize));
}
diff --git a/chromium/fuchsia/engine/browser/fake_semantic_tree.cc b/chromium/fuchsia/engine/browser/fake_semantic_tree.cc
index 1c3c006f07d..87c49e0f586 100644
--- a/chromium/fuchsia/engine/browser/fake_semantic_tree.cc
+++ b/chromium/fuchsia/engine/browser/fake_semantic_tree.cc
@@ -61,6 +61,21 @@ void FakeSemanticTree::RunUntilNodeCountAtLeast(size_t count) {
run_loop.Run();
}
+void FakeSemanticTree::RunUntilNodeWithLabelIsInTree(base::StringPiece label) {
+ DCHECK(!on_commit_updates_);
+ if (GetNodeFromLabel(label))
+ return;
+
+ base::RunLoop run_loop;
+ base::AutoReset<base::RepeatingClosure> auto_reset(
+ &on_commit_updates_,
+ base::BindLambdaForTesting([this, label, &run_loop]() {
+ if (GetNodeFromLabel(label))
+ run_loop.Quit();
+ }));
+ run_loop.Run();
+}
+
void FakeSemanticTree::RunUntilCommitCountIs(size_t count) {
DCHECK(!on_commit_updates_);
if (count == num_commit_calls_)
diff --git a/chromium/fuchsia/engine/browser/fake_semantic_tree.h b/chromium/fuchsia/engine/browser/fake_semantic_tree.h
index da880efd3d4..8c79858b6a8 100644
--- a/chromium/fuchsia/engine/browser/fake_semantic_tree.h
+++ b/chromium/fuchsia/engine/browser/fake_semantic_tree.h
@@ -36,6 +36,7 @@ class FakeSemanticTree
void Disconnect();
void RunUntilNodeCountAtLeast(size_t count);
+ void RunUntilNodeWithLabelIsInTree(base::StringPiece label);
void RunUntilCommitCountIs(size_t count);
void SetNodeUpdatedCallback(uint32_t node_id,
base::OnceClosure node_updated_callback);
diff --git a/chromium/fuchsia/engine/browser/frame_impl.cc b/chromium/fuchsia/engine/browser/frame_impl.cc
index 781cdcb53ae..55e40649835 100644
--- a/chromium/fuchsia/engine/browser/frame_impl.cc
+++ b/chromium/fuchsia/engine/browser/frame_impl.cc
@@ -328,7 +328,7 @@ void FrameImpl::ExecuteJavaScriptInternal(std::vector<std::string> origins,
return;
}
- base::string16 script_utf16;
+ std::u16string script_utf16;
if (!cr_fuchsia::ReadUTF8FromVMOAsUTF16(script, &script_utf16)) {
result.set_err(fuchsia::web::FrameError::BUFFER_NOT_UTF8);
callback(std::move(result));
@@ -720,11 +720,11 @@ void FrameImpl::PostMessage(std::string origin,
return;
}
- base::Optional<base::string16> origin_utf16;
+ base::Optional<std::u16string> origin_utf16;
if (origin != kWildcardOrigin)
origin_utf16 = base::UTF8ToUTF16(origin);
- base::string16 data_utf16;
+ std::u16string data_utf16;
if (!cr_fuchsia::ReadUTF8FromVMOAsUTF16(message.data(), &data_utf16)) {
result.set_err(fuchsia::web::FrameError::BUFFER_NOT_UTF8);
callback(std::move(result));
@@ -757,7 +757,7 @@ void FrameImpl::PostMessage(std::string origin,
}
content::MessagePortProvider::PostMessageToFrame(
- web_contents_.get(), base::string16(), origin_utf16,
+ web_contents_.get(), std::u16string(), origin_utf16,
std::move(data_utf16), std::move(message_ports));
result.set_response(fuchsia::web::Frame_PostMessage_Response());
callback(std::move(result));
@@ -1005,9 +1005,9 @@ void FrameImpl::SetBlockMediaLoading(bool blocked) {
bool FrameImpl::DidAddMessageToConsole(
content::WebContents* source,
blink::mojom::ConsoleMessageLevel log_level,
- const base::string16& message,
+ const std::u16string& message,
int32_t line_no,
- const base::string16& source_id) {
+ const std::u16string& source_id) {
fx_log_severity_t severity =
BlinkConsoleMessageLevelToFxLogSeverity(log_level);
if (severity < log_level_) {
@@ -1130,6 +1130,7 @@ void FrameImpl::DidFinishLoad(content::RenderFrameHost* render_frame_host,
void FrameImpl::RenderFrameCreated(content::RenderFrameHost* frame_host) {
// The top-level frame is given a transparent background color.
+ // GetView() is guaranteed to be non-null until |frame_host| teardown.
if (frame_host == web_contents()->GetMainFrame())
frame_host->GetView()->SetBackgroundColor(SK_AlphaTRANSPARENT);
}
diff --git a/chromium/fuchsia/engine/browser/frame_impl.h b/chromium/fuchsia/engine/browser/frame_impl.h
index 9bdcbcc9fed..fea7e90aa11 100644
--- a/chromium/fuchsia/engine/browser/frame_impl.h
+++ b/chromium/fuchsia/engine/browser/frame_impl.h
@@ -104,6 +104,9 @@ class FrameImpl : public fuchsia::web::Frame,
CastStreamingSessionClient* cast_streaming_session_client_for_test() {
return cast_streaming_session_client_.get();
}
+ FrameWindowTreeHost* window_tree_host_for_test() {
+ return window_tree_host_.get();
+ }
// Enables explicit sites filtering and set the error page. If |error_page| is
// empty, the default error page will be used.
@@ -227,9 +230,9 @@ class FrameImpl : public fuchsia::web::Frame,
void CloseContents(content::WebContents* source) override;
bool DidAddMessageToConsole(content::WebContents* source,
blink::mojom::ConsoleMessageLevel log_level,
- const base::string16& message,
+ const std::u16string& message,
int32_t line_no,
- const base::string16& source_id) override;
+ const std::u16string& source_id) override;
bool IsWebContentsCreationOverridden(
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
diff --git a/chromium/fuchsia/engine/browser/frame_impl_browsertest.cc b/chromium/fuchsia/engine/browser/frame_impl_browsertest.cc
index b3881d67cac..d9da3e66831 100644
--- a/chromium/fuchsia/engine/browser/frame_impl_browsertest.cc
+++ b/chromium/fuchsia/engine/browser/frame_impl_browsertest.cc
@@ -11,6 +11,7 @@
#include <string>
#include "base/bind.h"
+#include "base/callback_helpers.h"
#include "base/containers/span.h"
#include "base/fuchsia/process_context.h"
#include "base/macros.h"
diff --git a/chromium/fuchsia/engine/browser/frame_window_tree_host.cc b/chromium/fuchsia/engine/browser/frame_window_tree_host.cc
index edc008c430b..41a469f71c1 100644
--- a/chromium/fuchsia/engine/browser/frame_window_tree_host.cc
+++ b/chromium/fuchsia/engine/browser/frame_window_tree_host.cc
@@ -5,6 +5,7 @@
#include "fuchsia/engine/browser/frame_window_tree_host.h"
#include "base/fuchsia/fuchsia_logging.h"
+#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/client/window_parenting_client.h"
@@ -95,3 +96,12 @@ void FrameWindowTreeHost::OnWindowStateChanged(
web_contents_->WasShown();
}
}
+
+void FrameWindowTreeHost::OnWindowBoundsChanged(const BoundsChange& bounds) {
+ aura::WindowTreeHostPlatform::OnBoundsChanged(bounds);
+
+ if (web_contents_->GetMainFrame()->IsRenderFrameLive()) {
+ web_contents_->GetMainFrame()->GetView()->SetInsets(
+ bounds.system_ui_overlap);
+ }
+}
diff --git a/chromium/fuchsia/engine/browser/frame_window_tree_host.h b/chromium/fuchsia/engine/browser/frame_window_tree_host.h
index 9ca6ea24a3b..e4066c23c0b 100644
--- a/chromium/fuchsia/engine/browser/frame_window_tree_host.h
+++ b/chromium/fuchsia/engine/browser/frame_window_tree_host.h
@@ -34,6 +34,7 @@ class FrameWindowTreeHost : public aura::WindowTreeHostPlatform {
// aura::WindowTreeHostPlatform overrides.
void OnActivationChanged(bool active) final;
void OnWindowStateChanged(ui::PlatformWindowState new_state) final;
+ void OnWindowBoundsChanged(const BoundsChange& bounds);
const fuchsia::ui::views::ViewRef view_ref_;
std::unique_ptr<WindowParentingClientImpl> window_parenting_client_;
diff --git a/chromium/fuchsia/engine/browser/media_player_impl.cc b/chromium/fuchsia/engine/browser/media_player_impl.cc
index eb22d8b5f77..ec90a4c4ff8 100644
--- a/chromium/fuchsia/engine/browser/media_player_impl.cc
+++ b/chromium/fuchsia/engine/browser/media_player_impl.cc
@@ -47,6 +47,12 @@ fuchsia::media::sessions2::PlayerCapabilityFlags ActionToCapabilityFlag(
return {}; // PlayerControl assumes that stop is always supported.
case MediaSessionAction::kSwitchAudioDevice:
return {}; // PlayerControl does not support switching audio device.
+ case MediaSessionAction::kToggleMicrophone:
+ return {}; // PlayerControl does not support toggling microphone.
+ case MediaSessionAction::kToggleCamera:
+ return {}; // PlayerControl does not support toggling camera.
+ case MediaSessionAction::kHangUp:
+ return {}; // PlayerControl does not support hanging up.
}
}
diff --git a/chromium/fuchsia/engine/browser/media_player_impl_unittest.cc b/chromium/fuchsia/engine/browser/media_player_impl_unittest.cc
index 5eea168dd8e..cf81e993e50 100644
--- a/chromium/fuchsia/engine/browser/media_player_impl_unittest.cc
+++ b/chromium/fuchsia/engine/browser/media_player_impl_unittest.cc
@@ -37,6 +37,9 @@ class FakeMediaSession : public content::MediaSession {
MOCK_METHOD0(EnterPictureInPicture, void());
MOCK_METHOD0(ExitPictureInPicture, void());
MOCK_METHOD1(SetAudioSinkId, void(const base::Optional<std::string>& id));
+ MOCK_METHOD0(ToggleMicrophone, void());
+ MOCK_METHOD0(ToggleCamera, void());
+ MOCK_METHOD0(HangUp, void());
// content::MediaSession APIs faked to implement testing behaviour.
MOCK_METHOD1(DidReceiveAction,
diff --git a/chromium/fuchsia/engine/browser/navigation_controller_impl.cc b/chromium/fuchsia/engine/browser/navigation_controller_impl.cc
index e273491da44..7c22ca98719 100644
--- a/chromium/fuchsia/engine/browser/navigation_controller_impl.cc
+++ b/chromium/fuchsia/engine/browser/navigation_controller_impl.cc
@@ -216,7 +216,8 @@ void NavigationControllerImpl::TitleWasSet(content::NavigationEntry* entry) {
OnNavigationEntryChanged();
}
-void NavigationControllerImpl::DocumentAvailableInMainFrame() {
+void NavigationControllerImpl::DocumentAvailableInMainFrame(
+ content::RenderFrameHost* render_frame_host) {
// The main document is loaded, but not necessarily all the subresources. Some
// fields like "title" will change here.
@@ -260,11 +261,8 @@ void NavigationControllerImpl::DidStartNavigation(
void NavigationControllerImpl::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
- if (!navigation_handle->IsInMainFrame() ||
- navigation_handle->IsSameDocument() ||
- navigation_handle != active_navigation_) {
+ if (navigation_handle != active_navigation_)
return;
- }
active_navigation_ = nullptr;
uncommitted_load_error_ = !navigation_handle->HasCommitted() &&
diff --git a/chromium/fuchsia/engine/browser/navigation_controller_impl.h b/chromium/fuchsia/engine/browser/navigation_controller_impl.h
index 1b69519065e..88239ad3a05 100644
--- a/chromium/fuchsia/engine/browser/navigation_controller_impl.h
+++ b/chromium/fuchsia/engine/browser/navigation_controller_impl.h
@@ -58,7 +58,8 @@ class NavigationControllerImpl : public fuchsia::web::NavigationController,
// content::WebContentsObserver implementation.
void TitleWasSet(content::NavigationEntry*) final;
- void DocumentAvailableInMainFrame() final;
+ void DocumentAvailableInMainFrame(
+ content::RenderFrameHost* render_frame_host) final;
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) final;
void RenderProcessGone(base::TerminationStatus status) final;
diff --git a/chromium/fuchsia/engine/browser/permissions_browsertest.cc b/chromium/fuchsia/engine/browser/permissions_browsertest.cc
new file mode 100644
index 00000000000..8a8d1089566
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/permissions_browsertest.cc
@@ -0,0 +1,144 @@
+// Copyright 2021 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 "base/files/file_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/threading/scoped_blocking_call.h"
+#include "content/public/test/browser_test.h"
+#include "fuchsia/base/frame_test_util.h"
+#include "fuchsia/base/mem_buffer_util.h"
+#include "fuchsia/engine/browser/frame_impl_browser_test_base.h"
+#include "fuchsia/engine/test/test_data.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+static const char kIframeTestPagePath[] = "/iframe.html";
+static const char kMicTestPagePath[] = "/mic.html";
+static const char kMicNoPermissionTestPagePath[] = "/mic.html?NoPermission";
+
+class PermissionsBrowserTest : public FrameImplTestBaseWithServer {
+ public:
+ PermissionsBrowserTest() = default;
+ ~PermissionsBrowserTest() override = default;
+
+ void SetUpOnMainThread() override {
+ FrameImplTestBaseWithServer::SetUpOnMainThread();
+ frame_ = CreateFrame();
+ }
+
+ void GrantPermission(fuchsia::web::PermissionType type,
+ const std::string& origin) {
+ fuchsia::web::PermissionDescriptor permission;
+ permission.set_type(type);
+ frame_->SetPermissionState(std::move(permission), origin,
+ fuchsia::web::PermissionState::GRANTED);
+ }
+
+ protected:
+ void InjectBeforeLoadJs(const std::string& code);
+
+ // Loads iframe.html with the specified URL used for the embedded page.
+ void LoadPageInIframe(const std::string& url);
+
+ std::unique_ptr<net::test_server::HttpResponse>
+ RequestHandlerWithPermissionPolicy(
+ const net::test_server::HttpRequest& request);
+
+ uint64_t before_load_js_id_ = 1;
+ fuchsia::web::FramePtr frame_;
+};
+
+void PermissionsBrowserTest::InjectBeforeLoadJs(const std::string& code) {
+ frame_->AddBeforeLoadJavaScript(
+ before_load_js_id_++, {"*"},
+ cr_fuchsia::MemBufferFromString(code, "test"),
+ [](fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) {
+ CHECK(result.is_response());
+ });
+}
+
+void PermissionsBrowserTest::LoadPageInIframe(const std::string& url) {
+ // Before loading a page on the default embedded test server, set the iframe
+ // src to be |url|.
+ InjectBeforeLoadJs(base::StringPrintf("iframeSrc = '%s';", url.c_str()));
+
+ fuchsia::web::NavigationControllerPtr controller;
+ frame_->GetNavigationController(controller.NewRequest());
+
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), {},
+ embedded_test_server()->GetURL(kIframeTestPagePath).spec()));
+}
+
+IN_PROC_BROWSER_TEST_F(PermissionsBrowserTest, PermissionInSameOriginIframe) {
+ GrantPermission(fuchsia::web::PermissionType::MICROPHONE,
+ embedded_test_server()->GetURL("/").GetOrigin().spec());
+
+ // Mic permission is expected to be granted since the iframe is loaded from
+ // the same origin.
+ GURL iframe_src = embedded_test_server()->GetURL(kMicTestPagePath);
+
+ ASSERT_NO_FATAL_FAILURE(LoadPageInIframe(iframe_src.spec()));
+
+ navigation_listener_.RunUntilTitleEquals("ended");
+}
+
+IN_PROC_BROWSER_TEST_F(PermissionsBrowserTest, NoPermissionInSameOriginIframe) {
+ // Mic permission is expected to be denied since it wasn't granted to the
+ // parent frame.
+ GURL iframe_src =
+ embedded_test_server()->GetURL(kMicNoPermissionTestPagePath);
+
+ ASSERT_NO_FATAL_FAILURE(LoadPageInIframe(iframe_src.spec()));
+
+ navigation_listener_.RunUntilTitleEquals("ended-NotFoundError");
+}
+
+IN_PROC_BROWSER_TEST_F(PermissionsBrowserTest, PermissionInCrossOriginIframe) {
+ GrantPermission(fuchsia::web::PermissionType::MICROPHONE,
+ embedded_test_server()->GetURL("/").GetOrigin().spec());
+
+ // Start a second embedded test server. It's used to load the page inside
+ // the <iframe> from an origin different from the origin of the embedding
+ // page.
+ net::EmbeddedTestServer second_test_server;
+ second_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(cr_fuchsia::kTestServerRoot));
+ ASSERT_TRUE(second_test_server.Start());
+
+ // Mic permissions are expected to be denied since the page is cross-origin.
+ GURL iframe_src = second_test_server.GetURL(kMicNoPermissionTestPagePath);
+
+ ASSERT_NO_FATAL_FAILURE(LoadPageInIframe(iframe_src.spec()));
+
+ navigation_listener_.RunUntilTitleEquals("ended-NotAllowedError");
+}
+
+IN_PROC_BROWSER_TEST_F(PermissionsBrowserTest,
+ PermissionInCrossOriginIframeWithPermissionPolicy) {
+ GrantPermission(fuchsia::web::PermissionType::MICROPHONE,
+ embedded_test_server()->GetURL("/").GetOrigin().spec());
+
+ // Start a second embedded test server. It's used to load the page inside
+ // the <iframe> from an origin different from the origin of the embedding
+ // page.
+ net::EmbeddedTestServer second_test_server;
+ second_test_server.ServeFilesFromSourceDirectory(
+ base::FilePath(cr_fuchsia::kTestServerRoot));
+ ASSERT_TRUE(second_test_server.Start());
+
+ // Mic permissions are expected to be granted because the parent frame has
+ // access to the microphone and it's delegated to the child by the permission
+ // policy (see code below).
+ GURL iframe_src = second_test_server.GetURL(kMicTestPagePath);
+
+ InjectBeforeLoadJs(
+ base::StringPrintf("iframePermissionPolicy = 'microphone %s';",
+ iframe_src.GetOrigin().spec().c_str()));
+
+ ASSERT_NO_FATAL_FAILURE(LoadPageInIframe(iframe_src.spec()));
+
+ navigation_listener_.RunUntilTitleEquals("ended");
+}
diff --git a/chromium/fuchsia/engine/browser/theme_manager.cc b/chromium/fuchsia/engine/browser/theme_manager.cc
index 983a7e17146..cccca3c9a40 100644
--- a/chromium/fuchsia/engine/browser/theme_manager.cc
+++ b/chromium/fuchsia/engine/browser/theme_manager.cc
@@ -4,6 +4,7 @@
#include "fuchsia/engine/browser/theme_manager.h"
+#include "base/callback_helpers.h"
#include "base/check.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "third_party/blink/public/mojom/css/preferred_color_scheme.mojom.h"
diff --git a/chromium/fuchsia/engine/browser/virtual_keyboard_browsertest.cc b/chromium/fuchsia/engine/browser/virtual_keyboard_browsertest.cc
new file mode 100644
index 00000000000..6c646f955ed
--- /dev/null
+++ b/chromium/fuchsia/engine/browser/virtual_keyboard_browsertest.cc
@@ -0,0 +1,376 @@
+// Copyright 2021 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/input/virtualkeyboard/cpp/fidl.h>
+#include <lib/fit/function.h>
+#include <lib/ui/scenic/cpp/view_ref_pair.h>
+#include <lib/ui/scenic/cpp/view_token_pair.h>
+
+#include "base/callback.h"
+#include "base/fuchsia/fuchsia_logging.h"
+#include "base/fuchsia/scoped_service_binding.h"
+#include "base/fuchsia/test_component_context_for_process.h"
+#include "base/strings/stringprintf.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "fuchsia/base/frame_test_util.h"
+#include "fuchsia/base/test_navigation_listener.h"
+#include "fuchsia/engine/browser/frame_impl.h"
+#include "fuchsia/engine/browser/frame_window_tree_host.h"
+#include "fuchsia/engine/test/test_data.h"
+#include "fuchsia/engine/test/web_engine_browser_test.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace virtualkeyboard = fuchsia::input::virtualkeyboard;
+
+namespace {
+
+const gfx::Rect kBounds = {1000, 1000};
+const gfx::Point kNoTarget = {999, 999};
+
+constexpr char kInputFieldText[] = "input-text";
+constexpr char kInputFieldTel[] = "input-tel";
+constexpr char kInputFieldNumeric[] = "input-numeric";
+constexpr char kInputFieldUrl[] = "input-url";
+constexpr char kInputFieldEmail[] = "input-email";
+constexpr char kInputFieldDecimal[] = "input-decimal";
+constexpr char kInputFieldSearch[] = "input-search";
+
+zx_handle_t GetKoidFromEventPair(const zx::eventpair& object) {
+ zx_info_handle_basic_t handle_info{};
+ zx_status_t status =
+ object.get_info(ZX_INFO_HANDLE_BASIC, &handle_info,
+ sizeof(zx_info_handle_basic_t), nullptr, nullptr);
+ ZX_CHECK(status == ZX_OK, status) << "zx_object_get_info";
+ return handle_info.koid;
+}
+
+class MockVirtualKeyboardController : public virtualkeyboard::Controller {
+ public:
+ MockVirtualKeyboardController() : binding_(this) {}
+ ~MockVirtualKeyboardController() override {}
+
+ MockVirtualKeyboardController(MockVirtualKeyboardController&) = delete;
+ MockVirtualKeyboardController operator=(MockVirtualKeyboardController&) =
+ delete;
+
+ void Bind(fuchsia::ui::views::ViewRef view_ref,
+ virtualkeyboard::TextType text_type,
+ fidl::InterfaceRequest<fuchsia::input::virtualkeyboard::Controller>
+ controller_request) {
+ text_type_ = text_type;
+ view_ref_ = std::move(view_ref);
+ binding_.Bind(std::move(controller_request));
+ }
+
+ // Spins a RunLoop until the client calls WatchVisibility().
+ void AwaitWatchAndRespondWith(bool is_visible) {
+ if (!watch_vis_callback_) {
+ base::RunLoop run_loop;
+ on_watch_visibility_ = run_loop.QuitClosure();
+ run_loop.Run();
+ ASSERT_TRUE(watch_vis_callback_);
+ }
+
+ (*watch_vis_callback_)(is_visible);
+ watch_vis_callback_ = {};
+ }
+
+ const fuchsia::ui::views::ViewRef& view_ref() const { return view_ref_; }
+ virtualkeyboard::TextType text_type() const { return text_type_; }
+
+ // virtualkeyboard::Controller implementation.
+ MOCK_METHOD0(RequestShow, void());
+ MOCK_METHOD0(RequestHide, void());
+ MOCK_METHOD1(SetTextType, void(virtualkeyboard::TextType text_type));
+
+ private:
+ // virtualkeyboard::Controller implementation.
+ void WatchVisibility(
+ virtualkeyboard::Controller::WatchVisibilityCallback callback) final {
+ watch_vis_callback_ = std::move(callback);
+
+ if (on_watch_visibility_)
+ std::move(on_watch_visibility_).Run();
+ }
+
+ base::OnceClosure on_watch_visibility_;
+ base::Optional<virtualkeyboard::Controller::WatchVisibilityCallback>
+ watch_vis_callback_;
+ fuchsia::ui::views::ViewRef view_ref_;
+ virtualkeyboard::TextType text_type_;
+ fidl::Binding<fuchsia::input::virtualkeyboard::Controller> binding_;
+};
+
+// Services connection requests for MockVirtualKeyboardControllers.
+class MockVirtualKeyboardControllerCreator
+ : public virtualkeyboard::ControllerCreator {
+ public:
+ explicit MockVirtualKeyboardControllerCreator(
+ base::TestComponentContextForProcess* component_context)
+ : binding_(component_context->additional_services(), this) {}
+
+ ~MockVirtualKeyboardControllerCreator() override {
+ CHECK(!pending_controller_);
+ }
+
+ MockVirtualKeyboardControllerCreator(MockVirtualKeyboardControllerCreator&) =
+ delete;
+ MockVirtualKeyboardControllerCreator operator=(
+ MockVirtualKeyboardControllerCreator&) = delete;
+
+ // Returns an unbound MockVirtualKeyboardController, which will later be
+ // connected when |this| handles a call to the FIDL method Create().
+ std::unique_ptr<MockVirtualKeyboardController> CreateController() {
+ DCHECK(!pending_controller_);
+
+ auto controller = std::make_unique<MockVirtualKeyboardController>();
+ pending_controller_ = controller.get();
+ return controller;
+ }
+
+ private:
+ // fuchsia::input::virtualkeyboard implementation.
+ void Create(
+ fuchsia::ui::views::ViewRef view_ref,
+ fuchsia::input::virtualkeyboard::TextType text_type,
+ fidl::InterfaceRequest<fuchsia::input::virtualkeyboard::Controller>
+ controller_request) final {
+ CHECK(pending_controller_);
+ pending_controller_->Bind(std::move(view_ref), text_type,
+ std::move(controller_request));
+ pending_controller_ = nullptr;
+ }
+
+ MockVirtualKeyboardController* pending_controller_ = nullptr;
+ base::ScopedServiceBinding<virtualkeyboard::ControllerCreator> binding_;
+};
+
+class VirtualKeyboardTest : public cr_fuchsia::WebEngineBrowserTest {
+ public:
+ VirtualKeyboardTest() {
+ set_test_server_root(base::FilePath(cr_fuchsia::kTestServerRoot));
+ }
+ ~VirtualKeyboardTest() override = default;
+
+ void SetUpOnMainThread() override {
+ cr_fuchsia::WebEngineBrowserTest::SetUpOnMainThread();
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ component_context_.emplace(
+ base::TestComponentContextForProcess::InitialState::kCloneAll);
+ controller_creator_.emplace(&*component_context_);
+ controller_ = controller_creator_->CreateController();
+
+ frame_ = CreateFrame(&navigation_listener_);
+ frame_impl_ = context_impl()->GetFrameImplForTest(&frame_);
+
+ // Navigate to the test page.
+ fuchsia::web::NavigationControllerPtr controller;
+ frame_->GetNavigationController(controller.NewRequest());
+ const GURL test_url(embedded_test_server()->GetURL("/input_fields.html"));
+ EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
+ controller.get(), fuchsia::web::LoadUrlParams(), test_url.spec()));
+ navigation_listener_.RunUntilUrlEquals(test_url);
+
+ // Simulate the creation of a Scenic View, except bypassing the actual
+ // construction of a Scenic PlatformWindow in favor of using an injected
+ // StubWindow.
+ scenic::ViewRefPair view_ref_pair = scenic::ViewRefPair::New();
+ view_ref_ = std::move(view_ref_pair.view_ref);
+ fuchsia::ui::views::ViewRef view_ref_dup;
+ zx_status_t status = view_ref_.reference.duplicate(ZX_RIGHT_SAME_RIGHTS,
+ &view_ref_dup.reference);
+ ZX_CHECK(status == ZX_OK, status) << "zx_object_duplicate";
+
+ auto view_tokens = scenic::ViewTokenPair::New();
+ frame_->CreateViewWithViewRef(std::move(view_tokens.view_token),
+ std::move(view_ref_pair.control_ref),
+ std::move(view_ref_dup));
+ base::RunLoop().RunUntilIdle();
+ frame_impl_->window_tree_host_for_test()->Show();
+
+ // Prepare the view for headless interaction by setting its focus state and
+ // size.
+ web_contents_ = frame_impl_->web_contents();
+ content::RenderWidgetHostView* view =
+ web_contents_->GetMainFrame()->GetView();
+ view->SetBounds(kBounds);
+ view->Focus();
+
+ controller_->AwaitWatchAndRespondWith(false);
+
+ ASSERT_EQ(GetKoidFromEventPair(controller_->view_ref().reference),
+ GetKoidFromEventPair(view_ref_.reference));
+ }
+
+ void TearDownOnMainThread() override {
+ frame_.Unbind();
+ base::RunLoop().RunUntilIdle();
+ }
+
+ gfx::Point GetCoordinatesOfInputField(base::StringPiece id) {
+ // Distance to click from the top/left extents of an input field.
+ constexpr int kInputFieldClickInset = 8;
+
+ base::Optional<base::Value> result = cr_fuchsia::ExecuteJavaScript(
+ frame_.get(),
+ base::StringPrintf("getPointInsideText('%s')", id.data()));
+ CHECK(result);
+
+ // Note that coordinates are floating point and must be retrieved as such
+ // from the Value, but we can cast them to integers and disregard the
+ // fractional value with no major consequences.
+ return gfx::Point(*result->FindDoublePath("x") + kInputFieldClickInset,
+ *result->FindDoublePath("y") + kInputFieldClickInset);
+ }
+
+ protected:
+ // Used to publish fake virtual keyboard services for the InputMethod to use.
+ base::Optional<base::TestComponentContextForProcess> component_context_;
+ base::Optional<MockVirtualKeyboardControllerCreator> controller_creator_;
+ std::unique_ptr<MockVirtualKeyboardController> controller_;
+
+ fuchsia::web::FramePtr frame_;
+ FrameImpl* frame_impl_ = nullptr;
+ content::WebContents* web_contents_ = nullptr;
+ cr_fuchsia::TestNavigationListener navigation_listener_;
+ fuchsia::ui::views::ViewRef view_ref_;
+};
+
+// Verifies that RequestShow() is invoked multiple times if the virtual
+// keyboard service does not indicate that the keyboard is made visible.
+IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, ShowAndHideCalledButIgnored) {
+ testing::InSequence s;
+ EXPECT_CALL(*controller_, RequestShow()).Times(2);
+ EXPECT_CALL(*controller_, RequestHide());
+ base::RunLoop run_loop;
+ EXPECT_CALL(*controller_, RequestShow())
+ .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
+
+ // Tap inside the text field. The IME should be summoned via a call to
+ // RequestShow().
+ content::SimulateTapAt(web_contents_,
+ GetCoordinatesOfInputField(kInputFieldText));
+
+ // Change fields. RequestShow() should be called again, since the keyboard
+ // is not yet known to be visible.
+ content::SimulateTapAt(web_contents_,
+ GetCoordinatesOfInputField(kInputFieldNumeric));
+
+ // Tap outside the text field. The IME should be dismissed, which will result
+ // in a call to RequestHide().
+ content::SimulateTapAt(web_contents_, kNoTarget);
+
+ // Tap back on a text field. RequestShow should be called.
+ content::SimulateTapAt(web_contents_,
+ GetCoordinatesOfInputField(kInputFieldText));
+ run_loop.Run();
+}
+
+// Verifies that RequestShow() is not called redundantly if the virtual
+// keyboard is reported as visible.
+IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, ShowAndHideWithVisibility) {
+ testing::InSequence s;
+ base::RunLoop on_show_run_loop;
+ EXPECT_CALL(*controller_,
+ SetTextType(virtualkeyboard::TextType::ALPHANUMERIC));
+ EXPECT_CALL(*controller_, RequestShow())
+ .WillOnce(testing::InvokeWithoutArgs(
+ [&on_show_run_loop]() { on_show_run_loop.Quit(); }));
+ EXPECT_CALL(*controller_, SetTextType(virtualkeyboard::TextType::NUMERIC));
+ base::RunLoop on_hide_run_loop;
+ EXPECT_CALL(*controller_, RequestHide())
+ .WillOnce(testing::InvokeWithoutArgs(
+ [&on_hide_run_loop]() { on_hide_run_loop.Quit(); }));
+
+ // Give focus to an input field, which will result in RequestShow() being
+ // called.
+ content::SimulateTapAt(web_contents_,
+ GetCoordinatesOfInputField(kInputFieldText));
+ on_show_run_loop.Run();
+
+ // Indicate that the virtual keyboard is now visible.
+ controller_->AwaitWatchAndRespondWith(true);
+
+ // Tap on another text field. RequestShow should not be called a second time
+ // since the keyboard is already onscreen.
+ content::SimulateTapAt(web_contents_,
+ GetCoordinatesOfInputField(kInputFieldNumeric));
+ base::RunLoop().RunUntilIdle();
+
+ content::SimulateTapAt(web_contents_, kNoTarget);
+ on_hide_run_loop.Run();
+}
+
+// Gives focus to a sequence of HTML <input> nodes with different InputModes,
+// and verifies that the InputMode's FIDL equivalent is sent via SetTextType().
+IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, InputModeMappings) {
+ const std::vector<std::pair<base::StringPiece, virtualkeyboard::TextType>>
+ kInputTypeMappings = {
+ {kInputFieldText, virtualkeyboard::TextType::ALPHANUMERIC},
+ {kInputFieldTel, virtualkeyboard::TextType::PHONE},
+ {kInputFieldNumeric, virtualkeyboard::TextType::NUMERIC},
+ {kInputFieldUrl, virtualkeyboard::TextType::ALPHANUMERIC},
+ {kInputFieldEmail, virtualkeyboard::TextType::ALPHANUMERIC},
+ {kInputFieldDecimal, virtualkeyboard::TextType::NUMERIC},
+ {kInputFieldSearch, virtualkeyboard::TextType::ALPHANUMERIC},
+ };
+
+ // Simulate like the keyboard is already shown, so that the test can focus on
+ // input type mappings without clutter from visibility management.
+ controller_->AwaitWatchAndRespondWith(true);
+ base::RunLoop().RunUntilIdle();
+
+ // GMock expectations must be set upfront, hence the redundant for-each loop.
+ for (const auto& field_type_pair : kInputTypeMappings) {
+ EXPECT_CALL(*controller_, SetTextType(field_type_pair.second))
+ .RetiresOnSaturation();
+ }
+
+ base::RunLoop run_loop;
+ EXPECT_CALL(*controller_, RequestHide())
+ .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); }));
+
+ for (const auto& field_type_pair : kInputTypeMappings) {
+ content::SimulateTapAt(web_contents_,
+ GetCoordinatesOfInputField(field_type_pair.first));
+ }
+
+ // Dismiss the virtual keyboard and wait for RequestHide().
+ content::SimulateTapAt(web_contents_, kNoTarget);
+ run_loop.Run();
+}
+
+IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, Disconnection) {
+ testing::InSequence s;
+ base::RunLoop on_show_run_loop;
+ EXPECT_CALL(*controller_,
+ SetTextType(virtualkeyboard::TextType::ALPHANUMERIC));
+ EXPECT_CALL(*controller_, RequestShow())
+ .WillOnce(testing::InvokeWithoutArgs(
+ [&on_show_run_loop]() { on_show_run_loop.Quit(); }));
+
+ // Tapping inside the text field should show the IME and signal RequestShow.
+ content::SimulateTapAt(web_contents_,
+ GetCoordinatesOfInputField(kInputFieldText));
+ on_show_run_loop.Run();
+
+ controller_->AwaitWatchAndRespondWith(true);
+ base::RunLoop().RunUntilIdle();
+
+ // Disconnect the FIDL service.
+ controller_.reset();
+ base::RunLoop().RunUntilIdle();
+
+ // Focus on another text field, then defocus. Nothing should crash.
+ content::SimulateTapAt(web_contents_,
+ GetCoordinatesOfInputField(kInputFieldNumeric));
+ content::SimulateTapAt(web_contents_, kNoTarget);
+}
+
+} // namespace
diff --git a/chromium/fuchsia/engine/browser/web_engine_browser_context.cc b/chromium/fuchsia/engine/browser/web_engine_browser_context.cc
index 448bc10167c..bfaeccf85da 100644
--- a/chromium/fuchsia/engine/browser/web_engine_browser_context.cc
+++ b/chromium/fuchsia/engine/browser/web_engine_browser_context.cc
@@ -11,13 +11,11 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
-#include "base/i18n/rtl.h"
#include "base/path_service.h"
#include "base/system/sys_info.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/keyed_service/core/simple_key_map.h"
#include "components/site_isolation/site_isolation_policy.h"
-#include "components/strings/grit/components_locale_settings.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
@@ -27,7 +25,6 @@
#include "media/capabilities/in_memory_video_decode_stats_db_impl.h"
#include "media/mojo/services/video_decode_perf_history.h"
#include "services/network/public/cpp/network_switches.h"
-#include "ui/base/l10n/l10n_util.h"
namespace {
@@ -189,36 +186,17 @@ WebEngineBrowserContext::GetBrowsingDataRemoverDelegate() {
return nullptr;
}
-media::VideoDecodePerfHistory*
-WebEngineBrowserContext::GetVideoDecodePerfHistory() {
- if (IsOffTheRecord())
- return GetInMemoryVideoDecodePerfHistory();
-
- // Delegate to the base class for stateful VideoDecodePerfHistory DB
- // creation.
- return BrowserContext::GetVideoDecodePerfHistory();
-}
-
-std::string WebEngineBrowserContext::GetPreferredLanguages() const {
- return l10n_util::GetStringUTF8(IDS_ACCEPT_LANGUAGES);
-}
-
-media::VideoDecodePerfHistory*
-WebEngineBrowserContext::GetInMemoryVideoDecodePerfHistory() {
- constexpr char kUserDataKeyName[] = "video-decode-perf-history";
- auto* decode_history = static_cast<media::VideoDecodePerfHistory*>(
- GetUserData(kUserDataKeyName));
-
- // Get, and potentially lazily create, the in-memory VideoDecodePerfHistory
- // DB.
- if (!decode_history) {
- auto owned_decode_history = std::make_unique<media::VideoDecodePerfHistory>(
- std::make_unique<media::InMemoryVideoDecodeStatsDBImpl>(
- nullptr /* seed_db_provider */),
- media::learning::FeatureProviderFactoryCB());
- decode_history = owned_decode_history.get();
- SetUserData(kUserDataKeyName, std::move(owned_decode_history));
+std::unique_ptr<media::VideoDecodePerfHistory>
+WebEngineBrowserContext::CreateVideoDecodePerfHistory() {
+ if (!IsOffTheRecord()) {
+ // Delegate to the base class for stateful VideoDecodePerfHistory DB
+ // creation.
+ return BrowserContext::CreateVideoDecodePerfHistory();
}
- return decode_history;
+ // Return in-memory VideoDecodePerfHistory.
+ return std::make_unique<media::VideoDecodePerfHistory>(
+ std::make_unique<media::InMemoryVideoDecodeStatsDBImpl>(
+ nullptr /* seed_db_provider */),
+ media::learning::FeatureProviderFactoryCB());
}
diff --git a/chromium/fuchsia/engine/browser/web_engine_browser_context.h b/chromium/fuchsia/engine/browser/web_engine_browser_context.h
index d20108d7ce3..76965a9d108 100644
--- a/chromium/fuchsia/engine/browser/web_engine_browser_context.h
+++ b/chromium/fuchsia/engine/browser/web_engine_browser_context.h
@@ -42,20 +42,13 @@ class WebEngineBrowserContext : public content::BrowserContext {
content::BackgroundSyncController* GetBackgroundSyncController() override;
content::BrowsingDataRemoverDelegate* GetBrowsingDataRemoverDelegate()
override;
- media::VideoDecodePerfHistory* GetVideoDecodePerfHistory() override;
-
- // Returns a comma-separated list of language codes, in preference order.
- // This is suitable for direct use setting the "sec-ch-lang" header, or
- // passed to net::HttpUtil::GenerateAcceptLanguageHeader() to generate a
- // legacy "accept-language" header value.
- std::string GetPreferredLanguages() const;
+ std::unique_ptr<media::VideoDecodePerfHistory> CreateVideoDecodePerfHistory()
+ override;
private:
// Contains URLRequestContextGetter required for resource loading.
class ResourceContext;
- media::VideoDecodePerfHistory* GetInMemoryVideoDecodePerfHistory();
-
base::FilePath data_dir_path_;
std::unique_ptr<WebEngineNetLogObserver> net_log_observer_;
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 7e526f4ec79..167d2fc9f9c 100644
--- a/chromium/fuchsia/engine/browser/web_engine_browser_main_parts.cc
+++ b/chromium/fuchsia/engine/browser/web_engine_browser_main_parts.cc
@@ -15,11 +15,13 @@
#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/histogram_fetcher.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/main_function_params.h"
+#include "content/public/common/result_codes.h"
#include "fuchsia/base/legacymetrics_client.h"
#include "fuchsia/engine/browser/context_impl.h"
#include "fuchsia/engine/browser/media_resource_provider_service.h"
@@ -56,9 +58,12 @@ void FetchHistogramsFromChildProcesses(
} // namespace
WebEngineBrowserMainParts::WebEngineBrowserMainParts(
+ content::ContentBrowserClient* browser_client,
const content::MainFunctionParams& parameters,
fidl::InterfaceRequest<fuchsia::web::Context> request)
- : parameters_(parameters), request_(std::move(request)) {
+ : browser_client_(browser_client),
+ parameters_(parameters),
+ request_(std::move(request)) {
DCHECK(request_);
}
@@ -66,11 +71,20 @@ WebEngineBrowserMainParts::~WebEngineBrowserMainParts() {
display::Screen::SetScreenInstance(nullptr);
}
+std::vector<content::BrowserContext*>
+WebEngineBrowserMainParts::browser_contexts() const {
+ std::vector<content::BrowserContext*> contexts;
+ contexts.reserve(context_bindings_.size());
+ for (auto& binding : context_bindings_.bindings())
+ contexts.push_back(binding->impl()->browser_context());
+ return contexts;
+}
+
void WebEngineBrowserMainParts::PostEarlyInitialization() {
base::ImportantFileWriterCleaner::GetInstance().Initialize();
}
-void WebEngineBrowserMainParts::PreMainMessageLoopRun() {
+int WebEngineBrowserMainParts::PreMainMessageLoopRun() {
DCHECK(!screen_);
// Watch for changes to the user's locale setting.
@@ -92,16 +106,27 @@ void WebEngineBrowserMainParts::PreMainMessageLoopRun() {
gpu_data_manager->DisableHardwareAcceleration();
}
- DCHECK(!browser_context_);
- browser_context_ = std::make_unique<WebEngineBrowserContext>(
+ DCHECK_EQ(context_bindings_.size(), 0u);
+ auto browser_context = std::make_unique<WebEngineBrowserContext>(
base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kIncognito));
devtools_controller_ = WebEngineDevToolsController::CreateFromCommandLine(
*base::CommandLine::ForCurrentProcess());
- context_service_ = std::make_unique<ContextImpl>(browser_context_.get(),
- devtools_controller_.get());
- context_binding_ = std::make_unique<fidl::Binding<fuchsia::web::Context>>(
- context_service_.get(), std::move(request_));
+
+ // TODO(crbug.com/1163073): Instead of creating a single ContextImpl instance
+ // the code below should public fuchsia.web.Context to the outgoing directory.
+ // Also it shouldn't quit main loop after Context disconnects.
+ context_bindings_.AddBinding(
+ std::make_unique<ContextImpl>(std::move(browser_context),
+ devtools_controller_.get()),
+ std::move(request_), /* dispatcher */ nullptr,
+ // Quit the browser main loop when the Context connection is dropped.
+ [this](zx_status_t status) {
+ ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status)
+ << " Context disconnected.";
+ // context_service_.reset();
+ std::move(quit_closure_).Run();
+ });
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseLegacyMetricsService)) {
@@ -122,22 +147,13 @@ void WebEngineBrowserMainParts::PreMainMessageLoopRun() {
media_resource_provider_service_ =
std::make_unique<MediaResourceProviderService>();
- // Quit the browser main loop when the Context connection is dropped.
- context_binding_->set_error_handler([this](zx_status_t status) {
- ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status)
- << " Context disconnected.";
- context_service_.reset();
- std::move(quit_closure_).Run();
- });
-
// Disable RenderFrameHost's Javascript injection restrictions so that the
// Context and Frames can implement their own JS injection policy at a higher
// level.
content::RenderFrameHost::AllowInjectingJavaScript();
if (parameters_.ui_task) {
- // Since the main loop won't run, there is nothing to quit in the
- // |context_binding_| error handler.
+ // Since the main loop won't run, there is nothing to quit.
quit_closure_ = base::DoNothing::Once();
std::move(*parameters_.ui_task).Run();
@@ -147,35 +163,37 @@ void WebEngineBrowserMainParts::PreMainMessageLoopRun() {
// Make sure temporary files associated with this process are cleaned up.
base::ImportantFileWriterCleaner::GetInstance().Start();
-}
-void WebEngineBrowserMainParts::PreDefaultMainMessageLoopRun(
- base::OnceClosure quit_closure) {
- quit_closure_ = std::move(quit_closure);
+ return content::RESULT_CODE_NORMAL_EXIT;
}
-bool WebEngineBrowserMainParts::MainMessageLoopRun(int* result_code) {
- return !run_message_loop_;
+void WebEngineBrowserMainParts::WillRunMainMessageLoop(
+ std::unique_ptr<base::RunLoop>& run_loop) {
+ if (run_message_loop_)
+ quit_closure_ = run_loop->QuitClosure();
+ else
+ run_loop.reset();
}
void WebEngineBrowserMainParts::PostMainMessageLoopRun() {
- // The service and its binding should have already been released by the error
- // handler.
- DCHECK(!context_service_);
- DCHECK(!context_binding_->is_bound());
+ // Main loop should quit only after all Context instances have been destroyed.
+ DCHECK_EQ(context_bindings_.size(), 0u);
// These resources must be freed while a MessageLoop is still available, so
// that they may post cleanup tasks during teardown.
- // NOTE: Please destroy objects in the reverse order of their creation.
+ // NOTE: Objects are destroyed in the reverse order of their creation.
legacy_metrics_client_.reset();
- context_binding_.reset();
- browser_context_.reset();
screen_.reset();
intl_profile_watcher_.reset();
base::ImportantFileWriterCleaner::GetInstance().Stop();
}
+ContextImpl* WebEngineBrowserMainParts::context_for_test() const {
+ DCHECK_EQ(context_bindings_.size(), 1u);
+ return context_bindings_.bindings().front()->impl().get();
+}
+
void WebEngineBrowserMainParts::OnIntlProfileChanged(
const fuchsia::intl::Profile& profile) {
// Configure the ICU library in this process with the new primary locale.
@@ -189,9 +207,14 @@ void WebEngineBrowserMainParts::OnIntlProfileChanged(
base::i18n::GetConfiguredLocale());
VLOG(1) << "Reloaded locale resources: " << loaded_locale;
- // Reconfigure the network process.
- content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
- ->GetNetworkContext()
- ->SetAcceptLanguage(net::HttpUtil::GenerateAcceptLanguageHeader(
- browser_context_->GetPreferredLanguages()));
+ // Reconfigure each web.Context's NetworkContext with the new setting.
+ for (auto& binding : context_bindings_.bindings()) {
+ content::BrowserContext* const browser_context =
+ binding->impl()->browser_context();
+ std::string accept_language = net::HttpUtil::GenerateAcceptLanguageHeader(
+ browser_client_->GetAcceptLangs(browser_context));
+ content::BrowserContext::GetDefaultStoragePartition(browser_context)
+ ->GetNetworkContext()
+ ->SetAcceptLanguage(accept_language);
+ }
}
diff --git a/chromium/fuchsia/engine/browser/web_engine_browser_main_parts.h b/chromium/fuchsia/engine/browser/web_engine_browser_main_parts.h
index be584748940..0e557eadb93 100644
--- a/chromium/fuchsia/engine/browser/web_engine_browser_main_parts.h
+++ b/chromium/fuchsia/engine/browser/web_engine_browser_main_parts.h
@@ -15,6 +15,7 @@
#include "content/public/browser/browser_main_parts.h"
#include "fuchsia/engine/browser/context_impl.h"
#include "fuchsia/engine/browser/web_engine_browser_context.h"
+#include "fuchsia/engine/web_engine_export.h"
namespace base {
class FuchsiaIntlProfileWatcher;
@@ -25,6 +26,7 @@ class Screen;
}
namespace content {
+class ContentBrowserClient;
struct MainFunctionParams;
}
@@ -34,16 +36,16 @@ class LegacyMetricsClient;
class MediaResourceProviderService;
-class WebEngineBrowserMainParts : public content::BrowserMainParts {
+class WEB_ENGINE_EXPORT WebEngineBrowserMainParts
+ : public content::BrowserMainParts {
public:
explicit WebEngineBrowserMainParts(
+ content::ContentBrowserClient* browser_client,
const content::MainFunctionParams& parameters,
fidl::InterfaceRequest<fuchsia::web::Context> request);
~WebEngineBrowserMainParts() override;
- content::BrowserContext* browser_context() const {
- return browser_context_.get();
- }
+ std::vector<content::BrowserContext*> browser_contexts() const;
WebEngineDevToolsController* devtools_controller() const {
return devtools_controller_.get();
}
@@ -53,24 +55,24 @@ class WebEngineBrowserMainParts : public content::BrowserMainParts {
// content::BrowserMainParts overrides.
void PostEarlyInitialization() override;
- void PreMainMessageLoopRun() override;
- void PreDefaultMainMessageLoopRun(base::OnceClosure quit_closure) override;
- bool MainMessageLoopRun(int* result_code) override;
+ int PreMainMessageLoopRun() override;
+ void WillRunMainMessageLoop(
+ std::unique_ptr<base::RunLoop>& run_loop) override;
void PostMainMessageLoopRun() override;
- ContextImpl* context_for_test() const { return context_service_.get(); }
+ ContextImpl* context_for_test() const;
private:
void OnIntlProfileChanged(const fuchsia::intl::Profile& profile);
+ content::ContentBrowserClient* const browser_client_;
const content::MainFunctionParams& parameters_;
fidl::InterfaceRequest<fuchsia::web::Context> request_;
std::unique_ptr<display::Screen> screen_;
- std::unique_ptr<WebEngineBrowserContext> browser_context_;
- std::unique_ptr<ContextImpl> context_service_;
- std::unique_ptr<fidl::Binding<fuchsia::web::Context>> context_binding_;
+ fidl::BindingSet<fuchsia::web::Context, std::unique_ptr<ContextImpl>>
+ context_bindings_;
std::unique_ptr<WebEngineDevToolsController> devtools_controller_;
std::unique_ptr<cr_fuchsia::LegacyMetricsClient> legacy_metrics_client_;
std::unique_ptr<MediaResourceProviderService>
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 86ec922a9f5..1be5181e60d 100644
--- a/chromium/fuchsia/engine/browser/web_engine_content_browser_client.cc
+++ b/chromium/fuchsia/engine/browser/web_engine_content_browser_client.cc
@@ -14,6 +14,7 @@
#include "components/policy/content/safe_sites_navigation_throttle.h"
#include "components/site_isolation/features.h"
#include "components/site_isolation/preloaded_isolated_origins.h"
+#include "components/strings/grit/components_locale_settings.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/devtools_manager_delegate.h"
@@ -37,32 +38,35 @@
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "third_party/blink/public/mojom/webpreferences/web_preferences.mojom.h"
+#include "ui/base/l10n/l10n_util.h"
namespace {
class DevToolsManagerDelegate : public content::DevToolsManagerDelegate {
public:
- DevToolsManagerDelegate(content::BrowserContext* browser_context,
- WebEngineDevToolsController* controller)
- : browser_context_(browser_context), controller_(controller) {
- DCHECK(browser_context_);
- DCHECK(controller_);
+ explicit DevToolsManagerDelegate(WebEngineBrowserMainParts* main_parts)
+ : main_parts_(main_parts) {
+ DCHECK(main_parts_);
}
~DevToolsManagerDelegate() final = default;
+ DevToolsManagerDelegate(const DevToolsManagerDelegate&) = delete;
+ DevToolsManagerDelegate& operator=(const DevToolsManagerDelegate&) = delete;
+
// content::DevToolsManagerDelegate implementation.
+ std::vector<content::BrowserContext*> GetBrowserContexts() final {
+ return main_parts_->browser_contexts();
+ }
content::BrowserContext* GetDefaultBrowserContext() final {
- return browser_context_;
+ std::vector<content::BrowserContext*> contexts = GetBrowserContexts();
+ return contexts.empty() ? nullptr : contexts.front();
}
content::DevToolsAgentHost::List RemoteDebuggingTargets() final {
- return controller_->RemoteDebuggingTargets();
+ return main_parts_->devtools_controller()->RemoteDebuggingTargets();
}
private:
- content::BrowserContext* const browser_context_;
- WebEngineDevToolsController* const controller_;
-
- DISALLOW_COPY_AND_ASSIGN(DevToolsManagerDelegate);
+ WebEngineBrowserMainParts* const main_parts_;
};
std::vector<std::string> GetCorsExemptHeaders() {
@@ -88,18 +92,17 @@ WebEngineContentBrowserClient::CreateBrowserMainParts(
const content::MainFunctionParams& parameters) {
DCHECK(request_);
auto browser_main_parts = std::make_unique<WebEngineBrowserMainParts>(
- parameters, std::move(request_));
+ this, parameters, std::move(request_));
main_parts_ = browser_main_parts.get();
return browser_main_parts;
}
-content::DevToolsManagerDelegate*
-WebEngineContentBrowserClient::GetDevToolsManagerDelegate() {
+std::unique_ptr<content::DevToolsManagerDelegate>
+WebEngineContentBrowserClient::CreateDevToolsManagerDelegate() {
DCHECK(main_parts_);
- return new DevToolsManagerDelegate(main_parts_->browser_context(),
- main_parts_->devtools_controller());
+ return std::make_unique<DevToolsManagerDelegate>(main_parts_);
}
std::string WebEngineContentBrowserClient::GetProduct() {
@@ -197,9 +200,11 @@ std::string WebEngineContentBrowserClient::GetApplicationLocale() {
std::string WebEngineContentBrowserClient::GetAcceptLangs(
content::BrowserContext* context) {
- DCHECK_EQ(main_parts_->browser_context(), context);
- return static_cast<WebEngineBrowserContext*>(context)
- ->GetPreferredLanguages();
+ // Returns a comma-separated list of language codes, in preference order.
+ // This is suitable for direct use setting the "sec-ch-lang" header, or
+ // passed to net::HttpUtil::GenerateAcceptLanguageHeader() to generate a
+ // legacy "accept-language" header value.
+ return l10n_util::GetStringUTF8(IDS_ACCEPT_LANGUAGES);
}
base::OnceClosure WebEngineContentBrowserClient::SelectClientCertificate(
@@ -270,9 +275,8 @@ void WebEngineContentBrowserClient::ConfigureNetworkContextParams(
cert_verifier::mojom::CertVerifierCreationParams*
cert_verifier_creation_params) {
network_context_params->user_agent = GetUserAgent();
- network_context_params
- ->accept_language = net::HttpUtil::GenerateAcceptLanguageHeader(
- static_cast<WebEngineBrowserContext*>(context)->GetPreferredLanguages());
+ network_context_params->accept_language =
+ net::HttpUtil::GenerateAcceptLanguageHeader(GetAcceptLangs(context));
// Set the list of cors_exempt_headers which may be specified in a URLRequest,
// starting with the headers passed in via
@@ -292,4 +296,4 @@ WebEngineContentBrowserClient::GetOriginsRequiringDedicatedProcess() {
std::back_inserter(isolated_origin_list));
return isolated_origin_list;
-} \ No newline at end of file
+}
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 cab50c3a4e1..eef19310697 100644
--- a/chromium/fuchsia/engine/browser/web_engine_content_browser_client.h
+++ b/chromium/fuchsia/engine/browser/web_engine_content_browser_client.h
@@ -12,7 +12,6 @@
#include <string>
#include <vector>
-#include "base/macros.h"
#include "content/public/browser/content_browser_client.h"
#include "fuchsia/engine/browser/content_directory_loader_factory.h"
#include "mojo/public/cpp/bindings/binder_map.h"
@@ -26,12 +25,15 @@ class WebEngineContentBrowserClient : public content::ContentBrowserClient {
fidl::InterfaceRequest<fuchsia::web::Context> request);
~WebEngineContentBrowserClient() final;
- WebEngineBrowserMainParts* main_parts_for_test() const { return main_parts_; }
+ WebEngineContentBrowserClient(const WebEngineContentBrowserClient&) = delete;
+ WebEngineContentBrowserClient& operator=(
+ const WebEngineContentBrowserClient&) = delete;
// ContentBrowserClient overrides.
std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(
const content::MainFunctionParams& parameters) final;
- content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() final;
+ std::unique_ptr<content::DevToolsManagerDelegate>
+ CreateDevToolsManagerDelegate() final;
std::string GetProduct() final;
std::string GetUserAgent() final;
void OverrideWebkitPrefs(content::WebContents* web_contents,
@@ -76,6 +78,8 @@ class WebEngineContentBrowserClient : public content::ContentBrowserClient {
cert_verifier_creation_params) final;
std::vector<url::Origin> GetOriginsRequiringDedicatedProcess() final;
+ WebEngineBrowserMainParts* main_parts_for_test() const { return main_parts_; }
+
private:
fidl::InterfaceRequest<fuchsia::web::Context> request_;
@@ -84,8 +88,6 @@ class WebEngineContentBrowserClient : public content::ContentBrowserClient {
// Owned by content::BrowserMainLoop.
WebEngineBrowserMainParts* main_parts_;
-
- DISALLOW_COPY_AND_ASSIGN(WebEngineContentBrowserClient);
};
#endif // FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_CONTENT_BROWSER_CLIENT_H_
diff --git a/chromium/fuchsia/engine/browser/web_engine_devtools_controller.cc b/chromium/fuchsia/engine/browser/web_engine_devtools_controller.cc
index 5deb754b232..ef8e9a87512 100644
--- a/chromium/fuchsia/engine/browser/web_engine_devtools_controller.cc
+++ b/chromium/fuchsia/engine/browser/web_engine_devtools_controller.cc
@@ -200,11 +200,10 @@ class UserModeController : public WebEngineDevToolsController {
class DebugModeController : public WebEngineDevToolsController {
public:
explicit DebugModeController(
- std::vector<fuchsia::web::DevToolsPerContextListenerPtr> listeners) {
- for (auto& listener : listeners) {
- devtools_listeners_.AddInterfacePtr(std::move(listener));
- }
- }
+ std::vector<fuchsia::web::DevToolsPerContextListenerPtr> listeners)
+ : DebugModeController(
+ std::move(listeners),
+ net::IPEndPoint(net::IPAddress::IPv4Localhost(), 0)) {}
~DebugModeController() override = default;
DebugModeController(const DebugModeController&) = delete;
@@ -215,7 +214,7 @@ class DebugModeController : public WebEngineDevToolsController {
StartRemoteDebuggingServer(
base::BindOnce(&DebugModeController::OnDevToolsPortChanged,
base::Unretained(this)),
- net::IPEndPoint(net::IPAddress::IPv4Localhost(), 0));
+ ip_endpoint_);
}
void OnContextDestroyed() override {
content::DevToolsAgentHost::StopRemoteDebuggingServer();
@@ -236,12 +235,25 @@ class DebugModeController : public WebEngineDevToolsController {
std::move(callback).Run(0);
}
- private:
- void OnDevToolsPortChanged(uint16_t port) {
+ protected:
+ DebugModeController(
+ std::vector<fuchsia::web::DevToolsPerContextListenerPtr> listeners,
+ net::IPEndPoint ip_endpoint)
+ : ip_endpoint_(std::move(ip_endpoint)) {
+ for (auto& listener : listeners) {
+ devtools_listeners_.AddInterfacePtr(std::move(listener));
+ }
+ }
+
+ virtual void OnDevToolsPortChanged(uint16_t port) {
devtools_port_ = port;
MaybeSendRemoteDebuggingCallbacks();
}
+ // Currently active DevTools port. Set to 0 on service startup error.
+ base::Optional<uint16_t> devtools_port_;
+
+ private:
void MaybeSendRemoteDebuggingCallbacks() {
if (!frame_loaded_ || !devtools_port_)
return;
@@ -257,8 +269,7 @@ class DebugModeController : public WebEngineDevToolsController {
}
}
- // Currently active DevTools port. Set to 0 on service startup error.
- base::Optional<uint16_t> devtools_port_;
+ const net::IPEndPoint ip_endpoint_;
bool frame_loaded_ = false;
@@ -269,53 +280,30 @@ class DebugModeController : public WebEngineDevToolsController {
// "Mixed-mode" is used when both user and debug remote debugging are active at
// the same time. The service lifespan is tied to the Context and all Frames are
// available for remote debugging.
-class MixedModeController : public WebEngineDevToolsController {
+class MixedModeController : public DebugModeController {
public:
- explicit MixedModeController(
+ MixedModeController(
std::vector<fuchsia::web::DevToolsPerContextListenerPtr> listeners,
uint16_t server_port)
- : ip_endpoint_(net::IPAddress::IPv6AllZeros(), server_port) {
- for (auto& listener : listeners) {
- devtools_listeners_.AddInterfacePtr(std::move(listener));
- }
- }
+ : DebugModeController(
+ std::move(listeners),
+ net::IPEndPoint(net::IPAddress::IPv6AllZeros(), server_port)) {}
~MixedModeController() override = default;
- MixedModeController(const MixedModeController&) = delete;
- MixedModeController& operator=(const MixedModeController&) = delete;
-
- // WebEngineDevToolsController implementation:
- void OnContextCreated() override {
- StartRemoteDebuggingServer(
- base::BindOnce(&MixedModeController::OnDevToolsPortChanged,
- base::Unretained(this)),
- ip_endpoint_);
- }
- void OnContextDestroyed() override {
- content::DevToolsAgentHost::StopRemoteDebuggingServer();
- }
+ // WebEngineDevToolsController overrides:
bool OnFrameCreated(content::WebContents* contents,
bool user_debugging) override {
return true;
}
- void OnFrameLoaded(content::WebContents* contents) override {
- frame_loaded_ = true;
- MaybeSendRemoteDebuggingCallbacks();
- }
- void OnFrameDestroyed(content::WebContents* contents) override {}
- content::DevToolsAgentHost::List RemoteDebuggingTargets() override {
- return content::DevToolsAgentHost::GetOrCreateAll();
- }
void GetDevToolsPort(base::OnceCallback<void(uint16_t)> callback) override {
get_port_callbacks_.emplace_back(std::move(callback));
MaybeNotifyGetPortCallbacks();
}
- private:
- void OnDevToolsPortChanged(uint16_t port) {
- devtools_port_ = port;
+ // DebugModeController overrides:
+ void OnDevToolsPortChanged(uint16_t port) override {
+ DebugModeController::OnDevToolsPortChanged(port);
MaybeNotifyGetPortCallbacks();
- MaybeSendRemoteDebuggingCallbacks();
}
void MaybeNotifyGetPortCallbacks() {
@@ -326,32 +314,7 @@ class MixedModeController : public WebEngineDevToolsController {
get_port_callbacks_.clear();
}
- void MaybeSendRemoteDebuggingCallbacks() {
- if (!frame_loaded_ || !devtools_port_)
- return;
-
- // If |devtools_port_| is valid then notify all listeners, otherwise
- // disconnect them.
- if (devtools_port_.value() == 0) {
- devtools_listeners_.CloseAll();
- } else {
- for (const auto& listener : devtools_listeners_.ptrs()) {
- listener->get()->OnHttpPortOpen(devtools_port_.value());
- }
- }
- }
-
- const net::IPEndPoint ip_endpoint_;
-
- // Currently active DevTools port. Set to 0 on service startup error.
- base::Optional<uint16_t> devtools_port_;
-
std::vector<base::OnceCallback<void(uint16_t)>> get_port_callbacks_;
-
- bool frame_loaded_ = false;
-
- fidl::InterfacePtrSet<fuchsia::web::DevToolsPerContextListener>
- devtools_listeners_;
};
} // namespace
@@ -364,7 +327,7 @@ WebEngineDevToolsController::CreateFromCommandLine(
if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
// Set up DevTools to listen on all network routes on the command-line
// provided port.
- base::StringPiece command_line_port_value =
+ std::string command_line_port_value =
command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
int parsed_port = 0;
diff --git a/chromium/fuchsia/engine/browser/web_engine_permission_delegate.cc b/chromium/fuchsia/engine/browser/web_engine_permission_delegate.cc
index c18b8be7cdf..2ab7dd52502 100644
--- a/chromium/fuchsia/engine/browser/web_engine_permission_delegate.cc
+++ b/chromium/fuchsia/engine/browser/web_engine_permission_delegate.cc
@@ -4,6 +4,8 @@
#include "fuchsia/engine/browser/web_engine_permission_delegate.h"
+#include <utility>
+
#include "base/callback.h"
#include "base/check_op.h"
#include "base/notreached.h"
@@ -15,7 +17,7 @@
WebEnginePermissionDelegate::WebEnginePermissionDelegate() = default;
WebEnginePermissionDelegate::~WebEnginePermissionDelegate() = default;
-int WebEnginePermissionDelegate::RequestPermission(
+void WebEnginePermissionDelegate::RequestPermission(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& origin,
@@ -30,12 +32,10 @@ int WebEnginePermissionDelegate::RequestPermission(
DCHECK_EQ(state.size(), 1U);
std::move(callback).Run(state[0]);
},
- base::Passed(std::move(callback))));
-
- return content::PermissionController::kNoPendingOperation;
+ std::move(callback)));
}
-int WebEnginePermissionDelegate::RequestPermissions(
+void WebEnginePermissionDelegate::RequestPermissions(
const std::vector<content::PermissionType>& permissions,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
@@ -47,8 +47,6 @@ int WebEnginePermissionDelegate::RequestPermissions(
frame->permission_controller()->RequestPermissions(
permissions, url::Origin::Create(requesting_origin), user_gesture,
std::move(callback));
-
- return content::PermissionController::kNoPendingOperation;
}
void WebEnginePermissionDelegate::ResetPermission(
diff --git a/chromium/fuchsia/engine/browser/web_engine_permission_delegate.h b/chromium/fuchsia/engine/browser/web_engine_permission_delegate.h
index c39989b471c..adafc1d5704 100644
--- a/chromium/fuchsia/engine/browser/web_engine_permission_delegate.h
+++ b/chromium/fuchsia/engine/browser/web_engine_permission_delegate.h
@@ -20,13 +20,14 @@ class WebEnginePermissionDelegate
WebEnginePermissionDelegate& operator=(WebEnginePermissionDelegate&) = delete;
// content::PermissionControllerDelegate implementation:
- int RequestPermission(content::PermissionType permission,
- content::RenderFrameHost* render_frame_host,
- const GURL& requesting_origin,
- bool user_gesture,
- base::OnceCallback<void(blink::mojom::PermissionStatus)>
- callback) override;
- int RequestPermissions(
+ void RequestPermission(
+ content::PermissionType permission,
+ content::RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ base::OnceCallback<void(blink::mojom::PermissionStatus)> callback)
+ override;
+ void RequestPermissions(
const std::vector<content::PermissionType>& permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
diff --git a/chromium/fuchsia/engine/common/web_engine_content_client.cc b/chromium/fuchsia/engine/common/web_engine_content_client.cc
index 30d007dfe4c..1f9a18a3d33 100644
--- a/chromium/fuchsia/engine/common/web_engine_content_client.cc
+++ b/chromium/fuchsia/engine/common/web_engine_content_client.cc
@@ -14,7 +14,7 @@
WebEngineContentClient::WebEngineContentClient() = default;
WebEngineContentClient::~WebEngineContentClient() = default;
-base::string16 WebEngineContentClient::GetLocalizedString(int message_id) {
+std::u16string WebEngineContentClient::GetLocalizedString(int message_id) {
return l10n_util::GetStringUTF16(message_id);
}
diff --git a/chromium/fuchsia/engine/common/web_engine_content_client.h b/chromium/fuchsia/engine/common/web_engine_content_client.h
index 95a9e1d6500..2383b07944d 100644
--- a/chromium/fuchsia/engine/common/web_engine_content_client.h
+++ b/chromium/fuchsia/engine/common/web_engine_content_client.h
@@ -14,7 +14,7 @@ class WebEngineContentClient : public content::ContentClient {
~WebEngineContentClient() override;
// content::ContentClient implementation.
- base::string16 GetLocalizedString(int message_id) override;
+ std::u16string GetLocalizedString(int message_id) override;
base::StringPiece GetDataResource(int resource_id,
ui::ScaleFactor scale_factor) override;
base::RefCountedMemory* GetDataResourceBytes(int resource_id) override;
diff --git a/chromium/fuchsia/engine/context_provider_impl.cc b/chromium/fuchsia/engine/context_provider_impl.cc
index cacb6e9905b..5c8dc52312e 100644
--- a/chromium/fuchsia/engine/context_provider_impl.cc
+++ b/chromium/fuchsia/engine/context_provider_impl.cc
@@ -170,6 +170,7 @@ bool MaybeAddCommandLineArgsFromConfig(const base::Value& config,
switches::kGoogleApiKey,
switches::kMaxDecodedImageSizeMb,
switches::kRendererProcessLimit,
+ switches::kUseCmdDecoder,
switches::kVModule,
switches::kVulkanHeapMemoryLimitMb,
switches::kVulkanSyncCpuMemoryLimitMb,
diff --git a/chromium/fuchsia/engine/renderer/DEPS b/chromium/fuchsia/engine/renderer/DEPS
index f6d592b8e85..3a2d94b1d26 100644
--- a/chromium/fuchsia/engine/renderer/DEPS
+++ b/chromium/fuchsia/engine/renderer/DEPS
@@ -4,5 +4,5 @@ include_rules = [
"+media",
"+mojo/public/cpp/bindings",
"+services/service_manager/public/cpp",
- "+third_party/blink/public/common/associated_interfaces",
+ "+third_party/blink/public",
]
diff --git a/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.cc b/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.cc
index ceee3e16c72..56f71f59732 100644
--- a/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.cc
+++ b/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.cc
@@ -13,6 +13,7 @@
#include "components/on_load_script_injector/renderer/on_load_script_injector.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_view.h"
#include "fuchsia/engine/common/cast_streaming.h"
#include "fuchsia/engine/features.h"
#include "fuchsia/engine/renderer/cast_streaming_demuxer.h"
@@ -23,6 +24,7 @@
#include "services/network/public/cpp/features.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
+#include "third_party/blink/public/web/web_view.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
namespace {
@@ -30,7 +32,7 @@ namespace {
// Returns true if the specified video format can be decoded on hardware.
bool IsSupportedHardwareVideoCodec(const media::VideoType& type) {
// TODO(crbug.com/1013412): Replace these hardcoded checks with a query to the
- // fuchsia.mediacodec FIDL service when fxb/36000 is resolved.
+ // fuchsia.mediacodec FIDL service.
if (type.codec == media::kCodecH264 && type.level <= 41)
return true;
@@ -43,11 +45,9 @@ bool IsSupportedHardwareVideoCodec(const media::VideoType& type) {
class PlayreadyKeySystemProperties : public ::media::KeySystemProperties {
public:
PlayreadyKeySystemProperties(const std::string& key_system_name,
- media::SupportedCodecs supported_codecs,
- bool persistent_usage_record_support)
+ media::SupportedCodecs supported_codecs)
: key_system_name_(key_system_name),
- supported_codecs_(supported_codecs),
- persistent_usage_record_support_(persistent_usage_record_support) {}
+ supported_codecs_(supported_codecs) {}
std::string GetKeySystemName() const override { return key_system_name_; }
@@ -75,24 +75,9 @@ class PlayreadyKeySystemProperties : public ::media::KeySystemProperties {
return media::EmeConfigRule::NOT_SUPPORTED;
}
- // For backward compatible, currently JS will create a persistent license
- // session and inject a special init data as the persistent usage record
- // session signal. In other words, the platform has to announce the support of
- // persistent license session to allow JS use the persistent usage record
- // session functions.
- // TODO(internal b/142749428): Remove once the temporary solution is removed.
media::EmeSessionTypeSupport GetPersistentLicenseSessionSupport()
const override {
- return persistent_usage_record_support_
- ? media::EmeSessionTypeSupport::SUPPORTED
- : media::EmeSessionTypeSupport::NOT_SUPPORTED;
- }
-
- media::EmeSessionTypeSupport GetPersistentUsageRecordSessionSupport()
- const override {
- return persistent_usage_record_support_
- ? media::EmeSessionTypeSupport::SUPPORTED
- : media::EmeSessionTypeSupport::NOT_SUPPORTED;
+ return media::EmeSessionTypeSupport::NOT_SUPPORTED;
}
media::EmeFeatureSupport GetPersistentStateSupport() const override {
@@ -115,7 +100,6 @@ class PlayreadyKeySystemProperties : public ::media::KeySystemProperties {
private:
const std::string key_system_name_;
const media::SupportedCodecs supported_codecs_;
- const bool persistent_usage_record_support_;
};
} // namespace
@@ -156,6 +140,14 @@ void WebEngineContentRendererClient::RenderThreadStarted() {
void WebEngineContentRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) {
+ // If this is a top-level frame then it should have a transparent background.
+ // Both the RenderView and WebView should be guaranteed to be non-null, since
+ // the |render_frame| was only just created.
+ if (render_frame->IsMainFrame()) {
+ render_frame->GetRenderView()->GetWebView()->SetBaseBackgroundColor(
+ SK_AlphaTRANSPARENT);
+ }
+
// Add WebEngine services to the new RenderFrame.
// The objects' lifetimes are bound to the RenderFrame's lifetime.
new on_load_script_injector::OnLoadScriptInjector(render_frame);
@@ -174,13 +166,13 @@ void WebEngineContentRendererClient::RenderFrameCreated(
new media_control::MediaPlaybackOptions(render_frame);
}
-std::unique_ptr<content::URLLoaderThrottleProvider>
+std::unique_ptr<blink::URLLoaderThrottleProvider>
WebEngineContentRendererClient::CreateURLLoaderThrottleProvider(
- content::URLLoaderThrottleProviderType type) {
+ blink::URLLoaderThrottleProviderType type) {
DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
// TODO(crbug.com/976975): Add support for service workers.
- if (type == content::URLLoaderThrottleProviderType::kWorker)
+ if (type == blink::URLLoaderThrottleProviderType::kWorker)
return nullptr;
return std::make_unique<WebEngineURLLoaderThrottleProvider>(this);
@@ -221,6 +213,8 @@ void WebEngineContentRendererClient::AddSupportedKeySystems(
// Fuchsia always decrypts audio into clear buffers and return them back to
// Chromium. Hardware secured decoders are only available for supported
// video codecs.
+ // TODO(crbug.com/1013412): Replace these hardcoded values with a query to
+ // the fuchsia.mediacodec FIDL service.
key_systems->emplace_back(new cdm::WidevineKeySystemProperties(
supported_codecs, // codecs
encryption_schemes, // encryption schemes
@@ -229,11 +223,10 @@ void WebEngineContentRendererClient::AddSupportedKeySystems(
cdm::WidevineKeySystemProperties::Robustness::
HW_SECURE_CRYPTO, // max audio robustness
cdm::WidevineKeySystemProperties::Robustness::
- HW_SECURE_ALL, // max video robustness
- media::EmeSessionTypeSupport::SUPPORTED, // persistent license
- media::EmeSessionTypeSupport::SUPPORTED, // persistent usage record
- media::EmeFeatureSupport::ALWAYS_ENABLED, // persistent state
- media::EmeFeatureSupport::ALWAYS_ENABLED)); // distinctive identifier
+ HW_SECURE_ALL, // max video robustness
+ media::EmeSessionTypeSupport::NOT_SUPPORTED, // persistent license
+ media::EmeFeatureSupport::ALWAYS_ENABLED, // persistent state
+ media::EmeFeatureSupport::ALWAYS_ENABLED)); // distinctive identifier
}
std::string playready_key_system =
@@ -241,8 +234,7 @@ void WebEngineContentRendererClient::AddSupportedKeySystems(
switches::kPlayreadyKeySystem);
if (!playready_key_system.empty()) {
key_systems->emplace_back(new PlayreadyKeySystemProperties(
- playready_key_system, supported_codecs,
- /*persistent_usage_record_support=*/true));
+ playready_key_system, supported_codecs));
}
}
diff --git a/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.h b/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.h
index 9d718570b01..b5a57304cd9 100644
--- a/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.h
+++ b/chromium/fuchsia/engine/renderer/web_engine_content_renderer_client.h
@@ -35,9 +35,9 @@ class WebEngineContentRendererClient : public content::ContentRendererClient {
std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems)
override;
bool IsSupportedVideoType(const media::VideoType& type) override;
- std::unique_ptr<content::URLLoaderThrottleProvider>
+ std::unique_ptr<blink::URLLoaderThrottleProvider>
CreateURLLoaderThrottleProvider(
- content::URLLoaderThrottleProviderType type) override;
+ blink::URLLoaderThrottleProviderType type) override;
bool DeferMediaLoad(content::RenderFrame* render_frame,
bool has_played_media_before,
base::OnceClosure closure) override;
diff --git a/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.cc b/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.cc
index ea5b4b1d3fa..7fda178d227 100644
--- a/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.cc
+++ b/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.cc
@@ -18,14 +18,14 @@ WebEngineURLLoaderThrottleProvider::~WebEngineURLLoaderThrottleProvider() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
-std::unique_ptr<content::URLLoaderThrottleProvider>
+std::unique_ptr<blink::URLLoaderThrottleProvider>
WebEngineURLLoaderThrottleProvider::Clone() {
// This should only happen for service workers, which we do not support here.
NOTREACHED();
return nullptr;
}
-std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
+blink::WebVector<std::unique_ptr<blink::URLLoaderThrottle>>
WebEngineURLLoaderThrottleProvider::CreateThrottles(
int render_frame_id,
const blink::WebURLRequest& request) {
@@ -35,7 +35,7 @@ WebEngineURLLoaderThrottleProvider::CreateThrottles(
// bug has been found.
CHECK_NE(render_frame_id, MSG_ROUTING_NONE);
- std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
+ blink::WebVector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
scoped_refptr<WebEngineURLLoaderThrottle::UrlRequestRewriteRules>& rules =
content_renderer_client_
->GetWebEngineRenderFrameObserverForRenderFrameId(render_frame_id)
diff --git a/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.h b/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.h
index 88d656a8600..b4924576367 100644
--- a/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.h
+++ b/chromium/fuchsia/engine/renderer/web_engine_url_loader_throttle_provider.h
@@ -7,7 +7,7 @@
#include "base/macros.h"
#include "base/sequence_checker.h"
-#include "content/public/renderer/url_loader_throttle_provider.h"
+#include "third_party/blink/public/platform/url_loader_throttle_provider.h"
class WebEngineContentRendererClient;
@@ -15,15 +15,15 @@ class WebEngineContentRendererClient;
// URLLoaderThrottles, implemented as WebEngineURLLoaderThrottles for network
// requests.
class WebEngineURLLoaderThrottleProvider
- : public content::URLLoaderThrottleProvider {
+ : public blink::URLLoaderThrottleProvider {
public:
explicit WebEngineURLLoaderThrottleProvider(
WebEngineContentRendererClient* content_renderer_client);
~WebEngineURLLoaderThrottleProvider() override;
- // content::URLLoaderThrottleProvider implementation.
- std::unique_ptr<content::URLLoaderThrottleProvider> Clone() override;
- std::vector<std::unique_ptr<blink::URLLoaderThrottle>> CreateThrottles(
+ // blink::URLLoaderThrottleProvider implementation.
+ std::unique_ptr<blink::URLLoaderThrottleProvider> Clone() override;
+ blink::WebVector<std::unique_ptr<blink::URLLoaderThrottle>> CreateThrottles(
int render_frame_id,
const blink::WebURLRequest& request) override;
void SetOnline(bool is_online) override;
diff --git a/chromium/fuchsia/engine/web_engine_integration_test.cc b/chromium/fuchsia/engine/web_engine_integration_test.cc
index 8c3e51118c2..6d77bfb2383 100644
--- a/chromium/fuchsia/engine/web_engine_integration_test.cc
+++ b/chromium/fuchsia/engine/web_engine_integration_test.cc
@@ -17,9 +17,8 @@
#include "media/base/media_switches.h"
#include "media/fuchsia/audio/fake_audio_consumer.h"
#include "media/fuchsia/camera/fake_fuchsia_camera.h"
-#include "net/base/test_completion_callback.h"
#include "net/http/http_request_headers.h"
-#include "net/socket/tcp_client_socket.h"
+#include "testing/gmock/include/gmock/gmock.h"
namespace {
@@ -245,32 +244,8 @@ TEST_F(WebEngineIntegrationTest, RemoteDebuggingPort) {
// handled the Frame tear down.
controller_run_loop.Run();
- // Verify that devtools server is shut down properly. WebEngine may shutdown
- // the socket after shutting down the Frame, so make several attempts to
- // connect until it fails. Don't try to read or write from/to the socket to
- // avoid fxb/49779.
- bool failed_to_connect = false;
- for (int i = 0; i < 10; ++i) {
- net::TestCompletionCallback connect_callback;
- net::TCPClientSocket connecting_socket(
- net::AddressList(net::IPEndPoint(net::IPAddress::IPv4Localhost(),
- remote_debugging_port)),
- nullptr, nullptr, nullptr, net::NetLogSource());
- int connect_result = connecting_socket.Connect(connect_callback.callback());
- connect_result = connect_callback.GetResult(connect_result);
-
- if (connect_result == net::OK) {
- // If Connect() succeeded then try again a bit later.
- base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
- continue;
- }
-
- EXPECT_EQ(connect_result, net::ERR_CONNECTION_REFUSED);
- failed_to_connect = true;
- break;
- }
-
- EXPECT_TRUE(failed_to_connect);
+ devtools_list = cr_fuchsia::GetDevToolsListFromPort(remote_debugging_port);
+ EXPECT_TRUE(devtools_list.is_none());
}
// Check that remote debugging requests for Frames in non-debuggable Contexts
@@ -404,7 +379,7 @@ TEST_F(WebEngineIntegrationMediaTest, MicrophoneAccess_WithoutPermission) {
navigation_controller_.get(), fuchsia::web::LoadUrlParams(),
embedded_test_server_.GetURL("/mic.html?NoPermission").spec()));
- navigation_listener_->RunUntilTitleEquals("ended");
+ navigation_listener_->RunUntilTitleEquals("ended-NotFoundError");
}
TEST_F(WebEngineIntegrationMediaTest, SetBlockMediaLoading_Blocked) {
diff --git a/chromium/fuchsia/engine/web_engine_integration_test_base.cc b/chromium/fuchsia/engine/web_engine_integration_test_base.cc
index 513953a8a76..91345438687 100644
--- a/chromium/fuchsia/engine/web_engine_integration_test_base.cc
+++ b/chromium/fuchsia/engine/web_engine_integration_test_base.cc
@@ -81,13 +81,16 @@ WebEngineIntegrationTestBase::ContextParamsWithFilteredServiceDirectory() {
std::make_unique<base::FilteredServiceDirectory>(
base::ComponentContextForProcess()->svc().get());
fidl::InterfaceHandle<fuchsia::io::Directory> svc_dir;
- filtered_service_directory_->ConnectClient(svc_dir.NewRequest());
+ EXPECT_EQ(filtered_service_directory_->ConnectClient(svc_dir.NewRequest()),
+ ZX_OK);
// Push all services from /svc to the service directory.
base::FileEnumerator file_enum(base::FilePath("/svc"), false,
base::FileEnumerator::FILES);
for (auto file = file_enum.Next(); !file.empty(); file = file_enum.Next()) {
- filtered_service_directory_->AddService(file.BaseName().value().c_str());
+ EXPECT_EQ(filtered_service_directory_->AddService(
+ file.BaseName().value().c_str()),
+ ZX_OK);
}
fuchsia::web::CreateContextParams create_params;
diff --git a/chromium/fuchsia/engine/web_engine_integration_tests.cmx b/chromium/fuchsia/engine/web_engine_integration_tests.cmx
deleted file mode 100644
index a389cdc3417..00000000000
--- a/chromium/fuchsia/engine/web_engine_integration_tests.cmx
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "sandbox": {
- "features": [
- "hub",
- "isolated-persistent-storage",
- "isolated-temp"
- ],
- "services": [
- "fuchsia.accessibility.semantics.SemanticsManager",
- "fuchsia.device.NameProvider",
- "fuchsia.fonts.Provider",
- "fuchsia.intl.PropertyProvider",
- "fuchsia.logger.Log",
- "fuchsia.logger.LogSink",
- "fuchsia.media.Audio",
- "fuchsia.media.SessionAudioConsumerFactory",
- "fuchsia.memorypressure.Provider",
- "fuchsia.net.NameLookup",
- "fuchsia.net.interfaces.State",
- "fuchsia.posix.socket.Provider",
- "fuchsia.process.Launcher",
- "fuchsia.sys.Launcher",
- "fuchsia.sysmem.Allocator",
- "fuchsia.vulkan.loader.Loader",
- "fuchsia.web.ContextProvider"
- ]
- }
-}
diff --git a/chromium/fuchsia/http/BUILD.gn b/chromium/fuchsia/http/BUILD.gn
index 0144f0b4b8d..38afeabe2d2 100644
--- a/chromium/fuchsia/http/BUILD.gn
+++ b/chromium/fuchsia/http/BUILD.gn
@@ -54,6 +54,8 @@ test("http_service_tests") {
"//testing/gtest",
]
data = [ "testdata/" ]
+ additional_manifest_fragments =
+ [ "//build/config/fuchsia/test/network_capabilities.test-cmx" ]
}
if (is_official_build) {
diff --git a/chromium/fuchsia/release/size_tests/fyi_sizes.json b/chromium/fuchsia/release/size_tests/fyi_sizes.json
index 86ee4f8def5..c061514db12 100644
--- a/chromium/fuchsia/release/size_tests/fyi_sizes.json
+++ b/chromium/fuchsia/release/size_tests/fyi_sizes.json
@@ -3,11 +3,10 @@
"gen/fuchsia/engine/web_engine/web_engine.far",
"gen/fuchsia/runners/cast_runner/cast_runner.far"
],
- "zstd_args" : [ "-14" ],
"far_total_name" : "chrome_fuchsia",
"size_limits" : {
- "chrome_fuchsia_compressed": 54e6,
- "cast_runner_compressed": 7e6,
- "web_engine_compressed": 53e6
+ "chrome_fuchsia_compressed": 1e12,
+ "cast_runner_compressed": 1e12,
+ "web_engine_compressed": 1e12
}
}
diff --git a/chromium/fuchsia/release/size_tests/fyi_sizes_smoketest.json b/chromium/fuchsia/release/size_tests/fyi_sizes_smoketest.json
new file mode 100644
index 00000000000..c061514db12
--- /dev/null
+++ b/chromium/fuchsia/release/size_tests/fyi_sizes_smoketest.json
@@ -0,0 +1,12 @@
+{
+ "far_files" : [
+ "gen/fuchsia/engine/web_engine/web_engine.far",
+ "gen/fuchsia/runners/cast_runner/cast_runner.far"
+ ],
+ "far_total_name" : "chrome_fuchsia",
+ "size_limits" : {
+ "chrome_fuchsia_compressed": 1e12,
+ "cast_runner_compressed": 1e12,
+ "web_engine_compressed": 1e12
+ }
+}
diff --git a/chromium/fuchsia/release/size_tests/fyi_sizes_warning.json b/chromium/fuchsia/release/size_tests/fyi_sizes_warning.json
new file mode 100644
index 00000000000..443a0574415
--- /dev/null
+++ b/chromium/fuchsia/release/size_tests/fyi_sizes_warning.json
@@ -0,0 +1,10 @@
+{
+ "far_files" : [
+ "gen/fuchsia/engine/web_engine/web_engine.far",
+ "gen/fuchsia/runners/cast_runner/cast_runner.far"
+ ],
+ "far_total_name" : "chrome_fuchsia",
+ "size_limits" : {
+ "chrome_fuchsia_compressed": 38.6e6
+ }
+}
diff --git a/chromium/fuchsia/runners/BUILD.gn b/chromium/fuchsia/runners/BUILD.gn
index e5e6bc445ad..ebcbe0edde4 100644
--- a/chromium/fuchsia/runners/BUILD.gn
+++ b/chromium/fuchsia/runners/BUILD.gn
@@ -198,7 +198,11 @@ test("cast_runner_integration_tests") {
"web_engine",
],
]
- manifest = "runners_integration_tests.test-cmx"
+ additional_manifest_fragments = [
+ "//build/config/fuchsia/test/network_capabilities.test-cmx",
+ "//build/config/fuchsia/test/vulkan_capabilities.test-cmx",
+ "//build/config/fuchsia/test/web_engine_required_capabilities.test-cmx",
+ ]
}
test("cast_runner_browsertests") {
@@ -223,6 +227,11 @@ test("cast_runner_browsertests") {
"//testing/gtest",
"//ui/ozone",
]
+ additional_manifest_fragments = [
+ "//build/config/fuchsia/test/jit_capabilities.test-cmx",
+ "//build/config/fuchsia/test/network_capabilities.test-cmx",
+ "//build/config/fuchsia/test/vulkan_capabilities.test-cmx",
+ ]
}
executable("web_runner_exe") {
@@ -274,7 +283,11 @@ test("web_runner_integration_tests") {
"web_runner",
],
]
- manifest = "runners_integration_tests.test-cmx"
+ additional_manifest_fragments = [
+ "//build/config/fuchsia/test/network_capabilities.test-cmx",
+ "//build/config/fuchsia/test/vulkan_capabilities.test-cmx",
+ "//build/config/fuchsia/test/web_engine_required_capabilities.test-cmx",
+ ]
}
if (is_official_build) {
diff --git a/chromium/fuchsia/runners/cast/cast_component.cc b/chromium/fuchsia/runners/cast/cast_component.cc
index 886ad70d8c8..b22234ed50a 100644
--- a/chromium/fuchsia/runners/cast/cast_component.cc
+++ b/chromium/fuchsia/runners/cast/cast_component.cc
@@ -96,6 +96,38 @@ void CastComponent::SetOnDestroyedCallback(base::OnceClosure on_destroyed) {
on_destroyed_ = std::move(on_destroyed);
}
+void CastComponent::ConnectMetricsRecorder(
+ fidl::InterfaceRequest<fuchsia::legacymetrics::MetricsRecorder> request) {
+ startup_context()->svc()->Connect(std::move(request));
+}
+
+void CastComponent::ConnectAudio(
+ fidl::InterfaceRequest<fuchsia::media::Audio> request) {
+ agent_manager_->ConnectToAgentService(application_config_.agent_url(),
+ std::move(request));
+}
+
+void CastComponent::ConnectDeviceWatcher(
+ fidl::InterfaceRequest<fuchsia::camera3::DeviceWatcher> request) {
+ agent_manager_->ConnectToAgentService(application_config_.agent_url(),
+ std::move(request));
+}
+
+bool CastComponent::HasWebPermission(
+ fuchsia::web::PermissionType permission_type) const {
+ if (!application_config_.has_permissions()) {
+ return false;
+ }
+
+ for (auto& permission : application_config_.permissions()) {
+ if (permission.has_type() && permission.type() == permission_type) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void CastComponent::StartComponent() {
if (application_config_.has_enable_remote_debugging() &&
application_config_.enable_remote_debugging()) {
diff --git a/chromium/fuchsia/runners/cast/cast_component.h b/chromium/fuchsia/runners/cast/cast_component.h
index e575e041870..5a66d852c3f 100644
--- a/chromium/fuchsia/runners/cast/cast_component.h
+++ b/chromium/fuchsia/runners/cast/cast_component.h
@@ -5,8 +5,13 @@
#ifndef FUCHSIA_RUNNERS_CAST_CAST_COMPONENT_H_
#define FUCHSIA_RUNNERS_CAST_CAST_COMPONENT_H_
+#include <fuchsia/camera3/cpp/fidl.h>
+#include <fuchsia/legacymetrics/cpp/fidl.h>
+#include <fuchsia/media/cpp/fidl.h>
+#include <fuchsia/web/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <memory>
+#include <string>
#include <utility>
#include <vector>
@@ -72,17 +77,23 @@ class CastComponent : public WebComponent,
void SetOnDestroyedCallback(base::OnceClosure on_destroyed);
+ void ConnectMetricsRecorder(
+ fidl::InterfaceRequest<fuchsia::legacymetrics::MetricsRecorder> request);
+ void ConnectAudio(fidl::InterfaceRequest<fuchsia::media::Audio> request);
+ void ConnectDeviceWatcher(
+ fidl::InterfaceRequest<fuchsia::camera3::DeviceWatcher> request);
+
+ bool HasWebPermission(fuchsia::web::PermissionType permission_type) const;
+
+ const std::string& agent_url() const {
+ return application_config_.agent_url();
+ }
+
// WebComponent overrides.
void StartComponent() final;
void DestroyComponent(int64_t termination_exit_code,
fuchsia::sys::TerminationReason reason) final;
- const chromium::cast::ApplicationConfig& application_config() {
- return application_config_;
- }
-
- cr_fuchsia::AgentManager* agent_manager() { return agent_manager_.get(); }
-
private:
void OnRewriteRulesReceived(
std::vector<fuchsia::web::UrlRequestRewriteRule> url_rewrite_rules);
diff --git a/chromium/fuchsia/runners/cast/cast_runner.cc b/chromium/fuchsia/runners/cast/cast_runner.cc
index b40db1b4709..c9a72299009 100644
--- a/chromium/fuchsia/runners/cast/cast_runner.cc
+++ b/chromium/fuchsia/runners/cast/cast_runner.cc
@@ -39,6 +39,7 @@ static constexpr const char* kServices[] = {
"fuchsia.accessibility.semantics.SemanticsManager",
"fuchsia.device.NameProvider",
"fuchsia.fonts.Provider",
+ "fuchsia.input.virtualkeyboard.ControllerCreator",
"fuchsia.intl.PropertyProvider",
"fuchsia.logger.LogSink",
"fuchsia.media.SessionAudioConsumerFactory",
@@ -52,8 +53,7 @@ static constexpr const char* kServices[] = {
"fuchsia.process.Launcher",
"fuchsia.settings.Display",
"fuchsia.sysmem.Allocator",
- "fuchsia.ui.input.ImeService",
- "fuchsia.ui.input.ImeVisibilityService",
+ "fuchsia.ui.input3.Keyboard",
"fuchsia.ui.scenic.Scenic",
"fuchsia.vulkan.loader.Loader",
@@ -63,18 +63,6 @@ static constexpr const char* kServices[] = {
// * fuchsia.media.Audio
};
-bool IsPermissionGrantedInAppConfig(
- const chromium::cast::ApplicationConfig& application_config,
- fuchsia::web::PermissionType permission_type) {
- if (application_config.has_permissions()) {
- for (auto& permission : application_config.permissions()) {
- if (permission.has_type() && permission.type() == permission_type)
- return true;
- }
- }
- return false;
-}
-
// Names used to partition the Runner's persistent storage for different uses.
constexpr char kCdmDataSubdirectoryName[] = "cdm_data";
constexpr char kProfileSubdirectoryName[] = "web_profile";
@@ -294,23 +282,36 @@ CastRunner::CastRunner(bool is_headless)
// Specify the services to connect via the Runner process' service directory.
for (const char* name : kServices) {
- main_services_->AddService(name);
- isolated_services_->AddService(name);
+ zx_status_t status = main_services_->AddService(name);
+ ZX_CHECK(status == ZX_OK, status)
+ << "AddService(" << name << ") to main failed";
+ status = isolated_services_->AddService(name);
+ ZX_CHECK(status == ZX_OK, status)
+ << "AddService(" << name << ") to isolated failed";
}
// Add handlers to main context's service directory for redirected services.
- main_services_->outgoing_directory()->AddPublicService<fuchsia::media::Audio>(
- fit::bind_member(this, &CastRunner::OnAudioServiceRequest));
- main_services_->outgoing_directory()
- ->AddPublicService<fuchsia::camera3::DeviceWatcher>(
- fit::bind_member(this, &CastRunner::OnCameraServiceRequest));
- main_services_->outgoing_directory()
- ->AddPublicService<fuchsia::legacymetrics::MetricsRecorder>(
- fit::bind_member(this, &CastRunner::OnMetricsRecorderServiceRequest));
+ zx_status_t status =
+ main_services_->outgoing_directory()
+ ->AddPublicService<fuchsia::media::Audio>(
+ fit::bind_member(this, &CastRunner::OnAudioServiceRequest));
+ ZX_CHECK(status == ZX_OK, status) << "AddPublicService(Audio) to main failed";
+ status = main_services_->outgoing_directory()
+ ->AddPublicService<fuchsia::camera3::DeviceWatcher>(
+ fit::bind_member(this, &CastRunner::OnCameraServiceRequest));
+ ZX_CHECK(status == ZX_OK, status)
+ << "AddPublicService(DeviceWatcher) to main failed";
+ status = main_services_->outgoing_directory()
+ ->AddPublicService<fuchsia::legacymetrics::MetricsRecorder>(
+ fit::bind_member(
+ this, &CastRunner::OnMetricsRecorderServiceRequest));
+ ZX_CHECK(status == ZX_OK, status)
+ << "AddPublicService(MetricsRecorder) to main failed";
// Isolated contexts can use the normal Audio service, and don't record
// metrics.
- isolated_services_->AddService(fuchsia::media::Audio::Name_);
+ status = isolated_services_->AddService(fuchsia::media::Audio::Name_);
+ ZX_CHECK(status == ZX_OK, status) << "AddService(Audio) to isolated failed";
}
CastRunner::~CastRunner() = default;
@@ -456,34 +457,36 @@ void CastRunner::LaunchPendingComponent(PendingCastComponent* pending_component,
std::vector<fuchsia::net::http::Header>());
if (component_owner == main_context_.get()) {
- const auto& application_config = cast_component->application_config();
+ // For components in the main Context the cache sentinel file should have
+ // been created as a side-effect of |CastComponent::StartComponent()|.
+ DCHECK(was_cache_sentinel_created_);
// If this component has the microphone permission then use it to route
// Audio service requests through.
- if (IsPermissionGrantedInAppConfig(
- application_config, fuchsia::web::PermissionType::MICROPHONE)) {
+ if (cast_component->HasWebPermission(
+ fuchsia::web::PermissionType::MICROPHONE)) {
if (first_audio_capturer_agent_url_.empty()) {
- first_audio_capturer_agent_url_ = application_config.agent_url();
+ first_audio_capturer_agent_url_ = cast_component->agent_url();
} else {
- LOG_IF(WARNING, first_audio_capturer_agent_url_ !=
- application_config.agent_url())
+ LOG_IF(WARNING,
+ first_audio_capturer_agent_url_ != cast_component->agent_url())
<< "Audio capturer already in use for different agent. "
"Current agent: "
- << application_config.agent_url();
+ << cast_component->agent_url();
}
audio_capturer_components_.emplace(cast_component.get());
}
- if (IsPermissionGrantedInAppConfig(application_config,
- fuchsia::web::PermissionType::CAMERA)) {
+ if (cast_component->HasWebPermission(
+ fuchsia::web::PermissionType::CAMERA)) {
if (first_video_capturer_agent_url_.empty()) {
- first_video_capturer_agent_url_ = application_config.agent_url();
+ first_video_capturer_agent_url_ = cast_component->agent_url();
} else {
- LOG_IF(WARNING, first_video_capturer_agent_url_ !=
- application_config.agent_url())
+ LOG_IF(WARNING,
+ first_video_capturer_agent_url_ != cast_component->agent_url())
<< "Video capturer already in use for different agent. "
"Current agent: "
- << application_config.agent_url();
+ << cast_component->agent_url();
}
video_capturer_components_.emplace(cast_component.get());
}
@@ -555,8 +558,9 @@ fuchsia::web::CreateContextParams CastRunner::GetMainContextParams() {
*params.mutable_features() |=
fuchsia::web::ContextFeatureFlags::NETWORK |
fuchsia::web::ContextFeatureFlags::LEGACYMETRICS;
- main_services_->ConnectClient(
+ zx_status_t status = main_services_->ConnectClient(
params.mutable_service_directory()->NewRequest());
+ ZX_CHECK(status == ZX_OK, status) << "ConnectClient failed";
if (!disable_vulkan_for_test_)
SetCdmParamsForMainContext(&params);
@@ -581,8 +585,9 @@ CastRunner::GetIsolatedContextParamsWithFuchsiaDirs(
fuchsia::web::CreateContextParams params = GetCommonContextParams();
params.set_remote_debugging_port(kEphemeralRemoteDebuggingPort);
params.set_content_directories(std::move(content_directories));
- isolated_services_->ConnectClient(
+ zx_status_t status = isolated_services_->ConnectClient(
params.mutable_service_directory()->NewRequest());
+ ZX_CHECK(status == ZX_OK, status) << "ConnectClient failed";
return params;
}
@@ -593,8 +598,9 @@ CastRunner::GetIsolatedContextParamsForCastStreaming() {
ApplyCastStreamingContextParams(&params);
// TODO(crbug.com/1069746): Use a different FilteredServiceDirectory for Cast
// Streaming Contexts.
- main_services_->ConnectClient(
+ zx_status_t status = main_services_->ConnectClient(
params.mutable_service_directory()->NewRequest());
+ ZX_CHECK(status == ZX_OK, status) << "ConnectClient failed";
return params;
}
@@ -647,9 +653,7 @@ void CastRunner::OnAudioServiceRequest(
// fuchsia.media.Audio requests to the corresponding agent.
if (!audio_capturer_components_.empty()) {
CastComponent* capturer_component = *audio_capturer_components_.begin();
- capturer_component->agent_manager()->ConnectToAgentService(
- capturer_component->application_config().agent_url(),
- std::move(request));
+ capturer_component->ConnectAudio(std::move(request));
return;
}
@@ -665,9 +669,7 @@ void CastRunner::OnCameraServiceRequest(
// fuchsia.camera3.DeviceWatcher requests to the corresponding agent.
if (!video_capturer_components_.empty()) {
CastComponent* capturer_component = *video_capturer_components_.begin();
- capturer_component->agent_manager()->ConnectToAgentService(
- capturer_component->application_config().agent_url(),
- std::move(request));
+ capturer_component->ConnectDeviceWatcher(std::move(request));
return;
}
@@ -688,7 +690,7 @@ void CastRunner::OnMetricsRecorderServiceRequest(
if (any_component) {
VLOG(1) << "Connecting MetricsRecorder via CastComponent.";
CastComponent* component = reinterpret_cast<CastComponent*>(any_component);
- component->startup_context()->svc()->Connect(std::move(request));
+ component->ConnectMetricsRecorder(std::move(request));
return;
}
diff --git a/chromium/fuchsia/runners/cast/cast_runner.cmx b/chromium/fuchsia/runners/cast/cast_runner.cmx
index 4b64d375b6f..d6882df9542 100644
--- a/chromium/fuchsia/runners/cast/cast_runner.cmx
+++ b/chromium/fuchsia/runners/cast/cast_runner.cmx
@@ -11,6 +11,7 @@
"fuchsia.device.NameProvider",
"fuchsia.feedback.CrashReportingProductRegister",
"fuchsia.fonts.Provider",
+ "fuchsia.input.virtualkeyboard.ControllerCreator",
"fuchsia.intl.PropertyProvider",
"fuchsia.logger.LogSink",
"fuchsia.media.Audio",
@@ -25,8 +26,7 @@
"fuchsia.process.Launcher",
"fuchsia.settings.Display",
"fuchsia.sysmem.Allocator",
- "fuchsia.ui.input.ImeService",
- "fuchsia.ui.input.ImeVisibilityService",
+ "fuchsia.ui.input3.Keyboard",
"fuchsia.ui.scenic.Scenic",
"fuchsia.vulkan.loader.Loader",
"fuchsia.web.ContextProvider"
diff --git a/chromium/fuchsia/runners/cast/cast_runner_integration_test.cc b/chromium/fuchsia/runners/cast/cast_runner_integration_test.cc
index 00cf835855a..af0949ebda8 100644
--- a/chromium/fuchsia/runners/cast/cast_runner_integration_test.cc
+++ b/chromium/fuchsia/runners/cast/cast_runner_integration_test.cc
@@ -23,6 +23,7 @@
#include "base/fuchsia/process_context.h"
#include "base/fuchsia/scoped_service_binding.h"
#include "base/fuchsia/test_component_controller.h"
+#include "base/macros.h"
#include "base/path_service.h"
#include "base/strings/strcat.h"
#include "base/strings/string_piece.h"
@@ -222,146 +223,6 @@ class FakeComponentState : public cr_fuchsia::AgentImpl::ComponentStateBase {
base::OnceClosure on_delete_;
};
-enum CastRunnerFeatures {
- kCastRunnerFeaturesNone = 0,
- kCastRunnerFeaturesHeadless = 1,
- kCastRunnerFeaturesVulkan = 1 << 1,
- kCastRunnerFeaturesFrameHost = 1 << 2
-};
-
-sys::ServiceDirectory StartCastRunner(
- fidl::InterfaceHandle<fuchsia::io::Directory> web_engine_host_directory,
- CastRunnerFeatures runner_features,
- fidl::InterfaceRequest<fuchsia::sys::ComponentController>
- component_controller_request) {
- fuchsia::sys::LaunchInfo launch_info;
- launch_info.url =
- "fuchsia-pkg://fuchsia.com/cast_runner#meta/cast_runner.cmx";
-
- // Clone stderr from the current process to CastRunner and ask it to
- // redirect all logs to stderr.
- launch_info.err = fuchsia::sys::FileDescriptor::New();
- launch_info.err->type0 = PA_FD;
- zx_status_t status = fdio_fd_clone(
- STDERR_FILENO, launch_info.err->handle0.reset_and_get_address());
- ZX_CHECK(status == ZX_OK, status);
-
- base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
- command_line.AppendSwitchASCII("enable-logging", "stderr");
-
- if (runner_features & kCastRunnerFeaturesHeadless)
- command_line.AppendSwitch(kForceHeadlessForTestsSwitch);
- if (!(runner_features & kCastRunnerFeaturesVulkan))
- command_line.AppendSwitch(kDisableVulkanForTestsSwitch);
- if (runner_features & kCastRunnerFeaturesFrameHost)
- command_line.AppendSwitch(kEnableFrameHostComponent);
-
- // Add all switches and arguments, skipping the program.
- launch_info.arguments.emplace(std::vector<std::string>(
- command_line.argv().begin() + 1, command_line.argv().end()));
-
- fidl::InterfaceHandle<fuchsia::io::Directory> cast_runner_services_dir;
- launch_info.directory_request =
- cast_runner_services_dir.NewRequest().TakeChannel();
-
- // Redirect ContextProvider to |web_engine_host_directory|.
- launch_info.additional_services =
- std::make_unique<fuchsia::sys::ServiceList>();
- launch_info.additional_services->host_directory =
- web_engine_host_directory.TakeChannel();
- launch_info.additional_services->names.push_back(
- fuchsia::web::ContextProvider::Name_);
-
- fuchsia::sys::LauncherPtr launcher;
- base::ComponentContextForProcess()->svc()->Connect(launcher.NewRequest());
- launcher->CreateComponent(std::move(launch_info),
- std::move(component_controller_request));
- return sys::ServiceDirectory(std::move(cast_runner_services_dir));
-}
-
-} // namespace
-
-class CastRunnerIntegrationTest : public testing::Test {
- public:
- CastRunnerIntegrationTest()
- : CastRunnerIntegrationTest(kCastRunnerFeaturesNone) {}
-
- CastRunnerIntegrationTest(const CastRunnerIntegrationTest&) = delete;
- CastRunnerIntegrationTest& operator=(const CastRunnerIntegrationTest&) =
- delete;
-
- void TearDown() override {
- // Unbind the Runner channel, to prevent it from triggering an error when
- // the CastRunner and WebEngine are torn down.
- cast_runner_.Unbind();
- }
-
- protected:
- explicit CastRunnerIntegrationTest(CastRunnerFeatures runner_features) {
- StartAndPublishWebEngine();
-
- // Start CastRunner.
- fidl::InterfaceHandle<::fuchsia::io::Directory> incoming_services;
- services_for_cast_runner_.GetOrCreateDirectory("svc")->Serve(
- ::fuchsia::io::OPEN_RIGHT_READABLE | ::fuchsia::io::OPEN_RIGHT_WRITABLE,
- incoming_services.NewRequest().TakeChannel());
- sys::ServiceDirectory cast_runner_services =
- StartCastRunner(std::move(incoming_services), runner_features,
- cast_runner_controller_.ptr().NewRequest());
-
- // Connect to the CastRunner's fuchsia.sys.Runner interface.
- cast_runner_ = cast_runner_services.Connect<fuchsia::sys::Runner>();
- cast_runner_.set_error_handler([](zx_status_t status) {
- ZX_LOG(ERROR, status) << "CastRunner closed channel.";
- ADD_FAILURE();
- });
-
- test_server_.ServeFilesFromSourceDirectory(kTestServerRoot);
- net::test_server::RegisterDefaultHandlers(&test_server_);
- EXPECT_TRUE(test_server_.Start());
- }
-
- void StartAndPublishWebEngine() {
- fidl::InterfaceHandle<fuchsia::io::Directory> web_engine_outgoing_dir =
- cr_fuchsia::StartWebEngineForTests(
- web_engine_controller_.ptr().NewRequest());
- sys::ServiceDirectory web_engine_outgoing_services(
- std::move(web_engine_outgoing_dir));
-
- services_for_cast_runner_
- .RemovePublicService<fuchsia::web::ContextProvider>();
- services_for_cast_runner_.AddPublicService(
- std::make_unique<vfs::Service>(
- [web_engine_outgoing_services =
- std::move(web_engine_outgoing_services)](
- zx::channel channel, async_dispatcher_t* dispatcher) {
- web_engine_outgoing_services.Connect(
- fuchsia::web::ContextProvider::Name_, std::move(channel));
- }),
- fuchsia::web::ContextProvider::Name_);
- }
-
- base::test::SingleThreadTaskEnvironment task_environment_{
- base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
- net::EmbeddedTestServer test_server_;
-
- // TODO(https://crbug.com/1168538): Override the RunLoop timeout set by
- // |task_environment_| to allow for the very high variability in web.Context
- // launch times.
- const base::test::ScopedRunLoopTimeout scoped_timeout_{
- FROM_HERE, TestTimeouts::action_max_timeout()};
-
- base::TestComponentController web_engine_controller_;
- base::TestComponentController cast_runner_controller_;
-
- // Directory used to publish test ContextProvider to CastRunner. Some tests
- // restart ContextProvider, so we can't pass the services directory from
- // ContextProvider to CastRunner directly.
- sys::OutgoingDirectory services_for_cast_runner_;
-
- fuchsia::sys::RunnerPtr cast_runner_;
-};
-
class TestCastComponent {
public:
TestCastComponent(fuchsia::sys::Runner* cast_runner)
@@ -380,6 +241,8 @@ class TestCastComponent {
void CreateComponentContextAndStartComponent(
base::StringPiece app_id = kTestAppId) {
+ ASSERT_FALSE(component_context_)
+ << "ComponentContext may only be created once";
auto component_url = base::StrCat({"cast:", app_id});
InjectQueryApi();
CreateComponentContext(component_url);
@@ -389,6 +252,8 @@ class TestCastComponent {
}
void CreateComponentContext(const base::StringPiece& component_url) {
+ ASSERT_FALSE(component_context_)
+ << "ComponentContext may only be created once";
url_request_rewrite_rules_provider_ =
std::make_unique<FakeUrlRequestRewriteRulesProvider>();
component_context_ = std::make_unique<cr_fuchsia::FakeComponentContext>(
@@ -400,6 +265,9 @@ class TestCastComponent {
}
void StartCastComponent(base::StringPiece component_url) {
+ ASSERT_FALSE(component_services_client_)
+ << "Component may only be started once";
+
// Configure the Runner, including a service directory channel to publish
// services to.
fuchsia::sys::StartupInfo startup_info;
@@ -423,9 +291,11 @@ class TestCastComponent {
component_services_.GetOrCreateDirectory("svc")->Serve(
fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
directory.NewRequest().TakeChannel());
- component_services_.AddPublicService(
- cors_exempt_header_provider_binding_.GetHandler(
- &cors_exempt_header_provider_));
+
+ ASSERT_EQ(component_services_.AddPublicService(
+ cors_exempt_header_provider_binding_.GetHandler(
+ &cors_exempt_header_provider_)),
+ ZX_OK);
// Provide the directory of services in the |flat_namespace|.
startup_info.flat_namespace.paths.emplace_back(base::kServiceDirectoryPath);
@@ -627,6 +497,147 @@ class TestCastComponent {
fuchsia::sys::Runner* cast_runner_;
};
+enum CastRunnerFeatures {
+ kCastRunnerFeaturesNone = 0,
+ kCastRunnerFeaturesHeadless = 1,
+ kCastRunnerFeaturesVulkan = 1 << 1,
+ kCastRunnerFeaturesFrameHost = 1 << 2
+};
+
+sys::ServiceDirectory StartCastRunner(
+ fidl::InterfaceHandle<fuchsia::io::Directory> web_engine_host_directory,
+ CastRunnerFeatures runner_features,
+ fidl::InterfaceRequest<fuchsia::sys::ComponentController>
+ component_controller_request) {
+ fuchsia::sys::LaunchInfo launch_info;
+ launch_info.url =
+ "fuchsia-pkg://fuchsia.com/cast_runner#meta/cast_runner.cmx";
+
+ // Clone stderr from the current process to CastRunner and ask it to
+ // redirect all logs to stderr.
+ launch_info.err = fuchsia::sys::FileDescriptor::New();
+ launch_info.err->type0 = PA_FD;
+ zx_status_t status = fdio_fd_clone(
+ STDERR_FILENO, launch_info.err->handle0.reset_and_get_address());
+ ZX_CHECK(status == ZX_OK, status);
+
+ base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
+ command_line.AppendSwitchASCII("enable-logging", "stderr");
+
+ if (runner_features & kCastRunnerFeaturesHeadless)
+ command_line.AppendSwitch(kForceHeadlessForTestsSwitch);
+ if (!(runner_features & kCastRunnerFeaturesVulkan))
+ command_line.AppendSwitch(kDisableVulkanForTestsSwitch);
+ if (runner_features & kCastRunnerFeaturesFrameHost)
+ command_line.AppendSwitch(kEnableFrameHostComponent);
+
+ // Add all switches and arguments, skipping the program.
+ launch_info.arguments.emplace(std::vector<std::string>(
+ command_line.argv().begin() + 1, command_line.argv().end()));
+
+ fidl::InterfaceHandle<fuchsia::io::Directory> cast_runner_services_dir;
+ launch_info.directory_request =
+ cast_runner_services_dir.NewRequest().TakeChannel();
+
+ // Redirect ContextProvider to |web_engine_host_directory|.
+ launch_info.additional_services =
+ std::make_unique<fuchsia::sys::ServiceList>();
+ launch_info.additional_services->host_directory =
+ web_engine_host_directory.TakeChannel();
+ launch_info.additional_services->names.push_back(
+ fuchsia::web::ContextProvider::Name_);
+
+ fuchsia::sys::LauncherPtr launcher;
+ base::ComponentContextForProcess()->svc()->Connect(launcher.NewRequest());
+ launcher->CreateComponent(std::move(launch_info),
+ std::move(component_controller_request));
+ return sys::ServiceDirectory(std::move(cast_runner_services_dir));
+}
+
+} // namespace
+
+class CastRunnerIntegrationTest : public testing::Test {
+ public:
+ CastRunnerIntegrationTest()
+ : CastRunnerIntegrationTest(kCastRunnerFeaturesNone) {}
+
+ CastRunnerIntegrationTest(const CastRunnerIntegrationTest&) = delete;
+ CastRunnerIntegrationTest& operator=(const CastRunnerIntegrationTest&) =
+ delete;
+
+ void TearDown() override {
+ // Unbind the Runner channel, to prevent it from triggering an error when
+ // the CastRunner and WebEngine are torn down.
+ cast_runner_.Unbind();
+ }
+
+ protected:
+ explicit CastRunnerIntegrationTest(CastRunnerFeatures runner_features) {
+ StartAndPublishWebEngine();
+
+ // Start CastRunner.
+ fidl::InterfaceHandle<::fuchsia::io::Directory> incoming_services;
+ services_for_cast_runner_.GetOrCreateDirectory("svc")->Serve(
+ ::fuchsia::io::OPEN_RIGHT_READABLE | ::fuchsia::io::OPEN_RIGHT_WRITABLE,
+ incoming_services.NewRequest().TakeChannel());
+ sys::ServiceDirectory cast_runner_services =
+ StartCastRunner(std::move(incoming_services), runner_features,
+ cast_runner_controller_.ptr().NewRequest());
+
+ // Connect to the CastRunner's fuchsia.sys.Runner interface.
+ cast_runner_ = cast_runner_services.Connect<fuchsia::sys::Runner>();
+ cast_runner_.set_error_handler([](zx_status_t status) {
+ ZX_LOG(ERROR, status) << "CastRunner closed channel.";
+ ADD_FAILURE();
+ });
+
+ test_server_.ServeFilesFromSourceDirectory(kTestServerRoot);
+ net::test_server::RegisterDefaultHandlers(&test_server_);
+ EXPECT_TRUE(test_server_.Start());
+ }
+
+ void StartAndPublishWebEngine() {
+ fidl::InterfaceHandle<fuchsia::io::Directory> web_engine_outgoing_dir =
+ cr_fuchsia::StartWebEngineForTests(
+ web_engine_controller_.ptr().NewRequest());
+ sys::ServiceDirectory web_engine_outgoing_services(
+ std::move(web_engine_outgoing_dir));
+ ignore_result(services_for_cast_runner_
+ .RemovePublicService<fuchsia::web::ContextProvider>());
+ ASSERT_EQ(services_for_cast_runner_.AddPublicService(
+ std::make_unique<vfs::Service>(
+ [web_engine_outgoing_services =
+ std::move(web_engine_outgoing_services)](
+ zx::channel channel, async_dispatcher_t* dispatcher) {
+ web_engine_outgoing_services.Connect(
+ fuchsia::web::ContextProvider::Name_,
+ std::move(channel));
+ }),
+ fuchsia::web::ContextProvider::Name_),
+ ZX_OK);
+ }
+
+ base::test::SingleThreadTaskEnvironment task_environment_{
+ base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
+ net::EmbeddedTestServer test_server_;
+
+ // TODO(https://crbug.com/1168538): Override the RunLoop timeout set by
+ // |task_environment_| to allow for the very high variability in web.Context
+ // launch times.
+ const base::test::ScopedRunLoopTimeout scoped_timeout_{
+ FROM_HERE, TestTimeouts::action_max_timeout()};
+
+ base::TestComponentController web_engine_controller_;
+ base::TestComponentController cast_runner_controller_;
+
+ // Directory used to publish test ContextProvider to CastRunner. Some tests
+ // restart ContextProvider, so we can't pass the services directory from
+ // ContextProvider to CastRunner directly.
+ sys::OutgoingDirectory services_for_cast_runner_;
+
+ fuchsia::sys::RunnerPtr cast_runner_;
+};
+
// A basic integration test ensuring a basic cast request launches the right
// URL in the Chromium service.
TEST_F(CastRunnerIntegrationTest, BasicRequest) {
@@ -648,7 +659,7 @@ TEST_F(CastRunnerIntegrationTest, CanRecreateContext) {
component.app_config_manager()->AddApp(kTestAppId, app_url);
// Create a Cast component and verify that it has loaded.
- component.CreateComponentContextAndStartComponent();
+ component.CreateComponentContextAndStartComponent(kTestAppId);
component.CheckAppUrl(app_url);
// Terminate the component that provides the ContextProvider service and
@@ -663,9 +674,10 @@ TEST_F(CastRunnerIntegrationTest, CanRecreateContext) {
// WebContentRunner::CreateFrameWithParams() will synchronously verify that
// the web.Context is not-yet-closed, to work-around that.
StartAndPublishWebEngine();
- component.app_config_manager()->AddApp(kTestAppId, app_url);
- component.CreateComponentContextAndStartComponent();
- component.CheckAppUrl(app_url);
+ TestCastComponent second_component(cast_runner_.get());
+ second_component.app_config_manager()->AddApp(kTestAppId, app_url);
+ second_component.CreateComponentContextAndStartComponent(kTestAppId);
+ second_component.CheckAppUrl(app_url);
}
TEST_F(CastRunnerIntegrationTest, ApiBindings) {
@@ -911,13 +923,15 @@ TEST_F(CastRunnerIntegrationTest, MicrophoneRedirect) {
// Expect fuchsia.media.Audio connection to be redirected to the agent.
base::RunLoop run_loop;
- component.component_state()->outgoing_directory()->AddPublicService(
- std::make_unique<vfs::Service>(
- [quit_closure = run_loop.QuitClosure()](
- zx::channel channel, async_dispatcher_t* dispatcher) mutable {
- std::move(quit_closure).Run();
- }),
- fuchsia::media::Audio::Name_);
+ ASSERT_EQ(
+ component.component_state()->outgoing_directory()->AddPublicService(
+ std::make_unique<vfs::Service>(
+ [quit_closure = run_loop.QuitClosure()](
+ zx::channel channel, async_dispatcher_t* dispatcher) mutable {
+ std::move(quit_closure).Run();
+ }),
+ fuchsia::media::Audio::Name_),
+ ZX_OK);
component.ExecuteJavaScript("connectMicrophone();");
@@ -941,13 +955,15 @@ TEST_F(CastRunnerIntegrationTest, CameraRedirect) {
// Expect fuchsia.camera3.DeviceWatcher connection to be redirected to the
// agent.
bool received_device_watcher_request = false;
- component.component_state()->outgoing_directory()->AddPublicService(
- std::make_unique<vfs::Service>(
- [&received_device_watcher_request](
- zx::channel channel, async_dispatcher_t* dispatcher) mutable {
- received_device_watcher_request = true;
- }),
- fuchsia::camera3::DeviceWatcher::Name_);
+ ASSERT_EQ(
+ component.component_state()->outgoing_directory()->AddPublicService(
+ std::make_unique<vfs::Service>(
+ [&received_device_watcher_request](
+ zx::channel channel, async_dispatcher_t* dispatcher) mutable {
+ received_device_watcher_request = true;
+ }),
+ fuchsia::camera3::DeviceWatcher::Name_),
+ ZX_OK);
component.ExecuteJavaScript("connectCamera();");
EXPECT_TRUE(received_device_watcher_request);
@@ -1014,13 +1030,17 @@ TEST_F(CastRunnerIntegrationTest, MultipleComponentsUsingCamera) {
// Expect fuchsia.camera3.DeviceWatcher connection to be redirected to the
// agent.
bool received_device_watcher_request = false;
- second_component.component_state()->outgoing_directory()->AddPublicService(
- std::make_unique<vfs::Service>(
- [&received_device_watcher_request](
- zx::channel channel, async_dispatcher_t* dispatcher) mutable {
- received_device_watcher_request = true;
- }),
- fuchsia::camera3::DeviceWatcher::Name_);
+ ASSERT_EQ(
+ second_component.component_state()
+ ->outgoing_directory()
+ ->AddPublicService(std::make_unique<vfs::Service>(
+ [&received_device_watcher_request](
+ zx::channel channel,
+ async_dispatcher_t* dispatcher) mutable {
+ received_device_watcher_request = true;
+ }),
+ fuchsia::camera3::DeviceWatcher::Name_),
+ ZX_OK);
second_component.ExecuteJavaScript("connectCamera();");
EXPECT_TRUE(received_device_watcher_request);
@@ -1080,12 +1100,14 @@ TEST_F(CastRunnerIntegrationTest, LegacyMetricsRedirect) {
base::RunLoop run_loop;
// Add MetricsRecorder the the component's incoming_services.
- component.component_services()->AddPublicService(
- std::make_unique<vfs::Service>(
- [&run_loop](zx::channel request, async_dispatcher_t* dispatcher) {
- run_loop.Quit();
- }),
- fuchsia::legacymetrics::MetricsRecorder::Name_);
+ ASSERT_EQ(
+ component.component_services()->AddPublicService(
+ std::make_unique<vfs::Service>(
+ [&run_loop](zx::channel request, async_dispatcher_t* dispatcher) {
+ run_loop.Quit();
+ }),
+ fuchsia::legacymetrics::MetricsRecorder::Name_),
+ ZX_OK);
component.StartCastComponent(component_url);
diff --git a/chromium/fuchsia/runners/common/web_component.h b/chromium/fuchsia/runners/common/web_component.h
index 31dbc7c936b..62471b3a906 100644
--- a/chromium/fuchsia/runners/common/web_component.h
+++ b/chromium/fuchsia/runners/common/web_component.h
@@ -65,13 +65,13 @@ class WebComponent : public fuchsia::sys::ComponentController,
WebContentRunner* runner() const { return runner_; }
+ protected:
// Returns the component's startup context (e.g. incoming services, public
// service directory, etc).
base::StartupContext* startup_context() const {
return startup_context_.get();
}
- protected:
// fuchsia::sys::ComponentController implementation.
void Kill() override;
void Detach() override;
diff --git a/chromium/fuchsia/runners/runners_integration_tests.test-cmx b/chromium/fuchsia/runners/runners_integration_tests.test-cmx
deleted file mode 100644
index b9815624d0a..00000000000
--- a/chromium/fuchsia/runners/runners_integration_tests.test-cmx
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "facets": {
- "fuchsia.test": {
- "injected-services": {
- "fuchsia.fonts.Provider": "fuchsia-pkg://fuchsia.com/fonts#meta/fonts.cmx",
- "fuchsia.intl.PropertyProvider": "fuchsia-pkg://fuchsia.com/intl_property_manager#meta/intl_property_manager.cmx",
- "fuchsia.memorypressure.Provider": "fuchsia-pkg://fuchsia.com/memory_monitor#meta/memory_monitor.cmx",
- "fuchsia.net.interfaces.State": "fuchsia-pkg://fuchsia.com/netstack#meta/netstack.cmx",
- "fuchsia.posix.socket.Provider": "fuchsia-pkg://fuchsia.com/netstack#meta/netstack.cmx",
- "fuchsia.web.ContextProvider": "fuchsia-pkg://fuchsia.com/web_engine#meta/context_provider.cmx"
- },
- "system-services": [
- "fuchsia.device.NameProvider",
- "fuchsia.scheduler.ProfileProvider",
- "fuchsia.sysmem.Allocator",
- "fuchsia.vulkan.loader.Loader"
- ]
- }
- },
- "sandbox": {
- "features": [
- "isolated-persistent-storage",
- "isolated-temp"
- ],
- "services": [
- "fuchsia.fonts.Provider",
- "fuchsia.intl.PropertyProvider",
- "fuchsia.logger.LogSink",
- "fuchsia.memorypressure.Provider",
- "fuchsia.net.interfaces.State",
- "fuchsia.posix.socket.Provider",
- "fuchsia.process.Launcher",
- "fuchsia.sys.Launcher",
- "fuchsia.web.ContextProvider"
- ]
- }
-}
diff --git a/chromium/fuchsia/runners/web/web_runner.cmx b/chromium/fuchsia/runners/web/web_runner.cmx
index 36fc69d1d9b..f283078ea7f 100644
--- a/chromium/fuchsia/runners/web/web_runner.cmx
+++ b/chromium/fuchsia/runners/web/web_runner.cmx
@@ -8,6 +8,7 @@
"fuchsia.camera3.DeviceWatcher",
"fuchsia.device.NameProvider",
"fuchsia.fonts.Provider",
+ "fuchsia.input.virtualkeyboard.ControllerCreator",
"fuchsia.intl.PropertyProvider",
"fuchsia.logger.LogSink",
"fuchsia.media.Audio",
@@ -20,8 +21,7 @@
"fuchsia.posix.socket.Provider",
"fuchsia.process.Launcher",
"fuchsia.sysmem.Allocator",
- "fuchsia.ui.input.ImeService",
- "fuchsia.ui.input.ImeVisibilityService",
+ "fuchsia.ui.input3.Keyboard",
"fuchsia.ui.scenic.Scenic",
"fuchsia.vulkan.loader.Loader",
"fuchsia.web.ContextProvider"