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