0

[fuchsia] cast_streaming_shell and web_engine_shell attempt to PresentView with fuchsia.element.GraphicalPresenter.

As a fallback, we still connect to fuchsia.ui.policy.Presenter. This is preferred to using config-data or an
alternative component manifest to explicitly configure which
presentation protocol to use for the following reasons:
* The fallback is a temporary measure while the two shells are
  transitioned to the new presenter protocol. There is no intention of
  making this permanent, as the removal of the fallback protocol is
  scheduled soon after the safe migration onto the preferred protocol.
* If there are any issues in the migration, the shells will be resilient
  against any reverts or relands by being compatible to whichever
  protocol is available at the time.

Bug: 1351007
Test: autoninja -C out/fuchsia telemetry_gpu_integration_test_fuchsia && content/test/gpu/run_gpu_integration_test_fuchsia.py cast_streaming --browser=cast-streaming-shell --out-dir=out/fuchsia

Change-Id: I9910dc8fb4dd8e3c64bbaafdd7cc2a9b0da047fb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4067808
Reviewed-by: Wez <wez@chromium.org>
Commit-Queue: Caroline Liu <carolineliu@google.com>
Reviewed-by: Greg Thompson <grt@chromium.org>
Reviewed-by: Sergey Ulanov <sergeyu@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1094482}
This commit is contained in:
Caroline Liu
2023-01-19 16:17:18 +00:00
committed by Chromium LUCI CQ
parent c845d11ba8
commit 0605b82197
10 changed files with 170 additions and 32 deletions

@ -2900,7 +2900,7 @@ def CheckSpamLogging(input_api, output_api):
r"^extensions/renderer/logging_native_handler\.cc$",
r"^fuchsia_web/common/init_logging\.cc$",
r"^fuchsia_web/runners/common/web_component\.cc$",
r"^fuchsia_web/shell/.*_shell\.cc$",
r"^fuchsia_web/shell/.*\.cc$",
r"^headless/app/headless_shell\.cc$",
r"^ipc/ipc_logging\.cc$",
r"^native_client_sdk/",

@ -33,6 +33,23 @@ source_set("remote_debugging_port") {
deps = [ "//base" ]
}
source_set("present_frame") {
testonly = true
sources = [
"present_frame.cc",
"present_frame.h",
]
deps = [
"//base",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.policy",
"//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
]
public_deps = [
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.element",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.web",
]
}
fuchsia_component("web_engine_shell_component") {
testonly = true
manifest = "web_engine_shell.cml"
@ -79,14 +96,13 @@ executable("web_engine_shell_exec") {
data = [ "data" ]
deps = [
":present_frame",
":remote_debugging_port",
"//base",
"//components/fuchsia_component_support:annotations_manager",
"//fuchsia_web/common",
"//fuchsia_web/webinstance_host:webinstance_host_v1",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.policy",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.web",
"//third_party/fuchsia-sdk/sdk/pkg/fdio",
"//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
"//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
"//third_party/widevine/cdm:buildflags",
"//url",
@ -126,11 +142,13 @@ if (enable_cast_receiver) {
]
deps = [
":present_frame",
":remote_debugging_port",
"//base",
"//base/test:test_support",
"//components/cast/message_port:message_port",
"//components/cast_streaming/test:test_sender_using_net_sockets",
"//components/fuchsia_component_support:annotations_manager",
"//fuchsia_web/cast_streaming",
"//fuchsia_web/common",
"//fuchsia_web/common/test:test_support",
@ -138,10 +156,7 @@ if (enable_cast_receiver) {
"//fuchsia_web/webinstance_host:webinstance_host_v1",
"//media",
"//media/gpu/test:test_helpers",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.policy",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.web",
"//third_party/fuchsia-sdk/sdk/pkg/fdio",
"//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
"//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
"//url",
]

@ -1,4 +1,5 @@
include_rules = [
"+components/fuchsia_component_support",
"+fuchsia_web/webinstance_host",
]

@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <fuchsia/element/cpp/fidl.h>
#include <fuchsia/web/cpp/fidl.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include "base/command_line.h"
#include "base/files/file_path.h"
@ -22,10 +21,12 @@
#include "components/cast/message_port/fuchsia/create_web_message.h"
#include "components/cast/message_port/platform_message_port.h"
#include "components/cast_streaming/test/cast_streaming_test_sender.h"
#include "components/fuchsia_component_support/annotations_manager.h"
#include "fuchsia_web/cast_streaming/cast_streaming.h"
#include "fuchsia_web/common/init_logging.h"
#include "fuchsia_web/common/test/fit_adapter.h"
#include "fuchsia_web/common/test/frame_test_util.h"
#include "fuchsia_web/shell/present_frame.h"
#include "fuchsia_web/shell/remote_debugging_port.h"
#include "fuchsia_web/webengine/switches.h"
#include "fuchsia_web/webinstance_host/web_instance_host_v1.h"
@ -84,20 +85,15 @@ fuchsia::web::CreateContextParams GetCreateContextParams(
}
// Set autoplay, enable all logging, and present fullscreen view of `frame`.
void ConfigureFrame(fuchsia::web::Frame* frame) {
void ConfigureFrame(
fuchsia::web::Frame* frame,
fidl::InterfaceHandle<fuchsia::element::AnnotationController>
annotation_controller) {
fuchsia::web::ContentAreaSettings settings;
settings.set_autoplay_policy(fuchsia::web::AutoplayPolicy::ALLOW);
frame->SetContentAreaSettings(std::move(settings));
frame->SetJavaScriptLogLevel(fuchsia::web::ConsoleLogLevel::DEBUG);
auto view_tokens = scenic::ViewTokenPair::New();
frame->CreateView(std::move(view_tokens.view_token));
auto presenter = base::ComponentContextForProcess()
->svc()
->Connect<fuchsia::ui::policy::Presenter>();
presenter->PresentOrReplaceView(std::move(view_tokens.view_holder_token),
nullptr);
PresentFrame(frame, std::move(annotation_controller));
}
} // namespace
@ -157,7 +153,16 @@ int main(int argc, char** argv) {
quit_run_loop.Run();
});
ConfigureFrame(frame.get());
// The underlying PresentView call expects an AnnotationController and will
// return PresentViewError.INVALID_ARGS without one. The AnnotationController
// should serve WatchAnnotations, but it doesn't need to do anything.
// TODO(b/264899156): Remove this when AnnotationController becomes
// optional.
auto annotations_manager =
std::make_unique<fuchsia_component_support::AnnotationsManager>();
fuchsia::element::AnnotationControllerPtr annotation_controller;
annotations_manager->Connect(annotation_controller.NewRequest());
ConfigureFrame(frame.get(), std::move(annotation_controller));
// Register the MessagePort for the Cast Streaming Receiver.
std::unique_ptr<cast_api_bindings::MessagePort> sender_message_port;

@ -20,6 +20,7 @@
use: [
{
protocol: [
"fuchsia.element.GraphicalPresenter",
"fuchsia.feedback.ComponentDataRegister",
"fuchsia.feedback.CrashReportingProductRegister",
"fuchsia.sys.Environment",

@ -0,0 +1,91 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fuchsia_web/shell/present_frame.h"
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <stdint.h>
#include <zircon/rights.h>
#include <memory>
#include <utility>
#include <vector>
#include "base/check.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/process_context.h"
#include "base/logging.h"
fuchsia::ui::views::ViewRef CloneViewRef(
const fuchsia::ui::views::ViewRef& view_ref) {
fuchsia::ui::views::ViewRef dup;
zx_status_t status =
view_ref.reference.duplicate(ZX_RIGHT_SAME_RIGHTS, &dup.reference);
ZX_CHECK(status == ZX_OK, status) << "zx_object_duplicate";
return dup;
}
void PresentFrame(fuchsia::web::Frame* frame,
fidl::InterfaceHandle<fuchsia::element::AnnotationController>
annotation_controller) {
fuchsia::element::GraphicalPresenterSyncPtr presenter;
zx_status_t status = base::ComponentContextForProcess()->svc()->Connect(
presenter.NewRequest());
ZX_CHECK(status == ZX_OK, status)
<< "Couldn't connect to GraphicalPresenter.";
auto view_tokens = scenic::ViewTokenPair::New();
auto view_ref_pair = scenic::ViewRefPair::New();
fuchsia::element::ViewSpec view_spec;
view_spec.set_view_holder_token(std::move(view_tokens.view_holder_token));
view_spec.set_view_ref(CloneViewRef(view_ref_pair.view_ref));
view_spec.set_annotations({});
fuchsia::element::ViewControllerSyncPtr view_controller;
fuchsia::element::GraphicalPresenter_PresentView_Result present_view_result;
status = presenter->PresentView(
std::move(view_spec), std::move(annotation_controller),
view_controller.NewRequest(), &present_view_result);
// Note: We do not consider `present_view_result.is_err()` in the fallback
// condition in case the FIDL call succeeds but the method reports an error.
// This is because the only error type reported by the PresentView method is
// INVALID_ARGS, which we have carefully avoided by:
// * Providing a view_spec.view_holder_token and view_spec.view_ref (GFX)
// * Not providing _both_ GFX Views and Flatland Views at once.
//
// Therefore, we expect that if the FIDL call succeeds, the presentation
// should also succeed.
if (status == ZX_OK) {
DCHECK(!present_view_result.is_err())
<< "PresentView failed to display the view, reason: "
<< static_cast<uint32_t>(present_view_result.err());
} else {
// Fallback to connect to Root Presenter.
// TODO(http://crbug.com/1402457): Remove fallback.
LOG(INFO) << "PresentView failed to connect, reason: " << status
<< ". Falling back to fuchsia.ui.policy.Presenter.";
auto root_presenter = base::ComponentContextForProcess()
->svc()
->Connect<fuchsia::ui::policy::Presenter>();
// Replace the original ViewToken and ViewRefPair with new ones.
view_tokens = scenic::ViewTokenPair::New();
view_ref_pair = scenic::ViewRefPair::New();
root_presenter->PresentOrReplaceView2(
std::move(view_tokens.view_holder_token),
CloneViewRef(view_ref_pair.view_ref), nullptr);
}
// Present a fullscreen view of |frame|.
frame->CreateViewWithViewRef(std::move(view_tokens.view_token),
std::move(view_ref_pair.control_ref),
std::move(view_ref_pair.view_ref));
}

@ -0,0 +1,18 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FUCHSIA_WEB_SHELL_PRESENT_FRAME_H_
#define FUCHSIA_WEB_SHELL_PRESENT_FRAME_H_
#include <fuchsia/element/cpp/fidl.h>
#include <fuchsia/web/cpp/fidl.h>
// Presents the given frame by setting up the necessary views, connecting to a
// fuchsia view presentation protocol, and forwarding the given annotation
// controller and annotations.
void PresentFrame(fuchsia::web::Frame* frame,
fidl::InterfaceHandle<fuchsia::element::AnnotationController>
annotation_controller);
#endif // FUCHSIA_WEB_SHELL_PRESENT_FRAME_H_

@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fuchsia/element/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <fuchsia/web/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <lib/vfs/cpp/pseudo_file.h>
#include <iostream>
#include <utility>
@ -27,7 +26,9 @@
#include "base/task/single_thread_task_executor.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/fuchsia_component_support/annotations_manager.h"
#include "fuchsia_web/common/init_logging.h"
#include "fuchsia_web/shell/present_frame.h"
#include "fuchsia_web/shell/remote_debugging_port.h"
#include "fuchsia_web/webinstance_host/web_instance_host_v1.h"
#include "third_party/widevine/cdm/buildflags.h"
@ -183,10 +184,11 @@ int main(int argc, char** argv) {
#if BUILDFLAG(ENABLE_WIDEVINE)
features |= fuchsia::web::ContextFeatureFlags::WIDEVINE_CDM;
#endif
if (is_headless)
if (is_headless) {
features |= fuchsia::web::ContextFeatureFlags::HEADLESS;
else
} else {
features |= fuchsia::web::ContextFeatureFlags::VULKAN;
}
create_context_params.set_features(features);
create_context_params.set_remote_debugging_port(*remote_debugging_port);
@ -304,17 +306,20 @@ int main(int argc, char** argv) {
fuchsia::web::PermissionState::GRANTED);
}
// The underlying PresentView call expects an AnnotationController and will
// return PresentViewError.INVALID_ARGS without one. The AnnotationController
// should serve WatchAnnotations, but it doesn't need to do anything.
// TODO(b/264899156): Remove this when AnnotationController becomes
// optional.
auto annotations_manager =
std::make_unique<fuchsia_component_support::AnnotationsManager>();
fuchsia::element::AnnotationControllerPtr annotation_controller;
annotations_manager->Connect(annotation_controller.NewRequest());
if (is_headless) {
frame->EnableHeadlessRendering();
} else {
// Present a fullscreen view of |frame|.
auto view_tokens = scenic::ViewTokenPair::New();
frame->CreateView(std::move(view_tokens.view_token));
auto presenter = base::ComponentContextForProcess()
->svc()
->Connect<fuchsia::ui::policy::Presenter>();
presenter->PresentOrReplaceView(std::move(view_tokens.view_holder_token),
nullptr);
PresentFrame(frame.get(), std::move(annotation_controller));
}
LOG(INFO) << "Launched browser at URL " << url.spec();

@ -18,6 +18,7 @@
use: [
{
protocol: [
"fuchsia.element.GraphicalPresenter",
"fuchsia.feedback.ComponentDataRegister",
"fuchsia.feedback.CrashReportingProductRegister",
"fuchsia.sys.Environment",

@ -13,6 +13,7 @@
"fuchsia.buildinfo.Provider",
"fuchsia.camera3.DeviceWatcher",
"fuchsia.device.NameProvider",
"fuchsia.element.GraphicalPresenter",
"fuchsia.feedback.ComponentDataRegister",
"fuchsia.feedback.CrashReportingProductRegister",
"fuchsia.fonts.Provider",