1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef ANDROID_HARDWARE_SENSORS_V2_1_SENSOR_H
17 #define ANDROID_HARDWARE_SENSORS_V2_1_SENSOR_H
18 
19 #include <android/hardware/sensors/2.1/types.h>
20 #include <poll.h>
21 #include <condition_variable>
22 #include <memory>
23 #include <mutex>
24 #include <thread>
25 #include <vector>
26 
27 #include "SensorThread.h"
28 #include "V2_0/ScopedWakelock.h"
29 #include "iio_utils.h"
30 #include "sensor_hal_configuration_V1_0.h"
31 
32 #define NUM_OF_CHANNEL_SUPPORTED 4
33 // Subtract the timestamp channel to get the number of data channels
34 #define NUM_OF_DATA_CHANNELS NUM_OF_CHANNEL_SUPPORTED - 1
35 
36 using ::android::hardware::sensors::V1_0::AdditionalInfo;
37 using ::android::hardware::sensors::V1_0::OperationMode;
38 using ::android::hardware::sensors::V1_0::Result;
39 using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock;
40 using ::android::hardware::sensors::V2_1::Event;
41 using ::android::hardware::sensors::V2_1::SensorInfo;
42 using ::android::hardware::sensors::V2_1::SensorType;
43 using ::sensor::hal::configuration::V1_0::Configuration;
44 
45 namespace android {
46 namespace hardware {
47 namespace sensors {
48 namespace V2_1 {
49 namespace subhal {
50 namespace implementation {
51 
frequency_to_us(unsigned int x)52 static constexpr unsigned int frequency_to_us(unsigned int x) {
53     return (1E6 / x);
54 }
55 
ns_to_frequency(unsigned int x)56 static constexpr unsigned int ns_to_frequency(unsigned int x) {
57     return (1E9 / x);
58 }
59 
60 // SCMI IIO driver gives sensor power in microwatts. Sensor HAL expects
61 // it in mA. Conversion process needs the input voltage for the IMU.
62 // Based on commonly used IMUs, 3.6V is picked as the default.
63 constexpr auto SENSOR_VOLTAGE_DEFAULT = 3.6f;
64 
65 class ISensorsEventCallback {
66   public:
67     virtual ~ISensorsEventCallback() = default;
68     virtual void postEvents(const std::vector<Event>& events, ScopedWakelock wakelock) = 0;
69     virtual ScopedWakelock createScopedWakelock(bool lock) = 0;
70 };
71 
72 // Virtual Base Class for Sensor
73 class SensorBase {
74   public:
75     SensorBase(int32_t sensorHandle, ISensorsEventCallback* callback, SensorType type);
76     virtual ~SensorBase();
77     const SensorInfo& getSensorInfo() const;
78     virtual void batch(int32_t samplingPeriodNs) = 0;
79     virtual void activate(bool enable) = 0;
80     virtual Result flush();
81     void setOperationMode(OperationMode mode);
82     bool supportsDataInjection() const;
83     Result injectEvent(const Event& event);
84 
85     bool isEnabled() const;
86     OperationMode getOperationMode() const;
87 
88   protected:
89     friend class SensorThread;
90 
91     virtual void pollSensor() = 0;
92     bool isWakeUpSensor();
93 
94     bool mIsEnabled;
95     int64_t mSamplingPeriodNs;
96     SensorInfo mSensorInfo;
97     ISensorsEventCallback* mCallback;
98     OperationMode mMode;
99     SensorThread mSensorThread;
100 };
101 
102 class SensorThread;
103 
104 // HWSensorBase represents the actual physical sensor provided as the IIO device
105 class HWSensorBase : public SensorBase {
106   public:
107     static HWSensorBase* buildSensor(int32_t sensorHandle, ISensorsEventCallback* callback,
108                                      const struct iio_device_data& iio_data,
109                                      const std::optional<std::vector<Configuration>>& config);
110     ~HWSensorBase();
111     void batch(int32_t samplingPeriodNs);
112     void activate(bool enable);
113     Result flush();
114     struct iio_device_data mIioData;
115 
116   protected:
117     void pollSensor() override;
118 
119   private:
120     void idleLoop();
121     void pollForEvents();
122 
123     static constexpr uint8_t LOCATION_X_IDX = 3;
124     static constexpr uint8_t LOCATION_Y_IDX = 7;
125     static constexpr uint8_t LOCATION_Z_IDX = 11;
126     static constexpr uint8_t ROTATION_X_IDX = 0;
127     static constexpr uint8_t ROTATION_Y_IDX = 1;
128     static constexpr uint8_t ROTATION_Z_IDX = 2;
129 
130     ssize_t mScanSize;
131     struct pollfd mPollFdIio;
132     std::vector<uint8_t> mSensorRawData;
133     int64_t mXMap, mYMap, mZMap;
134     bool mXNegate, mYNegate, mZNegate;
135     std::vector<AdditionalInfo> mAdditionalInfoFrames;
136 
137     HWSensorBase(int32_t sensorHandle, ISensorsEventCallback* callback,
138                  const struct iio_device_data& iio_data,
139                  const std::optional<std::vector<Configuration>>& config);
140 
141     ssize_t calculateScanSize();
142     void run();
143     void setOrientation(std::optional<std::vector<Configuration>> config);
144     void processScanData(uint8_t* data, Event* evt);
145     void setAxisDefaultValues();
146     status_t setAdditionalInfoFrames(const std::optional<std::vector<Configuration>>& config);
147     void sendAdditionalInfoReport();
148     status_t getSensorPlacement(AdditionalInfo* sensorPlacement,
149                                 const std::optional<std::vector<Configuration>>& config);
150 };
151 }  // namespace implementation
152 }  // namespace subhal
153 }  // namespace V2_1
154 }  // namespace sensors
155 }  // namespace hardware
156 }  // namespace android
157 #endif  // ANDROID_HARDWARE_SENSORS_V2_1_SENSOR_H
158