1 /*
2 * Copyright (C) 2016 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 #include <algorithm>
18 #include <cinttypes>
19
20 #include "chre/platform/platform_sensor.h"
21
22 extern "C" {
23
24 #include "fixed_point.h"
25 #include "sns_smgr_api_v01.h"
26 #include "sns_smgr_internal_api_v02.h"
27 #include "sns_usmr.h"
28 #include "timetick.h"
29
30 } // extern "C"
31
32 #include "chre_api/chre/sensor.h"
33 #include "chre/core/event_loop_manager.h"
34 #include "chre/core/sensor.h"
35 #include "chre/core/timer_pool.h"
36 #include "chre/platform/assert.h"
37 #include "chre/platform/fatal_error.h"
38 #include "chre/platform/log.h"
39 #include "chre/platform/shared/platform_sensor_util.h"
40 #include "chre/platform/slpi/uimg_util.h"
41 #include "chre/platform/slpi/smgr/platform_sensor_util.h"
42 #include "chre/platform/slpi/smgr/smgr_client.h"
43 #include "chre/platform/slpi/smgr/smr_helper.h"
44 #include "chre/platform/system_time.h"
45 #include "chre/util/macros.h"
46
47 #ifdef CHREX_SENSOR_SUPPORT
48 #include "chre/extensions/platform/slpi/smgr/platform_sensor_util.h"
49 #include "chrex_variant_smgr_sensor_id.h"
50 #endif // CHREX_SENSOR_SUPPORT
51
52 // As SMGR doesn't support passive sensor request, it's now implemented on the
53 // client (CHRE) side using a combination of the SNS_SMGR_INTERNAL_API_V02 and a
54 // modified SNS_SMGR_API_V01.
55 //
56 // Here's a summary of its design:
57 // 1. A sensor status monitor is added in addSensorMonitor() to receive the
58 // SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02 message the first time a sensor is
59 // requested.
60 // 2. When a request is made in PlatformSensor::applyRequest(), it checkes
61 // whether it's allowed at that point and makes a corresponding QMI request.
62 // 1) The request is allowed if
63 // - it's an active or an off request, or
64 // - it's a passive request and the merged mode (to be explained
65 // shortly) is active or there exist other SMGR clients.
66 // 2) If the request is allowed, a QMI request to add the sensor request is
67 // made. Otherwise, a QMI request to remove the sensor request is made to
68 // handle the potential active-and-allowed to passive-and-disallowed
69 // transition.
70 // 3) The merged mode of a sensor is the strongest mode of all sensor
71 // requests of the same sensor ID, with active > passive > off.
72 // 3. When SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02 from SMGR is received, a new
73 // timer is set for kStatusDelayIntervalNanos in the future for each
74 // sensorId. Any future updates that occur before the timer fires are
75 // ignored.
76 // 4. Once the timer fires, an asynchronous SNS_SMGR_CLIENT_REQUEST_INFO_REQ_V01
77 // message is sent to query SMGR on the existence of other clients.
78 // - If a transition from absence-to-presence of other clients is detected,
79 // all pending passive requests are made.
80 // - If a transition from presence-to-absence of other clients is deteted,
81 // all passive requests are removed if the merged mode is passive.
82 //
83 // Note that currently the sensor status monitor indication only supports
84 // primary sensor status change. So for a secondary sensor that can be requested
85 // without an accompanying primary sensor (Light), this design doesn't work.
86 // In PlatformSensor::applyRequest(), a passive Light sensor request is
87 // overridden to be an active one.
88
89 namespace chre {
90 namespace {
91
92 //! The constant used to convert from SMGR to Android unit for magnetometer.
93 constexpr float kMicroTeslaPerGauss = 100.0f;
94
95 //! The maximum number of CHRE sensors that share the same SMGR sensor ID.
96 constexpr size_t kMaxNumSensorsPerSensorId = 3;
97
98 //! The value to override a default interval request.
99 constexpr uint64_t kDefaultInterval = Seconds(1).toRawNanoseconds();
100
101 //! The offset in nanoseconds each 32-bit tick rollover introduces in timestamp
102 constexpr uint64_t kTickRolloverOffset =
103 ((1ULL << 32) * Seconds(1).toRawNanoseconds()) / TIMETICK_NOMINAL_FREQ_HZ;
104
105 //! The delay in nanoseconds between receiving a sensor status change
106 //! and updating the sensor status.
107 constexpr Nanoseconds kStatusDelayIntervalNanos = Milliseconds(20);
108
109 smr_client_hndl gPlatformSensorServiceSmrClientHandle;
110 smr_client_hndl gPlatformSensorInternalServiceSmrClientHandle;
111
112 //! A struct to store the number of SMGR clients of a sensor ID.
113 struct SensorMonitor {
114 uint8_t sensorId;
115 bool otherClientPresent;
116 };
117
118 //! A vector that tracks the SensorMonitor of each supported sensor ID.
119 DynamicVector<SensorMonitor> gSensorMonitors;
120
121 //! Forward declarations
122 bool makeAllPendingRequests(uint8_t sensorId);
123 bool removeAllPassiveRequests(uint8_t sensorId);
124
125 /**
126 * Obtains the element index of gSensorMonitors that corresponds to the
127 * specified sensor ID. If it's not present, gSensorMonitors.size() is returned.
128 *
129 * @return The index of the element that belongs to sensorId.
130 */
getSensorMonitorIndex(uint8_t sensorId)131 size_t getSensorMonitorIndex(uint8_t sensorId) {
132 size_t i;
133 for (i = 0; i < gSensorMonitors.size(); i++) {
134 if (gSensorMonitors[i].sensorId == sensorId) {
135 break;
136 }
137 }
138 return i;
139 }
140
141 /**
142 * Converts a sensorId, dataType and calType as provided by SMGR to a
143 * SensorType as used by platform-independent CHRE code. This is useful in
144 * sensor discovery.
145 *
146 * @param sensorId The sensorID as provided by the SMGR request for sensor info.
147 * @param dataType The dataType for the sesnor as provided by the SMGR request
148 * for sensor info.
149 * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
150 * @return Returns the platform-independent sensor type or Unknown if no
151 * match is found.
152 */
getSensorTypeFromSensorId(uint8_t sensorId,uint8_t dataType,uint8_t calType)153 SensorType getSensorTypeFromSensorId(uint8_t sensorId, uint8_t dataType,
154 uint8_t calType) {
155 // Here be dragons. These constants below are defined in
156 // sns_smgr_common_v01.h. Refer to the section labelled "Define sensor
157 // identifier" for more details. This function relies on the ordering of
158 // constants provided by their API. Do not change these values without care.
159 // You have been warned!
160 if (dataType == SNS_SMGR_DATA_TYPE_PRIMARY_V01) {
161 if (sensorId >= SNS_SMGR_ID_ACCEL_V01
162 && sensorId < SNS_SMGR_ID_GYRO_V01) {
163 if (calType == SNS_SMGR_CAL_SEL_FULL_CAL_V01) {
164 return SensorType::Accelerometer;
165 } else if (calType == SNS_SMGR_CAL_SEL_FACTORY_CAL_V01) {
166 return SensorType::UncalibratedAccelerometer;
167 }
168 } else if (sensorId >= SNS_SMGR_ID_GYRO_V01
169 && sensorId < SNS_SMGR_ID_MAG_V01) {
170 if (calType == SNS_SMGR_CAL_SEL_FULL_CAL_V01) {
171 return SensorType::Gyroscope;
172 } else if (calType == SNS_SMGR_CAL_SEL_FACTORY_CAL_V01) {
173 return SensorType::UncalibratedGyroscope;
174 }
175 } else if (sensorId >= SNS_SMGR_ID_MAG_V01
176 && sensorId < SNS_SMGR_ID_PRESSURE_V01) {
177 if (calType == SNS_SMGR_CAL_SEL_FULL_CAL_V01) {
178 return SensorType::GeomagneticField;
179 } else if (calType == SNS_SMGR_CAL_SEL_FACTORY_CAL_V01) {
180 return SensorType::UncalibratedGeomagneticField;
181 }
182 } else if (sensorId >= SNS_SMGR_ID_PRESSURE_V01
183 && sensorId < SNS_SMGR_ID_PROX_LIGHT_V01) {
184 return SensorType::Pressure;
185 } else if (sensorId >= SNS_SMGR_ID_PROX_LIGHT_V01
186 && sensorId < SNS_SMGR_ID_HUMIDITY_V01) {
187 return SensorType::Proximity;
188 } else if (sensorId == SNS_SMGR_ID_OEM_SENSOR_09_V01) {
189 return SensorType::StationaryDetect;
190 } else if (sensorId == SNS_SMGR_ID_OEM_SENSOR_10_V01) {
191 return SensorType::InstantMotion;
192 #ifdef CHREX_SENSOR_SUPPORT
193 } else if (sensorId == CHREX_VENDOR_TYPE0_SENSOR_ID) {
194 return SensorType::VendorType0;
195 #endif // CHREX_SENSOR_SUPPORT
196 }
197 } else if (dataType == SNS_SMGR_DATA_TYPE_SECONDARY_V01) {
198 if (sensorId >= SNS_SMGR_ID_ACCEL_V01
199 && sensorId < SNS_SMGR_ID_GYRO_V01) {
200 return SensorType::AccelerometerTemperature;
201 } else if (sensorId >= SNS_SMGR_ID_GYRO_V01
202 && sensorId < SNS_SMGR_ID_MAG_V01) {
203 return SensorType::GyroscopeTemperature;
204 } else if ((sensorId >= SNS_SMGR_ID_PROX_LIGHT_V01
205 && sensorId < SNS_SMGR_ID_HUMIDITY_V01)
206 || (sensorId >= SNS_SMGR_ID_ULTRA_VIOLET_V01
207 && sensorId < SNS_SMGR_ID_OBJECT_TEMP_V01)) {
208 return SensorType::Light;
209 }
210 }
211
212 return SensorType::Unknown;
213 }
214
215 /**
216 * Converts a reportId as provided by SMGR to a SensorType.
217 *
218 * @param reportId The reportID as provided by the SMGR buffering index.
219 * @return Returns the sensorType that corresponds to the reportId.
220 */
getSensorTypeFromReportId(uint8_t reportId)221 SensorType getSensorTypeFromReportId(uint8_t reportId) {
222 SensorType sensorType;
223 if (reportId < static_cast<uint8_t>(SensorType::SENSOR_TYPE_COUNT)) {
224 sensorType = static_cast<SensorType>(reportId);
225 } else {
226 sensorType = SensorType::Unknown;
227 }
228 return sensorType;
229 }
230
231 /**
232 * Converts a PlatformSensor to a unique report ID through SensorType. This is
233 * useful in making sensor request.
234 *
235 * @param sensorId The sensorID as provided by the SMGR request for sensor info.
236 * @param dataType The dataType for the sesnor as provided by the SMGR request
237 * for sensor info.
238 * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
239 * @return Returns a unique report ID that is based on SensorType.
240 */
getReportId(uint8_t sensorId,uint8_t dataType,uint8_t calType)241 uint8_t getReportId(uint8_t sensorId, uint8_t dataType, uint8_t calType) {
242 SensorType sensorType = getSensorTypeFromSensorId(
243 sensorId, dataType, calType);
244
245 CHRE_ASSERT_LOG(sensorType != SensorType::Unknown,
246 "sensorId %" PRIu8 ", dataType %" PRIu8 ", calType %" PRIu8,
247 sensorId, dataType, calType);
248 return static_cast<uint8_t>(sensorType);
249 }
250
251 /**
252 * Checks whether the corresponding sensor is a sencondary temperature sensor.
253 *
254 * @param reportId The reportID as provided by the SMGR buffering index.
255 * @return true if the sensor is a secondary temperature sensor.
256 */
isSecondaryTemperature(uint8_t reportId)257 bool isSecondaryTemperature(uint8_t reportId) {
258 SensorType sensorType = getSensorTypeFromReportId(reportId);
259 return (sensorType == SensorType::AccelerometerTemperature
260 || sensorType == SensorType::GyroscopeTemperature);
261 }
262
263 /**
264 * Verifies whether the buffering index's report ID matches the expected
265 * indices length.
266 *
267 * @return true if it's a valid pair of indices length and report ID.
268 */
isValidIndicesLength(const sns_smgr_buffering_ind_msg_v01 & bufferingIndMsg)269 bool isValidIndicesLength(
270 const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg) {
271 return ((bufferingIndMsg.Indices_len == 1
272 && !isSecondaryTemperature(bufferingIndMsg.ReportId))
273 || (bufferingIndMsg.Indices_len == 2
274 && isSecondaryTemperature(bufferingIndMsg.ReportId)));
275 }
276
277 /**
278 * Allocates memory and specifies the memory size for an on-change sensor to
279 * store its last data event.
280 *
281 * @param sensorType The sensorType of this sensor.
282 * @param eventSize A non-null pointer to indicate the memory size allocated.
283 * @return Pointer to the memory allocated.
284 */
allocateLastEvent(SensorType sensorType,size_t * eventSize)285 ChreSensorData *allocateLastEvent(SensorType sensorType, size_t *eventSize) {
286 CHRE_ASSERT(eventSize);
287
288 *eventSize = 0;
289 ChreSensorData *event = nullptr;
290 if (sensorTypeIsOnChange(sensorType)) {
291 SensorSampleType sampleType = getSensorSampleTypeFromSensorType(sensorType);
292 switch (sampleType) {
293 case SensorSampleType::ThreeAxis:
294 *eventSize = sizeof(chreSensorThreeAxisData);
295 break;
296 case SensorSampleType::Float:
297 *eventSize = sizeof(chreSensorFloatData);
298 break;
299 case SensorSampleType::Byte:
300 *eventSize = sizeof(chreSensorByteData);
301 break;
302 case SensorSampleType::Occurrence:
303 *eventSize = sizeof(chreSensorOccurrenceData);
304 break;
305 default:
306 CHRE_ASSERT_LOG(false, "Unhandled sample type");
307 break;
308 }
309
310 event = static_cast<ChreSensorData *>(memoryAlloc(*eventSize));
311 if (event == nullptr) {
312 *eventSize = 0;
313 FATAL_ERROR("Failed to allocate last event memory for SensorType %d",
314 static_cast<int>(sensorType));
315 }
316 }
317 return event;
318 }
319
320 /**
321 * Constructs and initializes a sensor, and adds it to the sensor list.
322 *
323 * @param sensorInfo The sensorInfo as provided by the SMGR.
324 * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
325 * @param sensor The sensor list.
326 */
addSensor(const sns_smgr_sensor_datatype_info_s_v01 & sensorInfo,uint8_t calType,DynamicVector<Sensor> * sensors)327 void addSensor(const sns_smgr_sensor_datatype_info_s_v01& sensorInfo,
328 uint8_t calType, DynamicVector<Sensor> *sensors) {
329 Sensor sensor;
330 sensor.sensorId = sensorInfo.SensorID;
331 sensor.dataType = sensorInfo.DataType;
332 sensor.calType = calType;
333 size_t bytesToCopy = std::min(sizeof(sensor.sensorName) - 1,
334 static_cast<size_t>(sensorInfo.SensorName_len));
335 memcpy(sensor.sensorName, sensorInfo.SensorName, bytesToCopy);
336 sensor.sensorName[bytesToCopy] = '\0';
337
338 // Override one-shot sensor's minInterval to default
339 SensorType sensorType = getSensorTypeFromSensorId(
340 sensorInfo.SensorID, sensorInfo.DataType, calType);
341 sensor.minInterval = sensorTypeIsOneShot(sensorType) ?
342 CHRE_SENSOR_INTERVAL_DEFAULT : static_cast<uint64_t>(
343 Seconds(1).toRawNanoseconds() / sensorInfo.MaxSampleRate);
344
345 // Allocates memory for on-change sensor's last event.
346 sensor.lastEvent = allocateLastEvent(sensorType, &sensor.lastEventSize);
347
348 sensor.isSensorOff = true;
349 sensor.samplingStatus.enabled = false;
350 sensor.samplingStatus.interval = CHRE_SENSOR_INTERVAL_DEFAULT;
351 sensor.samplingStatus.latency = CHRE_SENSOR_LATENCY_DEFAULT;
352
353 if (!sensors->push_back(std::move(sensor))) {
354 FATAL_ERROR("Failed to allocate new sensor: out of memory");
355 }
356 }
357
358 /**
359 * Converts SMGR ticks to nanoseconds as a uint64_t.
360 *
361 * @param ticks The number of ticks.
362 * @return The number of nanoseconds represented by the ticks value.
363 */
getNanosecondsFromSmgrTicks(uint32_t ticks)364 uint64_t getNanosecondsFromSmgrTicks(uint32_t ticks) {
365 return (ticks * Seconds(1).toRawNanoseconds()) / TIMETICK_NOMINAL_FREQ_HZ;
366 }
367
populateSensorDataHeader(SensorType sensorType,chreSensorDataHeader * header,const sns_smgr_buffering_sample_index_s_v01 & sensorIndex)368 void populateSensorDataHeader(
369 SensorType sensorType, chreSensorDataHeader *header,
370 const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
371 // Compensate for header timestamp's 32-bit rollovers
372 uint64_t slpiTime = SystemTime::getMonotonicTime().toRawNanoseconds();
373 uint64_t baseTime = getNanosecondsFromSmgrTicks(
374 sensorIndex.FirstSampleTimestamp);
375 while (slpiTime > baseTime + kTickRolloverOffset / 2) {
376 baseTime += kTickRolloverOffset;
377 }
378 header->reserved = 0;
379 header->baseTimestamp = baseTime;
380 header->sensorHandle = getSensorHandleFromSensorType(sensorType);
381 header->readingCount = sensorIndex.SampleCount;
382 header->accuracy = CHRE_SENSOR_ACCURACY_UNKNOWN;
383 }
384
populateThreeAxisEvent(const sns_smgr_buffering_ind_msg_v01 & bufferingIndMsg,SensorType sensorType,chreSensorThreeAxisData * data,const sns_smgr_buffering_sample_index_s_v01 & sensorIndex)385 void populateThreeAxisEvent(
386 const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg,
387 SensorType sensorType, chreSensorThreeAxisData *data,
388 const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
389 populateSensorDataHeader(sensorType, &data->header, sensorIndex);
390
391 for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
392 const sns_smgr_buffering_sample_s_v01& sensorData =
393 bufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
394
395 // TimeStampOffset has max value of < 2 sec so it will not overflow here.
396 data->readings[i].timestampDelta =
397 getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
398
399 // Convert from SMGR's NED coordinate to Android coordinate.
400 data->readings[i].x = FX_FIXTOFLT_Q16_SP(sensorData.Data[1]);
401 data->readings[i].y = FX_FIXTOFLT_Q16_SP(sensorData.Data[0]);
402 data->readings[i].z = -FX_FIXTOFLT_Q16_SP(sensorData.Data[2]);
403
404 // Convert from Gauss to micro Tesla
405 if (sensorType == SensorType::GeomagneticField
406 || sensorType == SensorType::UncalibratedGeomagneticField) {
407 data->readings[i].x *= kMicroTeslaPerGauss;
408 data->readings[i].y *= kMicroTeslaPerGauss;
409 data->readings[i].z *= kMicroTeslaPerGauss;
410 }
411 }
412 }
413
populateFloatEvent(const sns_smgr_buffering_ind_msg_v01 & bufferingIndMsg,SensorType sensorType,chreSensorFloatData * data,const sns_smgr_buffering_sample_index_s_v01 & sensorIndex)414 void populateFloatEvent(
415 const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg,
416 SensorType sensorType, chreSensorFloatData *data,
417 const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
418 populateSensorDataHeader(sensorType, &data->header, sensorIndex);
419
420 for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
421 const sns_smgr_buffering_sample_s_v01& sensorData =
422 bufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
423
424 // TimeStampOffset has max value of < 2 sec so it will not overflow.
425 data->readings[i].timestampDelta =
426 getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
427 data->readings[i].value = FX_FIXTOFLT_Q16_SP(sensorData.Data[0]);
428 }
429 }
430
populateByteEvent(const sns_smgr_buffering_ind_msg_v01 & bufferingIndMsg,SensorType sensorType,chreSensorByteData * data,const sns_smgr_buffering_sample_index_s_v01 & sensorIndex)431 void populateByteEvent(
432 const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg,
433 SensorType sensorType, chreSensorByteData *data,
434 const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
435 populateSensorDataHeader(sensorType, &data->header, sensorIndex);
436
437 for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
438 const sns_smgr_buffering_sample_s_v01& sensorData =
439 bufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
440
441 // TimeStampOffset has max value of < 2 sec so it will not overflow.
442 data->readings[i].timestampDelta =
443 getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
444 // Zero out fields invalid and padding0.
445 data->readings[i].value = 0;
446 // SMGR reports 1 in Q16 for near, and 0 for far.
447 data->readings[i].isNear = sensorData.Data[0] ? 1 : 0;
448 }
449 }
450
populateOccurrenceEvent(const sns_smgr_buffering_ind_msg_v01 & bufferingIndMsg,SensorType sensorType,chreSensorOccurrenceData * data,const sns_smgr_buffering_sample_index_s_v01 & sensorIndex)451 void populateOccurrenceEvent(
452 const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg,
453 SensorType sensorType, chreSensorOccurrenceData *data,
454 const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
455 populateSensorDataHeader(sensorType, &data->header, sensorIndex);
456
457 for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
458 const sns_smgr_buffering_sample_s_v01& sensorData =
459 bufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
460
461 // TimeStampOffset has max value of < 2 sec so it will not overflow.
462 data->readings[i].timestampDelta =
463 getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
464 }
465 }
466
467 /**
468 * Allocate event memory according to SensorType and populate event readings.
469 */
allocateAndPopulateEvent(const sns_smgr_buffering_ind_msg_v01 & bufferingIndMsg,SensorType sensorType,const sns_smgr_buffering_sample_index_s_v01 & sensorIndex)470 void *allocateAndPopulateEvent(
471 const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg,
472 SensorType sensorType,
473 const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
474 SensorSampleType sampleType = getSensorSampleTypeFromSensorType(sensorType);
475 size_t memorySize = sizeof(chreSensorDataHeader);
476 switch (sampleType) {
477 case SensorSampleType::ThreeAxis: {
478 memorySize += sensorIndex.SampleCount *
479 sizeof(chreSensorThreeAxisData::chreSensorThreeAxisSampleData);
480 auto *event =
481 static_cast<chreSensorThreeAxisData *>(memoryAlloc(memorySize));
482 if (event != nullptr) {
483 populateThreeAxisEvent(bufferingIndMsg, sensorType, event, sensorIndex);
484 }
485 return event;
486 }
487
488 case SensorSampleType::Float: {
489 memorySize += sensorIndex.SampleCount *
490 sizeof(chreSensorFloatData::chreSensorFloatSampleData);
491 auto *event =
492 static_cast<chreSensorFloatData *>(memoryAlloc(memorySize));
493 if (event != nullptr) {
494 populateFloatEvent(bufferingIndMsg, sensorType, event, sensorIndex);
495 }
496 return event;
497 }
498
499 case SensorSampleType::Byte: {
500 memorySize += sensorIndex.SampleCount *
501 sizeof(chreSensorByteData::chreSensorByteSampleData);
502 auto *event =
503 static_cast<chreSensorByteData *>(memoryAlloc(memorySize));
504 if (event != nullptr) {
505 populateByteEvent(bufferingIndMsg, sensorType, event, sensorIndex);
506 }
507 return event;
508 }
509
510 case SensorSampleType::Occurrence: {
511 memorySize += sensorIndex.SampleCount *
512 sizeof(chreSensorOccurrenceData::chreSensorOccurrenceSampleData);
513 auto *event =
514 static_cast<chreSensorOccurrenceData *>(memoryAlloc(memorySize));
515 if (event != nullptr) {
516 populateOccurrenceEvent(
517 bufferingIndMsg, sensorType, event, sensorIndex);
518 }
519 return event;
520 }
521
522 #ifdef CHREX_SENSOR_SUPPORT
523 case SensorSampleType::Vendor0:
524 return allocateAndPopulateVendor0Event(
525 bufferingIndMsg, sensorType, sensorIndex,
526 populateSensorDataHeader, getNanosecondsFromSmgrTicks);
527 #endif // CHREX_SENSOR_SUPPORT
528
529 default:
530 LOGW("Unhandled sensor data %" PRIu8, static_cast<uint8_t>(sensorType));
531 return nullptr;
532 }
533 }
534
535 /**
536 * Handles sensor data provided by the SMGR framework.
537 *
538 * @param bufferingIndMsg Decoded buffering indication message
539 */
handleSensorDataIndication(const sns_smgr_buffering_ind_msg_v01 & bufferingIndMsg)540 void handleSensorDataIndication(
541 const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg) {
542 // We only requested one sensor per request except for a secondary
543 // temperature sensor.
544 bool validReport = isValidIndicesLength(bufferingIndMsg);
545 CHRE_ASSERT_LOG(validReport,
546 "Got buffering indication from %" PRIu32
547 " sensors with report ID %" PRIu8,
548 bufferingIndMsg.Indices_len,
549 bufferingIndMsg.ReportId);
550 if (validReport) {
551 // Identify the index for the desired sensor. It is always 0 except
552 // possibly for a secondary temperature sensor.
553 uint32_t index = 0;
554 if (isSecondaryTemperature(bufferingIndMsg.ReportId)) {
555 index = (bufferingIndMsg.Indices[0].DataType
556 == SNS_SMGR_DATA_TYPE_SECONDARY_V01) ? 0 : 1;
557 }
558 const sns_smgr_buffering_sample_index_s_v01& sensorIndex =
559 bufferingIndMsg.Indices[index];
560
561 // Use ReportID to identify sensors as
562 // bufferingIndMsg.Samples[i].Flags are not populated.
563 SensorType sensorType = getSensorTypeFromReportId(
564 bufferingIndMsg.ReportId);
565 if (sensorType == SensorType::Unknown) {
566 LOGW("Received sensor sample for unknown sensor %" PRIu8 " %" PRIu8,
567 sensorIndex.SensorId, sensorIndex.DataType);
568 } else if (sensorIndex.SampleCount == 0) {
569 LOGW("Received sensorType %d event with 0 sample",
570 static_cast<int>(sensorType));
571 } else {
572 void *eventData = allocateAndPopulateEvent(
573 bufferingIndMsg, sensorType, sensorIndex);
574 auto *header = static_cast< chreSensorDataHeader *>(eventData);
575 if (eventData == nullptr) {
576 LOGW("Dropping event due to allocation failure");
577 } else if (header->readingCount == 0) {
578 LOGW("Dropping zero readingCount event");
579 memoryFree(eventData);
580 } else {
581 // Schedule a deferred callback to update on-change sensor's last
582 // event in the main thread.
583 if (sensorTypeIsOnChange(sensorType)) {
584 updateLastEvent(sensorType, eventData);
585 }
586
587 EventLoopManagerSingleton::get()
588 ->getSensorRequestManager()
589 .handleSensorEvent(sensorType, eventData);
590 }
591 }
592 } // if (validReport)
593 }
594
595 /**
596 * This callback is invoked by the SMR framework when an asynchronous message is
597 * delivered. Unhandled messages are logged.
598 *
599 * @param handle Handle for the SMR client this indication was received on.
600 * @param messageId The message ID number.
601 * @param buffer Buffer containing decoded (C struct) message data.
602 * @param bufferLength Size of the decoded buffer in bytes.
603 * @param callbackData Data that is provided as a context to this callback. This
604 * is not used in this context.
605 *
606 * @see smr_client_ind_cb
607 */
platformSensorServiceIndicationCallback(smr_client_hndl handle,unsigned int messageId,void * decodedInd,unsigned int decodedIndLen,void * callbackData)608 void platformSensorServiceIndicationCallback(
609 smr_client_hndl handle, unsigned int messageId, void *decodedInd,
610 unsigned int decodedIndLen, void *callbackData) {
611 switch (messageId) {
612 case SNS_SMGR_BUFFERING_IND_V01: {
613 CHRE_ASSERT(decodedIndLen >= sizeof(sns_smgr_buffering_ind_msg_v01));
614 auto *bufferingInd =
615 static_cast<sns_smgr_buffering_ind_msg_v01 *>(decodedInd);
616 handleSensorDataIndication(*bufferingInd);
617 break;
618 }
619 default:
620 LOGW("Received unhandled sensor service message: 0x%x", messageId);
621 break;
622 };
623 }
624
625 /**
626 * Populates the supplied SensorTypes array with SensorTypes of the specified
627 * sensor ID.
628 *
629 * @param sensorId The sensor ID as provided by the SMGR.
630 * @param sensorTypes A non-null pointer to a SensorType array of size at least
631 * kMaxNumSensorsPerSensorId.
632 */
populateSensorTypeArrayFromSensorId(uint8_t sensorId,SensorType * sensorTypes)633 size_t populateSensorTypeArrayFromSensorId(uint8_t sensorId,
634 SensorType *sensorTypes) {
635 static_assert(kMaxNumSensorsPerSensorId >= 3,
636 "This function assumes kMaxNumSensorsPerSensorId >= 3");
637 CHRE_ASSERT(sensorTypes);
638
639 size_t numSensorTypes = 0;
640 if (sensorTypes != nullptr) {
641 if (sensorId >= SNS_SMGR_ID_ACCEL_V01
642 && sensorId < SNS_SMGR_ID_GYRO_V01) {
643 sensorTypes[0] = SensorType::Accelerometer;
644 sensorTypes[1] = SensorType::UncalibratedAccelerometer;
645 sensorTypes[2] = SensorType::AccelerometerTemperature;
646 numSensorTypes = 3;
647 } else if (sensorId >= SNS_SMGR_ID_GYRO_V01
648 && sensorId < SNS_SMGR_ID_MAG_V01) {
649 sensorTypes[0] = SensorType::Gyroscope;
650 sensorTypes[1] = SensorType::UncalibratedGyroscope;
651 sensorTypes[2] = SensorType::GyroscopeTemperature;
652 numSensorTypes = 3;
653 } else if (sensorId >= SNS_SMGR_ID_MAG_V01
654 && sensorId < SNS_SMGR_ID_PRESSURE_V01) {
655 sensorTypes[0] = SensorType::GeomagneticField;
656 sensorTypes[1] = SensorType::UncalibratedGeomagneticField;
657 numSensorTypes = 2;
658 } else {
659 SensorType sensorType = getSensorTypeFromSensorId(sensorId,
660 SNS_SMGR_DATA_TYPE_PRIMARY_V01, SNS_SMGR_CAL_SEL_FULL_CAL_V01);
661 if (sensorType != SensorType::Unknown) {
662 sensorTypes[0] = sensorType;
663 numSensorTypes = 1;
664 }
665 }
666 }
667 return numSensorTypes;
668 }
669
670 /**
671 * Obtains the merged SensorMode of the specified sensor ID, with sensorType's
672 * sensor request replaced by the supplied request.
673 *
674 * @param sensorId The sensor ID as provided by the SMGR.
675 * @param sensorType The SensorType whose sensor request is to be replaced by
676 * the supplied request.
677 * @param request The sensor request to replace the existing one.
678 * @return The merged SensorMode.
679 */
getMergedMode(uint8_t sensorId,SensorType sensorType,const SensorRequest & request)680 SensorMode getMergedMode(uint8_t sensorId, SensorType sensorType,
681 const SensorRequest& request) {
682 // Identify sensor requests to merge
683 SensorType sensorTypes[kMaxNumSensorsPerSensorId];
684 size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
685 sensorId, sensorTypes);
686
687 // merge requests
688 SensorRequest mergedRequest;
689 for (size_t i = 0; i < numSensorTypes; i++) {
690 const Sensor *sensor = EventLoopManagerSingleton::get()
691 ->getSensorRequestManager().getSensor(sensorTypes[i]);
692 if (sensor != nullptr) {
693 mergedRequest.mergeWith(
694 (sensorTypes[i] == sensorType) ? request : sensor->getRequest());
695 }
696 }
697 return mergedRequest.getMode();
698 }
699
700 /**
701 * Makes or removes passive sensor requests when the presence of other SMGR
702 * clients changes.
703 *
704 * @param sensorID The sensor ID being monitored.
705 * @param otherClientPresent The presence of other SMGR clients.
706 */
onOtherClientPresenceChange(uint8_t sensorId,bool otherClientPresent)707 void onOtherClientPresenceChange(uint8_t sensorId, bool otherClientPresent) {
708 bool makeAllRequests = otherClientPresent;
709
710 SensorRequest dummyRequest;
711 SensorMode mode = getMergedMode(sensorId, SensorType::Unknown, dummyRequest);
712 bool removeAllRequests = (sensorModeIsPassive(mode) && !otherClientPresent);
713
714 bool requestMade = false;
715 if (makeAllRequests) {
716 requestMade = makeAllPendingRequests(sensorId);
717 } else if (removeAllRequests) {
718 requestMade = removeAllPassiveRequests(sensorId);
719 }
720
721 if (requestMade) {
722 LOGD("%s: id %" PRIu8 ", otherClientPresent %d, mode %d",
723 makeAllRequests ? "+" : "-", sensorId, otherClientPresent,
724 static_cast<size_t>(mode));
725 }
726 }
727
728 /**
729 * Retrieves first valid sensor that has the given sensor ID. Can be
730 * invoked from any thread.
731 *
732 * @param sensorID The sensor handle that should be used to search
733 * the current list of sensors.
734 * @return The first non-null Sensor that matches the given sensor handle or
735 * nullptr if no match is found.
736 */
getFirstValidSensor(uint8_t sensorId)737 Sensor *getFirstValidSensor(uint8_t sensorId) {
738 SensorType sensorTypes[kMaxNumSensorsPerSensorId];
739 size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
740 sensorId, sensorTypes);
741
742 Sensor *sensor = nullptr;
743 for (size_t i = 0; i < numSensorTypes; i++) {
744 sensor = EventLoopManagerSingleton::get()
745 ->getSensorRequestManager().getSensor(sensorTypes[i]);
746 if (sensor != nullptr) {
747 break;
748 }
749 }
750 return sensor;
751 }
752
753 /**
754 * Processes the latest client request info response for the given sensor ID.
755 * Must be invoked from the CHRE thread.
756 *
757 * @param resp The SMGR client request info response.
758 * @param sensorId The sensor ID the response is for.
759 * @param transpErr The error related to the request.
760 */
onClientRequestInfoResponse(const sns_smgr_client_request_info_resp_msg_v01 & resp,uint8_t sensorId,smr_err transpErr)761 void onClientRequestInfoResponse(
762 const sns_smgr_client_request_info_resp_msg_v01& resp,
763 uint8_t sensorId,
764 smr_err transpErr) {
765 size_t index = getSensorMonitorIndex(sensorId);
766 if (transpErr != SMR_NO_ERR) {
767 LOGE("Error receiving client request info: %" PRIu8, transpErr);
768 } else if (resp.resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
769 LOGE("Client request info failed with error: %" PRIu8 ", id %" PRIu8,
770 resp.resp.sns_err_t, sensorId);
771 } else if (index == gSensorMonitors.size()) {
772 LOGE("Sensor status monitor update of invalid sensor ID %" PRIu8, sensorId);
773 } else {
774 bool otherClientPresent = resp.other_client_present;
775 if (gSensorMonitors[index].otherClientPresent != otherClientPresent) {
776 onOtherClientPresenceChange(sensorId, otherClientPresent);
777 gSensorMonitors[index].otherClientPresent = otherClientPresent;
778 }
779 }
780 }
781
782 /**
783 * Makes an asynchronous request to SMGR to receive the latest client
784 * request info.
785 *
786 * @param sensorId The handle to the sensor whose status has changed.
787 */
onStatusChange(uint8_t sensorId)788 void onStatusChange(uint8_t sensorId) {
789 // Sensor already verified to be valid before onStatusChange is called.
790 Sensor *sensor = getFirstValidSensor(sensorId);
791 // Invalidate timer first so a status update isn't potentially
792 // missed.
793 sensor->timerHandle = CHRE_TIMER_INVALID;
794
795 size_t index = getSensorMonitorIndex(sensorId);
796 if (index == gSensorMonitors.size()) {
797 LOGE("Sensor status monitor update of invalid sensor ID %" PRIu8, sensorId);
798 } else {
799 // Use the asynchronous sensor status monitor indication message as a cue
800 // to query and obtain the latest client request info. Since the status
801 // changes are processed on a delay, the current client status is out of
802 // date so query the latest status asynchronously to avoid holding up the
803 // CHRE thread.
804 auto infoRequest =
805 MakeUniqueZeroFill<sns_smgr_client_request_info_req_msg_v01>();
806 auto infoResponse = MakeUnique<sns_smgr_client_request_info_resp_msg_v01>();
807
808 if (infoRequest.isNull() || infoResponse.isNull()) {
809 LOG_OOM();
810 } else {
811 // Enables passing the sensor ID through the event data pointer to avoid
812 // allocating memory
813 union NestedSensorId {
814 void *eventData;
815 uint8_t sensorId;
816 };
817 NestedSensorId nestedId = {};
818 nestedId.sensorId = sensorId;
819
820 SmrReqCallback<sns_smgr_client_request_info_resp_msg_v01> callback =
821 [](UniquePtr<sns_smgr_client_request_info_resp_msg_v01> resp,
822 void *data,
823 smr_err transpErr) {
824 NestedSensorId nestedIdCb;
825 nestedIdCb.eventData = data;
826 onClientRequestInfoResponse(*resp.get(),
827 nestedIdCb.sensorId, transpErr);
828 };
829
830 infoRequest->sensor_id = sensorId;
831 smr_err smrStatus = getSmrHelper()->sendReqAsync(
832 gPlatformSensorServiceSmrClientHandle,
833 SNS_SMGR_CLIENT_REQUEST_INFO_REQ_V01,
834 &infoRequest, &infoResponse, callback, nestedId.eventData);
835 if (smrStatus != SMR_NO_ERR) {
836 LOGE("Error requesting client request info: %d", smrStatus);
837 }
838 }
839 }
840 }
841
842 /**
843 * Posts a CHRE_EVENT_SENSOR_SAMPLING_CHANGE event to the specified Nanoapp.
844 *
845 * @param instaceId The instance ID of the nanoapp with an open request
846 * @param eventRef A reference of the sampling status event to be posted.
847 */
postSamplingStatusEvent(uint32_t instanceId,uint32_t sensorHandle,const struct chreSensorSamplingStatus & status)848 void postSamplingStatusEvent(uint32_t instanceId, uint32_t sensorHandle,
849 const struct chreSensorSamplingStatus& status) {
850 // TODO: add a generic reference counted pointer class and use it for Event
851 // to share across interested nanoapps.
852 auto *event = memoryAlloc<struct chreSensorSamplingStatusEvent>();
853 if (event == nullptr) {
854 LOGE("Failed to allocate memory for sampling status change event");
855 } else {
856 event->sensorHandle = sensorHandle;
857 memcpy(&event->status, &status, sizeof(event->status));
858
859 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
860 CHRE_EVENT_SENSOR_SAMPLING_CHANGE, event, freeEventDataCallback,
861 instanceId);
862 }
863 }
864
865 /**
866 * Updates the sampling status after the sensor request is accepted by SMGR.
867 */
updateSamplingStatus(Sensor * sensor,const SensorRequest & request)868 void updateSamplingStatus(Sensor *sensor, const SensorRequest& request) {
869 // With SMGR's implementation, sampling interval will be filtered to be the
870 // same as requested. Latency can be shorter if there were other SMGR clients
871 // with proc_type also set to SNS_PROC_SSC_V01.
872 // If the request is passive, 'enabled' may change over time and needs to be
873 // updated.
874 if (sensor != nullptr) {
875 bool postUpdate = false;
876 struct chreSensorSamplingStatus& status = sensor->samplingStatus;
877 bool enabled = (request.getMode() != SensorMode::Off);
878 if (status.enabled != enabled) {
879 postUpdate = true;
880 status.enabled = enabled;
881 }
882 if (!sensorTypeIsOneShot(sensor->getSensorType())) {
883 if (status.interval != request.getInterval().toRawNanoseconds()) {
884 postUpdate = true;
885 status.interval = request.getInterval().toRawNanoseconds();
886 }
887 if (status.latency != request.getLatency().toRawNanoseconds()) {
888 postUpdate = true;
889 status.latency = request.getLatency().toRawNanoseconds();
890 }
891 }
892
893 if (postUpdate) {
894 uint32_t sensorHandle = getSensorHandleFromSensorType(
895 sensor->getSensorType());
896
897 // Only post to Nanoapps with an open request.
898 auto& requests = EventLoopManagerSingleton::get()->
899 getSensorRequestManager().getRequests(sensor->getSensorType());
900 for (const auto& req : requests) {
901 postSamplingStatusEvent(req.getInstanceId(), sensorHandle, status);
902 }
903 }
904 }
905 }
906
907 /**
908 * Handles sensor status provided by the SMGR framework.
909 *
910 * @param smgrMonitorIndMsg Indication message received from SMGR
911 */
handleSensorStatusMonitorIndication(const sns_smgr_sensor_status_monitor_ind_msg_v02 & smgrMonitorIndMsg)912 void handleSensorStatusMonitorIndication(
913 const sns_smgr_sensor_status_monitor_ind_msg_v02& smgrMonitorIndMsg) {
914 uint8_t sensorId = smgrMonitorIndMsg.sensor_id;
915
916 // Only use one Sensor to avoid multiple timers per sensorId.
917 Sensor *sensor = getFirstValidSensor(sensorId);
918 if (sensor == nullptr) {
919 LOGE("Sensor ID: %" PRIu8 " in status update doesn't correspond to "
920 "valid sensor.", sensorId);
921 // SMGR should send all callbacks back on the same thread which
922 // means the following code won't result in any timers overriding one
923 // another.
924 } else if (sensor->timerHandle.load() == CHRE_TIMER_INVALID) {
925 // Enables passing the sensor ID through the event data pointer to avoid
926 // allocating memory
927 union NestedSensorId {
928 void *eventData;
929 uint8_t sensorId;
930 };
931 NestedSensorId nestedId = {};
932 nestedId.sensorId = sensorId;
933
934 auto callback = [](uint16_t /* type */, void *data) {
935 NestedSensorId nestedIdCb;
936 nestedIdCb.eventData = data;
937 onStatusChange(nestedIdCb.sensorId);
938 };
939
940 // Schedule a delayed callback to handle sensor status change on the main
941 // thread.
942 TimerHandle timer = EventLoopManagerSingleton::get()->setDelayedCallback(
943 SystemCallbackType::SensorStatusUpdate,
944 nestedId.eventData,
945 callback,
946 kStatusDelayIntervalNanos);
947 sensor->timerHandle = timer;
948 }
949 }
950
951 /**
952 * This callback is invoked by the SMR framework when an asynchronous message is
953 * delivered. Unhandled messages are logged.
954 *
955 * @param handle Handle for the SMR client this indication was received on.
956 * @param messageId The message ID number.
957 * @param decodedInd Buffer containing decoded (C struct) message data.
958 * @param decodedIndLen Size of the decoded buffer in bytes.
959 * @param callbackData Data that is provided as a context to this callback. This
960 * is not used in this context.
961 *
962 * @see smr_client_ind_cb
963 */
platformSensorInternalServiceIndicationCallback(smr_client_hndl handle,unsigned int messageId,void * decodedInd,unsigned int decodedIndLen,void * callbackData)964 void platformSensorInternalServiceIndicationCallback(
965 smr_client_hndl handle, unsigned int messageId, void *decodedInd,
966 unsigned int decodedIndLen, void *callbackData) {
967 switch (messageId) {
968 case SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02: {
969 CHRE_ASSERT(decodedIndLen >=
970 sizeof(sns_smgr_sensor_status_monitor_ind_msg_v02));
971 auto *monitorInd =
972 static_cast<sns_smgr_sensor_status_monitor_ind_msg_v02 *>(decodedInd);
973 handleSensorStatusMonitorIndication(*monitorInd);
974 break;
975 }
976 default:
977 LOGW("Received unhandled sensor internal service message: 0x%x",
978 messageId);
979 break;
980 };
981 }
982
983 /**
984 * Adds or removes an SMGR sensor monitor for the specified sensor ID.
985 *
986 * @param sensorId The sensor ID to add/remove sensor status monitor for.
987 * @param enable true to add and false to remove the status monitor.
988 */
setSensorMonitorRequest(uint8_t sensorId,bool enable)989 void setSensorMonitorRequest(uint8_t sensorId, bool enable) {
990 auto monitorRequest =
991 MakeUniqueZeroFill<sns_smgr_sensor_status_monitor_req_msg_v02>();
992 auto monitorResponse =
993 MakeUnique<sns_smgr_sensor_status_monitor_resp_msg_v02>();
994
995 if (monitorRequest.isNull() || monitorResponse.isNull()) {
996 LOGE("Failed to allocate monitor request/response");
997 } else {
998 monitorRequest->sensor_id = sensorId;
999 monitorRequest->registering = enable;
1000
1001 smr_err status = getSmrHelper()->sendReqSync(
1002 gPlatformSensorInternalServiceSmrClientHandle,
1003 SNS_SMGR_SENSOR_STATUS_MONITOR_REQ_V02,
1004 &monitorRequest, &monitorResponse);
1005 if (status != SMR_NO_ERR) {
1006 LOGE("Error setting sensor status monitor: %d", status);
1007 } else if (monitorResponse->resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
1008 LOGE("Sensor status monitor request failed with error: %" PRIu8
1009 " sensor ID %" PRIu8 " enable %d",
1010 monitorResponse->resp.sns_err_t, sensorId, enable);
1011 }
1012 }
1013 }
1014
1015 /**
1016 * Adds and initializes a sensor monitor for the specified sensor ID if it
1017 * doesn't exist yet.
1018 *
1019 * @param sensorId The sensor ID to request monitor for.
1020 */
addSensorMonitor(uint8_t sensorId)1021 void addSensorMonitor(uint8_t sensorId) {
1022 size_t index = getSensorMonitorIndex(sensorId);
1023 if (index == gSensorMonitors.size()) {
1024 LOGD("Adding sensor status monitor for sensor ID %" PRIu8, sensorId);
1025
1026 // Initialize sensor monitor status before making the request.
1027 SensorMonitor monitor;
1028 monitor.sensorId = sensorId;
1029 monitor.otherClientPresent = false;
1030 gSensorMonitors.push_back(monitor);
1031
1032 // Make a request to add the status monitor
1033 setSensorMonitorRequest(sensorId, true);
1034 }
1035 }
1036
1037 /**
1038 * Requests the sensors for a given sensor ID and appends them to the provided
1039 * list of sensors. If an error occurs, false is returned.
1040 *
1041 * @param sensorId The sensor ID to request sensor info for.
1042 * @param sensors The list of sensors to append newly found sensors to.
1043 * @return Returns false if an error occurs.
1044 */
getSensorsForSensorId(uint8_t sensorId,DynamicVector<Sensor> * sensors)1045 bool getSensorsForSensorId(uint8_t sensorId,
1046 DynamicVector<Sensor> *sensors) {
1047 bool success = false;
1048 auto sensorInfoRequest =
1049 MakeUniqueZeroFill<sns_smgr_single_sensor_info_req_msg_v01>();
1050 auto sensorInfoResponse =
1051 MakeUnique<sns_smgr_single_sensor_info_resp_msg_v01>();
1052
1053 if (sensorInfoRequest.isNull() || sensorInfoResponse.isNull()) {
1054 LOGE("Failed to allocate sensor info msg");
1055 } else {
1056 sensorInfoRequest->SensorID = sensorId;
1057
1058 smr_err status = getSmrHelper()->sendReqSync(
1059 gPlatformSensorServiceSmrClientHandle,
1060 SNS_SMGR_SINGLE_SENSOR_INFO_REQ_V01,
1061 &sensorInfoRequest, &sensorInfoResponse);
1062
1063 if (status != SMR_NO_ERR) {
1064 LOGE("Error requesting single sensor info: %d", status);
1065 } else if (sensorInfoResponse->Resp.sns_result_t !=
1066 SNS_RESULT_SUCCESS_V01) {
1067 LOGE("Single sensor info request failed with error: %d",
1068 sensorInfoResponse->Resp.sns_err_t);
1069 } else {
1070 const sns_smgr_sensor_info_s_v01& sensorInfoList =
1071 sensorInfoResponse->SensorInfo;
1072 for (uint32_t i = 0; i < sensorInfoList.data_type_info_len; i++) {
1073 const sns_smgr_sensor_datatype_info_s_v01& sensorInfo =
1074 sensorInfoList.data_type_info[i];
1075 LOGD("SensorID %" PRIu8 ", DataType %" PRIu8 ", MaxRate %" PRIu16
1076 "Hz, SensorName %s",
1077 sensorInfo.SensorID, sensorInfo.DataType,
1078 sensorInfo.MaxSampleRate, sensorInfo.SensorName);
1079
1080 SensorType sensorType = getSensorTypeFromSensorId(
1081 sensorInfo.SensorID, sensorInfo.DataType,
1082 SNS_SMGR_CAL_SEL_FULL_CAL_V01);
1083 if (sensorType != SensorType::Unknown) {
1084 addSensor(sensorInfo, SNS_SMGR_CAL_SEL_FULL_CAL_V01, sensors);
1085
1086 // Add an uncalibrated version if defined.
1087 SensorType uncalibratedType = getSensorTypeFromSensorId(
1088 sensorInfo.SensorID, sensorInfo.DataType,
1089 SNS_SMGR_CAL_SEL_FACTORY_CAL_V01);
1090 if (sensorType != uncalibratedType) {
1091 addSensor(sensorInfo, SNS_SMGR_CAL_SEL_FACTORY_CAL_V01, sensors);
1092 }
1093 }
1094 }
1095 success = true;
1096 }
1097 }
1098
1099 return success;
1100 }
1101
1102 /**
1103 * Converts a SensorMode into an SMGR request action. When the net request for
1104 * a sensor is considered to be active an add operation is required for the
1105 * SMGR request. When the sensor becomes inactive the request is deleted.
1106 *
1107 * @param mode The sensor mode.
1108 * @return Returns the SMGR request action given the sensor mode.
1109 */
getSmgrRequestActionForMode(SensorMode mode)1110 uint8_t getSmgrRequestActionForMode(SensorMode mode) {
1111 if (mode != SensorMode::Off) {
1112 return SNS_SMGR_BUFFERING_ACTION_ADD_V01;
1113 } else {
1114 return SNS_SMGR_BUFFERING_ACTION_DELETE_V01;
1115 }
1116 }
1117
1118 /**
1119 * Specify the sensor decimation type.
1120 *
1121 * @param sensorId The sensorID as provided by the SMGR.
1122 * @param dataType The dataType for the sesnor as provided by the SMGR.
1123 * return The decimation type as defined by the SMGR.
1124 */
getDecimationType(uint8_t sensorId,uint8_t dataType)1125 uint8_t getDecimationType(uint8_t sensorId, uint8_t dataType) {
1126 // Request filtered data for accel and gyro to reduce noise aliasing in case
1127 // SMGR has other higher ODR clients.
1128 if ((sensorId == SNS_SMGR_ID_ACCEL_V01 || sensorId == SNS_SMGR_ID_GYRO_V01)
1129 && dataType == SNS_SMGR_DATA_TYPE_PRIMARY_V01) {
1130 return SNS_SMGR_DECIMATION_FILTER_V01;
1131 } else {
1132 return SNS_SMGR_DECIMATION_RECENT_SAMPLE_V01;
1133 }
1134 }
1135
1136 /**
1137 * Populates a sns_smgr_buffering_req_msg_v01 struct to request sensor data.
1138 *
1139 * @param request The new request to set this sensor to.
1140 * @param sensorId The sensorID as provided by the SMGR request for sensor info.
1141 * @param dataType The dataType for the sesnor as provided by the SMGR request
1142 * for sensor info.
1143 * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
1144 * @param minInterval The minimum interval allowed by this sensor.
1145 * @param sensorDataRequest The pointer to the data request to be populated.
1146 */
populateSensorRequest(const SensorRequest & chreRequest,uint8_t sensorId,uint8_t dataType,uint8_t calType,uint64_t minInterval,sns_smgr_buffering_req_msg_v01 * sensorRequest)1147 void populateSensorRequest(
1148 const SensorRequest& chreRequest, uint8_t sensorId, uint8_t dataType,
1149 uint8_t calType, uint64_t minInterval,
1150 sns_smgr_buffering_req_msg_v01 *sensorRequest) {
1151 // Zero the fields in the request. All mandatory and unused fields are
1152 // specified to be set to false or zero so this is safe.
1153 memset(sensorRequest, 0, sizeof(*sensorRequest));
1154
1155 // Reconstructs a request to deliver one-shot sensors' data ASAP and set
1156 // default interval to some meaningful number.
1157 bool isOneShot = sensorTypeIsOneShot(getSensorTypeFromSensorId(
1158 sensorId, dataType, calType));
1159 uint64_t cappedInterval = chreRequest.getInterval().toRawNanoseconds();
1160 if (cappedInterval == CHRE_SENSOR_INTERVAL_DEFAULT) {
1161 // For one-shot sensors, we've overridden minInterval to default in init.
1162 // However, for InstantMotion/StationaryDetect, making a request with
1163 // default interval will not trigger.
1164 cappedInterval =
1165 isOneShot ? kDefaultInterval : std::max(minInterval, kDefaultInterval);
1166 }
1167 SensorRequest request(chreRequest.getMode(), Nanoseconds(cappedInterval),
1168 isOneShot ? Nanoseconds(0) : chreRequest.getLatency());
1169
1170 // Build the request for one sensor at the requested rate. An add action for a
1171 // ReportID that is already in use causes a replacement of the last request.
1172 sensorRequest->ReportId = getReportId(sensorId, dataType, calType);
1173 sensorRequest->Action = getSmgrRequestActionForMode(request.getMode());
1174
1175 // SMGR report interval should be (interval + latency). However, to handle
1176 // fractional-interval latency setting and to guarantee meeting chre request,
1177 // report interval is set to latency only. Also, lower-bound batchInterval as
1178 // request to SMGR would fail if batchInterval < interval.
1179 Nanoseconds batchInterval =
1180 std::max(request.getLatency(), request.getInterval());
1181 sensorRequest->ReportRate = intervalToSmgrQ16ReportRate(batchInterval);
1182 sensorRequest->Item_len = 1; // One sensor per request if possible.
1183 sensorRequest->Item[0].SensorId = sensorId;
1184 sensorRequest->Item[0].DataType = dataType;
1185 sensorRequest->Item[0].Decimation = getDecimationType(sensorId, dataType);
1186 sensorRequest->Item[0].Calibration = calType;
1187 sensorRequest->Item[0].SamplingRate =
1188 intervalToSmgrSamplingRate(request.getInterval());
1189
1190 // Add a dummy primary sensor to accompany a secondary temperature sensor.
1191 // This is requred by the SMGR. The primary sensor is requested with the same
1192 // (low) rate and the same latency, whose response data will be ignored.
1193 if (isSecondaryTemperature(sensorRequest->ReportId)) {
1194 sensorRequest->Item_len = 2;
1195 sensorRequest->Item[1].SensorId = sensorId;
1196 sensorRequest->Item[1].DataType = SNS_SMGR_DATA_TYPE_PRIMARY_V01;
1197 sensorRequest->Item[1].Decimation = getDecimationType(
1198 sensorId, SNS_SMGR_DATA_TYPE_PRIMARY_V01);
1199 sensorRequest->Item[1].Calibration = SNS_SMGR_CAL_SEL_FULL_CAL_V01;
1200 sensorRequest->Item[1].SamplingRate = sensorRequest->Item[0].SamplingRate;
1201 }
1202
1203 // Synchronize fifo flushes with other clients that have SSC proc_type.
1204 // send_indications_during_suspend has no effect on data sent to SLPI.
1205 // Default is to synchronize with AP clients, which may shorten flush
1206 // intervals for data sent to the AP.
1207 sensorRequest->notify_suspend_valid = true;
1208 sensorRequest->notify_suspend.proc_type = SNS_PROC_SSC_V01;
1209 sensorRequest->notify_suspend.send_indications_during_suspend = true;
1210 }
1211
1212 /**
1213 * Determines whether a request is allowed. A passive request is not always
1214 * allowed.
1215 *
1216 * @param sensorType The SensorType of this request
1217 * @param request The intended sensor request
1218 * @return true if the request is allowed.
1219 */
isRequestAllowed(SensorType sensorType,const SensorRequest & request)1220 bool isRequestAllowed(SensorType sensorType, const SensorRequest& request) {
1221 bool allowed = false;
1222
1223 const Sensor *sensor = EventLoopManagerSingleton::get()
1224 ->getSensorRequestManager().getSensor(sensorType);
1225 if (sensor != nullptr) {
1226 if (sensorModeIsPassive(request.getMode())) {
1227 size_t index = getSensorMonitorIndex(sensor->sensorId);
1228 if (index == gSensorMonitors.size()) {
1229 LOGE("SensorId %" PRIu8 " doesn't have a monitor", sensor->sensorId);
1230 } else {
1231 SensorMode mergedMode = getMergedMode(
1232 sensor->sensorId, sensorType, request);
1233 bool otherClientPresent = gSensorMonitors[index].otherClientPresent;
1234 allowed = (sensorModeIsActive(mergedMode) || otherClientPresent);
1235 LOGD("sensorType %d allowed %d: mergedMode %d, otherClientPresent %d",
1236 static_cast<size_t>(sensorType), allowed,
1237 static_cast<int>(mergedMode), otherClientPresent);
1238 }
1239 } else {
1240 // If it's an ACTIVE or an OFF request, it's always allowed.
1241 allowed = true;
1242 }
1243 }
1244 return allowed;
1245 }
1246
1247 /**
1248 * Makes a SNS_SMGR_BUFFERING_REQ request based on the arguments provided.
1249 *
1250 * @param sensorId The sensorID as provided by the SMGR.
1251 * @param dataType The dataType for the sesnor as provided by the MSGR.
1252 * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
1253 * @param minInterval The minimum interval of this sensor.
1254 * @param request The sensor request
1255 * @return true if the request has been made successfully.
1256 */
makeBufferingReq(uint8_t sensorId,uint8_t dataType,uint8_t calType,uint64_t minInterval,const SensorRequest & request)1257 bool makeBufferingReq(uint8_t sensorId, uint8_t dataType, uint8_t calType,
1258 uint64_t minInterval, const SensorRequest& request) {
1259 bool success = false;
1260 auto sensorRequest = MakeUniqueZeroFill<sns_smgr_buffering_req_msg_v01>();
1261 auto sensorResponse = MakeUnique<sns_smgr_buffering_resp_msg_v01>();
1262
1263 if (sensorRequest.isNull() || sensorResponse.isNull()) {
1264 LOGE("Failed to allocate buffering msg");
1265 } else {
1266 populateSensorRequest(request, sensorId, dataType, calType,
1267 minInterval, sensorRequest.get());
1268
1269 smr_err status = getSmrHelper()->sendReqSync(
1270 gPlatformSensorServiceSmrClientHandle, SNS_SMGR_BUFFERING_REQ_V01,
1271 &sensorRequest, &sensorResponse);
1272
1273 if (status != SMR_NO_ERR) {
1274 LOGE("Error requesting sensor data: %d", status);
1275 } else if (sensorResponse->Resp.sns_result_t != SNS_RESULT_SUCCESS_V01
1276 || (sensorResponse->AckNak != SNS_SMGR_RESPONSE_ACK_SUCCESS_V01
1277 && sensorResponse->AckNak != SNS_SMGR_RESPONSE_ACK_MODIFIED_V01)) {
1278 LOGE("Sensor data request failed with error: %d, AckNak: %d",
1279 sensorResponse->Resp.sns_err_t, sensorResponse->AckNak);
1280 } else {
1281 success = true;
1282 }
1283 }
1284
1285 return success;
1286 }
1287
1288 /**
1289 * Makes a SNS_SMGR_BUFFERING_REQ request if necessary.
1290 *
1291 * @param sensorType The sensor type of the request.
1292 * @param request The sensor request to be made.
1293 * @return true if the request has been accepted.
1294 */
makeRequest(SensorType sensorType,const SensorRequest & request)1295 bool makeRequest(SensorType sensorType, const SensorRequest& request) {
1296 bool success = false;
1297
1298 Sensor *sensor = EventLoopManagerSingleton::get()->getSensorRequestManager()
1299 .getSensor(sensorType);
1300 if (sensor != nullptr) {
1301 // Do not make an off request if the sensor is already off. Otherwise, SMGR
1302 // returns an error.
1303 if (request.getMode() == SensorMode::Off) {
1304 success = sensor->isSensorOff;
1305 }
1306
1307 // Make a SMGR buffering request if necessary.
1308 if (!success) {
1309 success = makeBufferingReq(sensor->sensorId, sensor->dataType,
1310 sensor->calType, sensor->minInterval, request);
1311 }
1312 }
1313
1314 // TODO: handle makeBufferingReq failures
1315 if (success) {
1316 // Update internal states if request was accepted by SMGR.
1317 sensor->isSensorOff = (request.getMode() == SensorMode::Off);
1318
1319 if (request.getMode() == SensorMode::Off) {
1320 sensor->lastEventValid = false;
1321 }
1322
1323 updateSamplingStatus(sensor, request);
1324 }
1325 return success;
1326 }
1327
1328 /**
1329 * Makes all pending requests of the specified sensor ID to SMGR.
1330 *
1331 * @param sensorId The sensor ID whose pending requests are to be made.
1332 * @return true if an ADD request has been accepted.
1333 */
makeAllPendingRequests(uint8_t sensorId)1334 bool makeAllPendingRequests(uint8_t sensorId) {
1335 // Identify sensor types to check for pending requests
1336 SensorType sensorTypes[kMaxNumSensorsPerSensorId];
1337 size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
1338 sensorId, sensorTypes);
1339 bool accepted = false;
1340 for (size_t i = 0; i < numSensorTypes; i++) {
1341 const Sensor *sensor = EventLoopManagerSingleton::get()
1342 ->getSensorRequestManager().getSensor(sensorTypes[i]);
1343
1344 // If sensor is off and the request is not off, it's a pending request.
1345 if (sensor != nullptr && sensor->isSensorOff
1346 && sensor->getRequest().getMode() != SensorMode::Off) {
1347 accepted |= makeRequest(sensorTypes[i], sensor->getRequest());
1348 }
1349 }
1350 return accepted;
1351 }
1352
1353 /**
1354 * Identifies and removes passive requests that have been made to the SMGR, and
1355 * adds them to the sensor monitor.
1356 *
1357 * @param sensorId The sensor ID whose passive requests are to be removed.
1358 * @return true if a DELETE request has been accepted.
1359 */
removeAllPassiveRequests(uint8_t sensorId)1360 bool removeAllPassiveRequests(uint8_t sensorId) {
1361 // Specify sensor types to check for passive requests
1362 SensorType sensorTypes[kMaxNumSensorsPerSensorId];
1363 size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
1364 sensorId, sensorTypes);
1365 bool accepted = false;
1366 for (size_t i = 0; i < numSensorTypes; i++) {
1367 const Sensor *sensor = EventLoopManagerSingleton::get()
1368 ->getSensorRequestManager().getSensor(sensorTypes[i]);
1369
1370 // Turn off sensors that have a passive request
1371 if (sensor != nullptr
1372 && sensorModeIsPassive(sensor->getRequest().getMode())) {
1373 SensorRequest offRequest;
1374 accepted |= makeRequest(sensorTypes[i], offRequest);
1375 }
1376 }
1377 return accepted;
1378 }
1379
1380 } // anonymous namespace
1381
~PlatformSensor()1382 PlatformSensor::~PlatformSensor() {
1383 if (lastEvent != nullptr) {
1384 LOGD("Releasing lastEvent: id %" PRIu8 ", type %" PRIu8 ", cal %" PRIu8
1385 ", size %zu", sensorId, dataType, calType, lastEventSize);
1386 memoryFree(lastEvent);
1387 }
1388 }
1389
init()1390 void PlatformSensor::init() {
1391 // Timeout for SMR client initialization, in milliseconds.
1392 constexpr uint32_t kSmrInitTimeoutMs = 10;
1393
1394 SmrHelperSingleton::init();
1395
1396 // sns_smgr_api_v01
1397 qmi_idl_service_object_type smgrSvcObj =
1398 SNS_SMGR_SVC_get_service_object_v01();
1399 if (smgrSvcObj == nullptr) {
1400 FATAL_ERROR("Failed to obtain the SNS SMGR service instance");
1401 }
1402
1403 smr_err result = getSmrHelper()->waitForService(smgrSvcObj);
1404 if (result != SMR_NO_ERR) {
1405 FATAL_ERROR("Failed while waiting for SNS SMGR service");
1406 }
1407
1408 // Note: giving nullptr for err_cb prevents this from degrading to a regular
1409 // QMI client if the service is not found.
1410 smr_err status = smr_client_init(
1411 smgrSvcObj, SMR_CLIENT_INSTANCE_ANY,
1412 platformSensorServiceIndicationCallback, nullptr /* ind_cb_data */,
1413 kSmrInitTimeoutMs, nullptr /* err_cb */, nullptr /* err_cb_data */,
1414 &gPlatformSensorServiceSmrClientHandle, isSlpiUimgSupported());
1415 if (status != SMR_NO_ERR) {
1416 FATAL_ERROR("Failed to initialize SMGR client: %d", status);
1417 }
1418
1419 // sns_smgr_interal_api_v02
1420 qmi_idl_service_object_type smgrInternalSvcObj =
1421 SNS_SMGR_INTERNAL_SVC_get_service_object_v02();
1422 if (smgrInternalSvcObj == nullptr) {
1423 FATAL_ERROR("Failed to obtain the SNS SMGR internal service instance");
1424 }
1425
1426 result = getSmrHelper()->waitForService(smgrInternalSvcObj);
1427 if (result != SMR_NO_ERR) {
1428 FATAL_ERROR("Failed while waiting for SNS SMGR internal service");
1429 }
1430
1431 status = smr_client_init(
1432 smgrInternalSvcObj, SMR_CLIENT_INSTANCE_ANY,
1433 platformSensorInternalServiceIndicationCallback,
1434 nullptr /* ind_cb_data */, kSmrInitTimeoutMs, nullptr /* err_cb */,
1435 nullptr /* err_cb_data */, &gPlatformSensorInternalServiceSmrClientHandle,
1436 isSlpiUimgSupported());
1437 if (status != SMR_NO_ERR) {
1438 FATAL_ERROR("Failed to initialize SMGR internal client: %d", status);
1439 }
1440 }
1441
deinit()1442 void PlatformSensor::deinit() {
1443 smr_err err = getSmrHelper()->releaseSync(
1444 gPlatformSensorServiceSmrClientHandle);
1445 if (err != SMR_NO_ERR) {
1446 LOGE("Failed to release SMGR client: %d", err);
1447 }
1448 gPlatformSensorServiceSmrClientHandle = nullptr;
1449
1450 err = getSmrHelper()->releaseSync(
1451 gPlatformSensorInternalServiceSmrClientHandle);
1452 if (err != SMR_NO_ERR) {
1453 LOGE("Failed to release SMGR internal client: %d", err);
1454 }
1455 gPlatformSensorInternalServiceSmrClientHandle = nullptr;
1456
1457 // Clearing all sensor status monitors. Releasing an SMR client also releases
1458 // all sensor status monitor requests.
1459 gSensorMonitors.clear();
1460 SmrHelperSingleton::deinit();
1461 }
1462
getSensors(DynamicVector<Sensor> * sensors)1463 bool PlatformSensor::getSensors(DynamicVector<Sensor> *sensors) {
1464 CHRE_ASSERT(sensors);
1465
1466 auto sensorListRequest =
1467 MakeUniqueZeroFill<sns_smgr_all_sensor_info_req_msg_v01>();
1468 auto sensorListResponse = MakeUnique<sns_smgr_all_sensor_info_resp_msg_v01>();
1469
1470 smr_err status = getSmrHelper()->sendReqSync(
1471 gPlatformSensorServiceSmrClientHandle, SNS_SMGR_ALL_SENSOR_INFO_REQ_V01,
1472 &sensorListRequest, &sensorListResponse);
1473
1474 bool success = false;
1475 if (status != SMR_NO_ERR) {
1476 LOGE("Error requesting sensor list: %d", status);
1477 } else if (sensorListResponse->Resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
1478 LOGE("Sensor list lequest failed with error: %d",
1479 sensorListResponse->Resp.sns_err_t);
1480 } else {
1481 success = true;
1482 for (uint32_t i = 0; i < sensorListResponse->SensorInfo_len; i++) {
1483 uint8_t sensorId = sensorListResponse->SensorInfo[i].SensorID;
1484 if (!getSensorsForSensorId(sensorId, sensors)) {
1485 success = false;
1486 break;
1487 }
1488 }
1489 }
1490
1491 return success;
1492 }
1493
applyRequest(const SensorRequest & request)1494 bool PlatformSensor::applyRequest(const SensorRequest& request) {
1495 bool success;
1496
1497 if (!SmrHelperSingleton::isInitialized()) {
1498 // Off requests made as part of shutdown come after PlatformSensor::deinit()
1499 // which releases our SMGR clients, removing all requests. Report success in
1500 // this case.
1501 success = (request.getMode() == SensorMode::Off) ? true : false;
1502 CHRE_ASSERT_LOG(success, "Sensor request made before init/after deinit");
1503 } else {
1504 // Adds a sensor monitor the first time this sensor is requested.
1505 addSensorMonitor(this->sensorId);
1506
1507 // As sensor status monior indication doesn't support secondary sensor
1508 // status change, Light sensor (a secondary one) is always overridden to be
1509 // requested with an active mode.
1510 bool passiveLight = (getSensorType() == SensorType::Light
1511 && sensorModeIsPassive(request.getMode()));
1512 if (passiveLight) {
1513 LOGE("Passive request for Light sensor is not supported. "
1514 "Overriding request to active");
1515 }
1516 SensorRequest localRequest(
1517 passiveLight ? SensorMode::ActiveContinuous : request.getMode(),
1518 request.getInterval(), request.getLatency());
1519
1520 // Determines whether a (passive) request is allowed at this point.
1521 bool requestAllowed = isRequestAllowed(getSensorType(), localRequest);
1522
1523 // If request is not allowed, turn off the sensor. Otherwise, make request.
1524 SensorRequest offRequest;
1525 success = makeRequest(getSensorType(),
1526 requestAllowed ? localRequest : offRequest);
1527 }
1528 return success;
1529 }
1530
flushAsync()1531 bool PlatformSensor::flushAsync() {
1532 // NOTE: SMGR framework flushes all pending data when a new request comes in
1533 // (ref sns_rh_sol_schedule_existing_report() in sns_rh_sol.c).
1534 // In this implementation of flushAsync, we make a request identical to
1535 // the existing sensor request, blocking on an asynchronous response,
1536 // and assume that the flush request has completed when this identical
1537 // sensor request is successfully handled and executed. This
1538 // implementation mirrors the sensors HAL implementation of flush.
1539 bool success = false;
1540 Sensor *sensor = EventLoopManagerSingleton::get()->getSensorRequestManager()
1541 .getSensor(getSensorType());
1542 if (sensor != nullptr) {
1543 success = applyRequest(sensor->getRequest());
1544 if (success) {
1545 EventLoopManagerSingleton::get()->getSensorRequestManager()
1546 .handleFlushCompleteEvent(CHRE_ERROR_NONE, getSensorType());
1547 }
1548 }
1549 return success;
1550 }
1551
getSensorType() const1552 SensorType PlatformSensor::getSensorType() const {
1553 return getSensorTypeFromSensorId(this->sensorId, this->dataType,
1554 this->calType);
1555 }
1556
getMinInterval() const1557 uint64_t PlatformSensor::getMinInterval() const {
1558 return minInterval;
1559 }
1560
getSensorName() const1561 const char *PlatformSensor::getSensorName() const {
1562 return sensorName;
1563 }
1564
PlatformSensor(PlatformSensor && other)1565 PlatformSensor::PlatformSensor(PlatformSensor&& other) {
1566 // Our move assignment operator doesn't assume that "this" is initialized, so
1567 // we can just use that here
1568 *this = std::move(other);
1569 }
1570
operator =(PlatformSensor && other)1571 PlatformSensor& PlatformSensor::operator=(PlatformSensor&& other) {
1572 // Note: if this implementation is ever changed to depend on "this" containing
1573 // initialized values, the move constructor implemenation must be updated
1574 sensorId = other.sensorId;
1575 dataType = other.dataType;
1576 calType = other.calType;
1577 memcpy(sensorName, other.sensorName, SNS_SMGR_MAX_SENSOR_NAME_SIZE_V01);
1578 minInterval = other.minInterval;
1579
1580 lastEvent = other.lastEvent;
1581 other.lastEvent = nullptr;
1582
1583 lastEventSize = other.lastEventSize;
1584 other.lastEventSize = 0;
1585
1586 lastEventValid = other.lastEventValid;
1587 isSensorOff = other.isSensorOff;
1588 samplingStatus = other.samplingStatus;
1589
1590 return *this;
1591 }
1592
getLastEvent() const1593 ChreSensorData *PlatformSensor::getLastEvent() const {
1594 return (this->lastEventValid) ? this->lastEvent : nullptr;
1595 }
1596
getSamplingStatus(struct chreSensorSamplingStatus * status) const1597 bool PlatformSensor::getSamplingStatus(
1598 struct chreSensorSamplingStatus *status) const {
1599 CHRE_ASSERT(status);
1600
1601 memcpy(status, &samplingStatus, sizeof(*status));
1602 return true;
1603 }
1604
getThreeAxisBias(struct chreSensorThreeAxisData * bias) const1605 bool PlatformSensor::getThreeAxisBias(
1606 struct chreSensorThreeAxisData *bias) const {
1607 // TODO: Implement this.
1608 return false;
1609 }
1610
setLastEvent(const ChreSensorData * event)1611 void PlatformSensorBase::setLastEvent(const ChreSensorData *event) {
1612 memcpy(this->lastEvent, event, this->lastEventSize);
1613 this->lastEventValid = true;
1614 }
1615
getSensorServiceSmrClientHandle()1616 smr_client_hndl getSensorServiceSmrClientHandle() {
1617 return gPlatformSensorServiceSmrClientHandle;
1618 }
1619
1620 } // namespace chre
1621