Skip to main content

starnix_modules_battery_manager/
lib.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#![cfg_attr(test, recursion_limit = "256")]
6
7use starnix_core::fs::sysfs::build_device_directory;
8use starnix_core::task::Kernel;
9use starnix_core::vfs::pseudo::stub_bytes_file::StubBytesFile;
10use starnix_logging::bug_ref;
11use starnix_uapi::file_mode::mode;
12
13/// Initializes the stub `battery` power-supply device in sysfs.
14pub fn battery_manager_device_init(kernel: &Kernel) {
15    let registry = &kernel.device_registry;
16    // TODO(https://fxbug.dev/574568519): Back `/sys/class/power_supply/battery` with
17    // `fuchsia.power.battery.BatteryManager` / `BatterySimulator`.
18    registry.add_numberless_device(
19        "battery".into(),
20        /* parent = */ None,
21        registry.objects.power_supply_class(),
22        |device, dir| {
23            build_device_directory(device, dir);
24            dir.entry(
25                "capacity",
26                StubBytesFile::new_node_with_data(bug_ref!("https://fxbug.dev/573313995"), b"0"),
27                mode!(IFREG, 0o644),
28            );
29        },
30    );
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36    use starnix_core::testing::{anon_test_file, spawn_kernel_and_run};
37    use starnix_core::vfs::{VecInputBuffer, VecOutputBuffer};
38    use starnix_uapi::open_flags::OpenFlags;
39
40    #[::fuchsia::test]
41    async fn battery_manager_device_init_registers_power_supply_battery() {
42        spawn_kernel_and_run(async |current_task| {
43            let kernel = current_task.kernel();
44            battery_manager_device_init(kernel);
45
46            let root = &kernel.device_registry.objects.root;
47            assert!(root.lookup("class/power_supply/battery".into()).is_some());
48            let battery_capacity = root
49                .lookup("devices/virtual/power_supply/battery/capacity".into())
50                .expect("battery capacity node should exist");
51            assert_eq!(battery_capacity.info().mode, mode!(IFREG, 0o644));
52
53            let file_ops = battery_capacity.create_file_ops(current_task, OpenFlags::RDWR).unwrap();
54            let file = anon_test_file(current_task, file_ops, OpenFlags::RDWR);
55            let mut output = VecOutputBuffer::new(16);
56            let n = file.read(current_task, &mut output).unwrap();
57            assert_eq!(&Vec::from(output)[..n], b"0");
58
59            let mut input = VecInputBuffer::new(b"77\n");
60            assert_eq!(file.write(current_task, &mut input).unwrap(), 3);
61        })
62        .await;
63    }
64}