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