blob: 963910c047c3a6b2deac0191e054b14efad9d50d [file] [log] [blame]
// Copyright 2022 The Fuchsia 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 "src/ui/testing/scene_provider/scene_provider.h"
#include <fuchsia/session/scene/cpp/fidl.h>
#include <fuchsia/ui/app/cpp/fidl.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <zircon/status.h>
#include "sdk/lib/syslog/cpp/macros.h"
#include "src/lib/fsl/handles/object_info.h"
namespace ui_testing {
void FakeViewController::Dismiss() { dismiss_(); }
SceneProvider::SceneProvider(sys::ComponentContext* context) : context_(context) {
context_->svc()->Connect(scene_manager_.NewRequest());
}
void SceneProvider::AttachClientView(
fuchsia::ui::test::scene::ControllerAttachClientViewRequest request,
AttachClientViewCallback callback) {
FX_LOGS(INFO) << "Attach client view";
fuchsia::ui::views::ViewRef client_view_ref;
fuchsia::session::scene::Manager_SetRootView_Result set_root_view_result;
zx_status_t status = scene_manager_->SetRootView(std::move(*request.mutable_view_provider()),
&set_root_view_result);
FX_CHECK(status == ZX_OK) << "Failed to call SetRootView: " << zx_status_get_string(status);
FX_CHECK(set_root_view_result.is_response())
<< "Failed to set root view: " << set_root_view_result.err();
client_view_ref = std::move(set_root_view_result.response().view_ref);
pending_presented_view_count_++;
NotifyViewPresentationWatcher();
callback(fsl::GetKoid(client_view_ref.reference.get()));
}
void SceneProvider::PresentClientView(
fuchsia::ui::test::scene::ControllerPresentClientViewRequest request) {
FX_CHECK(request.has_viewport_creation_token()) << "Missing viewport creation token";
fuchsia::session::scene::Manager_PresentRootView_Result present_root_view_result;
scene_manager_->PresentRootView(std::move(*request.mutable_viewport_creation_token()),
&present_root_view_result);
FX_LOGS(INFO) << "Requested to present client view";
pending_presented_view_count_++;
NotifyViewPresentationWatcher();
}
void SceneProvider::RegisterViewTreeWatcher(
fidl::InterfaceRequest<fuchsia::ui::observation::geometry::ViewTreeWatcher> view_tree_watcher,
RegisterViewTreeWatcherCallback callback) {
// Register the client's view tree watcher.
fuchsia::ui::observation::test::RegistrySyncPtr observer_registry;
context_->svc()->Connect<fuchsia::ui::observation::test::Registry>(
observer_registry.NewRequest());
observer_registry->RegisterGlobalViewTreeWatcher(std::move(view_tree_watcher));
callback();
}
void SceneProvider::WatchViewPresentation(WatchViewPresentationCallback callback) {
if (view_presentation_callback_ != nullptr) {
FX_LOGS(ERROR)
<< "Received a WatchViewPresentation request while a prior one was still pending. Ignoring the request.";
return;
}
view_presentation_callback_ = std::move(callback);
NotifyViewPresentationWatcher();
}
void SceneProvider::NotifyViewPresentationWatcher() {
if (pending_presented_view_count_ == 0 || !view_presentation_callback_) {
return;
}
view_presentation_callback_();
view_presentation_callback_ = nullptr;
pending_presented_view_count_--;
}
// TODO(https://fxbug.dev/42064159): Refactor to accommodate Flatland + Geometry
// Observation.
void SceneProvider::PresentView(
fuchsia::element::ViewSpec view_spec,
fidl::InterfaceHandle<fuchsia::element::AnnotationController> annotation_controller,
fidl::InterfaceRequest<fuchsia::element::ViewController> view_controller,
PresentViewCallback callback) {
if (annotation_controller) {
annotation_controller_.Bind(std::move(annotation_controller));
}
if (view_controller) {
fake_view_controller_.emplace(std::move(view_controller), [this] { this->DismissView(); });
}
// TODO(https://fxbug.dev/42057396): Register client's scoped view tree watcher, if
// requested.
if (view_spec.has_viewport_creation_token()) {
fuchsia::session::scene::Manager_PresentRootView_Result set_root_view_result;
scene_manager_->PresentRootView(std::move(*view_spec.mutable_viewport_creation_token()),
&set_root_view_result);
if (set_root_view_result.is_err()) {
FX_LOGS(ERROR) << "fuchsia.session.scene.Manager/PresentRootView error:"
<< set_root_view_result.err();
fuchsia::element::GraphicalPresenter_PresentView_Result result;
result.set_err(fuchsia::element::PresentViewError::INVALID_ARGS);
callback(std::move(result));
return;
}
} else {
FX_LOGS(FATAL) << "Invalid view spec";
}
pending_presented_view_count_++;
NotifyViewPresentationWatcher();
fuchsia::element::GraphicalPresenter_PresentView_Result result;
result.set_response({});
callback(std::move(result));
}
fidl::InterfaceRequestHandler<fuchsia::ui::test::scene::Controller>
SceneProvider::GetSceneControllerHandler() {
return scene_controller_bindings_.GetHandler(this);
}
fidl::InterfaceRequestHandler<fuchsia::element::GraphicalPresenter>
SceneProvider::GetGraphicalPresenterHandler() {
return graphical_presenter_bindings_.GetHandler(this);
}
void SceneProvider::DismissView() {
FX_LOGS(FATAL)
<< "Dismissing views on flatland is not yet supported (https://fxbug.dev/42065735)";
}
} // namespace ui_testing