1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
|
// Copyright 2020 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_ACCELEROMETER_ACCELEROMETER_PROVIDER_MOJO_H_
#define ASH_ACCELEROMETER_ACCELEROMETER_PROVIDER_MOJO_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "ash/accelerometer/accelerometer_reader.h"
#include "ash/accelerometer/accel_gyro_samples_observer.h"
#include "ash/ash_export.h"
#include "base/sequence_checker.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"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace ash {
// As devices may be late-present, the state and available devices cannot be
// determined within any given time or requests. This MojoState helps
// AccelerometerProviderMojo determine the current available devices and
// provides a clear finite state machine. States that should provide samples:
// LID, LID_BASE, ANGL_LID.
enum class MojoState {
INITIALIZING, // No devices available yet.
LID, // Only lid-accelerometer is available.
BASE, // Only base-accelerometer is available.
LID_BASE, // Both accelerometers are available.
ANGL, // Only lid-angle driver is available.
ANGL_LID, // Both lid-angle driver and lid-accelerometer are available.
};
class AccelerometerProviderMojoTest;
// Work that runs on the UI thread. As a sensor client, it communicates with IIO
// Service, determines the accelerometers' configuration, and waits for the
// accelerometers' samples. Upon receiving a sample, it will notify all
// observers.
class ASH_EXPORT AccelerometerProviderMojo
: public AccelerometerProviderInterface,
public chromeos::sensors::mojom::SensorHalClient,
public chromeos::sensors::mojom::SensorServiceNewDevicesObserver {
public:
AccelerometerProviderMojo();
AccelerometerProviderMojo(const AccelerometerProviderMojo&) = delete;
AccelerometerProviderMojo& operator=(const AccelerometerProviderMojo&) =
delete;
// AccelerometerProviderInterface:
void PrepareAndInitialize() override;
void TriggerRead() override;
void CancelRead() 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;
MojoState GetInitializationStateForTesting() const;
protected:
// AccelerometerProviderInterface:
bool ShouldDelayOnTabletPhysicalStateChanged() override;
private:
friend AccelerometerProviderMojoTest;
struct AccelerometerData {
AccelerometerData();
~AccelerometerData();
bool ignored = false;
// Temporarily stores the accelerometer remote, waiting for it's scale and
// location information. It'll be passed to |samples_observer| as an
// argument after all information is collected.
mojo::Remote<chromeos::sensors::mojom::SensorDevice> remote;
absl::optional<AccelerometerSource> location;
absl::optional<float> scale;
std::unique_ptr<AccelGryoSamplesObserver> samples_observer;
};
~AccelerometerProviderMojo() override;
// Registers chromeos::sensors::mojom::SensorHalClient to Sensor Hal
// Dispatcher, waiting for the Mojo connection to IIO Service.
void RegisterSensorClient();
void OnSensorHalClientFailure();
void OnSensorServiceDisconnect();
void ResetSensorService();
// Called when an in-use device is unplugged, and we need to search for other
// devices to use.
// Assumes that the angle device won't be unplugged.
void ResetStates();
void QueryDevices();
void SetECLidAngleDriverSupported();
// Update |initialization_state_| upon new devices' arrival.
// MojoState (|initialization_state_|) transition:
// INITIALIZING -> ANGL
// LID -> ANGL_LID
// BASE -> ANGL
// ANGL Shouldn't happen
// ANGL_LID Shouldn't happen
void UpdateStateWithECLidAngleDriverSupported();
// MojoState (|initialization_state_|) transition:
// INITIALIZING -> LID
// LID Shouldn't happen
// BASE -> LID_BASE
// ANGL -> ANGL_LID
// ANGL_LID Shouldn't happen
void UpdateStateWithLidAccelerometer();
// MojoState (|initialization_state_|) transition:
// INITIALIZING -> BASE
// LID -> LID_BASE
// BASE Shouldn't happen
// ANGL -> ANGL
// ANGL_LID -> ANGL_LID
void UpdateStateWithBaseAccelerometer();
void SetNewDevicesObserver();
void OnNewDevicesObserverDisconnect();
// Timeout of new devices. If lid-angle driver is still not present, assumes
// it not supported and notifies observers.
// This class still listens to new devices after the timeout to catch the
// really late-present devices and avoid those issues, as the current use
// cases/observers allow that.
void OnNewDevicesTimeout();
// Callback of GetDeviceIds(ANGL), containing the lid-angle device's id if it
// exists.
void GetLidAngleIdsCallback(const std::vector<int32_t>& lid_angle_ids);
// Callback of GetDeviceIds(ACCEL), containing all iio_device_ids of
// accelerometers.
void GetAccelerometerIdsCallback(
const std::vector<int32_t>& accelerometer_ids);
// Creates the Mojo channel for the accelerometer, and requests the
// accelerometer's required attributes before creating the
// AccelGryoSamplesObserver of it.
void RegisterAccelerometerWithId(int32_t id);
void OnAccelerometerRemoteDisconnect(int32_t id,
uint32_t custom_reason_code,
const std::string& description);
void GetAttributesCallback(
int32_t id,
const std::vector<absl::optional<std::string>>& values);
// Ignores the accelerometer as the attributes are not expected.
void IgnoreAccelerometer(int32_t id);
// Creates the AccelGryoSamplesObserver for the accelerometer with |id|.
void CreateAccelerometerSamplesObserver(int32_t id);
// Controls accelerometer reading.
void EnableAccelerometerReading();
void DisableAccelerometerReading();
// Called by |AccelerometerData::samples_observer| stored in the
// |accelerometers_| map, containing a sample of the accelerometer.
void OnSampleUpdatedCallback(int iio_device_id, std::vector<float> sample);
// The state that contains the information of devices we have now. Used for
// late-present devices.
MojoState initialization_state_ = MojoState::INITIALIZING;
// The Mojo channel connecting to Sensor Hal Dispatcher.
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};
// First is the accelerometer's iio device id, second is it's data, mojo
// remote and samples observer.
std::map<int32_t, AccelerometerData> accelerometers_;
// First is the location index, second is the id of the accelerometer being
// used in this reader.
std::map<AccelerometerSource, int32_t> location_to_accelerometer_id_;
// The flag to delay |OnTabletPhysicalStateChanged| until
// |ec_lid_angle_driver_status_| is set.
bool pending_on_tablet_physical_state_changed_ = false;
// True if periodical accelerometer read is on.
bool accelerometer_read_on_ = false;
// The last seen accelerometer data.
AccelerometerUpdate update_;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace ash
#endif // ASH_ACCELEROMETER_ACCELEROMETER_PROVIDER_MOJO_H_
|