• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 "chre/platform/platform_sensor.h"
18 
19 #include "sns_std_sensor.pb.h"
20 #include "stringl.h"
21 
22 #include <cmath>
23 
24 #include "chre_api/chre/sensor.h"
25 #include "chre/core/event_loop_manager.h"
26 #include "chre/core/sensor.h"
27 #include "chre/platform/assert.h"
28 #include "chre/platform/fatal_error.h"
29 #include "chre/platform/log.h"
30 #include "chre/platform/shared/platform_sensor_util.h"
31 #include "chre/platform/slpi/see/see_client.h"
32 #include "chre/platform/slpi/see/see_helper.h"
33 #include "chre/platform/system_time.h"
34 
35 #ifdef CHREX_SENSOR_SUPPORT
36 #include "chre/extensions/platform/slpi/see/vendor_data_types.h"
37 #endif  // CHREX_SENSOR_SUPPORT
38 
39 #ifndef CHRE_SEE_NUM_TEMP_SENSORS
40 // There are usually more than one 'sensor_temperature' sensors in SEE.
41 // Define this in the variant-specific makefile to avoid missing sensors in
42 // sensor discovery.
43 #error "CHRE_SEE_NUM_TEMP_SENSORS is not defined"
44 #endif
45 
46 namespace chre {
47 namespace {
48 
49 //! A class that implements SeeHelperCallbackInterface.
50 class SeeHelperCallback : public SeeHelperCallbackInterface {
51   void onSamplingStatusUpdate(
52       UniquePtr<SeeHelperCallbackInterface::SamplingStatusData>&& status)
53       override;
54 
55   void onSensorDataEvent(
56       SensorType sensorType, UniquePtr<uint8_t>&& eventData) override;
57 
58   void onHostWakeSuspendEvent(bool awake) override;
59 };
60 
61 //! A struct to facilitate sensor discovery
62 struct SuidAttr {
63   sns_std_suid suid;
64   SeeAttributes attr;
65 };
66 
67 //! The list of SEE platform sensor data types that CHRE intends to support.
68 //! The standardized strings are defined in sns_xxx.proto.
69 const char *kSeeDataTypes[] = {
70   "accel",
71   "gyro",
72   "mag",
73   "pressure",
74   "ambient_light",
75   "proximity",
76   "motion_detect",
77   "stationary_detect",
78 };
79 
80 /**
81  * Obtains the sensor type given the specified data type and whether the sensor
82  * is runtime-calibrated or not.
83  */
getSensorTypeFromDataType(const char * dataType,bool calibrated)84 SensorType getSensorTypeFromDataType(const char *dataType, bool calibrated) {
85   SensorType sensorType;
86   if (strcmp(dataType, "accel") == 0) {
87     if (calibrated) {
88       sensorType = SensorType::Accelerometer;
89     } else {
90       sensorType = SensorType::UncalibratedAccelerometer;
91     }
92   } else if (strcmp(dataType, "gyro") == 0) {
93     if (calibrated) {
94       sensorType = SensorType::Gyroscope;
95     } else {
96       sensorType = SensorType::UncalibratedGyroscope;
97     }
98   } else if (strcmp(dataType, "mag") == 0) {
99     if (calibrated) {
100       sensorType = SensorType::GeomagneticField;
101     } else {
102       sensorType = SensorType::UncalibratedGeomagneticField;
103     }
104   } else if (strcmp(dataType, "pressure") == 0) {
105     sensorType = SensorType::Pressure;
106   } else if (strcmp(dataType, "ambient_light") == 0) {
107     sensorType = SensorType::Light;
108   } else if (strcmp(dataType, "proximity") == 0) {
109     sensorType = SensorType::Proximity;
110   } else if (strcmp(dataType, "motion_detect") == 0) {
111     sensorType = SensorType::InstantMotion;
112   } else if (strcmp(dataType, "stationary_detect") == 0) {
113     sensorType = SensorType::StationaryDetect;
114 #ifdef CHREX_SENSOR_SUPPORT
115   } else if (strcmp(dataType, kVendorDataTypes[0]) == 0) {
116     sensorType = SensorType::VendorType0;
117 #endif  // CHREX_SENSOR_SUPPORT
118   } else {
119     sensorType = SensorType::Unknown;
120   }
121   return sensorType;
122 }
123 
seeSensorDataEventFree(uint16_t eventType,void * eventData)124 void seeSensorDataEventFree(uint16_t eventType, void *eventData) {
125   memoryFree(eventData);
126 
127   // Remove all requests if it's a one-shot sensor and only after data has been
128   // delivered to all clients.
129   SensorType sensorType = getSensorTypeForSampleEventType(eventType);
130   if (sensorTypeIsOneShot(sensorType)) {
131     EventLoopManagerSingleton::get()->getSensorRequestManager()
132         .removeAllRequests(sensorType);
133   }
134 }
135 
136 /**
137  * Posts a CHRE_EVENT_SENSOR_SAMPLING_CHANGE event to the specified Nanoapp.
138  *
139  * @param instaceId The instance ID of the nanoapp with an open request.
140  * @param sensorHandle The handle of the sensor.
141  * @param status A reference of the sampling status to be posted.
142  */
postSamplingStatusEvent(uint32_t instanceId,uint32_t sensorHandle,const struct chreSensorSamplingStatus & status)143 void postSamplingStatusEvent(uint32_t instanceId, uint32_t sensorHandle,
144                              const struct chreSensorSamplingStatus& status) {
145   auto *event = memoryAlloc<struct chreSensorSamplingStatusEvent>();
146   if (event == nullptr) {
147     LOG_OOM();
148   } else {
149     event->sensorHandle = sensorHandle;
150     event->status = status;
151 
152     EventLoopManagerSingleton::get()->getEventLoop().postEventOrFree(
153         CHRE_EVENT_SENSOR_SAMPLING_CHANGE, event, freeEventDataCallback,
154         kSystemInstanceId, instanceId);
155   }
156 }
157 
158 /**
159  * Updates the sampling status.
160  */
updateSamplingStatus(const SeeHelperCallbackInterface::SamplingStatusData & update)161 void updateSamplingStatus(
162     const SeeHelperCallbackInterface::SamplingStatusData& update) {
163   Sensor *sensor = EventLoopManagerSingleton::get()->getSensorRequestManager()
164       .getSensor(update.sensorType);
165   struct chreSensorSamplingStatus prevStatus;
166 
167   if (sensor != nullptr && !sensorTypeIsOneShot(update.sensorType)
168       && sensor->getSamplingStatus(&prevStatus)) {
169     struct chreSensorSamplingStatus newStatus = prevStatus;
170 
171     if (update.enabledValid) {
172       newStatus.enabled = update.status.enabled;
173     }
174     if (update.intervalValid) {
175       newStatus.interval = update.status.interval;
176     }
177     if (update.latencyValid) {
178       newStatus.latency = update.status.latency;
179     }
180 
181     if (newStatus.enabled != prevStatus.enabled
182         || newStatus.interval != prevStatus.interval
183         || newStatus.latency != prevStatus.latency) {
184       sensor->setSamplingStatus(newStatus);
185 
186       // Only post to Nanoapps with an open request.
187       uint32_t sensorHandle = getSensorHandleFromSensorType(update.sensorType);
188       const DynamicVector<SensorRequest>& requests =
189           EventLoopManagerSingleton::get()->getSensorRequestManager()
190           .getRequests(update.sensorType);
191       for (const auto& req : requests) {
192         if (req.getNanoapp() != nullptr) {
193           postSamplingStatusEvent(req.getNanoapp()->getInstanceId(),
194                                   sensorHandle, newStatus);
195         }
196       }
197     }
198   }
199 }
200 
onSamplingStatusUpdate(UniquePtr<SeeHelperCallbackInterface::SamplingStatusData> && status)201 void SeeHelperCallback::onSamplingStatusUpdate(
202     UniquePtr<SeeHelperCallbackInterface::SamplingStatusData>&& status) {
203   auto callback = [](uint16_t /* type */, void *data) {
204     auto cbData = UniquePtr<SeeHelperCallbackInterface::SamplingStatusData>(
205         static_cast<SeeHelperCallbackInterface::SamplingStatusData *>(data));
206     updateSamplingStatus(*cbData);
207   };
208 
209   // Schedule a deferred callback to handle sensor status change in the main
210   // thread.
211   EventLoopManagerSingleton::get()->deferCallback(
212       SystemCallbackType::SensorStatusUpdate, status.release(), callback);
213 }
214 
onSensorDataEvent(SensorType sensorType,UniquePtr<uint8_t> && eventData)215 void SeeHelperCallback::onSensorDataEvent(
216     SensorType sensorType, UniquePtr<uint8_t>&& eventData) {
217   // Schedule a deferred callback to update on-change sensor's last event in
218   // the main thread.
219   if (sensorTypeIsOnChange(sensorType)) {
220     updateLastEvent(sensorType, eventData.get());
221   }
222 
223   uint16_t eventType = getSampleEventTypeForSensorType(sensorType);
224   EventLoopManagerSingleton::get()->getEventLoop().postEventOrFree(
225       eventType, eventData.get(), seeSensorDataEventFree);
226   eventData.release();
227 }
228 
onHostWakeSuspendEvent(bool awake)229 void SeeHelperCallback::onHostWakeSuspendEvent(bool awake) {
230   if (EventLoopManagerSingleton::isInitialized()) {
231     EventLoopManagerSingleton::get()->getEventLoop()
232         .getPowerControlManager().onHostWakeSuspendEvent(awake);
233   }
234 }
235 
236 /**
237  * Allocates memory and specifies the memory size for an on-change sensor to
238  * store its last data event.
239  *
240  * @param sensorType The sensorType of this sensor.
241  * @param eventSize A non-null pointer to indicate the memory size allocated.
242  * @return Pointer to the memory allocated.
243  */
allocateLastEvent(SensorType sensorType,size_t * eventSize)244 ChreSensorData *allocateLastEvent(SensorType sensorType, size_t *eventSize) {
245   CHRE_ASSERT(eventSize);
246 
247   *eventSize = 0;
248   ChreSensorData *event = nullptr;
249   if (sensorTypeIsOnChange(sensorType)) {
250     SensorSampleType sampleType = getSensorSampleTypeFromSensorType(sensorType);
251     switch (sampleType) {
252       case SensorSampleType::ThreeAxis:
253         *eventSize = sizeof(chreSensorThreeAxisData);
254         break;
255       case SensorSampleType::Float:
256         *eventSize = sizeof(chreSensorFloatData);
257         break;
258       case SensorSampleType::Byte:
259         *eventSize = sizeof(chreSensorByteData);
260         break;
261       case SensorSampleType::Occurrence:
262         *eventSize = sizeof(chreSensorOccurrenceData);
263         break;
264       default:
265         CHRE_ASSERT_LOG(false, "Unhandled sample type");
266         break;
267     }
268 
269     event = static_cast<ChreSensorData *>(memoryAlloc(*eventSize));
270     if (event == nullptr) {
271       *eventSize = 0;
272       FATAL_ERROR("Failed to allocate last event memory for SensorType %" PRIu8,
273                   static_cast<uint8_t>(sensorType));
274     }
275   }
276   return event;
277 }
278 
279 /**
280  * Constructs and initializes a sensor, and adds it to the sensor list.
281  *
282  * @param suid The SUID of the sensor as provided by SEE.
283  * @param sensorType The sensor type of the sensor.
284  * @param calibrated Whether the sensor is runtime-calibrated or not.
285  * @param attr A reference to SeeAttrbutes.
286  * @param sensor The sensor list.
287  */
addSensor(SensorType sensorType,const sns_std_suid & suid,const SeeAttributes & attr,DynamicVector<Sensor> * sensors)288 void addSensor(SensorType sensorType, const sns_std_suid& suid,
289                const SeeAttributes& attr, DynamicVector<Sensor> *sensors) {
290   // Concatenate vendor and name with a space in between.
291   char sensorName[kSensorNameMaxLen];
292   strlcpy(sensorName, attr.vendor, sizeof(sensorName));
293   strlcat(sensorName, " ", sizeof(sensorName));
294   strlcat(sensorName, attr.name, sizeof(sensorName));
295 
296   // Override one-shot sensor's minInterval to default
297   uint64_t minInterval = sensorTypeIsOneShot(sensorType) ?
298       CHRE_SENSOR_INTERVAL_DEFAULT : static_cast<uint64_t>(
299           ceilf(Seconds(1).toRawNanoseconds() / attr.maxSampleRate));
300 
301   // Allocates memory for on-change sensor's last event.
302   size_t lastEventSize;
303   ChreSensorData *lastEvent = allocateLastEvent(sensorType, &lastEventSize);
304 
305   // Constructs and initializes PlatformSensorBase.
306   Sensor sensor;
307   sensor.initBase(sensorType, minInterval, sensorName, lastEvent,
308                   lastEventSize, attr.passiveRequest);
309 
310   if (!sensors->push_back(std::move(sensor))) {
311     FATAL_ERROR("Failed to allocate new sensor: out of memory");
312   }
313 
314   bool prevRegistered;
315   bool registered = getSeeHelper()->registerSensor(
316       sensorType, suid, &prevRegistered);
317   if (!registered && prevRegistered) {
318     LOGW("SUID has been previously registered");
319   } else if (!registered) {
320     FATAL_ERROR("Failed to register SUID/SensorType mapping.");
321   }
322 }
323 
324 /**
325  * Compare SEE reported stream type attribute to the expected one. Some SEE
326  * sensors may support more than one stream type.
327  */
isStreamTypeCorrect(SensorType sensorType,uint8_t streamType)328 bool isStreamTypeCorrect(SensorType sensorType, uint8_t streamType) {
329   bool success = true;
330   if ((sensorTypeIsContinuous(sensorType)
331        && streamType != SNS_STD_SENSOR_STREAM_TYPE_STREAMING)
332       || (sensorTypeIsOnChange(sensorType)
333           && streamType != SNS_STD_SENSOR_STREAM_TYPE_ON_CHANGE)
334       || (sensorTypeIsOneShot(sensorType)
335           && streamType != SNS_STD_SENSOR_STREAM_TYPE_SINGLE_OUTPUT)) {
336     success = false;
337     LOGW("Inconsistent sensor type %" PRIu8 " and stream type %" PRIu8,
338          static_cast<uint8_t>(sensorType), streamType);
339   }
340   return success;
341 }
342 
343 /**
344  * Obtains the list of SUIDs and their attributes that support the specified
345  * data type.
346  */
getSuidAndAttrs(const char * dataType,DynamicVector<SuidAttr> * suidAttrs,uint8_t minNumSuids)347 bool getSuidAndAttrs(const char *dataType, DynamicVector<SuidAttr> *suidAttrs,
348                      uint8_t minNumSuids) {
349   DynamicVector<sns_std_suid> suids;
350   bool success = getSeeHelper()->findSuidSync(dataType, &suids, minNumSuids);
351   if (!success) {
352     LOGE("Failed to find sensor '%s'", dataType);
353   } else {
354     LOGD("Num of SUIDs found for '%s': %zu", dataType, suids.size());
355 
356     for (const auto& suid : suids) {
357       SeeAttributes attr;
358       if (!getSeeHelper()->getAttributesSync(suid, &attr)) {
359         success = false;
360         LOGE("Failed to get attributes of SUID 0x%" PRIx64 " %" PRIx64,
361              suid.suid_high, suid.suid_low);
362       } else {
363         LOGI("%s %s, hw id %" PRId64 ", max ODR %f Hz, stream type %" PRIu8
364              " passive %d",
365              attr.vendor, attr.name, attr.hwId, attr.maxSampleRate,
366              attr.streamType, attr.passiveRequest);
367         SuidAttr sensor = {
368           .suid = suid,
369           .attr = attr,
370         };
371         if (!suidAttrs->push_back(sensor)) {
372           success = false;
373           LOG_OOM();
374         }
375       }
376     }
377   }
378   return success;
379 }
380 
381 // Check whether two sensors with the specified attrtibutes belong to the same
382 // sensor hardware module.
sensorHwMatch(const SeeAttributes & attr0,const SeeAttributes & attr1)383 bool sensorHwMatch(const SeeAttributes& attr0, const SeeAttributes& attr1) {
384   // When HW ID is absent, it's default to 0 and won't be a factor.
385   return ((strncmp(attr0.vendor, attr1.vendor, kSeeAttrStrValLen) == 0)
386           && (strncmp(attr0.name, attr1.name, kSeeAttrStrValLen) == 0)
387           && (attr0.hwId == attr1.hwId));
388 }
389 
390 }  // anonymous namespace
391 
~PlatformSensor()392 PlatformSensor::~PlatformSensor() {
393   if (mLastEvent != nullptr) {
394     LOGD("Releasing lastEvent: sensor %s, size %zu",
395          getSensorTypeName(getSensorType()), mLastEventSize);
396     memoryFree(mLastEvent);
397   }
398 }
399 
init()400 void PlatformSensor::init() {
401   SeeHelperSingleton::init();
402 
403   static SeeHelperCallback seeHelperCallback;
404   if (!getSeeHelper()->init(&seeHelperCallback)) {
405     FATAL_ERROR("Failed to initialize SEE helper");
406   }
407 }
408 
deinit()409 void PlatformSensor::deinit() {
410   SeeHelperSingleton::deinit();
411 }
412 
getSensors(DynamicVector<Sensor> * sensors)413 bool PlatformSensor::getSensors(DynamicVector<Sensor> *sensors) {
414   CHRE_ASSERT(sensors);
415 
416   DynamicVector<SuidAttr> tempSensors;
417   if (!getSuidAndAttrs("sensor_temperature", &tempSensors,
418                        CHRE_SEE_NUM_TEMP_SENSORS)) {
419       FATAL_ERROR("Failed to get temperature sensor UID and attributes");
420   }
421 
422 #ifndef CHREX_SENSOR_SUPPORT
423   const char *kVendorDataTypes[] = {};
424 #endif  // CHREX_SENSOR_SUPPORT
425   constexpr size_t kNumSeeTypes = ARRAY_SIZE(kSeeDataTypes);
426   constexpr size_t kNumVendorTypes = ARRAY_SIZE(kVendorDataTypes);
427   for (size_t i = 0; i < kNumSeeTypes + kNumVendorTypes; i++) {
428     const char *dataType = (i < kNumSeeTypes)
429         ? kSeeDataTypes[i] : kVendorDataTypes[i - kNumSeeTypes];
430 
431     SensorType sensorType = getSensorTypeFromDataType(
432         dataType, false /* calibrated */);
433     if (sensorType == SensorType::Unknown) {
434       LOGE("Unknown sensor type found for '%s'", dataType);
435       continue;
436     }
437 
438     DynamicVector<SuidAttr> primarySensors;
439     if (!getSuidAndAttrs(dataType, &primarySensors, 1 /* minNumSuids */)) {
440       FATAL_ERROR("Failed to get primary sensor UID and attributes");
441     } else {
442       for (const auto& primarySensor : primarySensors) {
443         sns_std_suid suid = primarySensor.suid;
444         SeeAttributes attr = primarySensor.attr;
445 
446         // Some sensors support both continuous and on-change streams.
447         // If there are more than one SUIDs that support the data type,
448         // choose the first one that has the expected stream type.
449         if (isStreamTypeCorrect(sensorType, attr.streamType)) {
450           addSensor(sensorType, suid, attr, sensors);
451 
452           // Check if this sensor has a runtime-calibrated version.
453           SensorType calibratedType = getSensorTypeFromDataType(
454               dataType, true /* calibrated */);
455           if (calibratedType != sensorType) {
456             addSensor(calibratedType, suid, attr, sensors);
457           }
458 
459           // Check if this sensor has a secondary temperature sensor.
460           SensorType temperatureType = getTempSensorType(sensorType);
461           if (temperatureType != SensorType::Unknown) {
462             bool tempFound = false;
463             for (const auto& tempSensor : tempSensors) {
464               sns_std_suid tempSuid = tempSensor.suid;
465               SeeAttributes tempAttr = tempSensor.attr;
466 
467               if (sensorHwMatch(attr, tempAttr)) {
468                 LOGD("Found matching temperature sensor type");
469                 tempFound = true;
470                 addSensor(temperatureType, tempSuid, tempAttr, sensors);
471                 break;
472               }
473             }
474             if (!tempFound) {
475               LOGW("Temperature sensor type %" PRIu8 " not found!",
476                    static_cast<uint8_t>(temperatureType));
477             }
478           }
479           break;
480         }
481       }
482     }
483   }
484   return true;
485 }
486 
applyRequest(const SensorRequest & request)487 bool PlatformSensor::applyRequest(const SensorRequest& request) {
488   SeeSensorRequest req = {
489     .sensorType = getSensorType(),
490     .enable = (request.getMode() != SensorMode::Off),
491     .passive = sensorModeIsPassive(request.getMode()),
492     .samplingRateHz = static_cast<float>(
493         kOneSecondInNanoseconds / request.getInterval().toRawNanoseconds()),
494     // Override batch period to 0 for non-continuous sensors to ensure one
495     // sample per batch.
496     .batchPeriodUs = !sensorTypeIsContinuous(mSensorType) ? 0
497         : static_cast<uint32_t>(request.getLatency().toRawNanoseconds()
498                                 / kOneMicrosecondInNanoseconds),
499   };
500 
501   if (req.enable && req.passive && !mPassiveSupported) {
502     LOGD("Promoting sensor %" PRIu8 " passive request to active",
503          static_cast<uint8_t>(getSensorType()));
504   }
505 
506   bool success = SeeHelperSingleton::get()->makeRequest(req);
507 
508   // TODO: remove setSamplingStatus when .latency is available in status update
509   // from SEE.
510   if (success) {
511     struct chreSensorSamplingStatus status;
512     if (getSamplingStatus(&status)) {
513 
514       // If passive request is not supported by this SEE sensor, it won't be
515       // dynamically enabled/disabled and its status stays the same as set here.
516       if (!mPassiveSupported) {
517         status.enabled = req.enable;
518       }
519       status.latency = req.batchPeriodUs * kOneMicrosecondInNanoseconds;
520       setSamplingStatus(status);
521     }
522   }
523   return success;
524 }
525 
getSensorType() const526 SensorType PlatformSensor::getSensorType() const {
527   return mSensorType;
528 }
529 
getMinInterval() const530 uint64_t PlatformSensor::getMinInterval() const {
531   return mMinInterval;
532 }
533 
getSensorName() const534 const char *PlatformSensor::getSensorName() const {
535   return mSensorName;
536 }
537 
PlatformSensor(PlatformSensor && other)538 PlatformSensor::PlatformSensor(PlatformSensor&& other) {
539   // Our move assignment operator doesn't assume that "this" is initialized, so
540   // we can just use that here.
541   *this = std::move(other);
542 }
543 
operator =(PlatformSensor && other)544 PlatformSensor& PlatformSensor::operator=(PlatformSensor&& other) {
545   // Note: if this implementation is ever changed to depend on "this" containing
546   // initialized values, the move constructor implemenation must be updated.
547   mSensorType = other.mSensorType;
548   mMinInterval = other.mMinInterval;
549   memcpy(mSensorName, other.mSensorName, kSensorNameMaxLen);
550 
551   mLastEvent = other.mLastEvent;
552   other.mLastEvent = nullptr;
553 
554   mLastEventSize = other.mLastEventSize;
555   other.mLastEventSize = 0;
556 
557   mLastEventValid = other.mLastEventValid;
558   mSamplingStatus = other.mSamplingStatus;
559   mPassiveSupported = other.mPassiveSupported;
560 
561   return *this;
562 }
563 
getLastEvent() const564 ChreSensorData *PlatformSensor::getLastEvent() const {
565   return mLastEventValid ? mLastEvent : nullptr;
566 }
567 
getSamplingStatus(struct chreSensorSamplingStatus * status) const568 bool PlatformSensor::getSamplingStatus(
569     struct chreSensorSamplingStatus *status) const {
570   CHRE_ASSERT(status);
571 
572   memcpy(status, &mSamplingStatus, sizeof(*status));
573   return true;
574 }
575 
initBase(SensorType sensorType,uint64_t minInterval,const char * sensorName,ChreSensorData * lastEvent,size_t lastEventSize,bool passiveSupported)576 void PlatformSensorBase::initBase(
577     SensorType sensorType,uint64_t minInterval, const char *sensorName,
578     ChreSensorData *lastEvent, size_t lastEventSize, bool passiveSupported) {
579   mSensorType = sensorType;
580   mMinInterval = minInterval;
581   memcpy(mSensorName, sensorName, kSensorNameMaxLen);
582   mLastEvent = lastEvent;
583   mLastEventSize = lastEventSize;
584 
585   mSamplingStatus.enabled = false;
586   mSamplingStatus.interval = CHRE_SENSOR_INTERVAL_DEFAULT;
587   mSamplingStatus.latency = CHRE_SENSOR_LATENCY_DEFAULT;
588 
589   mPassiveSupported = passiveSupported;
590 }
591 
setLastEvent(const ChreSensorData * event)592 void PlatformSensorBase::setLastEvent(const ChreSensorData *event) {
593   memcpy(mLastEvent, event, mLastEventSize);
594   mLastEventValid = true;
595 }
596 
setSamplingStatus(const struct chreSensorSamplingStatus & status)597 void PlatformSensorBase::setSamplingStatus(
598     const struct chreSensorSamplingStatus& status) {
599   mSamplingStatus = status;
600 }
601 
602 }  // namespace chre
603