• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "chre_cross_validator_sensor_manager.h"
18 
19 #include <algorithm>
20 #include <cinttypes>
21 
22 #include <pb_decode.h>
23 #include <pb_encode.h>
24 
25 #include "chre/util/macros.h"
26 #include "chre/util/nanoapp/callbacks.h"
27 #include "chre/util/nanoapp/log.h"
28 #include "chre/util/time.h"
29 #include "chre_api/chre.h"
30 #include "send_message.h"
31 
32 #define LOG_TAG "[ChreCrossValidator]"
33 
34 namespace chre::cross_validator_sensor {
35 
36 namespace {
37 
38 struct SensorNameCallbackData {
39   const void *sensorName;
40   size_t size;
41 };
42 
decodeSensorName(pb_istream_t * stream,const pb_field_s * field,void ** arg)43 bool decodeSensorName(pb_istream_t *stream, const pb_field_s *field,
44                       void **arg) {
45   UNUSED_VAR(field);
46   auto *name = static_cast<unsigned char *>(*arg);
47 
48   if (stream->bytes_left > kMaxSensorNameSize - 1) {
49     return false;
50   }
51 
52   size_t bytesToCopy = stream->bytes_left;
53   if (!pb_read(stream, name, stream->bytes_left)) {
54     return false;
55   }
56 
57   name[bytesToCopy] = '\0';
58   return true;
59 }
60 
encodeSensorName(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)61 bool encodeSensorName(pb_ostream_t *stream, const pb_field_t *field,
62                       void *const *arg) {
63   auto *sensorNameData = static_cast<const SensorNameCallbackData *>(*arg);
64 
65   if (sensorNameData->size > 0) {
66     return pb_encode_tag_for_field(stream, field) &&
67            pb_encode_string(
68                stream,
69                static_cast<const pb_byte_t *>(sensorNameData->sensorName),
70                sensorNameData->size);
71   }
72 
73   return true;
74 }
75 
76 }  // namespace
77 
~Manager()78 Manager::~Manager() {
79   cleanup();
80 }
81 
cleanup()82 void Manager::cleanup() {
83   if (mCrossValidatorState.has_value() &&
84       mCrossValidatorState->crossValidatorType == CrossValidatorType::SENSOR &&
85       !chreSensorConfigureModeOnly(mCrossValidatorState->sensorHandle,
86                                    CHRE_SENSOR_CONFIGURE_MODE_DONE)) {
87     LOGE("Sensor cleanup failed to set mode to DONE. handle=%" PRIu32,
88          mCrossValidatorState->sensorHandle);
89   }
90 }
91 
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)92 void Manager::handleEvent(uint32_t senderInstanceId, uint16_t eventType,
93                           const void *eventData) {
94   switch (eventType) {
95     case CHRE_EVENT_MESSAGE_FROM_HOST:
96       handleMessageFromHost(
97           senderInstanceId,
98           static_cast<const chreMessageFromHostData *>(eventData));
99       break;
100     // TODO(b/146052784): Check that data received from CHRE apis is the correct
101     // type for current test.
102     case CHRE_EVENT_SENSOR_ACCELEROMETER_DATA:
103       handleSensorThreeAxisData(
104           static_cast<const chreSensorThreeAxisData *>(eventData),
105           CHRE_SENSOR_TYPE_ACCELEROMETER);
106       break;
107     case CHRE_EVENT_SENSOR_GYROSCOPE_DATA:
108       handleSensorThreeAxisData(
109           static_cast<const chreSensorThreeAxisData *>(eventData),
110           CHRE_SENSOR_TYPE_GYROSCOPE);
111       break;
112     case CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA:
113       handleSensorThreeAxisData(
114           static_cast<const chreSensorThreeAxisData *>(eventData),
115           CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD);
116       break;
117     case CHRE_EVENT_SENSOR_PRESSURE_DATA:
118       handleSensorFloatData(static_cast<const chreSensorFloatData *>(eventData),
119                             CHRE_SENSOR_TYPE_PRESSURE);
120       break;
121     case CHRE_EVENT_SENSOR_LIGHT_DATA:
122       handleSensorFloatData(static_cast<const chreSensorFloatData *>(eventData),
123                             CHRE_SENSOR_TYPE_LIGHT);
124       break;
125     case CHRE_EVENT_SENSOR_PROXIMITY_DATA:
126       handleProximityData(static_cast<const chreSensorByteData *>(eventData));
127       break;
128     case CHRE_EVENT_SENSOR_STEP_COUNTER_DATA:
129       handleStepCounterData(
130           static_cast<const chreSensorUint64Data *>(eventData));
131       break;
132     case CHRE_EVENT_SENSOR_SAMPLING_CHANGE:
133       // Ignore sampling state changes
134       break;
135     default:
136       LOGE("Got unknown event type %" PRIu16 " from senderInstanceId %" PRIu32,
137            eventType, senderInstanceId);
138   }
139 }
140 
encodeThreeAxisSensorDatapointValues(pb_ostream_t * stream,const pb_field_t *,void * const * arg)141 bool Manager::encodeThreeAxisSensorDatapointValues(pb_ostream_t *stream,
142                                                    const pb_field_t * /*field*/,
143                                                    void *const *arg) {
144   const auto *sensorThreeAxisDataSample = static_cast<
145       const chreSensorThreeAxisData::chreSensorThreeAxisSampleData *>(*arg);
146 
147   for (const float &value : sensorThreeAxisDataSample->values) {
148     if (!pb_encode_tag_for_field(
149             stream,
150             &chre_cross_validation_sensor_SensorDatapoint_fields
151                 [chre_cross_validation_sensor_SensorDatapoint_values_tag -
152                  1])) {
153       return false;
154     }
155     if (!pb_encode_fixed32(stream, &value)) {
156       return false;
157     }
158   }
159   return true;
160 }
161 
makeDatapoint(bool (* encodeFunc)(pb_ostream_t *,const pb_field_t *,void * const *),const void * sampleDataFromChre,uint64_t currentTimestamp)162 chre_cross_validation_sensor_SensorDatapoint Manager::makeDatapoint(
163     bool (*encodeFunc)(pb_ostream_t *, const pb_field_t *, void *const *),
164     const void *sampleDataFromChre, uint64_t currentTimestamp) {
165   return chre_cross_validation_sensor_SensorDatapoint{
166       .has_timestampInNs = true,
167       .timestampInNs = currentTimestamp,
168       .values = {.funcs = {.encode = encodeFunc},
169                  .arg = const_cast<void *>(sampleDataFromChre)}};
170 }
171 
encodeFloatSensorDatapointValue(pb_ostream_t * stream,const pb_field_t *,void * const * arg)172 bool Manager::encodeFloatSensorDatapointValue(pb_ostream_t *stream,
173                                               const pb_field_t * /*field*/,
174                                               void *const *arg) {
175   const auto *sensorFloatDataSample =
176       static_cast<const chreSensorFloatData::chreSensorFloatSampleData *>(*arg);
177   return pb_encode_tag_for_field(
178              stream,
179              &chre_cross_validation_sensor_SensorDatapoint_fields
180                  [chre_cross_validation_sensor_SensorDatapoint_values_tag -
181                   1]) &&
182          pb_encode_fixed32(stream, &sensorFloatDataSample->value);
183 }
184 
encodeProximitySensorDatapointValue(pb_ostream_t * stream,const pb_field_t *,void * const * arg)185 bool Manager::encodeProximitySensorDatapointValue(pb_ostream_t *stream,
186                                                   const pb_field_t * /*field*/,
187                                                   void *const *arg) {
188   const auto *sensorFloatDataSample =
189       static_cast<const chreSensorByteData::chreSensorByteSampleData *>(*arg);
190   float isNearFloat = sensorFloatDataSample->isNear ? 0.0 : 1.0;
191   return pb_encode_tag_for_field(
192              stream,
193              &chre_cross_validation_sensor_SensorDatapoint_fields
194                  [chre_cross_validation_sensor_SensorDatapoint_values_tag -
195                   1]) &&
196          pb_encode_fixed32(stream, &isNearFloat);
197 }
198 
encodeStepCounterSensorDatapointValue(pb_ostream_t * stream,const pb_field_t *,void * const * arg)199 bool Manager::encodeStepCounterSensorDatapointValue(
200     pb_ostream_t *stream, const pb_field_t * /*field*/, void *const *arg) {
201   const auto *sensorUint64DataSample =
202       static_cast<const chreSensorUint64Data::chreSensorUint64SampleData *>(
203           *arg);
204   // This value is casted to a float for the Java sensors framework so do it
205   // here to make it easier to encode into the existing proto message.
206   auto stepValue = static_cast<float>(sensorUint64DataSample->value);
207   return pb_encode_tag_for_field(
208              stream,
209              &chre_cross_validation_sensor_SensorDatapoint_fields
210                  [chre_cross_validation_sensor_SensorDatapoint_values_tag -
211                   1]) &&
212          pb_encode_fixed32(stream, &stepValue);
213 }
214 
encodeThreeAxisSensorDatapoints(pb_ostream_t * stream,const pb_field_t *,void * const * arg)215 bool Manager::encodeThreeAxisSensorDatapoints(pb_ostream_t *stream,
216                                               const pb_field_t * /*field*/,
217                                               void *const *arg) {
218   const auto *sensorThreeAxisData =
219       static_cast<const chreSensorThreeAxisData *>(*arg);
220   uint64_t currentTimestamp = sensorThreeAxisData->header.baseTimestamp +
221                               chreGetEstimatedHostTimeOffset();
222   for (size_t i = 0; i < sensorThreeAxisData->header.readingCount; i++) {
223     const chreSensorThreeAxisData::chreSensorThreeAxisSampleData &sampleData =
224         sensorThreeAxisData->readings[i];
225     currentTimestamp += sampleData.timestampDelta;
226     if (!pb_encode_tag_for_field(
227             stream,
228             &chre_cross_validation_sensor_SensorData_fields
229                 [chre_cross_validation_sensor_SensorData_datapoints_tag - 1])) {
230       return false;
231     }
232     chre_cross_validation_sensor_SensorDatapoint datapoint = makeDatapoint(
233         encodeThreeAxisSensorDatapointValues, &sampleData, currentTimestamp);
234     if (!pb_encode_submessage(
235             stream, chre_cross_validation_sensor_SensorDatapoint_fields,
236             &datapoint)) {
237       return false;
238     }
239   }
240   return true;
241 }
242 
encodeFloatSensorDatapoints(pb_ostream_t * stream,const pb_field_t *,void * const * arg)243 bool Manager::encodeFloatSensorDatapoints(pb_ostream_t *stream,
244                                           const pb_field_t * /*field*/,
245                                           void *const *arg) {
246   const auto *sensorFloatData = static_cast<const chreSensorFloatData *>(*arg);
247   uint64_t currentTimestamp =
248       sensorFloatData->header.baseTimestamp + chreGetEstimatedHostTimeOffset();
249   for (size_t i = 0; i < sensorFloatData->header.readingCount; i++) {
250     const chreSensorFloatData::chreSensorFloatSampleData &sampleData =
251         sensorFloatData->readings[i];
252     currentTimestamp += sampleData.timestampDelta;
253     if (!pb_encode_tag_for_field(
254             stream,
255             &chre_cross_validation_sensor_SensorData_fields
256                 [chre_cross_validation_sensor_SensorData_datapoints_tag - 1])) {
257       return false;
258     }
259     chre_cross_validation_sensor_SensorDatapoint datapoint = makeDatapoint(
260         encodeFloatSensorDatapointValue, &sampleData, currentTimestamp);
261     if (!pb_encode_submessage(
262             stream, chre_cross_validation_sensor_SensorDatapoint_fields,
263             &datapoint)) {
264       return false;
265     }
266   }
267   return true;
268 }
269 
encodeProximitySensorDatapoints(pb_ostream_t * stream,const pb_field_t *,void * const * arg)270 bool Manager::encodeProximitySensorDatapoints(pb_ostream_t *stream,
271                                               const pb_field_t * /*field*/,
272                                               void *const *arg) {
273   const auto *sensorProximityData =
274       static_cast<const chreSensorByteData *>(*arg);
275   uint64_t currentTimestamp = sensorProximityData->header.baseTimestamp +
276                               chreGetEstimatedHostTimeOffset();
277   for (size_t i = 0; i < sensorProximityData->header.readingCount; i++) {
278     const chreSensorByteData::chreSensorByteSampleData &sampleData =
279         sensorProximityData->readings[i];
280     currentTimestamp += sampleData.timestampDelta;
281     if (!pb_encode_tag_for_field(
282             stream,
283             &chre_cross_validation_sensor_SensorData_fields
284                 [chre_cross_validation_sensor_SensorData_datapoints_tag - 1])) {
285       return false;
286     }
287     chre_cross_validation_sensor_SensorDatapoint datapoint = makeDatapoint(
288         encodeProximitySensorDatapointValue, &sampleData, currentTimestamp);
289     if (!pb_encode_submessage(
290             stream, chre_cross_validation_sensor_SensorDatapoint_fields,
291             &datapoint)) {
292       return false;
293     }
294   }
295   return true;
296 }
297 
encodeStepCounterSensorDatapoints(pb_ostream_t * stream,const pb_field_t *,void * const * arg)298 bool Manager::encodeStepCounterSensorDatapoints(pb_ostream_t *stream,
299                                                 const pb_field_t * /*field*/,
300                                                 void *const *arg) {
301   const auto *sensorStepCounterData =
302       static_cast<const chreSensorUint64Data *>(*arg);
303   uint64_t currentTimestamp = sensorStepCounterData->header.baseTimestamp +
304                               chreGetEstimatedHostTimeOffset();
305   for (size_t i = 0; i < sensorStepCounterData->header.readingCount; i++) {
306     const chreSensorUint64Data::chreSensorUint64SampleData &sampleData =
307         sensorStepCounterData->readings[i];
308     currentTimestamp += sampleData.timestampDelta;
309     if (!pb_encode_tag_for_field(
310             stream,
311             &chre_cross_validation_sensor_SensorData_fields
312                 [chre_cross_validation_sensor_SensorData_datapoints_tag - 1])) {
313       return false;
314     }
315     chre_cross_validation_sensor_SensorDatapoint datapoint = makeDatapoint(
316         encodeStepCounterSensorDatapointValue, &sampleData, currentTimestamp);
317     if (!pb_encode_submessage(
318             stream, chre_cross_validation_sensor_SensorDatapoint_fields,
319             &datapoint)) {
320       return false;
321     }
322   }
323   return true;
324 }
325 
handleStartSensorMessage(const chre_cross_validation_sensor_StartSensorCommand & startSensorCommand)326 bool Manager::handleStartSensorMessage(
327     const chre_cross_validation_sensor_StartSensorCommand &startSensorCommand) {
328   uint8_t sensorType = startSensorCommand.chreSensorType;
329   uint64_t intervalFromApInNs =
330       startSensorCommand.intervalInMs * kOneMillisecondInNanoseconds;
331   uint64_t latencyInNs =
332       startSensorCommand.latencyInMs * kOneMillisecondInNanoseconds;
333   bool isContinuous = startSensorCommand.isContinuous;
334   uint32_t sensorIndex = startSensorCommand.sensorIndex;
335 
336   uint32_t handle;
337   if (!getSensor(sensorType, sensorIndex, &handle)) {
338     // TODO(b/146052784): Test other sensor configure modes
339     LOGE("Could not find default sensor for sensorType %" PRIu8
340          " index %" PRIu32,
341          sensorType, sensorIndex);
342     return false;
343   }
344 
345   LOGI("Starting x-validation for sensor type %" PRIu8 " index %" PRIu32,
346        sensorType, sensorIndex);
347   chreSensorInfo sensorInfo{};
348   if (!chreGetSensorInfo(handle, &sensorInfo)) {
349     LOGE("Error getting sensor info for sensor");
350     return false;
351   }
352 
353   // TODO(b/154271547): Send minInterval to AP and have the AP decide from
354   // both CHRE and AP min and max interval.
355   uint64_t intervalInNs = std::max(intervalFromApInNs, sensorInfo.minInterval);
356   // Copy hostEndpoint param from previous version of cross validator
357   // state
358   mCrossValidatorState = CrossValidatorState(
359       CrossValidatorType::SENSOR, sensorType, handle, chreGetTime(),
360       mCrossValidatorState->hostEndpoint, isContinuous);
361   if (!chreSensorConfigure(handle, CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS,
362                            intervalInNs, latencyInNs)) {
363     LOGE("Error configuring sensor with sensorType %" PRIu8
364          ", interval %" PRIu64 "ns, and latency %" PRIu64 "ns",
365          sensorType, intervalInNs, latencyInNs);
366     return false;
367   }
368   LOGD("Sensor with type %" PRIu8 " is configured", sensorType);
369   return true;
370 }
371 
isValidHeader(const chreSensorDataHeader & header)372 bool Manager::isValidHeader(const chreSensorDataHeader &header) {
373   // On-change sensors may send cached values because the data value has not
374   // changed since the test started
375   bool isTimestampValid =
376       !mCrossValidatorState->isContinuous ||
377       header.baseTimestamp >= mCrossValidatorState->timeStart;
378   return header.readingCount > 0 && isTimestampValid;
379 }
380 
handleStartMessage(uint16_t hostEndpoint,const chreMessageFromHostData * hostData)381 void Manager::handleStartMessage(uint16_t hostEndpoint,
382                                  const chreMessageFromHostData *hostData) {
383   bool success = true;
384   // Default values for everything but hostEndpoint param
385   mCrossValidatorState = CrossValidatorState(CrossValidatorType::SENSOR, 0, 0,
386                                              0, hostEndpoint, false);
387   pb_istream_t istream = pb_istream_from_buffer(
388       static_cast<const pb_byte_t *>(hostData->message), hostData->messageSize);
389   chre_cross_validation_sensor_StartCommand startCommand =
390       chre_cross_validation_sensor_StartCommand_init_default;
391   if (!pb_decode(&istream, chre_cross_validation_sensor_StartCommand_fields,
392                  &startCommand)) {
393     LOGE("Could not decode start command");
394   } else {
395     switch (startCommand.which_command) {
396       case chre_cross_validation_sensor_StartCommand_startSensorCommand_tag:
397         success =
398             handleStartSensorMessage(startCommand.command.startSensorCommand);
399         break;
400       default:
401         LOGE("Unknown start command type %" PRIu8, startCommand.which_command);
402     }
403   }
404   // If error occurred in validation setup then resetting mCrossValidatorState
405   // will alert the event handler
406   if (!success) {
407     mCrossValidatorState.reset();
408   }
409 }
410 
handleInfoMessage(uint16_t hostEndpoint,const chreMessageFromHostData * hostData)411 void Manager::handleInfoMessage(uint16_t hostEndpoint,
412                                 const chreMessageFromHostData *hostData) {
413   chre_cross_validation_sensor_SensorInfoResponse infoResponse =
414       chre_cross_validation_sensor_SensorInfoResponse_init_default;
415   pb_istream_t istream = pb_istream_from_buffer(
416       static_cast<const pb_byte_t *>(hostData->message), hostData->messageSize);
417   chre_cross_validation_sensor_SensorInfoCommand infoCommand =
418       chre_cross_validation_sensor_SensorInfoCommand_init_default;
419 
420   infoCommand.sensorName.funcs.decode = decodeSensorName;
421   infoCommand.sensorName.arg = mSensorNameArray;
422 
423   if (!pb_decode(&istream,
424                  chre_cross_validation_sensor_SensorInfoCommand_fields,
425                  &infoCommand)) {
426     LOGE("Could not decode info command");
427     sendInfoResponse(hostEndpoint, infoResponse);
428     return;
429   }
430   LOGI("Global sensor name: %s", mSensorNameArray);
431 
432   struct SensorNameCallbackData nameData{};
433   uint32_t handle;
434   infoResponse.has_chreSensorType = true;
435   infoResponse.chreSensorType = infoCommand.chreSensorType;
436   infoResponse.has_isAvailable = true;
437   infoResponse.isAvailable = false;
438   infoResponse.has_sensorIndex = false;
439 
440   bool supportsMultiSensors =
441       chreSensorFind(infoCommand.chreSensorType, 1, &handle);
442   for (uint8_t i = 0; chreSensorFind(infoCommand.chreSensorType, i, &handle);
443        i++) {
444     struct chreSensorInfo info{};
445     if (!chreGetSensorInfo(handle, &info)) {
446       LOGE("Failed to get sensor info");
447       continue;
448     }
449     LOGI("Found sensor %" PRIu8 ". name: %s", i, info.sensorName);
450     bool hasValidSensor =
451         !supportsMultiSensors || strcmp(info.sensorName, mSensorNameArray) == 0;
452     if (hasValidSensor) {
453       infoResponse.isAvailable = true;
454       infoResponse.has_sensorIndex = true;
455       infoResponse.sensorIndex = i;
456       nameData.sensorName = info.sensorName;
457       nameData.size = strlen(info.sensorName);
458       infoResponse.sensorName.funcs.encode = encodeSensorName;
459       infoResponse.sensorName.arg = &nameData;
460       break;
461     }
462   }
463   sendInfoResponse(hostEndpoint, infoResponse);
464 }
465 
handleMessageFromHost(uint32_t senderInstanceId,const chreMessageFromHostData * hostData)466 void Manager::handleMessageFromHost(uint32_t senderInstanceId,
467                                     const chreMessageFromHostData *hostData) {
468   if (senderInstanceId != CHRE_INSTANCE_ID) {
469     LOGE("Incorrect sender instance id: %" PRIu32, senderInstanceId);
470     return;
471   }
472   uint16_t hostEndpoint;
473   if (hostData->hostEndpoint != CHRE_HOST_ENDPOINT_UNSPECIFIED) {
474     hostEndpoint = hostData->hostEndpoint;
475   } else {
476     hostEndpoint = CHRE_HOST_ENDPOINT_BROADCAST;
477   }
478 
479   switch (hostData->messageType) {
480     case chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_START:
481       handleStartMessage(hostEndpoint, hostData);
482       break;
483     case chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_INFO:
484       handleInfoMessage(hostEndpoint, hostData);
485       break;
486     default:
487       LOGE("Unknown message type %" PRIu32 " for host message",
488            hostData->messageType);
489   }
490 }
491 
makeSensorThreeAxisData(const chreSensorThreeAxisData * threeAxisDataFromChre,uint8_t sensorType)492 chre_cross_validation_sensor_Data Manager::makeSensorThreeAxisData(
493     const chreSensorThreeAxisData *threeAxisDataFromChre, uint8_t sensorType) {
494   chre_cross_validation_sensor_SensorData newThreeAxisData = {
495       .has_chreSensorType = true,
496       .chreSensorType = sensorType,
497       .has_accuracy = true,
498       .accuracy = threeAxisDataFromChre->header.accuracy,
499       .datapoints = {
500           .funcs = {.encode = encodeThreeAxisSensorDatapoints},
501           .arg = const_cast<chreSensorThreeAxisData *>(threeAxisDataFromChre)}};
502   chre_cross_validation_sensor_Data newData = {
503       .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
504       .data =
505           {
506               .sensorData = newThreeAxisData,
507           },
508   };
509   return newData;
510 }
511 
makeSensorFloatData(const chreSensorFloatData * floatDataFromChre,uint8_t sensorType)512 chre_cross_validation_sensor_Data Manager::makeSensorFloatData(
513     const chreSensorFloatData *floatDataFromChre, uint8_t sensorType) {
514   chre_cross_validation_sensor_SensorData newfloatData = {
515       .has_chreSensorType = true,
516       .chreSensorType = sensorType,
517       .has_accuracy = true,
518       .accuracy = floatDataFromChre->header.accuracy,
519       .datapoints = {
520           .funcs = {.encode = encodeFloatSensorDatapoints},
521           .arg = const_cast<chreSensorFloatData *>(floatDataFromChre)}};
522   chre_cross_validation_sensor_Data newData = {
523       .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
524       .data =
525           {
526               .sensorData = newfloatData,
527           },
528   };
529   return newData;
530 }
531 
makeSensorProximityData(const chreSensorByteData * proximityDataFromChre)532 chre_cross_validation_sensor_Data Manager::makeSensorProximityData(
533     const chreSensorByteData *proximityDataFromChre) {
534   chre_cross_validation_sensor_SensorData newProximityData = {
535       .has_chreSensorType = true,
536       .chreSensorType = CHRE_SENSOR_TYPE_PROXIMITY,
537       .has_accuracy = true,
538       .accuracy = proximityDataFromChre->header.accuracy,
539       .datapoints = {
540           .funcs = {.encode = encodeProximitySensorDatapoints},
541           .arg = const_cast<chreSensorByteData *>(proximityDataFromChre)}};
542   chre_cross_validation_sensor_Data newData = {
543       .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
544       .data =
545           {
546               .sensorData = newProximityData,
547           },
548   };
549   return newData;
550 }
551 
makeSensorStepCounterData(const chreSensorUint64Data * stepCounterDataFromChre)552 chre_cross_validation_sensor_Data Manager::makeSensorStepCounterData(
553     const chreSensorUint64Data *stepCounterDataFromChre) {
554   chre_cross_validation_sensor_SensorData newStepCounterData = {
555       .has_chreSensorType = true,
556       .chreSensorType = CHRE_SENSOR_TYPE_STEP_COUNTER,
557       .has_accuracy = true,
558       .accuracy = stepCounterDataFromChre->header.accuracy,
559       .datapoints = {
560           .funcs = {.encode = encodeStepCounterSensorDatapoints},
561           .arg = const_cast<chreSensorUint64Data *>(stepCounterDataFromChre)}};
562   chre_cross_validation_sensor_Data newData = {
563       .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
564       .data =
565           {
566               .sensorData = newStepCounterData,
567           },
568   };
569   return newData;
570 }
571 
handleSensorThreeAxisData(const chreSensorThreeAxisData * threeAxisDataFromChre,uint8_t sensorType)572 void Manager::handleSensorThreeAxisData(
573     const chreSensorThreeAxisData *threeAxisDataFromChre, uint8_t sensorType) {
574   if (processSensorData(threeAxisDataFromChre->header, sensorType)) {
575     chre_cross_validation_sensor_Data newData =
576         makeSensorThreeAxisData(threeAxisDataFromChre, sensorType);
577     sendDataToHost(newData);
578   }
579 }
580 
handleSensorFloatData(const chreSensorFloatData * floatDataFromChre,uint8_t sensorType)581 void Manager::handleSensorFloatData(
582     const chreSensorFloatData *floatDataFromChre, uint8_t sensorType) {
583   if (processSensorData(floatDataFromChre->header, sensorType)) {
584     chre_cross_validation_sensor_Data newData =
585         makeSensorFloatData(floatDataFromChre, sensorType);
586     sendDataToHost(newData);
587   }
588 }
589 
handleProximityData(const chreSensorByteData * proximityDataFromChre)590 void Manager::handleProximityData(
591     const chreSensorByteData *proximityDataFromChre) {
592   if (processSensorData(proximityDataFromChre->header,
593                         CHRE_SENSOR_TYPE_PROXIMITY)) {
594     chre_cross_validation_sensor_Data newData =
595         makeSensorProximityData(proximityDataFromChre);
596     sendDataToHost(newData);
597   }
598 }
599 
handleStepCounterData(const chreSensorUint64Data * stepCounterDataFromChre)600 void Manager::handleStepCounterData(
601     const chreSensorUint64Data *stepCounterDataFromChre) {
602   if (processSensorData(stepCounterDataFromChre->header,
603                         CHRE_SENSOR_TYPE_STEP_COUNTER)) {
604     chre_cross_validation_sensor_Data newData =
605         makeSensorStepCounterData(stepCounterDataFromChre);
606     sendDataToHost(newData);
607   }
608 }
609 
sendDataToHost(const chre_cross_validation_sensor_Data & data)610 void Manager::sendDataToHost(const chre_cross_validation_sensor_Data &data) {
611   test_shared::sendMessageToHost(
612       mCrossValidatorState->hostEndpoint, &data,
613       chre_cross_validation_sensor_Data_fields,
614       chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_DATA);
615 }
616 
sendInfoResponse(uint16_t hostEndpoint,const chre_cross_validation_sensor_SensorInfoResponse & infoResponse)617 void Manager::sendInfoResponse(
618     uint16_t hostEndpoint,
619     const chre_cross_validation_sensor_SensorInfoResponse &infoResponse) {
620   test_shared::sendMessageToHost(
621       hostEndpoint, &infoResponse,
622       chre_cross_validation_sensor_SensorInfoResponse_fields,
623       chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_INFO_RESPONSE);
624 }
625 
processSensorData(const chreSensorDataHeader & header,uint8_t sensorType)626 bool Manager::processSensorData(const chreSensorDataHeader &header,
627                                 uint8_t sensorType) {
628   if (!mCrossValidatorState.has_value()) {
629     LOGE("Start message not received or invalid when data received");
630   } else if (!isValidHeader(header)) {
631     LOGE("Invalid data being thrown away");
632   } else if (!sensorTypeIsValid(sensorType)) {
633     LOGE("Unexpected sensor data type %" PRIu8 ", expected %" PRIu8, sensorType,
634          mCrossValidatorState->sensorType);
635   } else {
636     return true;
637   }
638   return false;
639 }
640 
sensorTypeIsValid(uint8_t sensorType)641 bool Manager::sensorTypeIsValid(uint8_t sensorType) {
642   return sensorType == mCrossValidatorState->sensorType;
643 }
644 
getSensor(uint32_t sensorType,uint32_t sensorIndex,uint32_t * handle)645 bool Manager::getSensor(uint32_t sensorType, uint32_t sensorIndex,
646                         uint32_t *handle) {
647   bool success = false;
648 
649   bool supportsMultiSensor = (chreGetApiVersion() >= CHRE_API_VERSION_1_5);
650   if (sensorIndex > UINT8_MAX) {
651     LOGE("CHRE only supports max of 255 sensor indices");
652   } else if (!supportsMultiSensor && sensorIndex != 0) {
653     LOGW("CHRE API does not support multi-sensors");
654   } else {
655     success = chreSensorFind(sensorType, sensorIndex, handle);
656   }
657 
658   return success;
659 }
660 
661 }  // namespace chre::cross_validator_sensor
662