blob: 80dd38256616c780d26dce544933d10cec8911be [file] [log] [blame]
// Copyright 2021 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/scenic/lib/focus/view_focuser_registry.h"
#include <lib/syslog/cpp/macros.h>
#include "src/ui/scenic/lib/utils/helpers.h"
namespace focus {
using ViewRef = fuchsia::ui::views::ViewRef;
using ViewFocuser = fuchsia::ui::views::Focuser;
using RequestFocusCallback = fuchsia::ui::views::Focuser::RequestFocusCallback;
using SetAutoFocusCallback = fuchsia::ui::views::Focuser::SetAutoFocusCallback;
ViewFocuserRegistry::ViewFocuserRegistry(RequestFocusFunc request_focus,
SetAutoFocusFunc set_auto_focus)
: request_focus_(std::move(request_focus)), set_auto_focus_(std::move(set_auto_focus)) {}
void ViewFocuserRegistry::Register(zx_koid_t view_ref_koid,
fidl::InterfaceRequest<ViewFocuser> view_focuser) {
endpoints_.try_emplace(
view_ref_koid, std::move(view_focuser),
/*error_handler*/
[this, view_ref_koid](auto) {
set_auto_focus_(view_ref_koid, ZX_KOID_INVALID);
endpoints_.erase(view_ref_koid);
},
/*request_focus*/
[this, requestor = view_ref_koid](ViewRef view_ref, RequestFocusCallback response) {
if (request_focus_(requestor, utils::ExtractKoid(view_ref))) {
response(fpromise::ok()); // Request received, and honored.
return;
}
response(fpromise::error(fuchsia::ui::views::Error::DENIED)); // Report a problem.
},
/*set_auto_focus*/
[this, requestor = view_ref_koid](zx_koid_t view_ref_koid) {
set_auto_focus_(requestor, view_ref_koid);
});
}
ViewFocuserRegistry::ViewFocuserEndpoint::ViewFocuserEndpoint(
fidl::InterfaceRequest<ViewFocuser> view_focuser,
fit::function<void(zx_status_t)> error_handler,
fit::function<void(ViewRef, RequestFocusCallback)> request_focus,
fit::function<void(zx_koid_t)> set_auto_focus)
: request_focus_(std::move(request_focus)),
set_auto_focus_(std::move(set_auto_focus)),
endpoint_(this, std::move(view_focuser)) {
FX_DCHECK(error_handler) << "invariant";
FX_DCHECK(request_focus_) << "invariant";
FX_DCHECK(set_auto_focus_) << "invariant";
endpoint_.set_error_handler(std::move(error_handler));
}
void ViewFocuserRegistry::ViewFocuserEndpoint::RequestFocus(ViewRef view_ref,
RequestFocusCallback response) {
request_focus_(std::move(view_ref), std::move(response));
}
void ViewFocuserRegistry::ViewFocuserEndpoint::SetAutoFocus(
fuchsia::ui::views::FocuserSetAutoFocusRequest request, SetAutoFocusCallback response) {
zx_koid_t target = ZX_KOID_INVALID;
if (request.has_view_ref()) {
target = utils::ExtractKoid(request.view_ref());
}
set_auto_focus_(target);
response(fpromise::ok());
}
} // namespace focus