| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef ASH_SENSOR_INFO_SENSOR_PROVIDER_H_ |
| #define ASH_SENSOR_INFO_SENSOR_PROVIDER_H_ |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "ash/accelerometer/accel_gyro_samples_observer.h" |
| #include "ash/accelerometer/accelerometer_constants.h" |
| #include "ash/ash_export.h" |
| #include "ash/sensor_info/sensor_types.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/observer_list.h" |
| #include "chromeos/components/sensors/mojom/cros_sensor_service.mojom.h" |
| #include "mojo/public/cpp/bindings/receiver.h" |
| #include "mojo/public/cpp/bindings/remote.h" |
| |
| namespace ash { |
| |
| class SensorProviderTest; |
| |
| // SensorProvider communicates with IIO Service, and provide information from |
| // three types of sensors: accelerometers, gyroscopes, lid_angle sensors. |
| // SensorProvider determines sensors' configuration, and waits for the |
| // sensors' samples. Upon receiving a sample, it will notify all |
| // observers. |
| class ASH_EXPORT SensorProvider |
| : public chromeos::sensors::mojom::SensorHalClient, |
| public chromeos::sensors::mojom::SensorServiceNewDevicesObserver { |
| public: |
| // Class tracking existence of sensors. |
| class DeviceState { |
| public: |
| DeviceState(); |
| ~DeviceState(); |
| |
| DeviceState(const DeviceState&) = delete; |
| DeviceState& operator=(const DeviceState&) = delete; |
| |
| // Returns true if all kinds of sensors available. |
| bool AllSensorsFound() const; |
| |
| void Reset(); |
| |
| // Returns true if all present sensors have update. |
| bool CompareUpdate(SensorUpdate update) const; |
| |
| // Adds a type of sensor. |
| void AddSource(SensorType source); |
| |
| // Removes a type of sensor. |
| void RemoveSource(SensorType source); |
| |
| // Gets the existence of `source`. |
| bool GetSource(SensorType source) const; |
| |
| // Gets DeviceState.present_ while testing. |
| std::vector<bool> GetStatesForTesting() const; |
| |
| private: |
| // Vector storing the existence of types of sensors. |
| std::vector<bool> present_; |
| }; |
| |
| // Struct tracking all sensor info. |
| struct SensorData { |
| SensorData(); |
| ~SensorData(); |
| |
| // Sensor marked ignored will not be used anymore. |
| bool ignored = false; |
| mojo::Remote<chromeos::sensors::mojom::SensorDevice> remote; |
| std::optional<SensorLocation> location; |
| // Data scale of this sensor (Used for initializing Samples_Observer, |
| // range:(0, 10)). Will be 1.0 for most of the cases. |
| std::optional<float> scale; |
| |
| // SamplesObserver of this sensor. |
| std::unique_ptr<ash::AccelGyroSamplesObserver> samples_observer; |
| }; |
| |
| SensorProvider(); |
| |
| SensorProvider(const SensorProvider&) = delete; |
| SensorProvider& operator=(const SensorProvider&) = delete; |
| |
| ~SensorProvider() override; |
| |
| // chromeos::sensors::mojom::SensorHalClient: |
| void SetUpChannel(mojo::PendingRemote<chromeos::sensors::mojom::SensorService> |
| pending_remote) override; |
| |
| // chromeos::sensors::mojom::SensorServiceNewDevicesObserver: |
| void OnNewDeviceAdded( |
| int32_t iio_device_id, |
| const std::vector<chromeos::sensors::mojom::DeviceType>& types) override; |
| |
| // Adds/Removes SensorObservers. |
| void AddObserver(SensorObserver* observer); |
| void RemoveObserver(SensorObserver* observer); |
| |
| // Starts/Stops sensor reading. |
| // Changes 'sensor_read_on_' and call EnableSensorReadingInternal. |
| void EnableSensorReading(); |
| void StopSensorReading(); |
| |
| // Gets DeviceState.state while testing. |
| std::vector<bool> GetStateForTesting(); |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(SensorProviderTest, CheckNoScale); |
| FRIEND_TEST_ALL_PREFIXES(SensorProviderTest, CheckNoLocation); |
| FRIEND_TEST_ALL_PREFIXES(SensorProviderTest, GetSamplesOfLidAccel); |
| FRIEND_TEST_ALL_PREFIXES(SensorProviderTest, GetSamplesOfLidAngleAndLidAccel); |
| FRIEND_TEST_ALL_PREFIXES(SensorProviderTest, GetSamplesOfBaseGyroscope); |
| FRIEND_TEST_ALL_PREFIXES(SensorProviderTest, |
| GetSamplesOfBaseGyroscopeAndBaseAccel); |
| FRIEND_TEST_ALL_PREFIXES(SensorProviderTest, AddSensorsWhileSampling); |
| FRIEND_TEST_ALL_PREFIXES(SensorProviderTest, GetSamplesOfAccelGyroDevices); |
| |
| // Gets all existing sensor devices then initialize sensor devices. |
| void QueryDevices(); |
| |
| // Callback of GetDeviceIds(DeviceType::ANGL), containing the lid_angle |
| // device's id if it exists. |
| void OnLidAngleIds(const std::vector<int32_t>& lid_angle_ids); |
| |
| // Callback of GetDeviceIds(DeviceType::ACCEL), containing all iio_device_ids |
| // of accelerometers. |
| void OnAccelerometerIds(const std::vector<int32_t>& accelerometer_ids); |
| |
| // Callback of GetDeviceIds(DeviceType::ANGLVEL), containing all |
| // iio_device_ids of gyroscopes. |
| void OnGyroscopeIds(const std::vector<int32_t>& gyroscope_ids); |
| |
| // Registers `chromeos::sensors::mojom::SensorHalClient` to Sensor Hal |
| // Dispatcher, waiting for the Mojo connection to IIO Service. |
| void RegisterSensorClient(); |
| void OnSensorServiceDisconnect(); |
| void OnSensorHalClientFailure(); |
| void ResetSensorService(); |
| void ResetStates(); |
| |
| // Waits for new devices from IIO Service. |
| void SetNewDevicesObserver(); |
| void OnNewDevicesObserverDisconnect(); |
| |
| // Creates the Mojo channel for the sensor, and requests the |
| // sensor's location and scale attributes before creating the |
| // SensorSamplesObserver of it. |
| void RegisterSensor(chromeos::sensors::mojom::DeviceType device_type, |
| int32_t id); |
| |
| // Ignores the sensor with id, device_type as the attributes are not expected. |
| void IgnoreSensor(chromeos::sensors::mojom::DeviceType device_type, |
| int32_t id); |
| |
| // Enables all SamplesObservers and sets frequency for SamplesObservers. |
| void EnableSensorReadingInternal(); |
| |
| void OnSensorRemoteDisconnect( |
| chromeos::sensors::mojom::DeviceType device_type, |
| int32_t id, |
| uint32_t custom_reason_code, |
| const std::string& description); |
| |
| // Callback for getting lid angle value. |
| void OnLidAngleValue(const std::vector<std::optional<std::string>>& values); |
| |
| // Callback for getting sensor's location and scale attributes. |
| void OnAttributes(chromeos::sensors::mojom::DeviceType device_type, |
| int32_t id, |
| const std::vector<std::optional<std::string>>& values); |
| |
| // Creates the SamplesObserver for the sensor with 'id'. |
| void CreateSensorSamplesObserver( |
| chromeos::sensors::mojom::DeviceType device_type, |
| int32_t id); |
| |
| // Called by `SensorData::samples_observer` stored in the |
| // `sensors_` map, containing a sample of the sensor. |
| void OnSampleUpdatedCallback(chromeos::sensors::mojom::DeviceType device_type, |
| int iio_device_id, |
| std::vector<float> sample); |
| |
| // Notifies external observer updates. |
| void NotifySensorUpdated(SensorUpdate update); |
| |
| // Returns true if all stored SensorData (excluding SensorData for lid_angle |
| // and SensorData for ignored devices) have a SamplesObserver. |
| bool CheckSensorSamplesObserver(); |
| |
| // Calls GetChannelsAttributesCallback to get lid_angle update. |
| void GetLidAngleUpdate(); |
| |
| // Stores <SensorType, device_id> pairs. |
| std::map<SensorType, int32_t> type_to_sensor_id_; |
| |
| // Map storing <device_id, <chromeos::sensors::mojom::DeviceType, |
| // SensorData>>. |
| std::map<int32_t, std::map<chromeos::sensors::mojom::DeviceType, SensorData>> |
| sensors_; |
| |
| DeviceState current_state_; |
| |
| // The Mojo channel connecting to Sensor Hal Dispatcher. SensorHalDispatcher |
| // will receive registrations of SensorService. |
| mojo::Receiver<chromeos::sensors::mojom::SensorHalClient> sensor_hal_client_{ |
| this}; |
| |
| // The Mojo channel to query and request for devices. |
| mojo::Remote<chromeos::sensors::mojom::SensorService> sensor_service_remote_; |
| |
| // The Mojo channel to get notified when new devices are added to IIO Service. |
| mojo::Receiver<chromeos::sensors::mojom::SensorServiceNewDevicesObserver> |
| new_devices_observer_{this}; |
| |
| // The last seen sensor data. |
| SensorUpdate update_; |
| |
| // Whether send updates to external observers. Value is only changed by |
| // external calls of EnableSensorReading() and StopSensorReading(). |
| bool sensor_read_on_ = false; |
| |
| // List of all external observers. |
| base::ObserverList<SensorObserver> observers_; |
| |
| base::WeakPtrFactory<SensorProvider> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace ash |
| #endif // ASH_SENSOR_INFO_SENSOR_PROVIDER_H_ |