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
38 namespace {
39
decodeSensorName(pb_istream_t * stream,const pb_field_s * field,void ** arg)40 bool decodeSensorName(pb_istream_t *stream, const pb_field_s *field,
41 void **arg) {
42 unsigned char *name = static_cast<unsigned char *>(*arg);
43
44 if (stream->bytes_left > kMaxSensorNameSize - 1) return false;
45
46 size_t bytesToCopy = stream->bytes_left;
47 if (!pb_read(stream, name, stream->bytes_left)) return false;
48 name[bytesToCopy] = '\0';
49
50 return true;
51 }
52
53 } // namespace
54
~Manager()55 Manager::~Manager() {
56 cleanup();
57 }
58
cleanup()59 void Manager::cleanup() {
60 if (mCrossValidatorState.has_value()) {
61 switch (mCrossValidatorState->crossValidatorType) {
62 case CrossValidatorType::SENSOR:
63 if (!chreSensorConfigureModeOnly(mCrossValidatorState->sensorHandle,
64 CHRE_SENSOR_CONFIGURE_MODE_DONE)) {
65 LOGE(
66 "Sensor cleanup failed when trying to configure sensor with "
67 "handle "
68 "%" PRIu32 " to done mode",
69 mCrossValidatorState->sensorHandle);
70 }
71 break;
72 default:
73 break;
74 }
75 }
76 }
77
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)78 void Manager::handleEvent(uint32_t senderInstanceId, uint16_t eventType,
79 const void *eventData) {
80 switch (eventType) {
81 case CHRE_EVENT_MESSAGE_FROM_HOST:
82 handleMessageFromHost(
83 senderInstanceId,
84 static_cast<const chreMessageFromHostData *>(eventData));
85 break;
86 // TODO(b/146052784): Check that data received from CHRE apis is the correct
87 // type for current test.
88 case CHRE_EVENT_SENSOR_ACCELEROMETER_DATA:
89 handleSensorThreeAxisData(
90 static_cast<const chreSensorThreeAxisData *>(eventData),
91 CHRE_SENSOR_TYPE_ACCELEROMETER);
92 break;
93 case CHRE_EVENT_SENSOR_GYROSCOPE_DATA:
94 handleSensorThreeAxisData(
95 static_cast<const chreSensorThreeAxisData *>(eventData),
96 CHRE_SENSOR_TYPE_GYROSCOPE);
97 break;
98 case CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA:
99 handleSensorThreeAxisData(
100 static_cast<const chreSensorThreeAxisData *>(eventData),
101 CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD);
102 break;
103 case CHRE_EVENT_SENSOR_PRESSURE_DATA:
104 handleSensorFloatData(static_cast<const chreSensorFloatData *>(eventData),
105 CHRE_SENSOR_TYPE_PRESSURE);
106 break;
107 case CHRE_EVENT_SENSOR_LIGHT_DATA:
108 handleSensorFloatData(static_cast<const chreSensorFloatData *>(eventData),
109 CHRE_SENSOR_TYPE_LIGHT);
110 break;
111 case CHRE_EVENT_SENSOR_PROXIMITY_DATA:
112 handleProximityData(static_cast<const chreSensorByteData *>(eventData));
113 break;
114 case CHRE_EVENT_SENSOR_STEP_COUNTER_DATA:
115 handleStepCounterData(
116 static_cast<const chreSensorUint64Data *>(eventData));
117 break;
118 case CHRE_EVENT_SENSOR_SAMPLING_CHANGE:
119 // Ignore sampling state changes
120 break;
121 default:
122 LOGE("Got unknown event type from senderInstanceId %" PRIu32
123 " and with eventType %" PRIu16,
124 senderInstanceId, eventType);
125 }
126 }
127
encodeThreeAxisSensorDatapointValues(pb_ostream_t * stream,const pb_field_t *,void * const * arg)128 bool Manager::encodeThreeAxisSensorDatapointValues(pb_ostream_t *stream,
129 const pb_field_t * /*field*/,
130 void *const *arg) {
131 const auto *sensorThreeAxisDataSample = static_cast<
132 const chreSensorThreeAxisData::chreSensorThreeAxisSampleData *>(*arg);
133
134 for (size_t i = 0; i < 3; i++) {
135 if (!pb_encode_tag_for_field(
136 stream,
137 &chre_cross_validation_sensor_SensorDatapoint_fields
138 [chre_cross_validation_sensor_SensorDatapoint_values_tag -
139 1])) {
140 return false;
141 }
142 if (!pb_encode_fixed32(stream, &sensorThreeAxisDataSample->values[i])) {
143 return false;
144 }
145 }
146 return true;
147 }
148
makeDatapoint(bool (* encodeFunc)(pb_ostream_t *,const pb_field_t *,void * const *),const void * sampleDataFromChre,uint64_t currentTimestamp)149 chre_cross_validation_sensor_SensorDatapoint Manager::makeDatapoint(
150 bool (*encodeFunc)(pb_ostream_t *, const pb_field_t *, void *const *),
151 const void *sampleDataFromChre, uint64_t currentTimestamp) {
152 return chre_cross_validation_sensor_SensorDatapoint{
153 .has_timestampInNs = true,
154 .timestampInNs = currentTimestamp,
155 .values = {.funcs = {.encode = encodeFunc},
156 .arg = const_cast<void *>(sampleDataFromChre)}};
157 }
158
encodeFloatSensorDatapointValue(pb_ostream_t * stream,const pb_field_t *,void * const * arg)159 bool Manager::encodeFloatSensorDatapointValue(pb_ostream_t *stream,
160 const pb_field_t * /*field*/,
161 void *const *arg) {
162 const auto *sensorFloatDataSample =
163 static_cast<const chreSensorFloatData::chreSensorFloatSampleData *>(*arg);
164 if (!pb_encode_tag_for_field(
165 stream,
166 &chre_cross_validation_sensor_SensorDatapoint_fields
167 [chre_cross_validation_sensor_SensorDatapoint_values_tag - 1])) {
168 return false;
169 }
170 if (!pb_encode_fixed32(stream, &sensorFloatDataSample->value)) {
171 return false;
172 }
173 return true;
174 }
175
encodeProximitySensorDatapointValue(pb_ostream_t * stream,const pb_field_t *,void * const * arg)176 bool Manager::encodeProximitySensorDatapointValue(pb_ostream_t *stream,
177 const pb_field_t * /*field*/,
178 void *const *arg) {
179 const auto *sensorFloatDataSample =
180 static_cast<const chreSensorByteData::chreSensorByteSampleData *>(*arg);
181 if (!pb_encode_tag_for_field(
182 stream,
183 &chre_cross_validation_sensor_SensorDatapoint_fields
184 [chre_cross_validation_sensor_SensorDatapoint_values_tag - 1])) {
185 return false;
186 }
187 float isNearFloat = sensorFloatDataSample->isNear ? 0.0 : 1.0;
188 if (!pb_encode_fixed32(stream, &isNearFloat)) {
189 return false;
190 }
191 return true;
192 }
193
encodeStepCounterSensorDatapointValue(pb_ostream_t * stream,const pb_field_t * field,void * const * arg)194 bool Manager::encodeStepCounterSensorDatapointValue(pb_ostream_t *stream,
195 const pb_field_t *field,
196 void *const *arg) {
197 const auto *sensorUint64DataSample =
198 static_cast<const chreSensorUint64Data::chreSensorUint64SampleData *>(
199 *arg);
200 if (!pb_encode_tag_for_field(
201 stream,
202 &chre_cross_validation_sensor_SensorDatapoint_fields
203 [chre_cross_validation_sensor_SensorDatapoint_values_tag - 1])) {
204 return false;
205 }
206 // This value is casted to a float for the Java sensors framework so do it
207 // here to make it easier to encode into the existing proto message.
208 float stepValue = float(sensorUint64DataSample->value);
209 if (!pb_encode_fixed32(stream, &stepValue)) {
210 return false;
211 }
212 return true;
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 * field,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 bool success = false;
329 uint8_t sensorType = startSensorCommand.chreSensorType;
330 uint64_t intervalFromApInNs =
331 startSensorCommand.intervalInMs * kOneMillisecondInNanoseconds;
332 uint64_t latencyInNs =
333 startSensorCommand.latencyInMs * kOneMillisecondInNanoseconds;
334 bool isContinuous = startSensorCommand.isContinuous;
335 uint32_t sensorIndex = startSensorCommand.sensorIndex;
336
337 uint32_t handle;
338 if (!getSensor(sensorType, sensorIndex, &handle)) {
339 LOGE("Could not find default sensor for sensorType %" PRIu8
340 " index %" PRIu32,
341 sensorType, sensorIndex);
342 // TODO(b/146052784): Test other sensor configure modes
343 } else {
344 LOGI("Starting x-validation for sensor type %" PRIu8 " index %" PRIu32,
345 sensorType, sensorIndex);
346 chreSensorInfo sensorInfo;
347 if (!chreGetSensorInfo(handle, &sensorInfo)) {
348 LOGE("Error getting sensor info for sensor");
349 } else {
350 // TODO(b/154271547): Send minInterval to AP and have the AP decide from
351 // both CHRE and AP min and max interval.
352 uint64_t intervalInNs =
353 std::max(intervalFromApInNs, sensorInfo.minInterval);
354 // Copy hostEndpoint param from previous version of cross validator
355 // state
356 mCrossValidatorState = CrossValidatorState(
357 CrossValidatorType::SENSOR, sensorType, handle, chreGetTime(),
358 mCrossValidatorState->hostEndpoint, isContinuous);
359 if (!chreSensorConfigure(handle, CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS,
360 intervalInNs, latencyInNs)) {
361 LOGE("Error configuring sensor with sensorType %" PRIu8
362 ", interval %" PRIu64 "ns, and latency %" PRIu64 "ns",
363 sensorType, intervalInNs, latencyInNs);
364 } else {
365 LOGD("Sensor with sensor type %" PRIu8 " configured", sensorType);
366 success = true;
367 }
368 }
369 }
370 return success;
371 }
372
isValidHeader(const chreSensorDataHeader & header)373 bool Manager::isValidHeader(const chreSensorDataHeader &header) {
374 // On-change sensors may send cached values because the data value has not
375 // changed since the test started
376 bool isTimestampValid =
377 !mCrossValidatorState->isContinuous ||
378 header.baseTimestamp >= mCrossValidatorState->timeStart;
379 return header.readingCount > 0 && isTimestampValid;
380 }
381
handleStartMessage(uint16_t hostEndpoint,const chreMessageFromHostData * hostData)382 void Manager::handleStartMessage(uint16_t hostEndpoint,
383 const chreMessageFromHostData *hostData) {
384 bool success = true;
385 // Default values for everything but hostEndpoint param
386 mCrossValidatorState = CrossValidatorState(CrossValidatorType::SENSOR, 0, 0,
387 0, hostEndpoint, false);
388 pb_istream_t istream = pb_istream_from_buffer(
389 static_cast<const pb_byte_t *>(hostData->message), hostData->messageSize);
390 chre_cross_validation_sensor_StartCommand startCommand =
391 chre_cross_validation_sensor_StartCommand_init_default;
392 if (!pb_decode(&istream, chre_cross_validation_sensor_StartCommand_fields,
393 &startCommand)) {
394 LOGE("Could not decode start command");
395 } else {
396 switch (startCommand.which_command) {
397 case chre_cross_validation_sensor_StartCommand_startSensorCommand_tag:
398 success =
399 handleStartSensorMessage(startCommand.command.startSensorCommand);
400 break;
401 default:
402 LOGE("Unknown start command type %" PRIu8, startCommand.which_command);
403 }
404 }
405 // If error occurred in validation setup then resetting mCrossValidatorState
406 // will alert the event handler
407 if (!success) {
408 mCrossValidatorState.reset();
409 }
410 }
411
handleInfoMessage(uint16_t hostEndpoint,const chreMessageFromHostData * hostData)412 void Manager::handleInfoMessage(uint16_t hostEndpoint,
413 const chreMessageFromHostData *hostData) {
414 chre_cross_validation_sensor_SensorInfoResponse infoResponse =
415 chre_cross_validation_sensor_SensorInfoResponse_init_default;
416 pb_istream_t istream = pb_istream_from_buffer(
417 static_cast<const pb_byte_t *>(hostData->message), hostData->messageSize);
418 chre_cross_validation_sensor_SensorInfoCommand infoCommand =
419 chre_cross_validation_sensor_SensorInfoCommand_init_default;
420
421 infoCommand.sensorName.funcs.decode = decodeSensorName;
422 infoCommand.sensorName.arg = mSensorNameArray;
423
424 if (!pb_decode(&istream,
425 chre_cross_validation_sensor_SensorInfoCommand_fields,
426 &infoCommand)) {
427 LOGE("Could not decode info command");
428 } else {
429 uint32_t handle;
430 infoResponse.has_chreSensorType = true;
431 infoResponse.chreSensorType = infoCommand.chreSensorType;
432 infoResponse.has_isAvailable = true;
433 infoResponse.isAvailable = false;
434 infoResponse.has_sensorIndex = false;
435
436 bool supportsMultiSensors =
437 chreSensorFind(infoCommand.chreSensorType, 1, &handle);
438 for (uint8_t i = 0; chreSensorFind(infoCommand.chreSensorType, i, &handle);
439 i++) {
440 struct chreSensorInfo info;
441 if (!chreGetSensorInfo(handle, &info)) {
442 LOGE("Failed to get sensor info");
443 } else {
444 bool equal = true;
445 if (supportsMultiSensors) {
446 equal = (strcmp(info.sensorName, mSensorNameArray) == 0);
447 LOGI("Got sensor name %s in-name %s, equal %d", info.sensorName,
448 mSensorNameArray, equal);
449 }
450 if (equal) {
451 infoResponse.isAvailable = true;
452 infoResponse.has_sensorIndex = true;
453 infoResponse.sensorIndex = i;
454 break;
455 }
456 }
457 }
458 }
459
460 sendInfoResponse(hostEndpoint, infoResponse);
461 }
462
handleMessageFromHost(uint32_t senderInstanceId,const chreMessageFromHostData * hostData)463 void Manager::handleMessageFromHost(uint32_t senderInstanceId,
464 const chreMessageFromHostData *hostData) {
465 if (senderInstanceId != CHRE_INSTANCE_ID) {
466 LOGE("Incorrect sender instance id: %" PRIu32, senderInstanceId);
467 } else {
468 uint16_t hostEndpoint;
469 if (hostData->hostEndpoint != CHRE_HOST_ENDPOINT_UNSPECIFIED) {
470 hostEndpoint = hostData->hostEndpoint;
471 } else {
472 hostEndpoint = CHRE_HOST_ENDPOINT_BROADCAST;
473 }
474
475 switch (hostData->messageType) {
476 case chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_START:
477 handleStartMessage(hostEndpoint, hostData);
478 break;
479 case chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_INFO:
480 handleInfoMessage(hostEndpoint, hostData);
481 break;
482 default:
483 LOGE("Unknown message type %" PRIu32 " for host message",
484 hostData->messageType);
485 }
486 }
487 }
488
makeSensorThreeAxisData(const chreSensorThreeAxisData * threeAxisDataFromChre,uint8_t sensorType)489 chre_cross_validation_sensor_Data Manager::makeSensorThreeAxisData(
490 const chreSensorThreeAxisData *threeAxisDataFromChre, uint8_t sensorType) {
491 chre_cross_validation_sensor_SensorData newThreeAxisData = {
492 .has_chreSensorType = true,
493 .chreSensorType = sensorType,
494 .has_accuracy = true,
495 .accuracy = threeAxisDataFromChre->header.accuracy,
496 .datapoints = {
497 .funcs = {.encode = encodeThreeAxisSensorDatapoints},
498 .arg = const_cast<chreSensorThreeAxisData *>(threeAxisDataFromChre)}};
499 chre_cross_validation_sensor_Data newData = {
500 .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
501 .data =
502 {
503 .sensorData = newThreeAxisData,
504 },
505 };
506 return newData;
507 }
508
makeSensorFloatData(const chreSensorFloatData * floatDataFromChre,uint8_t sensorType)509 chre_cross_validation_sensor_Data Manager::makeSensorFloatData(
510 const chreSensorFloatData *floatDataFromChre, uint8_t sensorType) {
511 chre_cross_validation_sensor_SensorData newfloatData = {
512 .has_chreSensorType = true,
513 .chreSensorType = sensorType,
514 .has_accuracy = true,
515 .accuracy = floatDataFromChre->header.accuracy,
516 .datapoints = {
517 .funcs = {.encode = encodeFloatSensorDatapoints},
518 .arg = const_cast<chreSensorFloatData *>(floatDataFromChre)}};
519 chre_cross_validation_sensor_Data newData = {
520 .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
521 .data =
522 {
523 .sensorData = newfloatData,
524 },
525 };
526 return newData;
527 }
528
makeSensorProximityData(const chreSensorByteData * proximityDataFromChre)529 chre_cross_validation_sensor_Data Manager::makeSensorProximityData(
530 const chreSensorByteData *proximityDataFromChre) {
531 chre_cross_validation_sensor_SensorData newProximityData = {
532 .has_chreSensorType = true,
533 .chreSensorType = CHRE_SENSOR_TYPE_PROXIMITY,
534 .has_accuracy = true,
535 .accuracy = proximityDataFromChre->header.accuracy,
536 .datapoints = {
537 .funcs = {.encode = encodeProximitySensorDatapoints},
538 .arg = const_cast<chreSensorByteData *>(proximityDataFromChre)}};
539 chre_cross_validation_sensor_Data newData = {
540 .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
541 .data =
542 {
543 .sensorData = newProximityData,
544 },
545 };
546 return newData;
547 }
548
makeSensorStepCounterData(const chreSensorUint64Data * stepCounterDataFromChre)549 chre_cross_validation_sensor_Data Manager::makeSensorStepCounterData(
550 const chreSensorUint64Data *stepCounterDataFromChre) {
551 chre_cross_validation_sensor_SensorData newStepCounterData = {
552 .has_chreSensorType = true,
553 .chreSensorType = CHRE_SENSOR_TYPE_STEP_COUNTER,
554 .has_accuracy = true,
555 .accuracy = stepCounterDataFromChre->header.accuracy,
556 .datapoints = {
557 .funcs = {.encode = encodeStepCounterSensorDatapoints},
558 .arg = const_cast<chreSensorUint64Data *>(stepCounterDataFromChre)}};
559 chre_cross_validation_sensor_Data newData = {
560 .which_data = chre_cross_validation_sensor_Data_sensorData_tag,
561 .data =
562 {
563 .sensorData = newStepCounterData,
564 },
565 };
566 return newData;
567 }
568
handleSensorThreeAxisData(const chreSensorThreeAxisData * threeAxisDataFromChre,uint8_t sensorType)569 void Manager::handleSensorThreeAxisData(
570 const chreSensorThreeAxisData *threeAxisDataFromChre, uint8_t sensorType) {
571 if (processSensorData(threeAxisDataFromChre->header, sensorType)) {
572 chre_cross_validation_sensor_Data newData =
573 makeSensorThreeAxisData(threeAxisDataFromChre, sensorType);
574 sendDataToHost(newData);
575 }
576 }
577
handleSensorFloatData(const chreSensorFloatData * floatDataFromChre,uint8_t sensorType)578 void Manager::handleSensorFloatData(
579 const chreSensorFloatData *floatDataFromChre, uint8_t sensorType) {
580 if (processSensorData(floatDataFromChre->header, sensorType)) {
581 chre_cross_validation_sensor_Data newData =
582 makeSensorFloatData(floatDataFromChre, sensorType);
583 sendDataToHost(newData);
584 }
585 }
586
handleProximityData(const chreSensorByteData * proximityDataFromChre)587 void Manager::handleProximityData(
588 const chreSensorByteData *proximityDataFromChre) {
589 if (processSensorData(proximityDataFromChre->header,
590 CHRE_SENSOR_TYPE_PROXIMITY)) {
591 chre_cross_validation_sensor_Data newData =
592 makeSensorProximityData(proximityDataFromChre);
593 sendDataToHost(newData);
594 }
595 }
596
handleStepCounterData(const chreSensorUint64Data * stepCounterDataFromChre)597 void Manager::handleStepCounterData(
598 const chreSensorUint64Data *stepCounterDataFromChre) {
599 if (processSensorData(stepCounterDataFromChre->header,
600 CHRE_SENSOR_TYPE_STEP_COUNTER)) {
601 chre_cross_validation_sensor_Data newData =
602 makeSensorStepCounterData(stepCounterDataFromChre);
603 sendDataToHost(newData);
604 }
605 }
606
sendDataToHost(const chre_cross_validation_sensor_Data & data)607 void Manager::sendDataToHost(const chre_cross_validation_sensor_Data &data) {
608 sendMessageToHost(
609 mCrossValidatorState->hostEndpoint,
610 chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_DATA,
611 chre_cross_validation_sensor_Data_fields, &data);
612 }
613
sendInfoResponse(uint16_t hostEndpoint,const chre_cross_validation_sensor_SensorInfoResponse & infoResponse)614 void Manager::sendInfoResponse(
615 uint16_t hostEndpoint,
616 const chre_cross_validation_sensor_SensorInfoResponse &infoResponse) {
617 sendMessageToHost(
618 hostEndpoint,
619 chre_cross_validation_sensor_MessageType_CHRE_CROSS_VALIDATION_INFO_RESPONSE,
620 chre_cross_validation_sensor_SensorInfoResponse_fields, &infoResponse);
621 }
622
sendMessageToHost(uint16_t hostEndpoint,uint16_t messageType,const pb_field_t fields[],const void * srcStruct)623 void Manager::sendMessageToHost(uint16_t hostEndpoint, uint16_t messageType,
624 const pb_field_t fields[],
625 const void *srcStruct) {
626 size_t encodedSize;
627 if (!pb_get_encoded_size(&encodedSize, fields, srcStruct)) {
628 LOGE("Could not get encoded size of proto message");
629 } else {
630 pb_byte_t *buffer = static_cast<pb_byte_t *>(chreHeapAlloc(encodedSize));
631 if (buffer == nullptr) {
632 LOG_OOM();
633 } else {
634 pb_ostream_t ostream = pb_ostream_from_buffer(buffer, encodedSize);
635 if (!pb_encode(&ostream, fields, srcStruct)) {
636 LOGE("Could not encode proto message");
637 } else if (!chreSendMessageToHostEndpoint(
638 static_cast<void *>(buffer), encodedSize, messageType,
639 hostEndpoint, heapFreeMessageCallback)) {
640 LOGE("Could not send message to host");
641 }
642 }
643 }
644 }
645
processSensorData(const chreSensorDataHeader & header,uint8_t sensorType)646 bool Manager::processSensorData(const chreSensorDataHeader &header,
647 uint8_t sensorType) {
648 if (!mCrossValidatorState.has_value()) {
649 LOGE("Start message not received or invalid when data received");
650 } else if (!isValidHeader(header)) {
651 LOGE("Invalid data being thrown away");
652 } else if (!sensorTypeIsValid(sensorType)) {
653 LOGE("Unexpected sensor data type %" PRIu8 ", expected %" PRIu8, sensorType,
654 mCrossValidatorState->sensorType);
655 } else {
656 return true;
657 }
658 return false;
659 }
660
sensorTypeIsValid(uint8_t sensorType)661 bool Manager::sensorTypeIsValid(uint8_t sensorType) {
662 return sensorType == mCrossValidatorState->sensorType;
663 }
664
getSensor(uint32_t sensorType,uint32_t sensorIndex,uint32_t * handle)665 bool Manager::getSensor(uint32_t sensorType, uint32_t sensorIndex,
666 uint32_t *handle) {
667 bool success = false;
668
669 bool supportsMultiSensor = (chreGetApiVersion() >= CHRE_API_VERSION_1_5);
670 if (sensorIndex > UINT8_MAX) {
671 LOGE("CHRE only supports max of 255 sensor indices");
672 } else if (!supportsMultiSensor && sensorIndex != 0) {
673 LOGW("CHRE API does not support multi-sensors");
674 } else {
675 success = chreSensorFind(sensorType, sensorIndex, handle);
676 }
677
678 return success;
679 }
680
681 } // namespace cross_validator_sensor
682
683 } // namespace chre
684