| // 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 "driver/src/backlight_driver.h" |
| |
| #include <fidl/fuchsia.hardware.acpi/cpp/wire.h> |
| #include <lib/async/cpp/task.h> |
| #include <lib/zx/clock.h> |
| |
| namespace backlight_driver { |
| |
| // Public methods. |
| zx::result<> BacklightDriver::Start() { |
| auto init_result = Initialize(); |
| if (init_result.is_error()) { |
| FDF_SLOG(ERROR, "Failed to initialize.", KV("status", init_result.status_string())); |
| return init_result.take_error(); |
| } |
| |
| auto set_result = backlight_manager_->SetBacklight(kMaxBacklight); |
| if (set_result.is_error()) { |
| FDF_SLOG(ERROR, "Failed to set backlight.", KV("status", set_result.status_string())); |
| return set_result.take_error(); |
| } |
| |
| auto get_result = backlight_manager_->GetBacklight(); |
| if (get_result.is_error()) { |
| FDF_SLOG(ERROR, "Failed to get backlight.", KV("status", get_result.status_string())); |
| return get_result.take_error(); |
| } |
| |
| // Starts a breathing animation on the keyboard. |
| StartBacklightBreathing(); |
| FDF_LOG(INFO, "Keyboard backlight driver started."); |
| return zx::ok(); |
| } |
| |
| // Private methods. |
| zx::result<> BacklightDriver::Initialize() { |
| // Connect to parent. |
| auto connect_result = context().incoming()->Connect<fuchsia_hardware_acpi::Service::Device>(); |
| if (!connect_result.is_ok()) { |
| return connect_result.take_error(); |
| } |
| |
| backlight_manager_.emplace(&logger(), std::move(connect_result.value())); |
| return zx::ok(); |
| } |
| |
| void BacklightDriver::StartBacklightBreathing() { |
| breathing_start = zx::clock::get_monotonic(); |
| BreathingBacklightImpl(0); |
| } |
| |
| void BacklightDriver::BreathingBacklightImpl(int next_index) { |
| if (zx::clock::get_monotonic() - breathing_start > kAnimationDuration) { |
| FDF_LOG(INFO, "Stopping breathing animation and setting backlight to maximum."); |
| auto set_result = backlight_manager_->SetBacklight(kMaxBacklight); |
| if (set_result.is_error()) { |
| FDF_SLOG(ERROR, "Failed to set backlight to max after breathing animation completion.", |
| KV("status", set_result.status_string())); |
| } |
| |
| return; |
| } |
| |
| uint64_t next_value = kAnimation[next_index]; |
| std::ignore = backlight_manager_->SetBacklight(next_value); |
| async::PostDelayedTask( |
| dispatcher(), |
| [this, next_index, vals = kAnimation.size()]() mutable { |
| BreathingBacklightImpl((next_index + 1) % vals); |
| }, |
| kAnimationInterval); |
| } |
| |
| } // namespace backlight_driver |
| |
| FUCHSIA_DRIVER_LIFECYCLE_CPP_V3(fdf::Lifecycle<backlight_driver::BacklightDriver>); |