1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75

fuchsia_web / shell / present_frame.cc [blame]

// 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 <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/service_directory.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;
}

fuchsia::element::GraphicalPresenterPtr PresentFrame(
    fuchsia::web::Frame* frame,
    fidl::InterfaceHandle<fuchsia::element::AnnotationController>
        annotation_controller) {
  // fuchsia.element.GraphicalPresenter is the only view presentation protocol
  // that supports Flatland, so we expect it to be provided.
  //
  // Note also that using a sync connection results in a 3-way deadlock
  // between web_engine, (Flatland) scene_manager, and scenic, so we use an
  // async connection for the Flatland branch.
  fuchsia::element::GraphicalPresenterPtr presenter =
      base::ComponentContextForProcess()
          ->svc()
          ->Connect<fuchsia::element::GraphicalPresenter>();
  presenter.set_error_handler([](zx_status_t status) {
    ZX_LOG(ERROR, status) << "GraphicalPresenter disconnected: ";
  });

  // Generate Flatland tokens and frame->CreateView2().
  fuchsia::ui::views::ViewCreationToken view_token;
  fuchsia::ui::views::ViewportCreationToken viewport_token;
  auto status =
      zx::channel::create(0, &viewport_token.value, &view_token.value);
  ZX_CHECK(status == ZX_OK, status);
  fuchsia::element::ViewSpec view_spec;
  view_spec.set_viewport_creation_token(std::move(viewport_token));
  view_spec.set_annotations({});

  fuchsia::element::ViewControllerPtr view_controller;
  presenter->PresentView(
      std::move(view_spec), std::move(annotation_controller),
      view_controller.NewRequest(),
      [](fuchsia::element::GraphicalPresenter_PresentView_Result result) {
        if (result.is_err()) {
          LOG(ERROR) << "PresentView failed to display the view, reason: "
                     << static_cast<uint32_t>(result.err());
        }
      });

  // Present a fullscreen view of |frame|.
  fuchsia::web::CreateView2Args create_view_args;
  create_view_args.set_view_creation_token(std::move(view_token));
  frame->CreateView2(std::move(create_view_args));

  return presenter;
}