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
ash / accelerometer / accelerometer_provider_mojo.h [blame]
// 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 <optional>
#include <string>
#include <vector>
#include "ash/accelerometer/accel_gyro_samples_observer.h"
#include "ash/accelerometer/accelerometer_reader.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"
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;
std::optional<AccelerometerSource> location;
std::optional<float> scale;
std::unique_ptr<AccelGyroSamplesObserver> 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
// AccelGyroSamplesObserver 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<std::optional<std::string>>& values);
// Ignores the accelerometer as the attributes are not expected.
void IgnoreAccelerometer(int32_t id);
// Creates the AccelGyroSamplesObserver 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_