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
smgrSensorDataEventFree(uint16_t eventType,void * eventData)535 void smgrSensorDataEventFree(uint16_t eventType, void *eventData) {
536 // Events are allocated using the simple memoryAlloc/memoryFree platform
537 // functions.
538 // TODO: Consider using a MemoryPool.
539 memoryFree(eventData);
540
541 // Remove all requests if it's a one-shot sensor and only after data has been
542 // delivered to all clients.
543 SensorType sensorType = getSensorTypeForSampleEventType(eventType);
544 if (sensorTypeIsOneShot(sensorType)) {
545 EventLoopManagerSingleton::get()->getSensorRequestManager()
546 .removeAllRequests(sensorType);
547 }
548 }
549
550 /**
551 * Handles sensor data provided by the SMGR framework.
552 *
553 * @param bufferingIndMsg Decoded buffering indication message
554 */
handleSensorDataIndication(const sns_smgr_buffering_ind_msg_v01 & bufferingIndMsg)555 void handleSensorDataIndication(
556 const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg) {
557 // We only requested one sensor per request except for a secondary
558 // temperature sensor.
559 bool validReport = isValidIndicesLength(bufferingIndMsg);
560 CHRE_ASSERT_LOG(validReport,
561 "Got buffering indication from %" PRIu32
562 " sensors with report ID %" PRIu8,
563 bufferingIndMsg.Indices_len,
564 bufferingIndMsg.ReportId);
565 if (validReport) {
566 // Identify the index for the desired sensor. It is always 0 except
567 // possibly for a secondary temperature sensor.
568 uint32_t index = 0;
569 if (isSecondaryTemperature(bufferingIndMsg.ReportId)) {
570 index = (bufferingIndMsg.Indices[0].DataType
571 == SNS_SMGR_DATA_TYPE_SECONDARY_V01) ? 0 : 1;
572 }
573 const sns_smgr_buffering_sample_index_s_v01& sensorIndex =
574 bufferingIndMsg.Indices[index];
575
576 // Use ReportID to identify sensors as
577 // bufferingIndMsg.Samples[i].Flags are not populated.
578 SensorType sensorType = getSensorTypeFromReportId(
579 bufferingIndMsg.ReportId);
580 if (sensorType == SensorType::Unknown) {
581 LOGW("Received sensor sample for unknown sensor %" PRIu8 " %" PRIu8,
582 sensorIndex.SensorId, sensorIndex.DataType);
583 } else if (sensorIndex.SampleCount == 0) {
584 LOGW("Received sensorType %d event with 0 sample",
585 static_cast<int>(sensorType));
586 } else {
587 void *eventData = allocateAndPopulateEvent(
588 bufferingIndMsg, sensorType, sensorIndex);
589 auto *header = static_cast< chreSensorDataHeader *>(eventData);
590 if (eventData == nullptr) {
591 LOGW("Dropping event due to allocation failure");
592 } else if (header->readingCount == 0) {
593 LOGW("Dropping zero readingCount event");
594 memoryFree(eventData);
595 } else {
596 // Schedule a deferred callback to update on-change sensor's last
597 // event in the main thread.
598 if (sensorTypeIsOnChange(sensorType)) {
599 updateLastEvent(sensorType, eventData);
600 }
601
602 EventLoopManagerSingleton::get()->getEventLoop().postEventOrFree(
603 getSampleEventTypeForSensorType(sensorType), eventData,
604 smgrSensorDataEventFree);
605 }
606 }
607 } // if (validReport)
608 }
609
610 /**
611 * This callback is invoked by the SMR framework when an asynchronous message is
612 * delivered. Unhandled messages are logged.
613 *
614 * @param handle Handle for the SMR client this indication was received on.
615 * @param messageId The message ID number.
616 * @param buffer Buffer containing decoded (C struct) message data.
617 * @param bufferLength Size of the decoded buffer in bytes.
618 * @param callbackData Data that is provided as a context to this callback. This
619 * is not used in this context.
620 *
621 * @see smr_client_ind_cb
622 */
platformSensorServiceIndicationCallback(smr_client_hndl handle,unsigned int messageId,void * decodedInd,unsigned int decodedIndLen,void * callbackData)623 void platformSensorServiceIndicationCallback(
624 smr_client_hndl handle, unsigned int messageId, void *decodedInd,
625 unsigned int decodedIndLen, void *callbackData) {
626 switch (messageId) {
627 case SNS_SMGR_BUFFERING_IND_V01: {
628 CHRE_ASSERT(decodedIndLen >= sizeof(sns_smgr_buffering_ind_msg_v01));
629 auto *bufferingInd =
630 static_cast<sns_smgr_buffering_ind_msg_v01 *>(decodedInd);
631 handleSensorDataIndication(*bufferingInd);
632 break;
633 }
634 default:
635 LOGW("Received unhandled sensor service message: 0x%x", messageId);
636 break;
637 };
638 }
639
640 /**
641 * Populates the supplied SensorTypes array with SensorTypes of the specified
642 * sensor ID.
643 *
644 * @param sensorId The sensor ID as provided by the SMGR.
645 * @param sensorTypes A non-null pointer to a SensorType array of size at least
646 * kMaxNumSensorsPerSensorId.
647 */
populateSensorTypeArrayFromSensorId(uint8_t sensorId,SensorType * sensorTypes)648 size_t populateSensorTypeArrayFromSensorId(uint8_t sensorId,
649 SensorType *sensorTypes) {
650 static_assert(kMaxNumSensorsPerSensorId >= 3,
651 "This function assumes kMaxNumSensorsPerSensorId >= 3");
652 CHRE_ASSERT(sensorTypes);
653
654 size_t numSensorTypes = 0;
655 if (sensorTypes != nullptr) {
656 if (sensorId >= SNS_SMGR_ID_ACCEL_V01
657 && sensorId < SNS_SMGR_ID_GYRO_V01) {
658 sensorTypes[0] = SensorType::Accelerometer;
659 sensorTypes[1] = SensorType::UncalibratedAccelerometer;
660 sensorTypes[2] = SensorType::AccelerometerTemperature;
661 numSensorTypes = 3;
662 } else if (sensorId >= SNS_SMGR_ID_GYRO_V01
663 && sensorId < SNS_SMGR_ID_MAG_V01) {
664 sensorTypes[0] = SensorType::Gyroscope;
665 sensorTypes[1] = SensorType::UncalibratedGyroscope;
666 sensorTypes[2] = SensorType::GyroscopeTemperature;
667 numSensorTypes = 3;
668 } else if (sensorId >= SNS_SMGR_ID_MAG_V01
669 && sensorId < SNS_SMGR_ID_PRESSURE_V01) {
670 sensorTypes[0] = SensorType::GeomagneticField;
671 sensorTypes[1] = SensorType::UncalibratedGeomagneticField;
672 numSensorTypes = 2;
673 } else {
674 SensorType sensorType = getSensorTypeFromSensorId(sensorId,
675 SNS_SMGR_DATA_TYPE_PRIMARY_V01, SNS_SMGR_CAL_SEL_FULL_CAL_V01);
676 if (sensorType != SensorType::Unknown) {
677 sensorTypes[0] = sensorType;
678 numSensorTypes = 1;
679 }
680 }
681 }
682 return numSensorTypes;
683 }
684
685 /**
686 * Obtains the merged SensorMode of the specified sensor ID, with sensorType's
687 * sensor request replaced by the supplied request.
688 *
689 * @param sensorId The sensor ID as provided by the SMGR.
690 * @param sensorType The SensorType whose sensor request is to be replaced by
691 * the supplied request.
692 * @param request The sensor request to replace the existing one.
693 * @return The merged SensorMode.
694 */
getMergedMode(uint8_t sensorId,SensorType sensorType,const SensorRequest & request)695 SensorMode getMergedMode(uint8_t sensorId, SensorType sensorType,
696 const SensorRequest& request) {
697 // Identify sensor requests to merge
698 SensorType sensorTypes[kMaxNumSensorsPerSensorId];
699 size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
700 sensorId, sensorTypes);
701
702 // merge requests
703 SensorRequest mergedRequest;
704 for (size_t i = 0; i < numSensorTypes; i++) {
705 const Sensor *sensor = EventLoopManagerSingleton::get()
706 ->getSensorRequestManager().getSensor(sensorTypes[i]);
707 if (sensor != nullptr) {
708 mergedRequest.mergeWith(
709 (sensorTypes[i] == sensorType) ? request : sensor->getRequest());
710 }
711 }
712 return mergedRequest.getMode();
713 }
714
715 /**
716 * Makes or removes passive sensor requests when the presence of other SMGR
717 * clients changes.
718 *
719 * @param sensorID The sensor ID being monitored.
720 * @param otherClientPresent The presence of other SMGR clients.
721 */
onOtherClientPresenceChange(uint8_t sensorId,bool otherClientPresent)722 void onOtherClientPresenceChange(uint8_t sensorId, bool otherClientPresent) {
723 bool makeAllRequests = otherClientPresent;
724
725 SensorRequest dummyRequest;
726 SensorMode mode = getMergedMode(sensorId, SensorType::Unknown, dummyRequest);
727 bool removeAllRequests = (sensorModeIsPassive(mode) && !otherClientPresent);
728
729 bool requestMade = false;
730 if (makeAllRequests) {
731 requestMade = makeAllPendingRequests(sensorId);
732 } else if (removeAllRequests) {
733 requestMade = removeAllPassiveRequests(sensorId);
734 }
735
736 if (requestMade) {
737 LOGD("%s: id %" PRIu8 ", otherClientPresent %d, mode %d",
738 makeAllRequests ? "+" : "-", sensorId, otherClientPresent,
739 static_cast<size_t>(mode));
740 }
741 }
742
743 /**
744 * Retrieves first valid sensor that has the given sensor ID. Can be
745 * invoked from any thread.
746 *
747 * @param sensorID The sensor handle that should be used to search
748 * the current list of sensors.
749 * @return The first non-null Sensor that matches the given sensor handle or
750 * nullptr if no match is found.
751 */
getFirstValidSensor(uint8_t sensorId)752 Sensor *getFirstValidSensor(uint8_t sensorId) {
753 SensorType sensorTypes[kMaxNumSensorsPerSensorId];
754 size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
755 sensorId, sensorTypes);
756
757 Sensor *sensor = nullptr;
758 for (size_t i = 0; i < numSensorTypes; i++) {
759 sensor = EventLoopManagerSingleton::get()
760 ->getSensorRequestManager().getSensor(sensorTypes[i]);
761 if (sensor != nullptr) {
762 break;
763 }
764 }
765 return sensor;
766 }
767
768 /**
769 * Processes the latest client request info response for the given sensor ID.
770 * Must be invoked from the CHRE thread.
771 *
772 * @param resp The SMGR client request info response.
773 * @param sensorId The sensor ID the response is for.
774 * @param transpErr The error related to the request.
775 */
onClientRequestInfoResponse(const sns_smgr_client_request_info_resp_msg_v01 & resp,uint8_t sensorId,smr_err transpErr)776 void onClientRequestInfoResponse(
777 const sns_smgr_client_request_info_resp_msg_v01& resp,
778 uint8_t sensorId,
779 smr_err transpErr) {
780 size_t index = getSensorMonitorIndex(sensorId);
781 if (transpErr != SMR_NO_ERR) {
782 LOGE("Error receiving client request info: %" PRIu8, transpErr);
783 } else if (resp.resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
784 LOGE("Client request info failed with error: %" PRIu8 ", id %" PRIu8,
785 resp.resp.sns_err_t, sensorId);
786 } else if (index == gSensorMonitors.size()) {
787 LOGE("Sensor status monitor update of invalid sensor ID %" PRIu8, sensorId);
788 } else {
789 bool otherClientPresent = resp.other_client_present;
790 if (gSensorMonitors[index].otherClientPresent != otherClientPresent) {
791 onOtherClientPresenceChange(sensorId, otherClientPresent);
792 gSensorMonitors[index].otherClientPresent = otherClientPresent;
793 }
794 }
795 }
796
797 /**
798 * Makes an asynchronous request to SMGR to receive the latest client
799 * request info.
800 *
801 * @param sensorId The handle to the sensor whose status has changed.
802 */
onStatusChange(uint8_t sensorId)803 void onStatusChange(uint8_t sensorId) {
804 // Sensor already verified to be valid before onStatusChange is called.
805 Sensor *sensor = getFirstValidSensor(sensorId);
806 // Invalidate timer first so a status update isn't potentially
807 // missed.
808 sensor->timerHandle = CHRE_TIMER_INVALID;
809
810 size_t index = getSensorMonitorIndex(sensorId);
811 if (index == gSensorMonitors.size()) {
812 LOGE("Sensor status monitor update of invalid sensor ID %" PRIu8, sensorId);
813 } else {
814 // Use the asynchronous sensor status monitor indication message as a cue
815 // to query and obtain the latest client request info. Since the status
816 // changes are processed on a delay, the current client status is out of
817 // date so query the latest status asynchronously to avoid holding up the
818 // CHRE thread.
819 auto infoRequest =
820 MakeUniqueZeroFill<sns_smgr_client_request_info_req_msg_v01>();
821 auto infoResponse = MakeUnique<sns_smgr_client_request_info_resp_msg_v01>();
822
823 if (infoRequest.isNull() || infoResponse.isNull()) {
824 LOG_OOM();
825 } else {
826 // Enables passing the sensor ID through the event data pointer to avoid
827 // allocating memory
828 union NestedSensorId {
829 void *eventData;
830 uint8_t sensorId;
831 };
832 NestedSensorId nestedId = {};
833 nestedId.sensorId = sensorId;
834
835 SmrReqCallback<sns_smgr_client_request_info_resp_msg_v01> callback =
836 [](UniquePtr<sns_smgr_client_request_info_resp_msg_v01> resp,
837 void *data,
838 smr_err transpErr) {
839 NestedSensorId nestedIdCb;
840 nestedIdCb.eventData = data;
841 onClientRequestInfoResponse(*resp.get(),
842 nestedIdCb.sensorId, transpErr);
843 };
844
845 infoRequest->sensor_id = sensorId;
846 smr_err smrStatus = getSmrHelper()->sendReqAsync(
847 gPlatformSensorServiceSmrClientHandle,
848 SNS_SMGR_CLIENT_REQUEST_INFO_REQ_V01,
849 &infoRequest, &infoResponse, callback, nestedId.eventData);
850 if (smrStatus != SMR_NO_ERR) {
851 LOGE("Error requesting client request info: %d", smrStatus);
852 }
853 }
854 }
855 }
856
857 /**
858 * Posts a CHRE_EVENT_SENSOR_SAMPLING_CHANGE event to the specified Nanoapp.
859 *
860 * @param instaceId The instance ID of the nanoapp with an open request
861 * @param eventRef A reference of the sampling status event to be posted.
862 */
postSamplingStatusEvent(uint32_t instanceId,uint32_t sensorHandle,const struct chreSensorSamplingStatus & status)863 void postSamplingStatusEvent(uint32_t instanceId, uint32_t sensorHandle,
864 const struct chreSensorSamplingStatus& status) {
865 // TODO: add a generic reference counted pointer class and use it for Event
866 // to share across interested nanoapps.
867 auto *event = memoryAlloc<struct chreSensorSamplingStatusEvent>();
868 if (event == nullptr) {
869 LOGE("Failed to allocate memory for sampling status change event");
870 } else {
871 event->sensorHandle = sensorHandle;
872 memcpy(&event->status, &status, sizeof(event->status));
873
874 EventLoopManagerSingleton::get()->getEventLoop().postEventOrFree(
875 CHRE_EVENT_SENSOR_SAMPLING_CHANGE, event, freeEventDataCallback,
876 kSystemInstanceId, instanceId);
877 }
878 }
879
880 /**
881 * Updates the sampling status after the sensor request is accepted by SMGR.
882 */
updateSamplingStatus(Sensor * sensor,const SensorRequest & request)883 void updateSamplingStatus(Sensor *sensor, const SensorRequest& request) {
884 // With SMGR's implementation, sampling interval will be filtered to be the
885 // same as requested. Latency can be shorter if there were other SMGR clients
886 // with proc_type also set to SNS_PROC_SSC_V01.
887 // If the request is passive, 'enabled' may change over time and needs to be
888 // updated.
889 if (sensor != nullptr) {
890 bool postUpdate = false;
891 struct chreSensorSamplingStatus& status = sensor->samplingStatus;
892 bool enabled = (request.getMode() != SensorMode::Off);
893 if (status.enabled != enabled) {
894 postUpdate = true;
895 status.enabled = enabled;
896 }
897 if (!sensorTypeIsOneShot(sensor->getSensorType())) {
898 if (status.interval != request.getInterval().toRawNanoseconds()) {
899 postUpdate = true;
900 status.interval = request.getInterval().toRawNanoseconds();
901 }
902 if (status.latency != request.getLatency().toRawNanoseconds()) {
903 postUpdate = true;
904 status.latency = request.getLatency().toRawNanoseconds();
905 }
906 }
907
908 if (postUpdate) {
909 uint32_t sensorHandle = getSensorHandleFromSensorType(
910 sensor->getSensorType());
911
912 // Only post to Nanoapps with an open request.
913 auto& requests = EventLoopManagerSingleton::get()->
914 getSensorRequestManager().getRequests(sensor->getSensorType());
915 for (const auto& req : requests) {
916 postSamplingStatusEvent(req.getInstanceId(), sensorHandle, status);
917 }
918 }
919 }
920 }
921
922 /**
923 * Handles sensor status provided by the SMGR framework.
924 *
925 * @param smgrMonitorIndMsg Indication message received from SMGR
926 */
handleSensorStatusMonitorIndication(const sns_smgr_sensor_status_monitor_ind_msg_v02 & smgrMonitorIndMsg)927 void handleSensorStatusMonitorIndication(
928 const sns_smgr_sensor_status_monitor_ind_msg_v02& smgrMonitorIndMsg) {
929 uint8_t sensorId = smgrMonitorIndMsg.sensor_id;
930
931 // Only use one Sensor to avoid multiple timers per sensorId.
932 Sensor *sensor = getFirstValidSensor(sensorId);
933 if (sensor == nullptr) {
934 LOGE("Sensor ID: %" PRIu8 " in status update doesn't correspond to "
935 "valid sensor.", sensorId);
936 // SMGR should send all callbacks back on the same thread which
937 // means the following code won't result in any timers overriding one
938 // another.
939 } else if (sensor->timerHandle.load() == CHRE_TIMER_INVALID) {
940 // Enables passing the sensor ID through the event data pointer to avoid
941 // allocating memory
942 union NestedSensorId {
943 void *eventData;
944 uint8_t sensorId;
945 };
946 NestedSensorId nestedId = {};
947 nestedId.sensorId = sensorId;
948
949 auto callback = [](uint16_t /* type */, void *data) {
950 NestedSensorId nestedIdCb;
951 nestedIdCb.eventData = data;
952 onStatusChange(nestedIdCb.sensorId);
953 };
954
955 // Schedule a delayed callback to handle sensor status change on the main
956 // thread.
957 TimerHandle timer = EventLoopManagerSingleton::get()->setDelayedCallback(
958 SystemCallbackType::SensorStatusUpdate,
959 nestedId.eventData,
960 callback,
961 kStatusDelayIntervalNanos);
962 sensor->timerHandle = timer;
963 }
964 }
965
966 /**
967 * This callback is invoked by the SMR framework when an asynchronous message is
968 * delivered. Unhandled messages are logged.
969 *
970 * @param handle Handle for the SMR client this indication was received on.
971 * @param messageId The message ID number.
972 * @param decodedInd Buffer containing decoded (C struct) message data.
973 * @param decodedIndLen Size of the decoded buffer in bytes.
974 * @param callbackData Data that is provided as a context to this callback. This
975 * is not used in this context.
976 *
977 * @see smr_client_ind_cb
978 */
platformSensorInternalServiceIndicationCallback(smr_client_hndl handle,unsigned int messageId,void * decodedInd,unsigned int decodedIndLen,void * callbackData)979 void platformSensorInternalServiceIndicationCallback(
980 smr_client_hndl handle, unsigned int messageId, void *decodedInd,
981 unsigned int decodedIndLen, void *callbackData) {
982 switch (messageId) {
983 case SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02: {
984 CHRE_ASSERT(decodedIndLen >=
985 sizeof(sns_smgr_sensor_status_monitor_ind_msg_v02));
986 auto *monitorInd =
987 static_cast<sns_smgr_sensor_status_monitor_ind_msg_v02 *>(decodedInd);
988 handleSensorStatusMonitorIndication(*monitorInd);
989 break;
990 }
991 default:
992 LOGW("Received unhandled sensor internal service message: 0x%x",
993 messageId);
994 break;
995 };
996 }
997
998 /**
999 * Adds or removes an SMGR sensor monitor for the specified sensor ID.
1000 *
1001 * @param sensorId The sensor ID to add/remove sensor status monitor for.
1002 * @param enable true to add and false to remove the status monitor.
1003 */
setSensorMonitorRequest(uint8_t sensorId,bool enable)1004 void setSensorMonitorRequest(uint8_t sensorId, bool enable) {
1005 auto monitorRequest =
1006 MakeUniqueZeroFill<sns_smgr_sensor_status_monitor_req_msg_v02>();
1007 auto monitorResponse =
1008 MakeUnique<sns_smgr_sensor_status_monitor_resp_msg_v02>();
1009
1010 if (monitorRequest.isNull() || monitorResponse.isNull()) {
1011 LOGE("Failed to allocate monitor request/response");
1012 } else {
1013 monitorRequest->sensor_id = sensorId;
1014 monitorRequest->registering = enable;
1015
1016 smr_err status = getSmrHelper()->sendReqSync(
1017 gPlatformSensorInternalServiceSmrClientHandle,
1018 SNS_SMGR_SENSOR_STATUS_MONITOR_REQ_V02,
1019 &monitorRequest, &monitorResponse);
1020 if (status != SMR_NO_ERR) {
1021 LOGE("Error setting sensor status monitor: %d", status);
1022 } else if (monitorResponse->resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
1023 LOGE("Sensor status monitor request failed with error: %" PRIu8
1024 " sensor ID %" PRIu8 " enable %d",
1025 monitorResponse->resp.sns_err_t, sensorId, enable);
1026 }
1027 }
1028 }
1029
1030 /**
1031 * Adds and initializes a sensor monitor for the specified sensor ID if it
1032 * doesn't exist yet.
1033 *
1034 * @param sensorId The sensor ID to request monitor for.
1035 */
addSensorMonitor(uint8_t sensorId)1036 void addSensorMonitor(uint8_t sensorId) {
1037 size_t index = getSensorMonitorIndex(sensorId);
1038 if (index == gSensorMonitors.size()) {
1039 LOGD("Adding sensor status monitor for sensor ID %" PRIu8, sensorId);
1040
1041 // Initialize sensor monitor status before making the request.
1042 SensorMonitor monitor;
1043 monitor.sensorId = sensorId;
1044 monitor.otherClientPresent = false;
1045 gSensorMonitors.push_back(monitor);
1046
1047 // Make a request to add the status monitor
1048 setSensorMonitorRequest(sensorId, true);
1049 }
1050 }
1051
1052 /**
1053 * Requests the sensors for a given sensor ID and appends them to the provided
1054 * list of sensors. If an error occurs, false is returned.
1055 *
1056 * @param sensorId The sensor ID to request sensor info for.
1057 * @param sensors The list of sensors to append newly found sensors to.
1058 * @return Returns false if an error occurs.
1059 */
getSensorsForSensorId(uint8_t sensorId,DynamicVector<Sensor> * sensors)1060 bool getSensorsForSensorId(uint8_t sensorId,
1061 DynamicVector<Sensor> *sensors) {
1062 bool success = false;
1063 auto sensorInfoRequest =
1064 MakeUniqueZeroFill<sns_smgr_single_sensor_info_req_msg_v01>();
1065 auto sensorInfoResponse =
1066 MakeUnique<sns_smgr_single_sensor_info_resp_msg_v01>();
1067
1068 if (sensorInfoRequest.isNull() || sensorInfoResponse.isNull()) {
1069 LOGE("Failed to allocate sensor info msg");
1070 } else {
1071 sensorInfoRequest->SensorID = sensorId;
1072
1073 smr_err status = getSmrHelper()->sendReqSync(
1074 gPlatformSensorServiceSmrClientHandle,
1075 SNS_SMGR_SINGLE_SENSOR_INFO_REQ_V01,
1076 &sensorInfoRequest, &sensorInfoResponse);
1077
1078 if (status != SMR_NO_ERR) {
1079 LOGE("Error requesting single sensor info: %d", status);
1080 } else if (sensorInfoResponse->Resp.sns_result_t !=
1081 SNS_RESULT_SUCCESS_V01) {
1082 LOGE("Single sensor info request failed with error: %d",
1083 sensorInfoResponse->Resp.sns_err_t);
1084 } else {
1085 const sns_smgr_sensor_info_s_v01& sensorInfoList =
1086 sensorInfoResponse->SensorInfo;
1087 for (uint32_t i = 0; i < sensorInfoList.data_type_info_len; i++) {
1088 const sns_smgr_sensor_datatype_info_s_v01& sensorInfo =
1089 sensorInfoList.data_type_info[i];
1090 LOGD("SensorID %" PRIu8 ", DataType %" PRIu8 ", MaxRate %" PRIu16
1091 "Hz, SensorName %s",
1092 sensorInfo.SensorID, sensorInfo.DataType,
1093 sensorInfo.MaxSampleRate, sensorInfo.SensorName);
1094
1095 SensorType sensorType = getSensorTypeFromSensorId(
1096 sensorInfo.SensorID, sensorInfo.DataType,
1097 SNS_SMGR_CAL_SEL_FULL_CAL_V01);
1098 if (sensorType != SensorType::Unknown) {
1099 addSensor(sensorInfo, SNS_SMGR_CAL_SEL_FULL_CAL_V01, sensors);
1100
1101 // Add an uncalibrated version if defined.
1102 SensorType uncalibratedType = getSensorTypeFromSensorId(
1103 sensorInfo.SensorID, sensorInfo.DataType,
1104 SNS_SMGR_CAL_SEL_FACTORY_CAL_V01);
1105 if (sensorType != uncalibratedType) {
1106 addSensor(sensorInfo, SNS_SMGR_CAL_SEL_FACTORY_CAL_V01, sensors);
1107 }
1108 }
1109 }
1110 success = true;
1111 }
1112 }
1113
1114 return success;
1115 }
1116
1117 /**
1118 * Converts a SensorMode into an SMGR request action. When the net request for
1119 * a sensor is considered to be active an add operation is required for the
1120 * SMGR request. When the sensor becomes inactive the request is deleted.
1121 *
1122 * @param mode The sensor mode.
1123 * @return Returns the SMGR request action given the sensor mode.
1124 */
getSmgrRequestActionForMode(SensorMode mode)1125 uint8_t getSmgrRequestActionForMode(SensorMode mode) {
1126 if (mode != SensorMode::Off) {
1127 return SNS_SMGR_BUFFERING_ACTION_ADD_V01;
1128 } else {
1129 return SNS_SMGR_BUFFERING_ACTION_DELETE_V01;
1130 }
1131 }
1132
1133 /**
1134 * Specify the sensor decimation type.
1135 *
1136 * @param sensorId The sensorID as provided by the SMGR.
1137 * @param dataType The dataType for the sesnor as provided by the SMGR.
1138 * return The decimation type as defined by the SMGR.
1139 */
getDecimationType(uint8_t sensorId,uint8_t dataType)1140 uint8_t getDecimationType(uint8_t sensorId, uint8_t dataType) {
1141 // Request filtered data for accel and gyro to reduce noise aliasing in case
1142 // SMGR has other higher ODR clients.
1143 if ((sensorId == SNS_SMGR_ID_ACCEL_V01 || sensorId == SNS_SMGR_ID_GYRO_V01)
1144 && dataType == SNS_SMGR_DATA_TYPE_PRIMARY_V01) {
1145 return SNS_SMGR_DECIMATION_FILTER_V01;
1146 } else {
1147 return SNS_SMGR_DECIMATION_RECENT_SAMPLE_V01;
1148 }
1149 }
1150
1151 /**
1152 * Populates a sns_smgr_buffering_req_msg_v01 struct to request sensor data.
1153 *
1154 * @param request The new request to set this sensor to.
1155 * @param sensorId The sensorID as provided by the SMGR request for sensor info.
1156 * @param dataType The dataType for the sesnor as provided by the SMGR request
1157 * for sensor info.
1158 * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
1159 * @param minInterval The minimum interval allowed by this sensor.
1160 * @param sensorDataRequest The pointer to the data request to be populated.
1161 */
populateSensorRequest(const SensorRequest & chreRequest,uint8_t sensorId,uint8_t dataType,uint8_t calType,uint64_t minInterval,sns_smgr_buffering_req_msg_v01 * sensorRequest)1162 void populateSensorRequest(
1163 const SensorRequest& chreRequest, uint8_t sensorId, uint8_t dataType,
1164 uint8_t calType, uint64_t minInterval,
1165 sns_smgr_buffering_req_msg_v01 *sensorRequest) {
1166 // Zero the fields in the request. All mandatory and unused fields are
1167 // specified to be set to false or zero so this is safe.
1168 memset(sensorRequest, 0, sizeof(*sensorRequest));
1169
1170 // Reconstructs a request to deliver one-shot sensors' data ASAP and set
1171 // default interval to some meaningful number.
1172 bool isOneShot = sensorTypeIsOneShot(getSensorTypeFromSensorId(
1173 sensorId, dataType, calType));
1174 uint64_t cappedInterval = chreRequest.getInterval().toRawNanoseconds();
1175 if (cappedInterval == CHRE_SENSOR_INTERVAL_DEFAULT) {
1176 // For one-shot sensors, we've overridden minInterval to default in init.
1177 // However, for InstantMotion/StationaryDetect, making a request with
1178 // default interval will not trigger.
1179 cappedInterval =
1180 isOneShot ? kDefaultInterval : std::max(minInterval, kDefaultInterval);
1181 }
1182 SensorRequest request(chreRequest.getMode(), Nanoseconds(cappedInterval),
1183 isOneShot ? Nanoseconds(0) : chreRequest.getLatency());
1184
1185 // Build the request for one sensor at the requested rate. An add action for a
1186 // ReportID that is already in use causes a replacement of the last request.
1187 sensorRequest->ReportId = getReportId(sensorId, dataType, calType);
1188 sensorRequest->Action = getSmgrRequestActionForMode(request.getMode());
1189
1190 // SMGR report interval should be (interval + latency). However, to handle
1191 // fractional-interval latency setting and to guarantee meeting chre request,
1192 // report interval is set to latency only. Also, lower-bound batchInterval as
1193 // request to SMGR would fail if batchInterval < interval.
1194 Nanoseconds batchInterval =
1195 std::max(request.getLatency(), request.getInterval());
1196 sensorRequest->ReportRate = intervalToSmgrQ16ReportRate(batchInterval);
1197 sensorRequest->Item_len = 1; // One sensor per request if possible.
1198 sensorRequest->Item[0].SensorId = sensorId;
1199 sensorRequest->Item[0].DataType = dataType;
1200 sensorRequest->Item[0].Decimation = getDecimationType(sensorId, dataType);
1201 sensorRequest->Item[0].Calibration = calType;
1202 sensorRequest->Item[0].SamplingRate =
1203 intervalToSmgrSamplingRate(request.getInterval());
1204
1205 // Add a dummy primary sensor to accompany a secondary temperature sensor.
1206 // This is requred by the SMGR. The primary sensor is requested with the same
1207 // (low) rate and the same latency, whose response data will be ignored.
1208 if (isSecondaryTemperature(sensorRequest->ReportId)) {
1209 sensorRequest->Item_len = 2;
1210 sensorRequest->Item[1].SensorId = sensorId;
1211 sensorRequest->Item[1].DataType = SNS_SMGR_DATA_TYPE_PRIMARY_V01;
1212 sensorRequest->Item[1].Decimation = getDecimationType(
1213 sensorId, SNS_SMGR_DATA_TYPE_PRIMARY_V01);
1214 sensorRequest->Item[1].Calibration = SNS_SMGR_CAL_SEL_FULL_CAL_V01;
1215 sensorRequest->Item[1].SamplingRate = sensorRequest->Item[0].SamplingRate;
1216 }
1217
1218 // Synchronize fifo flushes with other clients that have SSC proc_type.
1219 // send_indications_during_suspend has no effect on data sent to SLPI.
1220 // Default is to synchronize with AP clients, which may shorten flush
1221 // intervals for data sent to the AP.
1222 sensorRequest->notify_suspend_valid = true;
1223 sensorRequest->notify_suspend.proc_type = SNS_PROC_SSC_V01;
1224 sensorRequest->notify_suspend.send_indications_during_suspend = true;
1225 }
1226
1227 /**
1228 * Determines whether a request is allowed. A passive request is not always
1229 * allowed.
1230 *
1231 * @param sensorType The SensorType of this request
1232 * @param request The intended sensor request
1233 * @return true if the request is allowed.
1234 */
isRequestAllowed(SensorType sensorType,const SensorRequest & request)1235 bool isRequestAllowed(SensorType sensorType, const SensorRequest& request) {
1236 bool allowed = false;
1237
1238 const Sensor *sensor = EventLoopManagerSingleton::get()
1239 ->getSensorRequestManager().getSensor(sensorType);
1240 if (sensor != nullptr) {
1241 if (sensorModeIsPassive(request.getMode())) {
1242 size_t index = getSensorMonitorIndex(sensor->sensorId);
1243 if (index == gSensorMonitors.size()) {
1244 LOGE("SensorId %" PRIu8 " doesn't have a monitor", sensor->sensorId);
1245 } else {
1246 SensorMode mergedMode = getMergedMode(
1247 sensor->sensorId, sensorType, request);
1248 bool otherClientPresent = gSensorMonitors[index].otherClientPresent;
1249 allowed = (sensorModeIsActive(mergedMode) || otherClientPresent);
1250 LOGD("sensorType %d allowed %d: mergedMode %d, otherClientPresent %d",
1251 static_cast<size_t>(sensorType), allowed,
1252 static_cast<int>(mergedMode), otherClientPresent);
1253 }
1254 } else {
1255 // If it's an ACTIVE or an OFF request, it's always allowed.
1256 allowed = true;
1257 }
1258 }
1259 return allowed;
1260 }
1261
1262 /**
1263 * Makes a SNS_SMGR_BUFFERING_REQ request based on the arguments provided.
1264 *
1265 * @param sensorId The sensorID as provided by the SMGR.
1266 * @param dataType The dataType for the sesnor as provided by the MSGR.
1267 * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
1268 * @param minInterval The minimum interval of this sensor.
1269 * @param request The sensor request
1270 * @return true if the request has been made successfully.
1271 */
makeBufferingReq(uint8_t sensorId,uint8_t dataType,uint8_t calType,uint64_t minInterval,const SensorRequest & request)1272 bool makeBufferingReq(uint8_t sensorId, uint8_t dataType, uint8_t calType,
1273 uint64_t minInterval, const SensorRequest& request) {
1274 bool success = false;
1275 auto sensorRequest = MakeUniqueZeroFill<sns_smgr_buffering_req_msg_v01>();
1276 auto sensorResponse = MakeUnique<sns_smgr_buffering_resp_msg_v01>();
1277
1278 if (sensorRequest.isNull() || sensorResponse.isNull()) {
1279 LOGE("Failed to allocate buffering msg");
1280 } else {
1281 populateSensorRequest(request, sensorId, dataType, calType,
1282 minInterval, sensorRequest.get());
1283
1284 smr_err status = getSmrHelper()->sendReqSync(
1285 gPlatformSensorServiceSmrClientHandle, SNS_SMGR_BUFFERING_REQ_V01,
1286 &sensorRequest, &sensorResponse);
1287
1288 if (status != SMR_NO_ERR) {
1289 LOGE("Error requesting sensor data: %d", status);
1290 } else if (sensorResponse->Resp.sns_result_t != SNS_RESULT_SUCCESS_V01
1291 || (sensorResponse->AckNak != SNS_SMGR_RESPONSE_ACK_SUCCESS_V01
1292 && sensorResponse->AckNak != SNS_SMGR_RESPONSE_ACK_MODIFIED_V01)) {
1293 LOGE("Sensor data request failed with error: %d, AckNak: %d",
1294 sensorResponse->Resp.sns_err_t, sensorResponse->AckNak);
1295 } else {
1296 success = true;
1297 }
1298 }
1299
1300 return success;
1301 }
1302
1303 /**
1304 * Makes a SNS_SMGR_BUFFERING_REQ request if necessary.
1305 *
1306 * @param sensorType The sensor type of the request.
1307 * @param request The sensor request to be made.
1308 * @return true if the request has been accepted.
1309 */
makeRequest(SensorType sensorType,const SensorRequest & request)1310 bool makeRequest(SensorType sensorType, const SensorRequest& request) {
1311 bool success = false;
1312
1313 Sensor *sensor = EventLoopManagerSingleton::get()->getSensorRequestManager()
1314 .getSensor(sensorType);
1315 if (sensor != nullptr) {
1316 // Do not make an off request if the sensor is already off. Otherwise, SMGR
1317 // returns an error.
1318 if (request.getMode() == SensorMode::Off) {
1319 success = sensor->isSensorOff;
1320 }
1321
1322 // Make a SMGR buffering request if necessary.
1323 if (!success) {
1324 success = makeBufferingReq(sensor->sensorId, sensor->dataType,
1325 sensor->calType, sensor->minInterval, request);
1326 }
1327 }
1328
1329 // TODO: handle makeBufferingReq failures
1330 if (success) {
1331 // Update internal states if request was accepted by SMGR.
1332 sensor->isSensorOff = (request.getMode() == SensorMode::Off);
1333
1334 if (request.getMode() == SensorMode::Off) {
1335 sensor->lastEventValid = false;
1336 }
1337
1338 updateSamplingStatus(sensor, request);
1339 }
1340 return success;
1341 }
1342
1343 /**
1344 * Makes all pending requests of the specified sensor ID to SMGR.
1345 *
1346 * @param sensorId The sensor ID whose pending requests are to be made.
1347 * @return true if an ADD request has been accepted.
1348 */
makeAllPendingRequests(uint8_t sensorId)1349 bool makeAllPendingRequests(uint8_t sensorId) {
1350 // Identify sensor types to check for pending requests
1351 SensorType sensorTypes[kMaxNumSensorsPerSensorId];
1352 size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
1353 sensorId, sensorTypes);
1354 bool accepted = false;
1355 for (size_t i = 0; i < numSensorTypes; i++) {
1356 const Sensor *sensor = EventLoopManagerSingleton::get()
1357 ->getSensorRequestManager().getSensor(sensorTypes[i]);
1358
1359 // If sensor is off and the request is not off, it's a pending request.
1360 if (sensor != nullptr && sensor->isSensorOff
1361 && sensor->getRequest().getMode() != SensorMode::Off) {
1362 accepted |= makeRequest(sensorTypes[i], sensor->getRequest());
1363 }
1364 }
1365 return accepted;
1366 }
1367
1368 /**
1369 * Identifies and removes passive requests that have been made to the SMGR, and
1370 * adds them to the sensor monitor.
1371 *
1372 * @param sensorId The sensor ID whose passive requests are to be removed.
1373 * @return true if a DELETE request has been accepted.
1374 */
removeAllPassiveRequests(uint8_t sensorId)1375 bool removeAllPassiveRequests(uint8_t sensorId) {
1376 // Specify sensor types to check for passive requests
1377 SensorType sensorTypes[kMaxNumSensorsPerSensorId];
1378 size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
1379 sensorId, sensorTypes);
1380 bool accepted = false;
1381 for (size_t i = 0; i < numSensorTypes; i++) {
1382 const Sensor *sensor = EventLoopManagerSingleton::get()
1383 ->getSensorRequestManager().getSensor(sensorTypes[i]);
1384
1385 // Turn off sensors that have a passive request
1386 if (sensor != nullptr
1387 && sensorModeIsPassive(sensor->getRequest().getMode())) {
1388 SensorRequest offRequest;
1389 accepted |= makeRequest(sensorTypes[i], offRequest);
1390 }
1391 }
1392 return accepted;
1393 }
1394
1395 } // anonymous namespace
1396
~PlatformSensor()1397 PlatformSensor::~PlatformSensor() {
1398 if (lastEvent != nullptr) {
1399 LOGD("Releasing lastEvent: id %" PRIu8 ", type %" PRIu8 ", cal %" PRIu8
1400 ", size %zu", sensorId, dataType, calType, lastEventSize);
1401 memoryFree(lastEvent);
1402 }
1403 }
1404
init()1405 void PlatformSensor::init() {
1406 // Timeout for SMR client initialization, in milliseconds.
1407 constexpr uint32_t kSmrInitTimeoutMs = 10;
1408
1409 SmrHelperSingleton::init();
1410
1411 // sns_smgr_api_v01
1412 qmi_idl_service_object_type smgrSvcObj =
1413 SNS_SMGR_SVC_get_service_object_v01();
1414 if (smgrSvcObj == nullptr) {
1415 FATAL_ERROR("Failed to obtain the SNS SMGR service instance");
1416 }
1417
1418 smr_err result = getSmrHelper()->waitForService(smgrSvcObj);
1419 if (result != SMR_NO_ERR) {
1420 FATAL_ERROR("Failed while waiting for SNS SMGR service");
1421 }
1422
1423 // Note: giving nullptr for err_cb prevents this from degrading to a regular
1424 // QMI client if the service is not found.
1425 smr_err status = smr_client_init(
1426 smgrSvcObj, SMR_CLIENT_INSTANCE_ANY,
1427 platformSensorServiceIndicationCallback, nullptr /* ind_cb_data */,
1428 kSmrInitTimeoutMs, nullptr /* err_cb */, nullptr /* err_cb_data */,
1429 &gPlatformSensorServiceSmrClientHandle, isSlpiUimgSupported());
1430 if (status != SMR_NO_ERR) {
1431 FATAL_ERROR("Failed to initialize SMGR client: %d", status);
1432 }
1433
1434 // sns_smgr_interal_api_v02
1435 qmi_idl_service_object_type smgrInternalSvcObj =
1436 SNS_SMGR_INTERNAL_SVC_get_service_object_v02();
1437 if (smgrInternalSvcObj == nullptr) {
1438 FATAL_ERROR("Failed to obtain the SNS SMGR internal service instance");
1439 }
1440
1441 result = getSmrHelper()->waitForService(smgrInternalSvcObj);
1442 if (result != SMR_NO_ERR) {
1443 FATAL_ERROR("Failed while waiting for SNS SMGR internal service");
1444 }
1445
1446 status = smr_client_init(
1447 smgrInternalSvcObj, SMR_CLIENT_INSTANCE_ANY,
1448 platformSensorInternalServiceIndicationCallback,
1449 nullptr /* ind_cb_data */, kSmrInitTimeoutMs, nullptr /* err_cb */,
1450 nullptr /* err_cb_data */, &gPlatformSensorInternalServiceSmrClientHandle,
1451 isSlpiUimgSupported());
1452 if (status != SMR_NO_ERR) {
1453 FATAL_ERROR("Failed to initialize SMGR internal client: %d", status);
1454 }
1455 }
1456
deinit()1457 void PlatformSensor::deinit() {
1458 smr_err err = getSmrHelper()->releaseSync(
1459 gPlatformSensorServiceSmrClientHandle);
1460 if (err != SMR_NO_ERR) {
1461 LOGE("Failed to release SMGR client: %d", err);
1462 }
1463 gPlatformSensorServiceSmrClientHandle = nullptr;
1464
1465 err = getSmrHelper()->releaseSync(
1466 gPlatformSensorInternalServiceSmrClientHandle);
1467 if (err != SMR_NO_ERR) {
1468 LOGE("Failed to release SMGR internal client: %d", err);
1469 }
1470 gPlatformSensorInternalServiceSmrClientHandle = nullptr;
1471
1472 // Clearing all sensor status monitors. Releasing an SMR client also releases
1473 // all sensor status monitor requests.
1474 gSensorMonitors.clear();
1475 SmrHelperSingleton::deinit();
1476 }
1477
getSensors(DynamicVector<Sensor> * sensors)1478 bool PlatformSensor::getSensors(DynamicVector<Sensor> *sensors) {
1479 CHRE_ASSERT(sensors);
1480
1481 auto sensorListRequest =
1482 MakeUniqueZeroFill<sns_smgr_all_sensor_info_req_msg_v01>();
1483 auto sensorListResponse = MakeUnique<sns_smgr_all_sensor_info_resp_msg_v01>();
1484
1485 smr_err status = getSmrHelper()->sendReqSync(
1486 gPlatformSensorServiceSmrClientHandle, SNS_SMGR_ALL_SENSOR_INFO_REQ_V01,
1487 &sensorListRequest, &sensorListResponse);
1488
1489 bool success = false;
1490 if (status != SMR_NO_ERR) {
1491 LOGE("Error requesting sensor list: %d", status);
1492 } else if (sensorListResponse->Resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
1493 LOGE("Sensor list lequest failed with error: %d",
1494 sensorListResponse->Resp.sns_err_t);
1495 } else {
1496 success = true;
1497 for (uint32_t i = 0; i < sensorListResponse->SensorInfo_len; i++) {
1498 uint8_t sensorId = sensorListResponse->SensorInfo[i].SensorID;
1499 if (!getSensorsForSensorId(sensorId, sensors)) {
1500 success = false;
1501 break;
1502 }
1503 }
1504 }
1505
1506 return success;
1507 }
1508
applyRequest(const SensorRequest & request)1509 bool PlatformSensor::applyRequest(const SensorRequest& request) {
1510 bool success;
1511
1512 if (!SmrHelperSingleton::isInitialized()) {
1513 // Off requests made as part of shutdown come after PlatformSensor::deinit()
1514 // which releases our SMGR clients, removing all requests. Report success in
1515 // this case.
1516 success = (request.getMode() == SensorMode::Off) ? true : false;
1517 CHRE_ASSERT_LOG(success, "Sensor request made before init/after deinit");
1518 } else {
1519 // Adds a sensor monitor the first time this sensor is requested.
1520 addSensorMonitor(this->sensorId);
1521
1522 // As sensor status monior indication doesn't support secondary sensor
1523 // status change, Light sensor (a secondary one) is always overridden to be
1524 // requested with an active mode.
1525 bool passiveLight = (getSensorType() == SensorType::Light
1526 && sensorModeIsPassive(request.getMode()));
1527 if (passiveLight) {
1528 LOGE("Passive request for Light sensor is not supported. "
1529 "Overriding request to active");
1530 }
1531 SensorRequest localRequest(
1532 passiveLight ? SensorMode::ActiveContinuous : request.getMode(),
1533 request.getInterval(), request.getLatency());
1534
1535 // Determines whether a (passive) request is allowed at this point.
1536 bool requestAllowed = isRequestAllowed(getSensorType(), localRequest);
1537
1538 // If request is not allowed, turn off the sensor. Otherwise, make request.
1539 SensorRequest offRequest;
1540 success = makeRequest(getSensorType(),
1541 requestAllowed ? localRequest : offRequest);
1542 }
1543 return success;
1544 }
1545
flushAsync()1546 bool PlatformSensor::flushAsync() {
1547 // NOTE: SMGR framework flushes all pending data when a new request comes in
1548 // (ref sns_rh_sol_schedule_existing_report() in sns_rh_sol.c).
1549 // In this implementation of flushAsync, we make a request identical to
1550 // the existing sensor request, blocking on an asynchronous response,
1551 // and assume that the flush request has completed when this identical
1552 // sensor request is successfully handled and executed. This
1553 // implementation mirrors the sensors HAL implementation of flush.
1554 bool success = false;
1555 Sensor *sensor = EventLoopManagerSingleton::get()->getSensorRequestManager()
1556 .getSensor(getSensorType());
1557 if (sensor != nullptr) {
1558 success = applyRequest(sensor->getRequest());
1559 if (success) {
1560 EventLoopManagerSingleton::get()->getSensorRequestManager()
1561 .handleFlushCompleteEvent(CHRE_ERROR_NONE, getSensorType());
1562 }
1563 }
1564 return success;
1565 }
1566
getSensorType() const1567 SensorType PlatformSensor::getSensorType() const {
1568 return getSensorTypeFromSensorId(this->sensorId, this->dataType,
1569 this->calType);
1570 }
1571
getMinInterval() const1572 uint64_t PlatformSensor::getMinInterval() const {
1573 return minInterval;
1574 }
1575
getSensorName() const1576 const char *PlatformSensor::getSensorName() const {
1577 return sensorName;
1578 }
1579
PlatformSensor(PlatformSensor && other)1580 PlatformSensor::PlatformSensor(PlatformSensor&& other) {
1581 // Our move assignment operator doesn't assume that "this" is initialized, so
1582 // we can just use that here
1583 *this = std::move(other);
1584 }
1585
operator =(PlatformSensor && other)1586 PlatformSensor& PlatformSensor::operator=(PlatformSensor&& other) {
1587 // Note: if this implementation is ever changed to depend on "this" containing
1588 // initialized values, the move constructor implemenation must be updated
1589 sensorId = other.sensorId;
1590 dataType = other.dataType;
1591 calType = other.calType;
1592 memcpy(sensorName, other.sensorName, SNS_SMGR_MAX_SENSOR_NAME_SIZE_V01);
1593 minInterval = other.minInterval;
1594
1595 lastEvent = other.lastEvent;
1596 other.lastEvent = nullptr;
1597
1598 lastEventSize = other.lastEventSize;
1599 other.lastEventSize = 0;
1600
1601 lastEventValid = other.lastEventValid;
1602 isSensorOff = other.isSensorOff;
1603 samplingStatus = other.samplingStatus;
1604
1605 return *this;
1606 }
1607
getLastEvent() const1608 ChreSensorData *PlatformSensor::getLastEvent() const {
1609 return (this->lastEventValid) ? this->lastEvent : nullptr;
1610 }
1611
getSamplingStatus(struct chreSensorSamplingStatus * status) const1612 bool PlatformSensor::getSamplingStatus(
1613 struct chreSensorSamplingStatus *status) const {
1614 CHRE_ASSERT(status);
1615
1616 memcpy(status, &samplingStatus, sizeof(*status));
1617 return true;
1618 }
1619
getThreeAxisBias(struct chreSensorThreeAxisData * bias) const1620 bool PlatformSensor::getThreeAxisBias(
1621 struct chreSensorThreeAxisData *bias) const {
1622 // TODO: Implement this.
1623 return false;
1624 }
1625
setLastEvent(const ChreSensorData * event)1626 void PlatformSensorBase::setLastEvent(const ChreSensorData *event) {
1627 memcpy(this->lastEvent, event, this->lastEventSize);
1628 this->lastEventValid = true;
1629 }
1630
getSensorServiceSmrClientHandle()1631 smr_client_hndl getSensorServiceSmrClientHandle() {
1632 return gPlatformSensorServiceSmrClientHandle;
1633 }
1634
1635 } // namespace chre
1636