1 /*
2  * Copyright (C) 2018 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 
17 #ifndef CHRE_PLATFORM_SLPI_SEE_SEE_CAL_HELPER_H_
18 #define CHRE_PLATFORM_SLPI_SEE_SEE_CAL_HELPER_H_
19 
20 extern "C" {
21 
22 #include "sns_client.h"
23 
24 }  // extern "C"
25 
26 #include "sns_suid.pb.h"
27 
28 #include "chre/core/sensor_type.h"
29 #include "chre/platform/mutex.h"
30 #include "chre/util/non_copyable.h"
31 #include "chre/util/optional.h"
32 
33 namespace chre {
34 
35 class SeeHelper;
36 
37 /**
38  * Helps manage and apply sensor calibration data provided through SEE.
39  */
40 class SeeCalHelper : public NonCopyable {
41  public:
42   /**
43    * Applies cached calibration (if any) to raw 3-axis sensor readings.
44    * Thread-safe.
45    *
46    * @param sensorType Type of sensor that generated the sample
47    * @param input 3-axis raw sample {x,y,z}
48    * @param output Location to store sample with calibration applied (can be
49    *               same as input)
50    */
51   void applyCalibration(SensorType sensorType, const float input[3],
52                         float output[3]) const;
53 
54   /**
55    * Returns the cached calibration data. If the calibration data is available,
56    * this method will store all fields in the provided chreSensorThreeAxisData
57    * pointer, where the sample count is one. Thread-safe.
58    *
59    * @param sensorType Type of sensor to retrieve calibration data from, should
60    *                   be the type of a runtime-calibrated sensor
61    * @param biasData A non-null pointer to store the calibration data, not used
62    *                 if the calibration data is not available
63    *
64    * @return true if calibration data is successfully stored, false otherwise
65    */
66   bool getBias(
67       SensorType sensorType, struct chreSensorThreeAxisData *biasData) const;
68 
69   /**
70    * @return Whether calibration updates are enabled for the given SUID.
71    */
72   bool areCalUpdatesEnabled(const sns_std_suid &suid) const;
73 
74   /**
75    * Configures calibration updates for the given SUID.
76    *
77    * @param suid The cached SUID of a calibration sensor
78    * @param enable Whether to enable or disable updates
79    * @param helper SeeHelper used to configure updates
80    * @return true if updates were successfully configured
81    */
82   bool configureCalUpdates(const sns_std_suid &suid, bool enable,
83                            SeeHelper &helper);
84 
85   /**
86    * Get the cached SUID of a calibration sensor that corresponds to the
87    * specified sensorType.
88    *
89    * @param sensorType The sensor type of the calibration sensor
90    *
91    * @return If found, a valid pointer to the SUID. Otherwise, nullptr.
92    */
93   const sns_std_suid *getCalSuidFromSensorType(SensorType sensorType) const;
94 
95   /**
96    * Uses the supplied SeeHelper instance to register for updates to all
97    * supported SEE calibration sensors. The SeeHelper instance should then pass
98    * decoded calibration data to updateCalibration() and use applyCalibration()
99    * as needed.
100    *
101    * @param seeHelper SeeHelper instance to use when looking up calibration
102    *                  sensor SUIDs and registering for their output
103    *
104    * @return true if all SEE calibration sensors were successfully registered
105    */
106   bool registerForCalibrationUpdates(SeeHelper& seeHelper);
107 
108   /**
109    * Updates the cached calibration data used in subsequent calls to
110    * applyCalibration. Thread-safe.
111    *
112    * @param suid Sensor UID associated with the incoming calibration data
113    * @param hasBias true if bias was decoded from the proto
114    * @param bias 3-axis bias; only valid if hasBias is true
115    * @param hasScale true if scale was decoded from the proto
116    * @param scale 3-axis scale factor; only valid if hasScale is true
117    * @param hasMatrix true if matrix was decoded from the proto
118    * @param matrix 3x3 compensation matrix; only valid if hasMatrix is true
119    * @param accuracy CHRE accuracy rating of the calibration quality (see
120    *     CHRE_SENSOR_ACCURACY)
121    * @param timestamp The timestamp of the calibration event
122    *
123    * @see CHRE_SENSOR_ACCURACY
124    */
125   void updateCalibration(const sns_std_suid& suid, bool hasBias, float bias[3],
126                          bool hasScale, float scale[3], bool hasMatrix,
127                          float matrix[9], uint8_t accuracy, uint64_t timestamp);
128 
129   /**
130    * @param suid SUID of the calibration sensor
131    *
132    * @return the SensorType corresponding to this physical sensor
133    */
134   SensorType getSensorTypeFromSuid(const sns_std_suid& suid) const;
135 
136  private:
137   //! A struct to store a sensor's calibration data
138   struct SeeCalData {
139     float bias[3];
140     float scale[3];
141     float matrix[9];
142     bool hasBias;
143     bool hasScale;
144     bool hasMatrix;
145     uint8_t accuracy;
146     uint64_t timestamp;
147   };
148 
149   //! A struct to store a cal sensor's UID and its cal data.
150   struct SeeCalInfo {
151     Optional<sns_std_suid> suid;
152     SeeCalData cal;
153     bool enabled = false;
154   };
155 
156   //! The list of SEE cal sensors supported.
157   enum class SeeCalSensor : size_t {
158 #ifdef CHRE_ENABLE_ACCEL_CAL
159     AccelCal,
160 #endif  // CHRE_ENABLE_ACCEL_CAL
161     GyroCal,
162     MagCal,
163     NumCalSensors,
164   };
165 
166   //! A convenience constant.
167   static constexpr size_t kNumSeeCalSensors = static_cast<size_t>(
168       SeeCalSensor::NumCalSensors);
169 
170   //! Protects access to calibration data, which may be used in multiple threads
171   mutable Mutex mMutex;
172 
173   //! Cal info of all the cal sensors.
174   SeeCalInfo mCalInfo[kNumSeeCalSensors] = {};
175 
176   //! Map SensorType to associated index in mCalInfo
177   static size_t getCalIndexFromSensorType(SensorType sensorType);
178 
179   //! Map index in mCalInfo to SEE sensor data type string
180   static const char *getDataTypeForCalSensorIndex(size_t calSensorIndex);
181 
182   //! Map SUID to associated index in mCalInfo
183   size_t getCalIndexFromSuid(const sns_std_suid& suid) const;
184 };
185 
186 }  // namespace chre
187 
188 #endif  // CHRE_PLATFORM_SLPI_SEE_SEE_CAL_HELPER_H_
189