blob: beb5106f4c7f7a4dcc2685551f6248942ac4a022 [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/bin/root_presenter/virtual_keyboard_manager.h"
#include <fuchsia/input/virtualkeyboard/cpp/fidl.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/errors.h>
#include <zircon/status.h>
#include <zircon/types.h>
#include <utility>
#include "src/lib/fxl/memory/weak_ptr.h"
#include "src/ui/bin/root_presenter/virtual_keyboard_coordinator.h"
namespace root_presenter {
VirtualKeyboardManager::VirtualKeyboardManager(
fxl::WeakPtr<VirtualKeyboardCoordinator> coordinator,
fuchsia::input::virtualkeyboard::TextType initial_text_type)
: coordinator_(std::move(coordinator)) {
pending_config_ = KeyboardConfig{.text_type = initial_text_type, .is_visible = false};
}
void VirtualKeyboardManager::WatchTypeAndVisibility(WatchTypeAndVisibilityCallback callback) {
FX_LOGS(INFO) << __FUNCTION__;
if (watch_callback_) {
// The caller has violated the constraints of the protocol. Report the error
// to the coordinator. The coordinator will close the connection, and destroy
// this VirtualKeyboardManager.
if (coordinator_) {
coordinator_->NotifyManagerError(ZX_ERR_BAD_STATE);
} else {
FX_LOGS(WARNING) << "Ignorning redundant WatchTypeAndVisibility() call";
}
return;
}
watch_callback_ = std::move(callback);
MaybeNotifyWatcher();
}
void VirtualKeyboardManager::Notify(bool is_visible,
fuchsia::input::virtualkeyboard::VisibilityChangeReason reason,
NotifyCallback callback) {
FX_LOGS(INFO) << __FUNCTION__ << " is_visible=" << is_visible;
if (coordinator_) {
coordinator_->NotifyVisibilityChange(is_visible, reason);
} else {
FX_LOGS(WARNING) << "Ignorning Notify() call: no `coordinator_`";
}
callback();
}
void VirtualKeyboardManager::SetTypeAndVisibility(
fuchsia::input::virtualkeyboard::TextType text_type, bool is_visible) {
const KeyboardConfig proposed_config = {.text_type = text_type, .is_visible = is_visible};
if (last_sent_config_ != proposed_config) {
pending_config_ = proposed_config;
MaybeNotifyWatcher();
}
}
void VirtualKeyboardManager::SetVisibility(bool is_visible) {
FX_DCHECK(pending_config_.has_value() || last_sent_config_.has_value());
const KeyboardConfig proposed_config = {
.text_type = pending_config_.has_value() ? pending_config_.value().text_type
: last_sent_config_.has_value()
? last_sent_config_.value().text_type
: fuchsia::input::virtualkeyboard::TextType::ALPHANUMERIC,
.is_visible = is_visible};
if (last_sent_config_ != proposed_config) {
pending_config_ = proposed_config;
MaybeNotifyWatcher();
}
}
void VirtualKeyboardManager::MaybeNotifyWatcher() {
if (watch_callback_ && pending_config_) {
watch_callback_(pending_config_->text_type, pending_config_->is_visible);
last_sent_config_ = pending_config_;
pending_config_.reset();
watch_callback_ = {};
}
}
} // namespace root_presenter