sensors_lib/
playback.rs

1// Copyright 2024 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.
4use crate::sensor_manager::{Sensor, SensorId};
5use crate::utils::is_sensor_valid;
6use fidl::endpoints::Proxy;
7use fidl::AsHandleRef;
8use fidl_fuchsia_hardware_sensors::{self as driver_fidl, PlaybackSourceConfig};
9use fidl_fuchsia_sensors::ConfigurePlaybackError;
10use std::collections::{HashMap, HashSet};
11
12#[derive(Debug, Clone)]
13pub struct Playback {
14    pub(crate) driver_proxy: driver_fidl::DriverProxy,
15    pub(crate) playback_proxy: driver_fidl::PlaybackProxy,
16    pub(crate) playback_sensor_ids: Vec<SensorId>,
17    pub(crate) configured: bool,
18}
19
20impl Playback {
21    pub fn new(
22        driver_proxy: driver_fidl::DriverProxy,
23        playback_proxy: driver_fidl::PlaybackProxy,
24    ) -> Self {
25        Self { driver_proxy, playback_proxy, playback_sensor_ids: Vec::new(), configured: false }
26    }
27
28    pub(crate) async fn get_sensors_from_config(
29        &mut self,
30        source_config: PlaybackSourceConfig,
31    ) -> HashMap<SensorId, Sensor> {
32        self.playback_sensor_ids.clear();
33        let mut sensors = HashMap::<SensorId, Sensor>::new();
34
35        // In a FixedValuesConfig, the list of sensors is known, so they can be
36        // added directly to the map of sensors.
37        //
38        // In a FilePlaybackConfig, the playback_controller needs to read the list
39        // of sensors from a file first, so the list needs to come from the proxy.
40        let sensor_list = if let PlaybackSourceConfig::FixedValuesConfig(val) = source_config {
41            val.sensor_list.unwrap_or(Vec::new())
42        } else {
43            self.driver_proxy.get_sensors_list().await.unwrap_or(Vec::new())
44        };
45
46        for sensor in sensor_list {
47            if is_sensor_valid(&sensor) {
48                let id = sensor.sensor_id.expect("sensor_id");
49
50                sensors.insert(
51                    id,
52                    Sensor {
53                        driver: self.driver_proxy.clone(),
54                        info: sensor,
55                        clients: HashSet::new(),
56                    },
57                );
58                self.playback_sensor_ids.push(id);
59            }
60        }
61
62        sensors
63    }
64
65    pub(crate) fn is_playback_driver_proxy(&self, driver_proxy: &driver_fidl::DriverProxy) -> bool {
66        driver_proxy.as_channel().raw_handle() == self.driver_proxy.as_channel().raw_handle()
67    }
68}
69
70pub fn from_driver_playback_error(
71    val: driver_fidl::ConfigurePlaybackError,
72) -> ConfigurePlaybackError {
73    match val {
74        driver_fidl::ConfigurePlaybackError::InvalidConfigType => {
75            ConfigurePlaybackError::InvalidConfigType
76        }
77        driver_fidl::ConfigurePlaybackError::ConfigMissingFields => {
78            ConfigurePlaybackError::ConfigMissingFields
79        }
80        driver_fidl::ConfigurePlaybackError::DuplicateSensorInfo => {
81            ConfigurePlaybackError::DuplicateSensorInfo
82        }
83        driver_fidl::ConfigurePlaybackError::NoEventsForSensor => {
84            ConfigurePlaybackError::NoEventsForSensor
85        }
86        driver_fidl::ConfigurePlaybackError::EventFromUnknownSensor => {
87            ConfigurePlaybackError::EventFromUnknownSensor
88        }
89        driver_fidl::ConfigurePlaybackError::EventSensorTypeMismatch => {
90            ConfigurePlaybackError::EventSensorTypeMismatch
91        }
92        driver_fidl::ConfigurePlaybackError::EventPayloadTypeMismatch => {
93            ConfigurePlaybackError::EventPayloadTypeMismatch
94        }
95        driver_fidl::ConfigurePlaybackError::FileOpenFailed => {
96            ConfigurePlaybackError::FileOpenFailed
97        }
98        driver_fidl::ConfigurePlaybackError::FileParseError => {
99            ConfigurePlaybackError::FileParseError
100        }
101        driver_fidl::ConfigurePlaybackError::__SourceBreaking { unknown_ordinal } => {
102            // This should be unreachable because playback is subpackaged with the sensor manager.
103            log::error!(
104                "Received unknown error from Sensor Playback with ordinal: {:#?}",
105                unknown_ordinal
106            );
107            ConfigurePlaybackError::PlaybackUnavailable
108        }
109    }
110}