• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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