138bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol/*
238bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * Copyright (C) 2016 The Android Open Source Project
338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol *
438bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * Licensed under the Apache License, Version 2.0 (the "License");
538bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * you may not use this file except in compliance with the License.
638bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * You may obtain a copy of the License at
738bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol *
838bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol *      http://www.apache.org/licenses/LICENSE-2.0
938bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol *
1038bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * Unless required by applicable law or agreed to in writing, software
1138bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * distributed under the License is distributed on an "AS IS" BASIS,
1238bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * See the License for the specific language governing permissions and
1438bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol * limitations under the License.
1538bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol */
1638bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
1748fda6e1eedf6ba80ae7596fc7676f8318a1e88eMeng-hsuan Chung#include <algorithm>
18cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol#include <cinttypes>
19cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
2053cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie#include "chre/platform/platform_sensor.h"
2153cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie
2238bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignolextern "C" {
2338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
2483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol#include "fixed_point.h"
2538bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol#include "sns_smgr_api_v01.h"
2601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung#include "sns_smgr_internal_api_v02.h"
27b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie#include "sns_usmr.h"
2883a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol#include "timetick.h"
2938bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
3038bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol}  // extern "C"
3138bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
3283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol#include "chre_api/chre/sensor.h"
33c807971625839bf4689435f24b6cacbf7dbb3de9Andrew Rossignol#include "chre/core/event_loop_manager.h"
3453cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie#include "chre/core/sensor.h"
353e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung#include "chre/platform/assert.h"
3638bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol#include "chre/platform/fatal_error.h"
3738bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol#include "chre/platform/log.h"
38eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung#include "chre/platform/system_time.h"
390d94eb2fcf599754d9a1087c3292ab6ac6495de6Andrew Rossignol#include "chre/platform/slpi/platform_sensor_util.h"
40c6ef3f619155a7f6e2f0ff5fbc77a11526d9970fMeng-hsuan Chung#include "chre/platform/slpi/smgr_client.h"
41b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie#include "chre/platform/slpi/smr_helper.h"
42b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie#include "chre/platform/slpi/uimg_util.h"
43f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung#include "chre/util/macros.h"
44f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
45a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung// As SMGR doesn't support passive sensor request, it's now implemented on the
46a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung// client (CHRE) side using a combination of the SNS_SMGR_INTERNAL_API_V02 and a
47a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung// modified SNS_SMGR_API_V01.
48a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//
49a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung// Here's a summary of its design:
50a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung// 1. A sensor status monitor is added in addSensorMonitor() to receive the
51a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//    SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02 message the first time a sensor is
52a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//    requested.
53a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung// 2. When a request is made in PlatformSensor::applyRequest(), it checkes
54a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//    whether it's allowed at that point and makes a corresponding QMI request.
55a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//    1) The request is allowed if
56a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//       - it's an active or an off request, or
57a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//       - it's a passive request and the merged mode (to be explained
58a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//         shortly) is active or there exist other SMGR clients.
59a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//    2) If the request is allowed, a QMI request to add the sensor request is
60a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//       made. Otherwise, a QMI request to remove the sensor request is made to
61a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//       handle the potential active-and-allowed to passive-and-disallowed
62a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//       transition.
63a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//    3) The merged mode of a sensor is the strongest mode of all sensor
64a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//       requests of the same sensor ID, with active > passive > off.
65a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung// 3. When SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02 from SMGR is received, a
66a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//    SNS_SMGR_CLIENT_REQUEST_INFO_REQ_V01 message is sent to query SMGR on the
67a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//    existence of other clients.
68a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//    - If a transition from absence-to-presence of other clients is detected,
69a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//      all pending passive requests are made.
70a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//    - If a transition from presence-to-absence of other clients is deteted,
71a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung//      all passive requests are removed if the merged mode is passive.
729b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung//
739b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung// Note that currently the sensor status monitor indication only supports
749b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung// primary sensor status change. So for a secondary sensor that can be requested
759b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung// without an accompanying primary sensor (Light), this design doesn't work.
769b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung// In PlatformSensor::applyRequest(), a passive Light sensor request is
779b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung// overridden to be an active one.
7880b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
7901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungnamespace chre {
8080b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignolnamespace {
8180b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
82f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung//! The constant used to convert from SMGR to Android unit for magnetometer.
8301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungconstexpr float kMicroTeslaPerGauss = 100.0f;
8401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
85f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung//! The maximum number of CHRE sensors that share the same SMGR sensor ID.
86f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chungconstexpr size_t kMaxNumSensorsPerSensorId = 3;
87f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
882b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung//! The value to override a default interval request.
892b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chungconstexpr uint64_t kDefaultInterval = Seconds(1).toRawNanoseconds();
902b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung
91eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung//! The offset in nanoseconds each 32-bit tick rollover introduces in timestamp
92eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chungconstexpr uint64_t kTickRolloverOffset =
93eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung    ((1ULL << 32) * Seconds(1).toRawNanoseconds()) / TIMETICK_NOMINAL_FREQ_HZ;
94eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung
95b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddiesmr_client_hndl gPlatformSensorServiceSmrClientHandle;
96b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddiesmr_client_hndl gPlatformSensorInternalServiceSmrClientHandle;
9783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
98f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung//! A struct to store the number of SMGR clients of a sensor ID.
99f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chungstruct SensorMonitor {
10001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  uint8_t sensorId;
101a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung  bool otherClientPresent;
10201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung};
10338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
104f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung//! A vector that tracks the SensorMonitor of each supported sensor ID.
105f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan ChungDynamicVector<SensorMonitor> gSensorMonitors;
106f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
107f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung//! Forward declarations
108c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chungbool makeAllPendingRequests(uint8_t sensorId);
109c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chungbool removeAllPassiveRequests(uint8_t sensorId);
110f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
111f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
112f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * Obtains the element index of gSensorMonitors that corresponds to the
113f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * specified sensor ID. If it's not present, gSensorMonitors.size() is returned.
114f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
115f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @return The index of the element that belongs to sensorId.
116f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
117f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chungsize_t getSensorMonitorIndex(uint8_t sensorId) {
118f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  size_t i;
119f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  for (i = 0; i < gSensorMonitors.size(); i++) {
120f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    if (gSensorMonitors[i].sensorId == sensorId) {
121f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      break;
122f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    }
123f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  }
124f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  return i;
125f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung}
1269c8f6eb9f3429b0b8369e546ce2493b6c8829839Meng-hsuan Chung
12780b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol/**
128ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Converts a sensorId, dataType and calType as provided by SMGR to a
129ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * SensorType as used by platform-independent CHRE code. This is useful in
130ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * sensor discovery.
13183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *
13283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param sensorId The sensorID as provided by the SMGR request for sensor info.
13383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param dataType The dataType for the sesnor as provided by the SMGR request
13483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *                 for sensor info.
135ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
136ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @return Returns the platform-independent sensor type or Unknown if no
13783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *         match is found.
13883a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol */
139ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan ChungSensorType getSensorTypeFromSensorId(uint8_t sensorId, uint8_t dataType,
140ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung                                     uint8_t calType) {
141cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  // Here be dragons. These constants below are defined in
142cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  // sns_smgr_common_v01.h. Refer to the section labelled "Define sensor
143cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  // identifier" for more details. This function relies on the ordering of
144cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  // constants provided by their API. Do not change these values without care.
145cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  // You have been warned!
146cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  if (dataType == SNS_SMGR_DATA_TYPE_PRIMARY_V01) {
147cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    if (sensorId >= SNS_SMGR_ID_ACCEL_V01
148cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        && sensorId < SNS_SMGR_ID_GYRO_V01) {
149ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      if (calType == SNS_SMGR_CAL_SEL_FULL_CAL_V01) {
150ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::Accelerometer;
151ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      } else if (calType == SNS_SMGR_CAL_SEL_FACTORY_CAL_V01) {
152ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::UncalibratedAccelerometer;
153ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      }
154cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    } else if (sensorId >= SNS_SMGR_ID_GYRO_V01
155cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        && sensorId < SNS_SMGR_ID_MAG_V01) {
156ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      if (calType == SNS_SMGR_CAL_SEL_FULL_CAL_V01) {
157ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::Gyroscope;
158ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      } else if (calType == SNS_SMGR_CAL_SEL_FACTORY_CAL_V01) {
159ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::UncalibratedGyroscope;
160ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      }
161cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    } else if (sensorId >= SNS_SMGR_ID_MAG_V01
162cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        && sensorId < SNS_SMGR_ID_PRESSURE_V01) {
163ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      if (calType == SNS_SMGR_CAL_SEL_FULL_CAL_V01) {
164ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::GeomagneticField;
165ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      } else if (calType == SNS_SMGR_CAL_SEL_FACTORY_CAL_V01) {
166ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        return SensorType::UncalibratedGeomagneticField;
167ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      }
168cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    } else if (sensorId >= SNS_SMGR_ID_PRESSURE_V01
169cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        && sensorId < SNS_SMGR_ID_PROX_LIGHT_V01) {
170cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      return SensorType::Pressure;
171cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    } else if (sensorId >= SNS_SMGR_ID_PROX_LIGHT_V01
172cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        && sensorId < SNS_SMGR_ID_HUMIDITY_V01) {
173cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      return SensorType::Proximity;
17469fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    } else if (sensorId == SNS_SMGR_ID_OEM_SENSOR_09_V01) {
17569fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung      return SensorType::StationaryDetect;
17669fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    } else if (sensorId == SNS_SMGR_ID_OEM_SENSOR_10_V01) {
17769fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung      return SensorType::InstantMotion;
178cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    }
179cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  } else if (dataType == SNS_SMGR_DATA_TYPE_SECONDARY_V01) {
180ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    if (sensorId >= SNS_SMGR_ID_ACCEL_V01
181ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        && sensorId < SNS_SMGR_ID_GYRO_V01) {
182ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      return SensorType::AccelerometerTemperature;
183ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    } else if (sensorId >= SNS_SMGR_ID_GYRO_V01
184ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        && sensorId < SNS_SMGR_ID_MAG_V01) {
185ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      return SensorType::GyroscopeTemperature;
186ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    } else if ((sensorId >= SNS_SMGR_ID_PROX_LIGHT_V01
187ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        && sensorId < SNS_SMGR_ID_HUMIDITY_V01)
188cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        || (sensorId >= SNS_SMGR_ID_ULTRA_VIOLET_V01
189cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol            && sensorId < SNS_SMGR_ID_OBJECT_TEMP_V01)) {
190cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      return SensorType::Light;
191cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    }
192cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  }
193cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
194cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  return SensorType::Unknown;
195cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol}
196cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol
197cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol/**
198ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Converts a reportId as provided by SMGR to a SensorType.
199ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
200ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param reportId The reportID as provided by the SMGR buffering index.
201ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @return Returns the sensorType that corresponds to the reportId.
202ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
203ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan ChungSensorType getSensorTypeFromReportId(uint8_t reportId) {
204ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  SensorType sensorType;
205ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  if (reportId < static_cast<uint8_t>(SensorType::SENSOR_TYPE_COUNT)) {
206ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorType = static_cast<SensorType>(reportId);
207ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  } else {
208ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorType = SensorType::Unknown;
209ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  }
210ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  return sensorType;
211ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
212ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
213ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
214ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Converts a PlatformSensor to a unique report ID through SensorType. This is
215ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * useful in making sensor request.
216ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
217ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param sensorId The sensorID as provided by the SMGR request for sensor info.
218ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param dataType The dataType for the sesnor as provided by the SMGR request
219ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *                 for sensor info.
220ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
221ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @return Returns a unique report ID that is based on SensorType.
222ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
223ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chunguint8_t getReportId(uint8_t sensorId, uint8_t dataType, uint8_t calType) {
224ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  SensorType sensorType = getSensorTypeFromSensorId(
225ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      sensorId, dataType, calType);
226ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
227ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  CHRE_ASSERT_LOG(sensorType != SensorType::Unknown,
228ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung                  "sensorId %" PRIu8 ", dataType %" PRIu8 ", calType %" PRIu8,
229ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung                  sensorId, dataType, calType);
230ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  return static_cast<uint8_t>(sensorType);
231ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
232ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
233ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
234ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Checks whether the corresponding sensor is a sencondary temperature sensor.
235ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
236ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param reportId The reportID as provided by the SMGR buffering index.
237ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @return true if the sensor is a secondary temperature sensor.
238ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
239ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungbool isSecondaryTemperature(uint8_t reportId) {
240ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  SensorType sensorType = getSensorTypeFromReportId(reportId);
241ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  return (sensorType == SensorType::AccelerometerTemperature
242ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung          || sensorType == SensorType::GyroscopeTemperature);
243ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
244ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
245ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
246ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Verifies whether the buffering index's report ID matches the expected
247ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * indices length.
248ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
249ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @return true if it's a valid pair of indices length and report ID.
250ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
251b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddiebool isValidIndicesLength(
252b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg) {
253b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  return ((bufferingIndMsg.Indices_len == 1
254b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie           && !isSecondaryTemperature(bufferingIndMsg.ReportId))
255b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          || (bufferingIndMsg.Indices_len == 2
256b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie              && isSecondaryTemperature(bufferingIndMsg.ReportId)));
257ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
258ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
259ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
26067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung * Allocates memory and specifies the memory size for an on-change sensor to
26167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung * store its last data event.
26267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung *
26367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung * @param sensorType The sensorType of this sensor.
26467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung * @param eventSize A non-null pointer to indicate the memory size allocated.
26567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung * @return Pointer to the memory allocated.
26667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung */
26767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan ChungChreSensorData *allocateLastEvent(SensorType sensorType, size_t *eventSize) {
26867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  CHRE_ASSERT(eventSize);
26967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
27067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  *eventSize = 0;
27167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  ChreSensorData *event = nullptr;
27267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  if (sensorTypeIsOnChange(sensorType)) {
27367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    SensorSampleType sampleType = getSensorSampleTypeFromSensorType(sensorType);
27467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    switch (sampleType) {
27567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      case SensorSampleType::ThreeAxis:
27667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        *eventSize = sizeof(chreSensorThreeAxisData);
27767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        break;
27867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      case SensorSampleType::Float:
27967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        *eventSize = sizeof(chreSensorFloatData);
28067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        break;
28167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      case SensorSampleType::Byte:
28267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        *eventSize = sizeof(chreSensorByteData);
28367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        break;
28467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      case SensorSampleType::Occurrence:
28567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        *eventSize = sizeof(chreSensorOccurrenceData);
28667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        break;
28767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      default:
28867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        CHRE_ASSERT_LOG(false, "Unhandled sample type");
28967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        break;
29067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    }
29167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
29267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    event = static_cast<ChreSensorData *>(memoryAlloc(*eventSize));
29367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    if (event == nullptr) {
29467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      *eventSize = 0;
29567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      FATAL_ERROR("Failed to allocate last event memory for SensorType %d",
29667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung                  static_cast<int>(sensorType));
29767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    }
29867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  }
29967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  return event;
30067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung}
30167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
30267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung/**
30353cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie * Constructs and initializes a sensor, and adds it to the sensor list.
304ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
305e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung * @param sensorInfo The sensorInfo as provided by the SMGR.
306ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
307ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param sensor The sensor list.
308ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
30953cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddievoid addSensor(const sns_smgr_sensor_datatype_info_s_v01& sensorInfo,
31053cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie               uint8_t calType, DynamicVector<Sensor> *sensors) {
31153cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  Sensor sensor;
31253cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  sensor.sensorId = sensorInfo.SensorID;
31353cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  sensor.dataType = sensorInfo.DataType;
31453cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  sensor.calType = calType;
31553cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  size_t bytesToCopy = std::min(sizeof(sensor.sensorName) - 1,
31648fda6e1eedf6ba80ae7596fc7676f8318a1e88eMeng-hsuan Chung                                static_cast<size_t>(sensorInfo.SensorName_len));
31753cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  memcpy(sensor.sensorName, sensorInfo.SensorName, bytesToCopy);
31853cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  sensor.sensorName[bytesToCopy] = '\0';
31967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
320e349e7416181e31b019ca9004e881b22bab60ed3Meng-hsuan Chung  // Override one-shot sensor's minInterval to default
32167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  SensorType sensorType = getSensorTypeFromSensorId(
32267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      sensorInfo.SensorID, sensorInfo.DataType, calType);
3232323f21e236e76969531c1afcafa026d219e82a2Meng-hsuan Chung  sensor.minInterval = sensorTypeIsOneShot(sensorType) ?
324e349e7416181e31b019ca9004e881b22bab60ed3Meng-hsuan Chung      CHRE_SENSOR_INTERVAL_DEFAULT : static_cast<uint64_t>(
325e349e7416181e31b019ca9004e881b22bab60ed3Meng-hsuan Chung          Seconds(1).toRawNanoseconds() / sensorInfo.MaxSampleRate);
326e349e7416181e31b019ca9004e881b22bab60ed3Meng-hsuan Chung
327e349e7416181e31b019ca9004e881b22bab60ed3Meng-hsuan Chung  // Allocates memory for on-change sensor's last event.
32853cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  sensor.lastEvent = allocateLastEvent(sensorType, &sensor.lastEventSize);
32967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
3306797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  sensor.isSensorOff = true;
3316797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  sensor.samplingStatus.enabled = false;
3326797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  sensor.samplingStatus.interval = CHRE_SENSOR_INTERVAL_DEFAULT;
3336797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  sensor.samplingStatus.latency = CHRE_SENSOR_LATENCY_DEFAULT;
3346797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung
33553cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  if (!sensors->push_back(std::move(sensor))) {
336ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    FATAL_ERROR("Failed to allocate new sensor: out of memory");
337ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  }
338ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
339ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
340ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
34183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * Converts SMGR ticks to nanoseconds as a uint64_t.
34283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *
34383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param ticks The number of ticks.
34483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @return The number of nanoseconds represented by the ticks value.
34583a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol */
34683a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignoluint64_t getNanosecondsFromSmgrTicks(uint32_t ticks) {
34753cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  return (ticks * Seconds(1).toRawNanoseconds()) / TIMETICK_NOMINAL_FREQ_HZ;
34883a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol}
34983a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
350ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungvoid populateSensorDataHeader(
351ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    SensorType sensorType, chreSensorDataHeader *header,
352ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
353eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung  // Compensate for header timestamp's 32-bit rollovers
354eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung  uint64_t slpiTime = SystemTime::getMonotonicTime().toRawNanoseconds();
355eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung  uint64_t baseTime = getNanosecondsFromSmgrTicks(
356ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      sensorIndex.FirstSampleTimestamp);
357eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung  while (slpiTime > baseTime + kTickRolloverOffset / 2) {
358eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung    baseTime += kTickRolloverOffset;
359eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung  }
360bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung  memset(header->reserved, 0, sizeof(header->reserved));
361eef8a43284e93de1b5a38426d6f8687d0a009b00Meng-hsuan Chung  header->baseTimestamp = baseTime;
362bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung  header->sensorHandle = getSensorHandleFromSensorType(sensorType);
363ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  header->readingCount = sensorIndex.SampleCount;
364bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung}
365bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
366ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungvoid populateThreeAxisEvent(
367b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg,
368ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    SensorType sensorType, chreSensorThreeAxisData *data,
369ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
370ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  populateSensorDataHeader(sensorType, &data->header, sensorIndex);
3713e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
372ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
3733e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    const sns_smgr_buffering_sample_s_v01& sensorData =
374b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        bufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
3753e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
3763e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    // TimeStampOffset has max value of < 2 sec so it will not overflow here.
3773e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    data->readings[i].timestampDelta =
3783e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung        getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
3793e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
3803e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    // Convert from SMGR's NED coordinate to Android coordinate.
38101bfb64846ac21a263d47e1956a04c6063beac75Andrew Rossignol    data->readings[i].x = FX_FIXTOFLT_Q16_SP(sensorData.Data[1]);
38201bfb64846ac21a263d47e1956a04c6063beac75Andrew Rossignol    data->readings[i].y = FX_FIXTOFLT_Q16_SP(sensorData.Data[0]);
38301bfb64846ac21a263d47e1956a04c6063beac75Andrew Rossignol    data->readings[i].z = -FX_FIXTOFLT_Q16_SP(sensorData.Data[2]);
3843e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
3853e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    // Convert from Gauss to micro Tesla
386ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    if (sensorType == SensorType::GeomagneticField
387ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung        || sensorType == SensorType::UncalibratedGeomagneticField) {
3883e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      data->readings[i].x *= kMicroTeslaPerGauss;
3893e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      data->readings[i].y *= kMicroTeslaPerGauss;
3903e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      data->readings[i].z *= kMicroTeslaPerGauss;
3913e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    }
3929c8f6eb9f3429b0b8369e546ce2493b6c8829839Meng-hsuan Chung  }
393bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung}
394bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
395ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungvoid populateFloatEvent(
396b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg,
397ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    SensorType sensorType, chreSensorFloatData *data,
398ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
399ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  populateSensorDataHeader(sensorType, &data->header, sensorIndex);
4003e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
401ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
4023e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    const sns_smgr_buffering_sample_s_v01& sensorData =
403b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        bufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
4043e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung
4053e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    // TimeStampOffset has max value of < 2 sec so it will not overflow.
4063e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    data->readings[i].timestampDelta =
4073e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung        getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
40801bfb64846ac21a263d47e1956a04c6063beac75Andrew Rossignol    data->readings[i].value = FX_FIXTOFLT_Q16_SP(sensorData.Data[0]);
4093e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung  }
410bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung}
411bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
41290db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chungvoid populateByteEvent(
413b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg,
41490db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    SensorType sensorType, chreSensorByteData *data,
41590db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
41690db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung  populateSensorDataHeader(sensorType, &data->header, sensorIndex);
41790db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung
41890db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung  for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
41990db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    const sns_smgr_buffering_sample_s_v01& sensorData =
420b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        bufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
42190db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung
42290db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    // TimeStampOffset has max value of < 2 sec so it will not overflow.
42390db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    data->readings[i].timestampDelta =
42490db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung        getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
42590db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    // Zero out fields invalid and padding0.
42690db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    data->readings[i].value = 0;
42790db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    // SMGR reports 1 in Q16 for near, and 0 for far.
42890db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    data->readings[i].isNear = sensorData.Data[0] ? 1 : 0;
42990db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung  }
43090db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung}
43190db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung
43269fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chungvoid populateOccurrenceEvent(
433b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg,
43469fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    SensorType sensorType, chreSensorOccurrenceData *data,
43569fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
43669fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung  populateSensorDataHeader(sensorType, &data->header, sensorIndex);
43769fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung
43869fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung  for (size_t i = 0; i < sensorIndex.SampleCount; i++) {
43969fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    const sns_smgr_buffering_sample_s_v01& sensorData =
440b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        bufferingIndMsg.Samples[i + sensorIndex.FirstSampleIdx];
44169fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung
44269fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    // TimeStampOffset has max value of < 2 sec so it will not overflow.
44369fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    data->readings[i].timestampDelta =
44469fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung        getNanosecondsFromSmgrTicks(sensorData.TimeStampOffset);
44569fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung  }
44669fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung}
44769fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung
44869fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung/**
449bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung * Allocate event memory according to SensorType and populate event readings.
450bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung */
451ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungvoid *allocateAndPopulateEvent(
452b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg,
453ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    SensorType sensorType,
454ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    const sns_smgr_buffering_sample_index_s_v01& sensorIndex) {
455bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung  SensorSampleType sampleType = getSensorSampleTypeFromSensorType(sensorType);
4563e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung  size_t memorySize = sizeof(chreSensorDataHeader);
457bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung  switch (sampleType) {
458bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung    case SensorSampleType::ThreeAxis: {
459ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      memorySize += sensorIndex.SampleCount *
4603e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung          sizeof(chreSensorThreeAxisData::chreSensorThreeAxisSampleData);
4613e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      auto *event =
4623e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung          static_cast<chreSensorThreeAxisData *>(memoryAlloc(memorySize));
463bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      if (event != nullptr) {
464b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        populateThreeAxisEvent(bufferingIndMsg, sensorType, event, sensorIndex);
465bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      }
466bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      return event;
467bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung    }
468bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
469bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung    case SensorSampleType::Float: {
470ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung      memorySize += sensorIndex.SampleCount *
4713e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung          sizeof(chreSensorFloatData::chreSensorFloatSampleData);
4723e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      auto *event =
4733e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung          static_cast<chreSensorFloatData *>(memoryAlloc(memorySize));
474bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      if (event != nullptr) {
475b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        populateFloatEvent(bufferingIndMsg, sensorType, event, sensorIndex);
476bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      }
477bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      return event;
478bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung    }
479bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
48090db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    case SensorSampleType::Byte: {
48190db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung      memorySize += sensorIndex.SampleCount *
48290db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung          sizeof(chreSensorByteData::chreSensorByteSampleData);
48390db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung      auto *event =
48490db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung          static_cast<chreSensorByteData *>(memoryAlloc(memorySize));
48590db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung      if (event != nullptr) {
486b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        populateByteEvent(bufferingIndMsg, sensorType, event, sensorIndex);
48790db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung      }
48890db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung      return event;
48990db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung    }
49090db64e2ff34e67d967abf755c9dc2dd9a715079Meng-hsuan Chung
49169fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    case SensorSampleType::Occurrence: {
49269fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung      memorySize += sensorIndex.SampleCount *
49369fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung          sizeof(chreSensorOccurrenceData::chreSensorOccurrenceSampleData);
49469fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung      auto *event =
49569fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung          static_cast<chreSensorOccurrenceData *>(memoryAlloc(memorySize));
49669fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung      if (event != nullptr) {
497b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        populateOccurrenceEvent(
498b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie            bufferingIndMsg, sensorType, event, sensorIndex);
49969fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung      }
50069fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung      return event;
50169fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    }
50269fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung
503bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung    default:
504837bdb95b56d493cecad8d47f7fe113227056192Arthur Ishiguro      LOGW("Unhandled sensor data %" PRIu8, static_cast<uint8_t>(sensorType));
505bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung      return nullptr;
506bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung  }
507bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung}
508bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung
50967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chungvoid smgrSensorDataEventFree(uint16_t eventType, void *eventData) {
51067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  // Events are allocated using the simple memoryAlloc/memoryFree platform
51167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  // functions.
51267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  // TODO: Consider using a MemoryPool.
51367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  memoryFree(eventData);
51467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
51567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  // Remove all requests if it's a one-shot sensor and only after data has been
51667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  // delivered to all clients.
51767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  SensorType sensorType = getSensorTypeForSampleEventType(eventType);
51867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  if (sensorTypeIsOneShot(sensorType)) {
51967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    EventLoopManagerSingleton::get()->getSensorRequestManager()
52067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        .removeAllRequests(sensorType);
52167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  }
52267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung}
52367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
52467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung/**
52553cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie * A helper function that updates the last event of a sensor in the main thread.
52667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung * Platform should call this function only for an on-change sensor.
52767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung *
52867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung * @param sensorType The SensorType of the sensor.
52967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung * @param eventData A non-null pointer to the sensor's CHRE event data.
53067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung */
53167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chungvoid updateLastEvent(SensorType sensorType, const void *eventData) {
53267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  CHRE_ASSERT(eventData);
53367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
53467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  auto *header = static_cast<const chreSensorDataHeader *>(eventData);
53567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  if (header->readingCount != 1) {
53667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    // TODO: better error handling when SMGR behavior changes.
53767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    // SMGR delivers one sample per report for on-change sensors.
53867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    LOGE("%" PRIu16 " samples in an event for on-change sensor %d",
53967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung         header->readingCount, static_cast<int>(sensorType));
54067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  } else {
54167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    struct CallbackData {
54267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      SensorType sensorType;
54367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      const ChreSensorData *event;
54467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    };
54567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    auto *callbackData = memoryAlloc<CallbackData>();
54667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    if (callbackData == nullptr) {
54767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      LOGE("Failed to allocate deferred callback memory");
54867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    } else {
54967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      callbackData->sensorType = sensorType;
55067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      callbackData->event = static_cast<const ChreSensorData *>(eventData);
55167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
55267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      auto callback = [](uint16_t /* type */, void *data) {
55367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        auto *cbData = static_cast<CallbackData *>(data);
55467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
55567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        Sensor *sensor = EventLoopManagerSingleton::get()
55667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung            ->getSensorRequestManager().getSensor(cbData->sensorType);
55753cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie
55853cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie        // Mark last event as valid only if the sensor is enabled. Event data
55953cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie        // may arrive after sensor is disabled.
56053cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie        if (sensor != nullptr
56153cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie            && sensor->getRequest().getMode() != SensorMode::Off) {
56267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung          sensor->setLastEvent(cbData->event);
56367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        }
56467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        memoryFree(cbData);
56567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      };
56667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
56767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      // Schedule a deferred callback.
56867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      if (!EventLoopManagerSingleton::get()->deferCallback(
56967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung          SystemCallbackType::SensorLastEventUpdate, callbackData, callback)) {
57067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        LOGE("Failed to schedule a deferred callback for sensorType %d",
57167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung             static_cast<int>(sensorType));
57267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung        memoryFree(callbackData);
57367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung      }
57467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    }  // if (callbackData == nullptr)
57567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  }
57667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung}
57767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
578bf7f9e866c31f63b321172dec0a8d8037aa2460bMeng-hsuan Chung/**
57901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * Handles sensor data provided by the SMGR framework.
58083a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *
581b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param bufferingIndMsg Decoded buffering indication message
58283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol */
583b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddievoid handleSensorDataIndication(
584b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    const sns_smgr_buffering_ind_msg_v01& bufferingIndMsg) {
585b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  // We only requested one sensor per request except for a secondary
586b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  // temperature sensor.
587b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  bool validReport = isValidIndicesLength(bufferingIndMsg);
588b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  CHRE_ASSERT_LOG(validReport,
589b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie                  "Got buffering indication from %" PRIu32
590b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie                  " sensors with report ID %" PRIu8,
591b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie                  bufferingIndMsg.Indices_len,
592b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie                  bufferingIndMsg.ReportId);
593b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (validReport) {
594b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // Identify the index for the desired sensor. It is always 0 except
595b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // possibly for a secondary temperature sensor.
596b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    uint32_t index = 0;
597b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    if (isSecondaryTemperature(bufferingIndMsg.ReportId)) {
598b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      index = (bufferingIndMsg.Indices[0].DataType
599b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie               == SNS_SMGR_DATA_TYPE_SECONDARY_V01) ? 0 : 1;
600b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    }
601b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    const sns_smgr_buffering_sample_index_s_v01& sensorIndex =
602b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        bufferingIndMsg.Indices[index];
603b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
604b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // Use ReportID to identify sensors as
605b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // bufferingIndMsg.Samples[i].Flags are not populated.
606b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    SensorType sensorType = getSensorTypeFromReportId(
607b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        bufferingIndMsg.ReportId);
608b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    if (sensorType == SensorType::Unknown) {
609b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      LOGW("Received sensor sample for unknown sensor %" PRIu8 " %" PRIu8,
610b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie           sensorIndex.SensorId, sensorIndex.DataType);
611b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    } else if (sensorIndex.SampleCount == 0) {
612b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      LOGW("Received sensorType %d event with 0 sample",
613b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie           static_cast<int>(sensorType));
614b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    } else {
615b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      void *eventData = allocateAndPopulateEvent(
616b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          bufferingIndMsg, sensorType, sensorIndex);
617b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      if (eventData == nullptr) {
618b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        LOGW("Dropping event due to allocation failure");
61983a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol      } else {
620b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        // Schedule a deferred callback to update on-change sensor's last
621b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        // event in the main thread.
622b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        if (sensorTypeIsOnChange(sensorType)) {
623b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          updateLastEvent(sensorType, eventData);
62401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        }
625b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
626b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        EventLoopManagerSingleton::get()->getEventLoop().postEvent(
627b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie            getSampleEventTypeForSensorType(sensorType), eventData,
628b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie            smgrSensorDataEventFree);
62983a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol      }
630b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    }
631b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  }  // if (validReport)
63283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol}
63383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
63483a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol/**
635b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * This callback is invoked by the SMR framework when an asynchronous message is
636b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * delivered. Unhandled messages are logged.
63783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *
638b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param handle Handle for the SMR client this indication was received on.
639b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param messageId The message ID number.
640b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param buffer Buffer containing decoded (C struct) message data.
641b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param bufferLength Size of the decoded buffer in bytes.
64283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol * @param callbackData Data that is provided as a context to this callback. This
64383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol *                     is not used in this context.
644b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie *
645b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @see smr_client_ind_cb
64683a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol */
647b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddievoid platformSensorServiceIndicationCallback(
648b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    smr_client_hndl handle, unsigned int messageId, void *decodedInd,
649b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    unsigned int decodedIndLen, void *callbackData) {
65083a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  switch (messageId) {
651b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    case SNS_SMGR_BUFFERING_IND_V01: {
652b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      CHRE_ASSERT(decodedIndLen >= sizeof(sns_smgr_buffering_ind_msg_v01));
653b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      auto *bufferingInd =
654b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          static_cast<sns_smgr_buffering_ind_msg_v01 *>(decodedInd);
655b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      handleSensorDataIndication(*bufferingInd);
65683a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol      break;
657b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    }
65883a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol    default:
65901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      LOGW("Received unhandled sensor service message: 0x%x", messageId);
66083a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol      break;
66183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  };
66283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol}
66383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
664f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
665f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * Populates the supplied SensorTypes array with SensorTypes of the specified
666f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * sensor ID.
667f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
668f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorId The sensor ID as provided by the SMGR.
669f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorTypes A non-null pointer to a SensorType array of size at least
670f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *        kMaxNumSensorsPerSensorId.
671f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
672f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chungsize_t populateSensorTypeArrayFromSensorId(uint8_t sensorId,
673f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung                                           SensorType *sensorTypes) {
674f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  static_assert(kMaxNumSensorsPerSensorId >= 3,
675f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung                "This function assumes kMaxNumSensorsPerSensorId >= 3");
676f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  CHRE_ASSERT(sensorTypes);
677f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
678f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  size_t numSensorTypes = 0;
679f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  if (sensorTypes != nullptr) {
680f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    if (sensorId >= SNS_SMGR_ID_ACCEL_V01
681f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung          && sensorId < SNS_SMGR_ID_GYRO_V01) {
682f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorTypes[0] = SensorType::Accelerometer;
683f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorTypes[1] = SensorType::UncalibratedAccelerometer;
684f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorTypes[2] = SensorType::AccelerometerTemperature;
685f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      numSensorTypes = 3;
686f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    } else if (sensorId >= SNS_SMGR_ID_GYRO_V01
687f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung          && sensorId < SNS_SMGR_ID_MAG_V01) {
688f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorTypes[0] = SensorType::Gyroscope;
689f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorTypes[1] = SensorType::UncalibratedGyroscope;
690f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorTypes[2] = SensorType::GyroscopeTemperature;
691f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      numSensorTypes = 3;
692f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    } else if (sensorId >= SNS_SMGR_ID_MAG_V01
693f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung          && sensorId < SNS_SMGR_ID_PRESSURE_V01) {
694f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorTypes[0] = SensorType::GeomagneticField;
695f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorTypes[1] = SensorType::UncalibratedGeomagneticField;
696f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      numSensorTypes = 2;
697f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    } else {
698f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      SensorType sensorType = getSensorTypeFromSensorId(sensorId,
699f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung          SNS_SMGR_DATA_TYPE_PRIMARY_V01, SNS_SMGR_CAL_SEL_FULL_CAL_V01);
700f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      if (sensorType != SensorType::Unknown) {
701f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung        sensorTypes[0] = sensorType;
702f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung        numSensorTypes = 1;
703f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      }
70401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    }
70583a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  }
706f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  return numSensorTypes;
70701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
70883a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
709f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
710f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * Obtains the merged SensorMode of the specified sensor ID, with sensorType's
711f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * sensor request replaced by the supplied request.
712f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
713f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorId The sensor ID as provided by the SMGR.
714f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorType The SensorType whose sensor request is to be replaced by
715f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *        the supplied request.
716f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param request The sensor request to replace the existing one.
717f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @return The merged SensorMode.
718f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
719f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan ChungSensorMode getMergedMode(uint8_t sensorId, SensorType sensorType,
720f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung                         const SensorRequest& request) {
721f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  // Identify sensor requests to merge
722f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  SensorType sensorTypes[kMaxNumSensorsPerSensorId];
723f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
724f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorId, sensorTypes);
725f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
726f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  // merge requests
727f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  SensorRequest mergedRequest;
728f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  for (size_t i = 0; i < numSensorTypes; i++) {
729f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    const Sensor *sensor = EventLoopManagerSingleton::get()
730f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      ->getSensorRequestManager().getSensor(sensorTypes[i]);
731f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    if (sensor != nullptr) {
732f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      mergedRequest.mergeWith(
733f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung          (sensorTypes[i] == sensorType) ? request : sensor->getRequest());
734f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    }
735f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  }
736f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  return mergedRequest.getMode();
737f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung}
738f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
739f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
740a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung * Makes or removes passive sensor requests when the presence of other SMGR
741a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung * clients changes.
742f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
743f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorID The sensor ID being monitored.
744a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung * @param otherClientPresent The presence of other SMGR clients.
745f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
746a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chungvoid onOtherClientPresenceChange(uint8_t sensorId, bool otherClientPresent) {
747a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung  bool makeAllRequests = otherClientPresent;
748a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung
749f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  SensorRequest dummyRequest;
750f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  SensorMode mode = getMergedMode(sensorId, SensorType::Unknown, dummyRequest);
751a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung  bool removeAllRequests = (sensorModeIsPassive(mode) && !otherClientPresent);
752a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung
753b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  bool requestMade = false;
754f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  if (makeAllRequests) {
755b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    requestMade = makeAllPendingRequests(sensorId);
756f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  } else if (removeAllRequests) {
757b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    requestMade = removeAllPassiveRequests(sensorId);
758c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chung  }
759c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chung
760b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (requestMade) {
761a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung    LOGD("%s: id %" PRIu8 ", otherClientPresent %d, mode %d",
762a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung         makeAllRequests ? "+" : "-", sensorId, otherClientPresent,
763a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung         static_cast<size_t>(mode));
764f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  }
765f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung}
766f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
767f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
768f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * Processes sensor status monitor indication message.
769f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
770f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param status The new sensor status indication from SMGR
771f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
772f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chungvoid onStatusChange(const sns_smgr_sensor_status_monitor_ind_msg_v02& status) {
773f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  size_t index = getSensorMonitorIndex(status.sensor_id);
774f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  if (index == gSensorMonitors.size()) {
775f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    LOGE("Sensor status monitor update of invalid sensor ID %" PRIu64,
776f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung         status.sensor_id);
777f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  } else {
778a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung    // Use asynchronous sensor status monitor indication message as a cue to
779a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung    // query and obtain the synchronous client request info.
780a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung    // As the info conveyed in the indication is asynchronous from current
781a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung    // status and is insufficient to determine other clients' status, relying on
782a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung    // it to enable/disable passive sensors may put the system in an incorrect
783a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung    // state or lead to a request loop.
784b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    auto infoRequest =
785b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        MakeUniqueZeroFill<sns_smgr_client_request_info_req_msg_v01>();
786b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    auto infoResponse = MakeUnique<sns_smgr_client_request_info_resp_msg_v01>();
787a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung
788b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    if (infoRequest.isNull() || infoResponse.isNull()) {
789b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      LOGE("Failed to allocate client request info message");
790b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    } else {
791b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      infoRequest->sensor_id = status.sensor_id;
792b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
793b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      smr_err smrStatus = getSmrHelper()->sendReqSync(
794b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          gPlatformSensorServiceSmrClientHandle,
795b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          SNS_SMGR_CLIENT_REQUEST_INFO_REQ_V01,
796b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          &infoRequest, &infoResponse);
797b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
798b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      if (smrStatus != SMR_NO_ERR) {
799b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        LOGE("Error requesting client request info: %d", smrStatus);
800b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      } else if (infoResponse->resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
801b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        LOGE("Client request info failed with error: %" PRIu8 ", id %" PRIu8,
802b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie             infoResponse->resp.sns_err_t, infoRequest->sensor_id);
803b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      }
804b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
805b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      bool otherClientPresent = infoResponse->other_client_present;
806b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      if (gSensorMonitors[index].otherClientPresent != otherClientPresent) {
807b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        onOtherClientPresenceChange(status.sensor_id, otherClientPresent);
808b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        gSensorMonitors[index].otherClientPresent = otherClientPresent;
809b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      }
81001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    }
81101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
81201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
81301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
81486bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung/**
81586bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung * Posts a CHRE_EVENT_SENSOR_SAMPLING_CHANGE event to the specified Nanoapp.
81686bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung *
81786bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung * @param instaceId The instance ID of the nanoapp with an open request
81886bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung * @param eventRef A reference of the sampling status event to be posted.
81986bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung */
82086bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chungvoid postSamplingStatusEvent(uint32_t instanceId, uint32_t sensorHandle,
82186bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung                             const struct chreSensorSamplingStatus& status) {
82286bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung  // TODO: add a generic reference counted pointer class and use it for Event
82386bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung  // to share across interested nanoapps.
82486bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung  auto *event = memoryAlloc<struct chreSensorSamplingStatusEvent>();
82586bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung  if (event == nullptr) {
82686bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung    LOGE("Failed to allocate memory for sampling status change event");
82786bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung  } else {
82886bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung    event->sensorHandle = sensorHandle;
82986bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung    memcpy(&event->status, &status, sizeof(event->status));
83086bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung
83186bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung    if (!EventLoopManagerSingleton::get()->getEventLoop().postEvent(
83286bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung            CHRE_EVENT_SENSOR_SAMPLING_CHANGE, event, freeEventDataCallback,
83386bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung            kSystemInstanceId, instanceId)) {
83486bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung      LOGE("Failed to post sampling status change event");
83586bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung    }
83686bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung  }
8376797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung}
8386797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung
8396797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung/**
840b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * Updates the sampling status after the sensor request is accepted by SMGR.
8416797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung */
8426797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chungvoid updateSamplingStatus(Sensor *sensor, const SensorRequest& request) {
8436797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  // With SMGR's implementation, sampling interval will be filtered to be the
844a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung  // same as requested. Latency can be shorter if there were other SMGR clients
8456797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  // with proc_type also set to SNS_PROC_SSC_V01.
8466797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  // If the request is passive, 'enabled' may change over time and needs to be
8476797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  // updated.
8486797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  if (sensor != nullptr) {
8496797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    bool postUpdate = false;
8506797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    struct chreSensorSamplingStatus& status = sensor->samplingStatus;
8516797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    bool enabled = (request.getMode() != SensorMode::Off);
8526797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    if (status.enabled != enabled) {
8536797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung      postUpdate = true;
8546797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung      status.enabled = enabled;
8556797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    }
8566797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    if (!sensorTypeIsOneShot(sensor->getSensorType())) {
8576797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung      if (status.interval != request.getInterval().toRawNanoseconds()) {
8586797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung        postUpdate = true;
8596797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung        status.interval = request.getInterval().toRawNanoseconds();
8606797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung      }
8616797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung      if (status.latency != request.getLatency().toRawNanoseconds()) {
8626797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung        postUpdate = true;
8636797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung        status.latency = request.getLatency().toRawNanoseconds();
8646797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung      }
8656797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    }
8666797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung
8676797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    if (postUpdate) {
86886bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung      uint32_t sensorHandle = getSensorHandleFromSensorType(
86986bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung          sensor->getSensorType());
87086bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung
87186bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung      // Only post to Nanoapps with an open request.
87286bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung      auto& requests = EventLoopManagerSingleton::get()->
87386bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung          getSensorRequestManager().getRequests(sensor->getSensorType());
87486bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung      for (const auto& req : requests) {
87586bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung        if (req.getNanoapp() != nullptr) {
87686bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung          postSamplingStatusEvent(req.getNanoapp()->getInstanceId(),
87786bb62ca9e700b72f182d2473300a6accd9c4818Meng-hsuan Chung                                  sensorHandle, status);
8786797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung        }
8796797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung      }
8806797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    }
8816797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  }
8826797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung}
8836797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung
88401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung/**
88501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * Handles sensor status provided by the SMGR framework.
88601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung *
887b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param smgrMonitorIndMsg Indication message received from SMGR
88801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung */
889b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddievoid handleSensorStatusMonitorIndication(
890b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    const sns_smgr_sensor_status_monitor_ind_msg_v02& smgrMonitorIndMsg) {
891b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  auto *callbackData =
892b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      memoryAlloc<sns_smgr_sensor_status_monitor_ind_msg_v02>();
893b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (callbackData == nullptr) {
894b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    LOGE("Failed to allocate status update deferred callback memory");
89501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  } else {
896b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    *callbackData = smgrMonitorIndMsg;
897b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    auto callback = [](uint16_t /* type */, void *data) {
898b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      auto *cbData =
899b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          static_cast<sns_smgr_sensor_status_monitor_ind_msg_v02 *>(data);
900b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      onStatusChange(*cbData);
901b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      memoryFree(cbData);
902b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    };
903f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
904b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // Schedule a deferred callback to handle sensor status change in the main
905b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // thread.
906b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    if (!EventLoopManagerSingleton::get()->deferCallback(
907b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        SystemCallbackType::SensorStatusUpdate, callbackData, callback)) {
908b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      LOGE("Failed to schedule a deferred callback for status update");
909b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      memoryFree(callbackData);
91001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    }
91183a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol  }
91283a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol}
91383a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
91401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung/**
915b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * This callback is invoked by the SMR framework when an asynchronous message is
916b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * delivered. Unhandled messages are logged.
91701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung *
918b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param handle Handle for the SMR client this indication was received on.
919b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param messageId The message ID number.
920b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param decodedInd Buffer containing decoded (C struct) message data.
921b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param decodedIndLen Size of the decoded buffer in bytes.
92201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung * @param callbackData Data that is provided as a context to this callback. This
92301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung *                     is not used in this context.
924b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie *
925b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @see smr_client_ind_cb
92601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung */
927b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddievoid platformSensorInternalServiceIndicationCallback(
928b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    smr_client_hndl handle, unsigned int messageId, void *decodedInd,
929b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    unsigned int decodedIndLen, void *callbackData) {
93001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  switch (messageId) {
931b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    case SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02: {
932b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      CHRE_ASSERT(decodedIndLen >=
933b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie                  sizeof(sns_smgr_sensor_status_monitor_ind_msg_v02));
934b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      auto *monitorInd =
935b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          static_cast<sns_smgr_sensor_status_monitor_ind_msg_v02 *>(decodedInd);
936b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      handleSensorStatusMonitorIndication(*monitorInd);
93701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      break;
938b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    }
93901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    default:
94001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      LOGW("Received unhandled sensor internal service message: 0x%x",
94101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung           messageId);
94201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      break;
94301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  };
94401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
94501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
946f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
947f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * Adds or removes an SMGR sensor monitor for the specified sensor ID.
948f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
949f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorId The sensor ID to add/remove sensor status monitor for.
950f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param enable true to add and false to remove the status monitor.
951f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
952f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chungvoid setSensorMonitorRequest(uint8_t sensorId, bool enable) {
953b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  auto monitorRequest =
954b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      MakeUniqueZeroFill<sns_smgr_sensor_status_monitor_req_msg_v02>();
955b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  auto monitorResponse =
956b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      MakeUnique<sns_smgr_sensor_status_monitor_resp_msg_v02>();
957b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
958b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (monitorRequest.isNull() || monitorResponse.isNull()) {
959b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    LOGE("Failed to allocate monitor request/response");
960b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  } else {
961b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    monitorRequest->sensor_id = sensorId;
962b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    monitorRequest->registering = enable;
963b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
964b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    smr_err status = getSmrHelper()->sendReqSync(
965b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        gPlatformSensorInternalServiceSmrClientHandle,
966b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        SNS_SMGR_SENSOR_STATUS_MONITOR_REQ_V02,
967b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        &monitorRequest, &monitorResponse);
968b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    if (status != SMR_NO_ERR) {
969b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      LOGE("Error setting sensor status monitor: %d", status);
970b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    } else if (monitorResponse->resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
971b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      LOGE("Sensor status monitor request failed with error: %" PRIu8
972b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie           " sensor ID %" PRIu8 " enable %d",
973b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie           monitorResponse->resp.sns_err_t, sensorId, enable);
974b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    }
97501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
97683a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol}
97783a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol
97883a6e8255099bcbd0758c1dbe6e002bb8542ec4dAndrew Rossignol/**
979f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * Adds and initializes a sensor monitor for the specified sensor ID if it
980f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * doesn't exist yet.
981f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
982f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorId The sensor ID to request monitor for.
983f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
984f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chungvoid addSensorMonitor(uint8_t sensorId) {
985f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  size_t index = getSensorMonitorIndex(sensorId);
986f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  if (index == gSensorMonitors.size()) {
987f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    LOGD("Adding sensor status monitor for sensor ID %" PRIu8, sensorId);
988f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
989b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // Initialize sensor monitor status before making the request.
990f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    SensorMonitor monitor;
991f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    monitor.sensorId = sensorId;
992a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung    monitor.otherClientPresent = false;
993f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    gSensorMonitors.push_back(monitor);
994f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
995b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // Make a request to add the status monitor
996f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    setSensorMonitorRequest(sensorId, true);
997f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  }
998f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung}
999f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1000f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
1001cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol * Requests the sensors for a given sensor ID and appends them to the provided
1002cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol * list of sensors. If an error occurs, false is returned.
1003cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol *
1004cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol * @param sensorId The sensor ID to request sensor info for.
1005cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol * @param sensors The list of sensors to append newly found sensors to.
1006cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol * @return Returns false if an error occurs.
1007cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol */
1008cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignolbool getSensorsForSensorId(uint8_t sensorId,
100953cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie                           DynamicVector<Sensor> *sensors) {
1010cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  bool success = false;
1011b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  auto sensorInfoRequest =
1012b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      MakeUniqueZeroFill<sns_smgr_single_sensor_info_req_msg_v01>();
1013b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  auto sensorInfoResponse =
1014b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      MakeUnique<sns_smgr_single_sensor_info_resp_msg_v01>();
1015ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
1016b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (sensorInfoRequest.isNull() || sensorInfoResponse.isNull()) {
1017b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    LOGE("Failed to allocate sensor info msg");
1018b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  } else {
1019b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    sensorInfoRequest->SensorID = sensorId;
1020b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
1021b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    smr_err status = getSmrHelper()->sendReqSync(
1022b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        gPlatformSensorServiceSmrClientHandle,
1023b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        SNS_SMGR_SINGLE_SENSOR_INFO_REQ_V01,
1024b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        &sensorInfoRequest, &sensorInfoResponse);
1025b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
1026b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    if (status != SMR_NO_ERR) {
1027b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      LOGE("Error requesting single sensor info: %d", status);
1028b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    } else if (sensorInfoResponse->Resp.sns_result_t !=
1029b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie                   SNS_RESULT_SUCCESS_V01) {
1030b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      LOGE("Single sensor info request failed with error: %d",
1031b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie           sensorInfoResponse->Resp.sns_err_t);
1032b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    } else {
1033b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      const sns_smgr_sensor_info_s_v01& sensorInfoList =
1034b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          sensorInfoResponse->SensorInfo;
1035b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      for (uint32_t i = 0; i < sensorInfoList.data_type_info_len; i++) {
1036b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        const sns_smgr_sensor_datatype_info_s_v01& sensorInfo =
1037b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie            sensorInfoList.data_type_info[i];
1038b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        LOGD("SensorID %" PRIu8 ", DataType %" PRIu8 ", MaxRate %" PRIu16
1039b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie             "Hz, SensorName %s",
1040b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie             sensorInfo.SensorID, sensorInfo.DataType,
1041b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie             sensorInfo.MaxSampleRate, sensorInfo.SensorName);
1042b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
1043b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        SensorType sensorType = getSensorTypeFromSensorId(
1044e62f9949c5aa827e175cfb239d9840d7517e8052Meng-hsuan Chung            sensorInfo.SensorID, sensorInfo.DataType,
1045b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie            SNS_SMGR_CAL_SEL_FULL_CAL_V01);
1046b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        if (sensorType != SensorType::Unknown) {
1047b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          addSensor(sensorInfo, SNS_SMGR_CAL_SEL_FULL_CAL_V01, sensors);
1048b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
1049b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          // Add an uncalibrated version if defined.
1050b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          SensorType uncalibratedType = getSensorTypeFromSensorId(
1051b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie              sensorInfo.SensorID, sensorInfo.DataType,
1052b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie              SNS_SMGR_CAL_SEL_FACTORY_CAL_V01);
1053b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          if (sensorType != uncalibratedType) {
1054b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie            addSensor(sensorInfo, SNS_SMGR_CAL_SEL_FACTORY_CAL_V01, sensors);
1055b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie          }
1056cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol        }
1057cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol      }
1058b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      success = true;
1059cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol    }
106038bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol  }
1061b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
1062cd70ffd7dc683bd0d473f98ba593362e9cc5a877Andrew Rossignol  return success;
106338bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol}
106438bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol
106580b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol/**
106680b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol * Converts a SensorMode into an SMGR request action. When the net request for
106780b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol * a sensor is considered to be active an add operation is required for the
106880b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol * SMGR request. When the sensor becomes inactive the request is deleted.
106980b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol *
107080b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol * @param mode The sensor mode.
107180b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol * @return Returns the SMGR request action given the sensor mode.
107280b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol */
107380b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignoluint8_t getSmgrRequestActionForMode(SensorMode mode) {
1074f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  if (mode != SensorMode::Off) {
10753e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    return SNS_SMGR_BUFFERING_ACTION_ADD_V01;
107680b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  } else {
10773e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung    return SNS_SMGR_BUFFERING_ACTION_DELETE_V01;
107880b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  }
107980b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol}
108080b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
1081ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung/**
108221dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung * Specify the sensor decimation type.
108321dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung *
108421dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung * @param sensorId The sensorID as provided by the SMGR.
108521dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung * @param dataType The dataType for the sesnor as provided by the SMGR.
108621dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung * return The decimation type as defined by the SMGR.
108721dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung */
108821dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chunguint8_t getDecimationType(uint8_t sensorId, uint8_t dataType) {
108921dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung  // Request filtered data for accel and gyro to reduce noise aliasing in case
109021dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung  // SMGR has other higher ODR clients.
109121dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung  if ((sensorId == SNS_SMGR_ID_ACCEL_V01 || sensorId == SNS_SMGR_ID_GYRO_V01)
109221dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung      && dataType == SNS_SMGR_DATA_TYPE_PRIMARY_V01) {
109321dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung    return SNS_SMGR_DECIMATION_FILTER_V01;
109421dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung  } else {
109521dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung    return SNS_SMGR_DECIMATION_RECENT_SAMPLE_V01;
109621dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung  }
109721dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung}
109821dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung
109921dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung/**
1100ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * Populates a sns_smgr_buffering_req_msg_v01 struct to request sensor data.
1101ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *
1102ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param request The new request to set this sensor to.
1103ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param sensorId The sensorID as provided by the SMGR request for sensor info.
1104ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param dataType The dataType for the sesnor as provided by the SMGR request
1105ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung *                 for sensor info.
1106ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
110769fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung * @param minInterval The minimum interval allowed by this sensor.
1108ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung * @param sensorDataRequest The pointer to the data request to be populated.
1109ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung */
1110ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chungvoid populateSensorRequest(
111169fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    const SensorRequest& chreRequest, uint8_t sensorId, uint8_t dataType,
111269fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    uint8_t calType, uint64_t minInterval,
111369fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung    sns_smgr_buffering_req_msg_v01 *sensorRequest) {
111480b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  // Zero the fields in the request. All mandatory and unused fields are
111580b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  // specified to be set to false or zero so this is safe.
1116ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  memset(sensorRequest, 0, sizeof(*sensorRequest));
111780b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
11182b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  // Reconstructs a request to deliver one-shot sensors' data ASAP and set
11192b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  // default interval to some meaningful number.
112069fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung  bool isOneShot = sensorTypeIsOneShot(getSensorTypeFromSensorId(
112169fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung      sensorId, dataType, calType));
11222b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  uint64_t cappedInterval = chreRequest.getInterval().toRawNanoseconds();
11232b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  if (cappedInterval == CHRE_SENSOR_INTERVAL_DEFAULT) {
11248fb8be9b9efbd8e7efdb0d6ed83f0dbe01743d24Meng-hsuan Chung    // For one-shot sensors, we've overridden minInterval to default in init.
11258fb8be9b9efbd8e7efdb0d6ed83f0dbe01743d24Meng-hsuan Chung    // However, for InstantMotion/StationaryDetect, making a request with
11268fb8be9b9efbd8e7efdb0d6ed83f0dbe01743d24Meng-hsuan Chung    // default interval will not trigger.
11278fb8be9b9efbd8e7efdb0d6ed83f0dbe01743d24Meng-hsuan Chung    cappedInterval =
11288fb8be9b9efbd8e7efdb0d6ed83f0dbe01743d24Meng-hsuan Chung        isOneShot ? kDefaultInterval : std::max(minInterval, kDefaultInterval);
11292b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  }
11302b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  SensorRequest request(chreRequest.getMode(), Nanoseconds(cappedInterval),
11312b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung                        isOneShot ? Nanoseconds(0) : chreRequest.getLatency());
113269fb1d72e0aba8aeb7b7e8adf6acddff6f2b079dMeng-hsuan Chung
113380b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  // Build the request for one sensor at the requested rate. An add action for a
113480b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  // ReportID that is already in use causes a replacement of the last request.
1135ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->ReportId = getReportId(sensorId, dataType, calType);
1136ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Action = getSmgrRequestActionForMode(request.getMode());
11372b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung
11382b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  // SMGR report interval should be (interval + latency). However, to handle
11392b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  // fractional-interval latency setting and to guarantee meeting chre request,
11402b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  // report interval is set to latency only. Also, lower-bound batchInterval as
11412b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  // request to SMGR would fail if batchInterval < interval.
11422b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  Nanoseconds batchInterval =
11432b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung      std::max(request.getLatency(), request.getInterval());
11442b8f386e109c5470fbe8da4d3242e75c70993a1eMeng-hsuan Chung  sensorRequest->ReportRate = intervalToSmgrQ16ReportRate(batchInterval);
114521dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung  sensorRequest->Item_len = 1;  // One sensor per request if possible.
1146ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Item[0].SensorId = sensorId;
1147ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Item[0].DataType = dataType;
114821dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung  sensorRequest->Item[0].Decimation = getDecimationType(sensorId, dataType);
1149ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Item[0].Calibration = calType;
1150ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  sensorRequest->Item[0].SamplingRate =
11513e1892c28b41fd0b76ea86b10d00c6ef669f9354Meng-hsuan Chung      intervalToSmgrSamplingRate(request.getInterval());
115280b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol
1153ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  // Add a dummy primary sensor to accompany a secondary temperature sensor.
1154ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  // This is requred by the SMGR. The primary sensor is requested with the same
1155ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  // (low) rate and the same latency, whose response data will be ignored.
1156ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  if (isSecondaryTemperature(sensorRequest->ReportId)) {
1157ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item_len = 2;
1158ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item[1].SensorId = sensorId;
1159ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item[1].DataType = SNS_SMGR_DATA_TYPE_PRIMARY_V01;
116021dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung    sensorRequest->Item[1].Decimation = getDecimationType(
116121dbd17bfcaf3fad5eddd05b8f2d414288edb09bMeng-hsuan Chung        sensorId, SNS_SMGR_DATA_TYPE_PRIMARY_V01);
1162ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item[1].Calibration = SNS_SMGR_CAL_SEL_FULL_CAL_V01;
1163ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung    sensorRequest->Item[1].SamplingRate = sensorRequest->Item[0].SamplingRate;
1164ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  }
11656728dd67ed72aae305f11bc0fa468a9ce0055817Meng-hsuan Chung
11666728dd67ed72aae305f11bc0fa468a9ce0055817Meng-hsuan Chung  // Synchronize fifo flushes with other clients that have SSC proc_type.
11676728dd67ed72aae305f11bc0fa468a9ce0055817Meng-hsuan Chung  // send_indications_during_suspend has no effect on data sent to SLPI.
11686797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  // Default is to synchronize with AP clients, which may shorten flush
11696797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  // intervals for data sent to the AP.
11706728dd67ed72aae305f11bc0fa468a9ce0055817Meng-hsuan Chung  sensorRequest->notify_suspend_valid = true;
11716728dd67ed72aae305f11bc0fa468a9ce0055817Meng-hsuan Chung  sensorRequest->notify_suspend.proc_type = SNS_PROC_SSC_V01;
11726728dd67ed72aae305f11bc0fa468a9ce0055817Meng-hsuan Chung  sensorRequest->notify_suspend.send_indications_during_suspend = true;
1173ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung}
1174ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
1175f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
1176a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung * Determines whether a request is allowed. A passive request is not always
1177f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * allowed.
1178f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
1179f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorType The SensorType of this request
1180f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param request The intended sensor request
1181f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @return true if the request is allowed.
1182f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
1183f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chungbool isRequestAllowed(SensorType sensorType, const SensorRequest& request) {
1184f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  bool allowed = false;
1185f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1186f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  const Sensor *sensor = EventLoopManagerSingleton::get()
1187f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      ->getSensorRequestManager().getSensor(sensorType);
1188f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  if (sensor != nullptr) {
1189f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    if (sensorModeIsPassive(request.getMode())) {
1190a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung      size_t index = getSensorMonitorIndex(sensor->sensorId);
1191a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung      if (index == gSensorMonitors.size()) {
1192a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung        LOGE("SensorId %" PRIu8 " doesn't have a monitor", sensor->sensorId);
1193a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung      } else {
1194a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung        SensorMode mergedMode = getMergedMode(
1195a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung            sensor->sensorId, sensorType, request);
1196a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung        bool otherClientPresent = gSensorMonitors[index].otherClientPresent;
1197a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung        allowed = (sensorModeIsActive(mergedMode) || otherClientPresent);
1198a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung        LOGD("sensorType %d allowed %d: mergedMode %d, otherClientPresent %d",
1199a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung             static_cast<size_t>(sensorType), allowed,
1200a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung             static_cast<int>(mergedMode), otherClientPresent);
1201a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung      }
1202a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung    } else {
1203a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung      // If it's an ACTIVE or an OFF request, it's always allowed.
1204a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung      allowed = true;
1205f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    }
1206f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  }
1207f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  return allowed;
1208f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung}
1209f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1210f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
1211b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * Makes a SNS_SMGR_BUFFERING_REQ request based on the arguments provided.
1212f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
1213f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorId The sensorID as provided by the SMGR.
1214f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param dataType The dataType for the sesnor as provided by the MSGR.
1215f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param calType The calibration type (CAL_SEL) as defined in the SMGR API.
1216f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param minInterval The minimum interval of this sensor.
1217f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param request The sensor request
1218f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @return true if the request has been made successfully.
1219f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
1220b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddiebool makeBufferingReq(uint8_t sensorId, uint8_t dataType, uint8_t calType,
1221b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie                      uint64_t minInterval, const SensorRequest& request) {
1222f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  bool success = false;
1223b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  auto sensorRequest = MakeUniqueZeroFill<sns_smgr_buffering_req_msg_v01>();
1224b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  auto sensorResponse = MakeUnique<sns_smgr_buffering_resp_msg_v01>();
1225f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1226b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (sensorRequest.isNull() || sensorResponse.isNull()) {
1227b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    LOGE("Failed to allocate buffering msg");
1228f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  } else {
1229f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    populateSensorRequest(request, sensorId, dataType, calType,
1230b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie                          minInterval, sensorRequest.get());
1231f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1232b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    smr_err status = getSmrHelper()->sendReqSync(
1233b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        gPlatformSensorServiceSmrClientHandle, SNS_SMGR_BUFFERING_REQ_V01,
1234b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie        &sensorRequest, &sensorResponse);
1235f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1236b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    if (status != SMR_NO_ERR) {
1237f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      LOGE("Error requesting sensor data: %d", status);
1238f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    } else if (sensorResponse->Resp.sns_result_t != SNS_RESULT_SUCCESS_V01
1239f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung        || (sensorResponse->AckNak != SNS_SMGR_RESPONSE_ACK_SUCCESS_V01
1240f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung            && sensorResponse->AckNak != SNS_SMGR_RESPONSE_ACK_MODIFIED_V01)) {
1241f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      LOGE("Sensor data request failed with error: %d, AckNak: %d",
1242f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung           sensorResponse->Resp.sns_err_t, sensorResponse->AckNak);
1243f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    } else {
1244f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      success = true;
1245f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    }
1246f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  }
1247b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
1248f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  return success;
1249f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung}
1250f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1251f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
1252b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * Makes a SNS_SMGR_BUFFERING_REQ request if necessary.
1253f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
1254f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorType The sensor type of the request.
1255f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param request The sensor request to be made.
1256f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @return true if the request has been accepted.
1257f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
1258f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chungbool makeRequest(SensorType sensorType, const SensorRequest& request) {
1259f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  bool success = false;
1260f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1261f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  Sensor *sensor = EventLoopManagerSingleton::get()->getSensorRequestManager()
1262f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      .getSensor(sensorType);
1263a265e07f2a3bdf0a0ebb4d76048eb021eabd6126Meng-hsuan Chung  if (sensor != nullptr) {
1264b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // Do not make an off request if the sensor is already off. Otherwise, SMGR
1265f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    // returns an error.
1266f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    if (request.getMode() == SensorMode::Off) {
1267f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      success = sensor->isSensorOff;
1268f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    }
1269f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1270b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // Make a SMGR buffering request if necessary.
1271f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    if (!success) {
1272b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      success = makeBufferingReq(sensor->sensorId, sensor->dataType,
1273b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie                                 sensor->calType, sensor->minInterval, request);
1274f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    }
1275f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  }
1276f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1277b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  // TODO: handle makeBufferingReq failures
1278f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  if (success) {
1279f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    // Update internal states if request was accepted by SMGR.
1280f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    sensor->isSensorOff = (request.getMode() == SensorMode::Off);
1281f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1282f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    if (request.getMode() == SensorMode::Off) {
1283f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensor->lastEventValid = false;
1284f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    }
12856797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung
12866797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    updateSamplingStatus(sensor, request);
1287f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  }
1288f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  return success;
1289f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung}
1290f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1291f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
1292f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * Makes all pending requests of the specified sensor ID to SMGR.
1293f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
1294f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * @param sensorId The sensor ID whose pending requests are to be made.
1295c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chung * @return true if an ADD request has been accepted.
1296f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
1297c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chungbool makeAllPendingRequests(uint8_t sensorId) {
1298f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  // Identify sensor types to check for pending requests
1299f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  SensorType sensorTypes[kMaxNumSensorsPerSensorId];
1300f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
1301f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorId, sensorTypes);
1302c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chung  bool accepted = false;
1303f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  for (size_t i = 0; i < numSensorTypes; i++) {
1304f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    const Sensor *sensor = EventLoopManagerSingleton::get()
1305f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung        ->getSensorRequestManager().getSensor(sensorTypes[i]);
1306f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1307f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    // If sensor is off and the request is not off, it's a pending request.
1308f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    if (sensor != nullptr && sensor->isSensorOff
1309f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung        && sensor->getRequest().getMode() != SensorMode::Off) {
1310c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chung      accepted |= makeRequest(sensorTypes[i], sensor->getRequest());
1311f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    }
1312f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  }
1313c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chung  return accepted;
1314f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung}
1315f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1316f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung/**
1317f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * Identifies and removes passive requests that have been made to the SMGR, and
1318f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung * adds them to the sensor monitor.
1319f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung *
1320b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie * @param sensorId The sensor ID whose passive requests are to be removed.
1321c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chung * @return true if a DELETE request has been accepted.
1322f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung */
1323c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chungbool removeAllPassiveRequests(uint8_t sensorId) {
1324f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  // Specify sensor types to check for passive requests
1325f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  SensorType sensorTypes[kMaxNumSensorsPerSensorId];
1326f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
1327f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      sensorId, sensorTypes);
1328c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chung  bool accepted = false;
1329f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  for (size_t i = 0; i < numSensorTypes; i++) {
1330f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    const Sensor *sensor = EventLoopManagerSingleton::get()
1331f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung        ->getSensorRequestManager().getSensor(sensorTypes[i]);
1332f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1333f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    // Turn off sensors that have a passive request
1334f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    if (sensor != nullptr
1335f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung        && sensorModeIsPassive(sensor->getRequest().getMode())) {
1336f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung      SensorRequest offRequest;
1337c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chung      accepted |= makeRequest(sensorTypes[i], offRequest);
1338f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung    }
1339f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  }
1340c19ad86fa95a9a9a069ad6a43038593a4cbca1ebMeng-hsuan Chung  return accepted;
1341f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung}
1342f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
134301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}  // anonymous namespace
134401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
134567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan ChungPlatformSensor::~PlatformSensor() {
134667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  if (lastEvent != nullptr) {
134767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    LOGD("Releasing lastEvent: 0x%p, id %" PRIu8 ", type %" PRIu8 ", cal %"
134867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung         PRIu8 ", size %zu",
134967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung         lastEvent, sensorId, dataType, calType, lastEventSize);
135067de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung    memoryFree(lastEvent);
135167de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  }
135267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung}
135367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
135401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungvoid PlatformSensor::init() {
1355e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro  // Timeout for SMR client initialization, in milliseconds.
1356e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro  constexpr uint32_t kSmrInitTimeoutMs = 10;
1357e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro
1358b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  SmrHelperSingleton::init();
1359b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
136001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  // sns_smgr_api_v01
1361b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  qmi_idl_service_object_type smgrSvcObj =
136201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      SNS_SMGR_SVC_get_service_object_v01();
1363b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (smgrSvcObj == nullptr) {
136401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    FATAL_ERROR("Failed to obtain the SNS SMGR service instance");
136501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
136601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
1367e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro  smr_err result = getSmrHelper()->waitForService(smgrSvcObj);
1368e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro  if (result != SMR_NO_ERR) {
1369e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro    FATAL_ERROR("Failed while waiting for SNS SMGR service");
1370e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro  }
1371e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro
1372b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  // Note: giving nullptr for err_cb prevents this from degrading to a regular
1373b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  // QMI client if the service is not found.
1374b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  smr_err status = smr_client_init(
1375b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      smgrSvcObj, SMR_CLIENT_INSTANCE_ANY,
1376b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      platformSensorServiceIndicationCallback, nullptr /* ind_cb_data */,
1377b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      kSmrInitTimeoutMs, nullptr /* err_cb */, nullptr /* err_cb_data */,
1378b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      &gPlatformSensorServiceSmrClientHandle, isSlpiUimgSupported());
1379b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (status != SMR_NO_ERR) {
1380b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    FATAL_ERROR("Failed to initialize SMGR client: %d", status);
138101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
138201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
138301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  // sns_smgr_interal_api_v02
1384b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  qmi_idl_service_object_type smgrInternalSvcObj =
1385b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      SNS_SMGR_INTERNAL_SVC_get_service_object_v02();
1386b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (smgrInternalSvcObj == nullptr) {
138701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    FATAL_ERROR("Failed to obtain the SNS SMGR internal service instance");
138801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
138901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
1390e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro  result = getSmrHelper()->waitForService(smgrInternalSvcObj);
1391e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro  if (result != SMR_NO_ERR) {
1392e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro    FATAL_ERROR("Failed while waiting for SNS SMGR internal service");
1393e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro  }
1394e0653a607542819b492d789952159a528c9a5e4eArthur Ishiguro
1395b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  status = smr_client_init(
1396b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      smgrInternalSvcObj, SMR_CLIENT_INSTANCE_ANY,
1397b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      platformSensorInternalServiceIndicationCallback,
1398b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      nullptr /* ind_cb_data */, kSmrInitTimeoutMs, nullptr /* err_cb */,
1399b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      nullptr /* err_cb_data */, &gPlatformSensorInternalServiceSmrClientHandle,
1400b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      isSlpiUimgSupported());
1401b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (status != SMR_NO_ERR) {
1402b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    FATAL_ERROR("Failed to initialize SMGR internal client: %d", status);
140301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
140401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
140501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
140601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chungvoid PlatformSensor::deinit() {
1407b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  smr_err err = getSmrHelper()->releaseSync(
1408b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      gPlatformSensorServiceSmrClientHandle);
1409b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (err != SMR_NO_ERR) {
1410b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    LOGE("Failed to release SMGR client: %d", err);
1411d9fd3fc29ccc7b91ba01dade085c2fc927b4e7b2Brian Duddie  }
1412b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  gPlatformSensorServiceSmrClientHandle = nullptr;
141301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
1414b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  err = getSmrHelper()->releaseSync(
1415b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      gPlatformSensorInternalServiceSmrClientHandle);
1416b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (err != SMR_NO_ERR) {
1417b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    LOGE("Failed to release SMGR internal client: %d", err);
1418d9fd3fc29ccc7b91ba01dade085c2fc927b4e7b2Brian Duddie  }
1419b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  gPlatformSensorInternalServiceSmrClientHandle = nullptr;
1420d9fd3fc29ccc7b91ba01dade085c2fc927b4e7b2Brian Duddie
1421b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  // Clearing all sensor status monitors. Releasing an SMR client also releases
1422b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  // all sensor status monitor requests.
1423f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  gSensorMonitors.clear();
1424b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  SmrHelperSingleton::deinit();
142501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
142601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
142753cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddiebool PlatformSensor::getSensors(DynamicVector<Sensor> *sensors) {
142801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  CHRE_ASSERT(sensors);
142901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
1430b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  auto sensorListRequest =
1431b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      MakeUniqueZeroFill<sns_smgr_all_sensor_info_req_msg_v01>();
1432b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  auto sensorListResponse = MakeUnique<sns_smgr_all_sensor_info_resp_msg_v01>();
143301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
1434b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  smr_err status = getSmrHelper()->sendReqSync(
1435b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      gPlatformSensorServiceSmrClientHandle, SNS_SMGR_ALL_SENSOR_INFO_REQ_V01,
1436b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      &sensorListRequest, &sensorListResponse);
143701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
143801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  bool success = false;
1439b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (status != SMR_NO_ERR) {
144001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    LOGE("Error requesting sensor list: %d", status);
1441b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  } else if (sensorListResponse->Resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
144201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    LOGE("Sensor list lequest failed with error: %d",
1443b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie         sensorListResponse->Resp.sns_err_t);
144401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  } else {
144501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    success = true;
1446b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    for (uint32_t i = 0; i < sensorListResponse->SensorInfo_len; i++) {
1447b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie      uint8_t sensorId = sensorListResponse->SensorInfo[i].SensorID;
144801d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      if (!getSensorsForSensorId(sensorId, sensors)) {
144901d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        success = false;
145001d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung        break;
145101d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung      }
145201d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung    }
145301d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  }
145401d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
145501d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung  return success;
145601d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung}
145701d59972774453f9b0b7b92035f2919f8b6a5b35Meng-hsuan Chung
145853cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddiebool PlatformSensor::applyRequest(const SensorRequest& request) {
1459b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  bool success;
1460b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
1461b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  if (!SmrHelperSingleton::isInitialized()) {
1462b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // Off requests made as part of shutdown come after PlatformSensor::deinit()
1463b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // which releases our SMGR clients, removing all requests. Report success in
1464b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // this case.
1465b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    success = (request.getMode() == SensorMode::Off) ? true : false;
1466b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    CHRE_ASSERT_LOG(success, "Sensor request made before init/after deinit");
1467b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  } else {
1468b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // Adds a sensor monitor the first time this sensor is requested.
1469b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    addSensorMonitor(this->sensorId);
1470b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie
14719b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung    // As sensor status monior indication doesn't support secondary sensor
14729b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung    // status change, Light sensor (a secondary one) is always overridden to be
14739b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung    // requested with an active mode.
14749b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung    bool passiveLight = (getSensorType() == SensorType::Light
14759b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung                         && sensorModeIsPassive(request.getMode()));
14769b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung    if (passiveLight) {
14779b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung      LOGE("Passive request for Light sensor is not supported. "
14789b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung           "Overriding request to active");
14799b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung    }
14809b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung    SensorRequest localRequest(
14819b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung        passiveLight ? SensorMode::ActiveContinuous : request.getMode(),
14829b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung        request.getInterval(), request.getLatency());
14839b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung
1484b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // Determines whether a (passive) request is allowed at this point.
14859b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung    bool requestAllowed = isRequestAllowed(getSensorType(), localRequest);
1486ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung
1487b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    // If request is not allowed, turn off the sensor. Otherwise, make request.
1488b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie    SensorRequest offRequest;
14899b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung    success = makeRequest(getSensorType(),
14909b1bbd8f55a6f8e943a66a6970c0c91efa36371bMeng-hsuan Chung                          requestAllowed ? localRequest : offRequest);
1491b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  }
149280b6b0c6ea5ce4c72ac738c560015de82edd788dAndrew Rossignol  return success;
1493f546f4c27e66dc4ea868e660cebac9ba0c31fad9Andrew Rossignol}
1494f546f4c27e66dc4ea868e660cebac9ba0c31fad9Andrew Rossignol
1495cb8312e5ce53430576e2343e4863af84676c93adAndrew RossignolSensorType PlatformSensor::getSensorType() const {
1496ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung  return getSensorTypeFromSensorId(this->sensorId, this->dataType,
1497ba02dd147fe1ab32de471743e1996b416d345a7aMeng-hsuan Chung                                   this->calType);
1498cb8312e5ce53430576e2343e4863af84676c93adAndrew Rossignol}
1499cb8312e5ce53430576e2343e4863af84676c93adAndrew Rossignol
15009cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chunguint64_t PlatformSensor::getMinInterval() const {
15019cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung  return minInterval;
15029cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung}
15039cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung
15049cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chungconst char *PlatformSensor::getSensorName() const {
15059cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung  return sensorName;
15069cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung}
15079cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung
150853cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian DuddiePlatformSensor::PlatformSensor(PlatformSensor&& other) {
150953cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  // Our move assignment operator doesn't assume that "this" is initialized, so
151053cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  // we can just use that here
151153cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  *this = std::move(other);
151253cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie}
151353cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie
15149cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan ChungPlatformSensor& PlatformSensor::operator=(PlatformSensor&& other) {
151553cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  // Note: if this implementation is ever changed to depend on "this" containing
151653cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  // initialized values, the move constructor implemenation must be updated
15179cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung  sensorId = other.sensorId;
15189cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung  dataType = other.dataType;
15199cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung  calType = other.calType;
15209cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung  memcpy(sensorName, other.sensorName, SNS_SMGR_MAX_SENSOR_NAME_SIZE_V01);
15219cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung  minInterval = other.minInterval;
152267de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
152367de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  lastEvent = other.lastEvent;
152467de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  other.lastEvent = nullptr;
152567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
152667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  lastEventSize = other.lastEventSize;
152767de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung  other.lastEventSize = 0;
1528f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
1529f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  lastEventValid = other.lastEventValid;
1530f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung  isSensorOff = other.isSensorOff;
15316797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  samplingStatus = other.samplingStatus;
1532f4f692d5178bf2ff40e33f7ebce86c84811d1178Meng-hsuan Chung
15339cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung  return *this;
15349cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung}
15359cab6df9598abbf843a7b37eed0c7039048deba7Meng-hsuan Chung
153667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan ChungChreSensorData *PlatformSensor::getLastEvent() const {
153753cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  return (this->lastEventValid) ? this->lastEvent : nullptr;
153867de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung}
153967de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
15406797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chungbool PlatformSensor::getSamplingStatus(
15416797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    struct chreSensorSamplingStatus *status) const {
15426797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  CHRE_ASSERT(status);
15436797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung
15446797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  bool success = false;
15456797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  if (status != nullptr) {
15466797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    success = true;
15476797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung    memcpy(status, &samplingStatus, sizeof(*status));
15486797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  }
15496797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung  return success;
15506797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung}
15516797f377898193cbf15b71eba313bd783e552836Meng-hsuan Chung
155253cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddievoid PlatformSensorBase::setLastEvent(const ChreSensorData *event) {
155353cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  memcpy(this->lastEvent, event, this->lastEventSize);
155453cec69ff23e5ffabf9f29d824c14fbdb18dc856Brian Duddie  this->lastEventValid = true;
155567de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung}
155667de3f239af66c0d5733950a916bc5566f2017f0Meng-hsuan Chung
1557b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddiesmr_client_hndl getSensorServiceSmrClientHandle() {
1558b9d199936165f42ac7e7eabac1bdb4968d938f4fBrian Duddie  return gPlatformSensorServiceSmrClientHandle;
1559c6ef3f619155a7f6e2f0ff5fbc77a11526d9970fMeng-hsuan Chung}
1560c6ef3f619155a7f6e2f0ff5fbc77a11526d9970fMeng-hsuan Chung
156138bec5401084a884b19e8523649548d6a4f7169aAndrew Rossignol}  // namespace chre
1562