Home | History | Annotate | Download | only in see
      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  */
     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 
    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  */
    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  */
    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 
    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 
    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 
    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  */
    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  */
    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  */
    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  */
    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.
    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 
    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 
    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 
    409 void PlatformSensor::deinit() {
    410   SeeHelperSingleton::deinit();
    411 }
    412 
    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 
    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 
    526 SensorType PlatformSensor::getSensorType() const {
    527   return mSensorType;
    528 }
    529 
    530 uint64_t PlatformSensor::getMinInterval() const {
    531   return mMinInterval;
    532 }
    533 
    534 const char *PlatformSensor::getSensorName() const {
    535   return mSensorName;
    536 }
    537 
    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 
    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 
    564 ChreSensorData *PlatformSensor::getLastEvent() const {
    565   return mLastEventValid ? mLastEvent : nullptr;
    566 }
    567 
    568 bool PlatformSensor::getSamplingStatus(
    569     struct chreSensorSamplingStatus *status) const {
    570   CHRE_ASSERT(status);
    571 
    572   memcpy(status, &mSamplingStatus, sizeof(*status));
    573   return true;
    574 }
    575 
    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 
    592 void PlatformSensorBase::setLastEvent(const ChreSensorData *event) {
    593   memcpy(mLastEvent, event, mLastEventSize);
    594   mLastEventValid = true;
    595 }
    596 
    597 void PlatformSensorBase::setSamplingStatus(
    598     const struct chreSensorSamplingStatus& status) {
    599   mSamplingStatus = status;
    600 }
    601 
    602 }  // namespace chre
    603