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::AsHandleRef;
7use fidl::endpoints::Proxy;
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().as_handle_ref().raw_handle()
67            == self.driver_proxy.as_channel().as_handle_ref().raw_handle()
68    }
69}
70
71pub fn from_driver_playback_error(
72    val: driver_fidl::ConfigurePlaybackError,
73) -> ConfigurePlaybackError {
74    match val {
75        driver_fidl::ConfigurePlaybackError::InvalidConfigType => {
76            ConfigurePlaybackError::InvalidConfigType
77        }
78        driver_fidl::ConfigurePlaybackError::ConfigMissingFields => {
79            ConfigurePlaybackError::ConfigMissingFields
80        }
81        driver_fidl::ConfigurePlaybackError::DuplicateSensorInfo => {
82            ConfigurePlaybackError::DuplicateSensorInfo
83        }
84        driver_fidl::ConfigurePlaybackError::NoEventsForSensor => {
85            ConfigurePlaybackError::NoEventsForSensor
86        }
87        driver_fidl::ConfigurePlaybackError::EventFromUnknownSensor => {
88            ConfigurePlaybackError::EventFromUnknownSensor
89        }
90        driver_fidl::ConfigurePlaybackError::EventSensorTypeMismatch => {
91            ConfigurePlaybackError::EventSensorTypeMismatch
92        }
93        driver_fidl::ConfigurePlaybackError::EventPayloadTypeMismatch => {
94            ConfigurePlaybackError::EventPayloadTypeMismatch
95        }
96        driver_fidl::ConfigurePlaybackError::FileOpenFailed => {
97            ConfigurePlaybackError::FileOpenFailed
98        }
99        driver_fidl::ConfigurePlaybackError::FileParseError => {
100            ConfigurePlaybackError::FileParseError
101        }
102        driver_fidl::ConfigurePlaybackError::__SourceBreaking { unknown_ordinal } => {
103            // This should be unreachable because playback is subpackaged with the sensor manager.
104            log::error!(
105                "Received unknown error from Sensor Playback with ordinal: {:#?}",
106                unknown_ordinal
107            );
108            ConfigurePlaybackError::PlaybackUnavailable
109        }
110    }
111}