1 /*
2 * Copyright (C) 2022 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 <algorithm>
18 #include <cstdint>
19
20 #include "chre_api_test_manager.h"
21
22 #include "chre.h"
23 #include "chre/util/nanoapp/log.h"
24 #include "chre/util/time.h"
25
26 namespace {
27
28 constexpr uint64_t kSyncFunctionTimeout = 2 * chre::kOneSecondInNanoseconds;
29
30 /**
31 * The following constants are defined in chre_api_test.options.
32 */
33 constexpr uint32_t kThreeAxisDataReadingsMaxCount = 10;
34 constexpr uint32_t kChreBleAdvertisementReportMaxCount = 10;
35 constexpr uint32_t kChreAudioDataEventMaxSampleBufferSize = 200;
36
37 chre_rpc_GeneralEventsMessage gGeneralEventsMessage;
38
39 /**
40 * Closes the writer and invalidates the writer.
41 *
42 * @param T the RPC message type.
43 * @param writer the RPC ServerWriter.
44 */
45 template <typename T>
finishAndCloseWriter(Optional<ChreApiTestService::ServerWriter<T>> & writer)46 void finishAndCloseWriter(
47 Optional<ChreApiTestService::ServerWriter<T>> &writer) {
48 CHRE_ASSERT(writer.has_value());
49
50 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
51 CHRE_MESSAGE_PERMISSION_NONE);
52 writer->Finish();
53 writer.reset();
54 }
55
56 /**
57 * Writes a message to the writer, then closes the writer and invalidates the
58 * writer.
59 *
60 * @param T the RPC message type.
61 * @param writer the RPC ServerWriter.
62 * @param message the message to write.
63 */
64 template <typename T>
sendFinishAndCloseWriter(Optional<ChreApiTestService::ServerWriter<T>> & writer,const T & message)65 void sendFinishAndCloseWriter(
66 Optional<ChreApiTestService::ServerWriter<T>> &writer, const T &message) {
67 CHRE_ASSERT(writer.has_value());
68
69 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
70 CHRE_MESSAGE_PERMISSION_NONE);
71 pw::Status status = writer->Write(message);
72 CHRE_ASSERT(status.ok());
73 finishAndCloseWriter(writer);
74 }
75
76 /**
77 * Sends a failure message. If there is not a valid writer, this returns
78 * without doing anything.
79 *
80 * @param T the RPC message type.
81 * @param writer the RPC ServerWriter.
82 */
83 template <typename T>
sendFailureAndFinishCloseWriter(Optional<ChreApiTestService::ServerWriter<T>> & writer)84 void sendFailureAndFinishCloseWriter(
85 Optional<ChreApiTestService::ServerWriter<T>> &writer) {
86 CHRE_ASSERT(writer.has_value());
87
88 T message;
89 message.status = false;
90 sendFinishAndCloseWriter(writer, message);
91 }
92
93 template <>
sendFailureAndFinishCloseWriter(Optional<ChreApiTestService::ServerWriter<chre_rpc_GeneralEventsMessage>> & writer)94 void sendFailureAndFinishCloseWriter<chre_rpc_GeneralEventsMessage>(
95 Optional<ChreApiTestService::ServerWriter<chre_rpc_GeneralEventsMessage>>
96 &writer) {
97 CHRE_ASSERT(writer.has_value());
98
99 std::memset(&gGeneralEventsMessage, 0, sizeof(gGeneralEventsMessage));
100 gGeneralEventsMessage.status = false;
101 sendFinishAndCloseWriter(writer, gGeneralEventsMessage);
102 }
103 } // namespace
104
105 // Start ChreApiTestService RPC generated functions
106
ChreBleGetCapabilities(const google_protobuf_Empty & request,chre_rpc_Capabilities & response)107 pw::Status ChreApiTestService::ChreBleGetCapabilities(
108 const google_protobuf_Empty &request, chre_rpc_Capabilities &response) {
109 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
110 CHRE_MESSAGE_PERMISSION_NONE);
111 return validateInputAndCallChreBleGetCapabilities(request, response)
112 ? pw::OkStatus()
113 : pw::Status::InvalidArgument();
114 }
115
ChreBleGetFilterCapabilities(const google_protobuf_Empty & request,chre_rpc_Capabilities & response)116 pw::Status ChreApiTestService::ChreBleGetFilterCapabilities(
117 const google_protobuf_Empty &request, chre_rpc_Capabilities &response) {
118 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
119 CHRE_MESSAGE_PERMISSION_NONE);
120 return validateInputAndCallChreBleGetFilterCapabilities(request, response)
121 ? pw::OkStatus()
122 : pw::Status::InvalidArgument();
123 }
124
ChreSensorFindDefault(const chre_rpc_ChreSensorFindDefaultInput & request,chre_rpc_ChreSensorFindDefaultOutput & response)125 pw::Status ChreApiTestService::ChreSensorFindDefault(
126 const chre_rpc_ChreSensorFindDefaultInput &request,
127 chre_rpc_ChreSensorFindDefaultOutput &response) {
128 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
129 CHRE_MESSAGE_PERMISSION_NONE);
130 return validateInputAndCallChreSensorFindDefault(request, response)
131 ? pw::OkStatus()
132 : pw::Status::InvalidArgument();
133 }
134
ChreGetSensorInfo(const chre_rpc_ChreHandleInput & request,chre_rpc_ChreGetSensorInfoOutput & response)135 pw::Status ChreApiTestService::ChreGetSensorInfo(
136 const chre_rpc_ChreHandleInput &request,
137 chre_rpc_ChreGetSensorInfoOutput &response) {
138 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
139 CHRE_MESSAGE_PERMISSION_NONE);
140 return validateInputAndCallChreGetSensorInfo(request, response)
141 ? pw::OkStatus()
142 : pw::Status::InvalidArgument();
143 }
144
ChreGetSensorSamplingStatus(const chre_rpc_ChreHandleInput & request,chre_rpc_ChreGetSensorSamplingStatusOutput & response)145 pw::Status ChreApiTestService::ChreGetSensorSamplingStatus(
146 const chre_rpc_ChreHandleInput &request,
147 chre_rpc_ChreGetSensorSamplingStatusOutput &response) {
148 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
149 CHRE_MESSAGE_PERMISSION_NONE);
150 return validateInputAndCallChreGetSensorSamplingStatus(request, response)
151 ? pw::OkStatus()
152 : pw::Status::InvalidArgument();
153 }
154
ChreSensorConfigure(const chre_rpc_ChreSensorConfigureInput & request,chre_rpc_Status & response)155 pw::Status ChreApiTestService::ChreSensorConfigure(
156 const chre_rpc_ChreSensorConfigureInput &request,
157 chre_rpc_Status &response) {
158 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
159 CHRE_MESSAGE_PERMISSION_NONE);
160 return validateInputAndCallChreSensorConfigure(request, response)
161 ? pw::OkStatus()
162 : pw::Status::InvalidArgument();
163 }
164
ChreSensorConfigureModeOnly(const chre_rpc_ChreSensorConfigureModeOnlyInput & request,chre_rpc_Status & response)165 pw::Status ChreApiTestService::ChreSensorConfigureModeOnly(
166 const chre_rpc_ChreSensorConfigureModeOnlyInput &request,
167 chre_rpc_Status &response) {
168 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
169 CHRE_MESSAGE_PERMISSION_NONE);
170 return validateInputAndCallChreSensorConfigureModeOnly(request, response)
171 ? pw::OkStatus()
172 : pw::Status::InvalidArgument();
173 }
174
ChreAudioGetSource(const chre_rpc_ChreHandleInput & request,chre_rpc_ChreAudioGetSourceOutput & response)175 pw::Status ChreApiTestService::ChreAudioGetSource(
176 const chre_rpc_ChreHandleInput &request,
177 chre_rpc_ChreAudioGetSourceOutput &response) {
178 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
179 CHRE_MESSAGE_PERMISSION_NONE);
180 return validateInputAndCallChreAudioGetSource(request, response)
181 ? pw::OkStatus()
182 : pw::Status::InvalidArgument();
183 }
184
ChreAudioConfigureSource(const chre_rpc_ChreAudioConfigureSourceInput & request,chre_rpc_Status & response)185 pw::Status ChreApiTestService::ChreAudioConfigureSource(
186 const chre_rpc_ChreAudioConfigureSourceInput &request,
187 chre_rpc_Status &response) {
188 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
189 CHRE_MESSAGE_PERMISSION_NONE);
190 return validateInputAndCallChreAudioConfigureSource(request, response)
191 ? pw::OkStatus()
192 : pw::Status::InvalidArgument();
193 }
194
ChreAudioGetStatus(const chre_rpc_ChreHandleInput & request,chre_rpc_ChreAudioGetStatusOutput & response)195 pw::Status ChreApiTestService::ChreAudioGetStatus(
196 const chre_rpc_ChreHandleInput &request,
197 chre_rpc_ChreAudioGetStatusOutput &response) {
198 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
199 CHRE_MESSAGE_PERMISSION_NONE);
200 return validateInputAndCallChreAudioGetStatus(request, response)
201 ? pw::OkStatus()
202 : pw::Status::InvalidArgument();
203 }
204
ChreConfigureHostEndpointNotifications(const chre_rpc_ChreConfigureHostEndpointNotificationsInput & request,chre_rpc_Status & response)205 pw::Status ChreApiTestService::ChreConfigureHostEndpointNotifications(
206 const chre_rpc_ChreConfigureHostEndpointNotificationsInput &request,
207 chre_rpc_Status &response) {
208 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
209 CHRE_MESSAGE_PERMISSION_NONE);
210 return validateInputAndCallChreConfigureHostEndpointNotifications(request,
211 response)
212 ? pw::OkStatus()
213 : pw::Status::InvalidArgument();
214 }
215
ChreGetHostEndpointInfo(const chre_rpc_ChreGetHostEndpointInfoInput & request,chre_rpc_ChreGetHostEndpointInfoOutput & response)216 pw::Status ChreApiTestService::ChreGetHostEndpointInfo(
217 const chre_rpc_ChreGetHostEndpointInfoInput &request,
218 chre_rpc_ChreGetHostEndpointInfoOutput &response) {
219 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
220 CHRE_MESSAGE_PERMISSION_NONE);
221 return validateInputAndCallChreGetHostEndpointInfo(request, response)
222 ? pw::OkStatus()
223 : pw::Status::InvalidArgument();
224 }
225
226 // End ChreApiTestService RPC generated functions
227
228 // Start ChreApiTestService RPC sync functions
229
ChreBleStartScanSync(const chre_rpc_ChreBleStartScanAsyncInput & request,ServerWriter<chre_rpc_GeneralSyncMessage> & writer)230 void ChreApiTestService::ChreBleStartScanSync(
231 const chre_rpc_ChreBleStartScanAsyncInput &request,
232 ServerWriter<chre_rpc_GeneralSyncMessage> &writer) {
233 if (mWriter.has_value()) {
234 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
235 CHRE_MESSAGE_PERMISSION_NONE);
236 writer.Finish();
237 LOGE("ChreBleStartScanSync: a sync message already exists");
238 return;
239 }
240
241 mWriter = std::move(writer);
242 CHRE_ASSERT(mSyncTimerHandle == CHRE_TIMER_INVALID);
243 mRequestType = CHRE_BLE_REQUEST_TYPE_START_SCAN;
244
245 chre_rpc_Status status;
246 if (!validateInputAndCallChreBleStartScanAsync(request, status) ||
247 !status.status || !startSyncTimer()) {
248 sendFailureAndFinishCloseWriter(mWriter);
249 mSyncTimerHandle = CHRE_TIMER_INVALID;
250 LOGD("ChreBleStartScanSync: status: false (error)");
251 }
252 }
253
ChreBleStopScanSync(const google_protobuf_Empty & request,ServerWriter<chre_rpc_GeneralSyncMessage> & writer)254 void ChreApiTestService::ChreBleStopScanSync(
255 const google_protobuf_Empty &request,
256 ServerWriter<chre_rpc_GeneralSyncMessage> &writer) {
257 if (mWriter.has_value()) {
258 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
259 CHRE_MESSAGE_PERMISSION_NONE);
260 writer.Finish();
261 LOGE("ChreBleStopScanSync: a sync message already exists");
262 return;
263 }
264
265 mWriter = std::move(writer);
266 CHRE_ASSERT(mSyncTimerHandle == CHRE_TIMER_INVALID);
267 mRequestType = CHRE_BLE_REQUEST_TYPE_STOP_SCAN;
268
269 chre_rpc_Status status;
270 if (!validateInputAndCallChreBleStopScanAsync(request, status) ||
271 !status.status || !startSyncTimer()) {
272 sendFailureAndFinishCloseWriter(mWriter);
273 mSyncTimerHandle = CHRE_TIMER_INVALID;
274 LOGD("ChreBleStopScanSync: status: false (error)");
275 }
276 }
277
278 // End ChreApiTestService RPC sync functions
279
280 // Start ChreApiTestService event functions
281
GatherEvents(const chre_rpc_GatherEventsInput & request,ServerWriter<chre_rpc_GeneralEventsMessage> & writer)282 void ChreApiTestService::GatherEvents(
283 const chre_rpc_GatherEventsInput &request,
284 ServerWriter<chre_rpc_GeneralEventsMessage> &writer) {
285 if (mEventWriter.has_value()) {
286 LOGE("GatherEvents: an event gathering call already exists");
287 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
288 CHRE_MESSAGE_PERMISSION_NONE);
289 writer.Finish();
290 return;
291 }
292
293 if (request.eventTypes_count == 0) {
294 LOGE("GatherEvents: request.eventTypes_count == 0");
295 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
296 CHRE_MESSAGE_PERMISSION_NONE);
297 writer.Finish();
298 return;
299 }
300
301 for (uint32_t i = 0; i < request.eventTypes_count; ++i) {
302 if (request.eventTypes[i] < std::numeric_limits<uint16_t>::min() ||
303 request.eventTypes[i] > std::numeric_limits<uint16_t>::max()) {
304 LOGE("GatherEvents: invalid request.eventTypes at index: %" PRIu32, i);
305 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
306 CHRE_MESSAGE_PERMISSION_NONE);
307 writer.Finish();
308 return;
309 }
310
311 mEventTypes[i] = static_cast<uint16_t>(request.eventTypes[i]);
312 LOGD("GatherEvents: Watching for events with type: %" PRIu16,
313 mEventTypes[i]);
314 }
315
316 mEventWriter = std::move(writer);
317 CHRE_ASSERT(mEventTimerHandle == CHRE_TIMER_INVALID);
318 mEventTimerHandle = chreTimerSet(
319 request.timeoutInNs, &mEventTimerHandle /* cookie */, true /* oneShot */);
320 if (mEventTimerHandle == CHRE_TIMER_INVALID) {
321 LOGE("GatherEvents: Cannot set the event timer");
322 sendFailureAndFinishCloseWriter(mEventWriter);
323 mEventTimerHandle = CHRE_TIMER_INVALID;
324 } else {
325 mEventTypeCount = request.eventTypes_count;
326 mEventExpectedCount = request.eventCount;
327 mEventSentCount = 0;
328 LOGD("GatherEvents: mEventTypeCount: %" PRIu32
329 " mEventExpectedCount: %" PRIu32,
330 mEventTypeCount, mEventExpectedCount);
331 }
332 }
333
334 // End ChreApiTestService event functions
335
handleBleAsyncResult(const chreAsyncResult * result)336 void ChreApiTestService::handleBleAsyncResult(const chreAsyncResult *result) {
337 if (result == nullptr || !mWriter.has_value()) {
338 return;
339 }
340
341 if (result->requestType == mRequestType) {
342 chreTimerCancel(mSyncTimerHandle);
343 mSyncTimerHandle = CHRE_TIMER_INVALID;
344
345 chre_rpc_GeneralSyncMessage generalSyncMessage;
346 generalSyncMessage.status = result->success;
347 sendFinishAndCloseWriter(mWriter, generalSyncMessage);
348 LOGD("Active BLE sync function: status: %s",
349 generalSyncMessage.status ? "true" : "false");
350 }
351 }
352
handleChreAudioDataEvent(const chreAudioDataEvent * data)353 bool ChreApiTestService::handleChreAudioDataEvent(
354 const chreAudioDataEvent *data) {
355 // send the metadata
356 std::memset(&gGeneralEventsMessage, 0, sizeof(gGeneralEventsMessage));
357 gGeneralEventsMessage.data.chreAudioDataMetadata.version = data->version;
358 gGeneralEventsMessage.data.chreAudioDataMetadata.reserved =
359 0; // Must be set to 0 always
360 gGeneralEventsMessage.data.chreAudioDataMetadata.handle = data->handle;
361 gGeneralEventsMessage.data.chreAudioDataMetadata.timestamp = data->timestamp;
362 gGeneralEventsMessage.data.chreAudioDataMetadata.sampleRate =
363 data->sampleRate;
364 gGeneralEventsMessage.data.chreAudioDataMetadata.sampleCount =
365 data->sampleCount;
366 gGeneralEventsMessage.data.chreAudioDataMetadata.format = data->format;
367 gGeneralEventsMessage.status = true;
368 gGeneralEventsMessage.which_data =
369 chre_rpc_GeneralEventsMessage_chreAudioDataMetadata_tag;
370 sendPartialGeneralEventToHost(gGeneralEventsMessage);
371
372 // send the samples
373 std::memset(&gGeneralEventsMessage, 0, sizeof(gGeneralEventsMessage));
374 gGeneralEventsMessage.status = false;
375
376 uint32_t totalSamples = data->sampleCount;
377 uint32_t maxSamplesPerMessage =
378 data->format == CHRE_AUDIO_DATA_FORMAT_16_BIT_SIGNED_PCM
379 ? kChreAudioDataEventMaxSampleBufferSize / 2
380 : kChreAudioDataEventMaxSampleBufferSize;
381 uint32_t samplesRemainingAfterSend = totalSamples > maxSamplesPerMessage
382 ? totalSamples - maxSamplesPerMessage
383 : 0;
384
385 uint32_t numSamplesToSend = MIN(maxSamplesPerMessage, totalSamples);
386 uint32_t sampleIdx = 0;
387 for (int id = 0; numSamplesToSend > 0; id++) {
388 gGeneralEventsMessage.data.chreAudioDataSamples.id = id;
389
390 // assign data
391 if (data->format == CHRE_AUDIO_DATA_FORMAT_8_BIT_U_LAW) {
392 gGeneralEventsMessage.data.chreAudioDataSamples.samples.size =
393 numSamplesToSend;
394 std::memcpy(gGeneralEventsMessage.data.chreAudioDataSamples.samples.bytes,
395 &data->samplesULaw8[sampleIdx], numSamplesToSend);
396
397 gGeneralEventsMessage.status = true;
398 gGeneralEventsMessage.which_data =
399 chre_rpc_GeneralEventsMessage_chreAudioDataSamples_tag;
400 } else if (data->format == CHRE_AUDIO_DATA_FORMAT_16_BIT_SIGNED_PCM) {
401 // send double the bytes since each sample is 2B
402 gGeneralEventsMessage.data.chreAudioDataSamples.samples.size =
403 numSamplesToSend * 2;
404 std::memcpy(gGeneralEventsMessage.data.chreAudioDataSamples.samples.bytes,
405 &data->samplesS16[sampleIdx], numSamplesToSend * 2);
406
407 gGeneralEventsMessage.status = true;
408 gGeneralEventsMessage.which_data =
409 chre_rpc_GeneralEventsMessage_chreAudioDataSamples_tag;
410 } else {
411 LOGE("Chre audio data event: format %" PRIu8 " unknown", data->format);
412 return false;
413 }
414
415 sendPartialGeneralEventToHost(gGeneralEventsMessage);
416
417 sampleIdx += numSamplesToSend;
418 if (samplesRemainingAfterSend > maxSamplesPerMessage) {
419 numSamplesToSend = maxSamplesPerMessage;
420 samplesRemainingAfterSend =
421 samplesRemainingAfterSend - maxSamplesPerMessage;
422 } else {
423 numSamplesToSend = samplesRemainingAfterSend;
424 samplesRemainingAfterSend = 0;
425 }
426 }
427 closePartialGeneralEventToHost();
428 return true;
429 }
430
sendGeneralEventToHost(const chre_rpc_GeneralEventsMessage & message)431 bool ChreApiTestService::sendGeneralEventToHost(
432 const chre_rpc_GeneralEventsMessage &message) {
433 sendPartialGeneralEventToHost(message);
434 return closePartialGeneralEventToHost();
435 }
436
sendPartialGeneralEventToHost(const chre_rpc_GeneralEventsMessage & message)437 void ChreApiTestService::sendPartialGeneralEventToHost(
438 const chre_rpc_GeneralEventsMessage &message) {
439 ChreApiTestManagerSingleton::get()->setPermissionForNextMessage(
440 CHRE_MESSAGE_PERMISSION_NONE);
441 pw::Status status = mEventWriter->Write(message);
442 CHRE_ASSERT(status.ok());
443 }
444
closePartialGeneralEventToHost()445 bool ChreApiTestService::closePartialGeneralEventToHost() {
446 ++mEventSentCount;
447
448 if (mEventSentCount == mEventExpectedCount) {
449 chreTimerCancel(mEventTimerHandle);
450 mEventTimerHandle = CHRE_TIMER_INVALID;
451 finishAndCloseWriter(mEventWriter);
452 LOGD("GatherEvents: Finish");
453 return false;
454 }
455 return true;
456 }
457
handleGatheringEvent(uint16_t eventType,const void * eventData)458 void ChreApiTestService::handleGatheringEvent(uint16_t eventType,
459 const void *eventData) {
460 if (!mEventWriter.has_value()) {
461 return;
462 }
463
464 bool matchedEvent = false;
465 for (uint32_t i = 0; i < mEventTypeCount; ++i) {
466 if (mEventTypes[i] == eventType) {
467 matchedEvent = true;
468 break;
469 }
470 }
471 if (!matchedEvent) {
472 LOGD("GatherEvents: Received event with type: %" PRIu16
473 " that did not match any gathered events",
474 eventType);
475 return;
476 }
477
478 LOGD("Gather events Received matching event with type: %" PRIu16, eventType);
479
480 bool messageSent = false;
481 std::memset(&gGeneralEventsMessage, 0, sizeof(gGeneralEventsMessage));
482 gGeneralEventsMessage.status = false;
483 switch (eventType) {
484 case CHRE_EVENT_SENSOR_ACCELEROMETER_DATA: {
485 gGeneralEventsMessage.status = true;
486 gGeneralEventsMessage.which_data =
487 chre_rpc_GeneralEventsMessage_chreSensorThreeAxisData_tag;
488
489 const auto *data =
490 static_cast<const struct chreSensorThreeAxisData *>(eventData);
491 gGeneralEventsMessage.data.chreSensorThreeAxisData.header.baseTimestamp =
492 data->header.baseTimestamp;
493 gGeneralEventsMessage.data.chreSensorThreeAxisData.header.sensorHandle =
494 data->header.sensorHandle;
495 gGeneralEventsMessage.data.chreSensorThreeAxisData.header.readingCount =
496 data->header.readingCount;
497 gGeneralEventsMessage.data.chreSensorThreeAxisData.header.accuracy =
498 data->header.accuracy;
499 gGeneralEventsMessage.data.chreSensorThreeAxisData.header.reserved =
500 data->header.reserved;
501
502 uint32_t numReadings =
503 MIN(data->header.readingCount, kThreeAxisDataReadingsMaxCount);
504 gGeneralEventsMessage.data.chreSensorThreeAxisData.readings_count =
505 numReadings;
506 for (uint32_t i = 0; i < numReadings; ++i) {
507 gGeneralEventsMessage.data.chreSensorThreeAxisData.readings[i]
508 .timestampDelta = data->readings[i].timestampDelta;
509 gGeneralEventsMessage.data.chreSensorThreeAxisData.readings[i].x =
510 data->readings[i].x;
511 gGeneralEventsMessage.data.chreSensorThreeAxisData.readings[i].y =
512 data->readings[i].y;
513 gGeneralEventsMessage.data.chreSensorThreeAxisData.readings[i].z =
514 data->readings[i].z;
515 }
516 break;
517 }
518 case CHRE_EVENT_SENSOR_SAMPLING_CHANGE: {
519 const auto *data =
520 static_cast<const struct chreSensorSamplingStatusEvent *>(eventData);
521 gGeneralEventsMessage.data.chreSensorSamplingStatusEvent.sensorHandle =
522 data->sensorHandle;
523 gGeneralEventsMessage.data.chreSensorSamplingStatusEvent.status.interval =
524 data->status.interval;
525 gGeneralEventsMessage.data.chreSensorSamplingStatusEvent.status.latency =
526 data->status.latency;
527 gGeneralEventsMessage.data.chreSensorSamplingStatusEvent.status.enabled =
528 data->status.enabled;
529
530 gGeneralEventsMessage.status = true;
531 gGeneralEventsMessage.which_data =
532 chre_rpc_GeneralEventsMessage_chreSensorSamplingStatusEvent_tag;
533 break;
534 }
535 case CHRE_EVENT_HOST_ENDPOINT_NOTIFICATION: {
536 const auto *data =
537 static_cast<const struct chreHostEndpointNotification *>(eventData);
538 gGeneralEventsMessage.data.chreHostEndpointNotification.hostEndpointId =
539 data->hostEndpointId;
540 gGeneralEventsMessage.data.chreHostEndpointNotification.notificationType =
541 data->notificationType;
542
543 gGeneralEventsMessage.status = true;
544 gGeneralEventsMessage.which_data =
545 chre_rpc_GeneralEventsMessage_chreHostEndpointNotification_tag;
546 break;
547 }
548 case CHRE_EVENT_BLE_ADVERTISEMENT: {
549 const auto *data =
550 static_cast<const struct chreBleAdvertisementEvent *>(eventData);
551 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reserved =
552 data->reserved;
553
554 uint32_t numReports =
555 MIN(kChreBleAdvertisementReportMaxCount, data->numReports);
556 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports_count =
557 numReports;
558 for (uint32_t i = 0; i < numReports; ++i) {
559 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
560 .timestamp = data->reports[i].timestamp;
561 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
562 .eventTypeAndDataStatus = data->reports[i].eventTypeAndDataStatus;
563 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
564 .addressType = data->reports[i].addressType;
565
566 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
567 .address.size = CHRE_BLE_ADDRESS_LEN;
568 std::memcpy(
569 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
570 .address.bytes,
571 data->reports[i].address, CHRE_BLE_ADDRESS_LEN);
572
573 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
574 .primaryPhy = data->reports[i].primaryPhy;
575 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
576 .secondaryPhy = data->reports[i].secondaryPhy;
577 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
578 .advertisingSid = data->reports[i].advertisingSid;
579 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
580 .txPower = data->reports[i].txPower;
581 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
582 .periodicAdvertisingInterval =
583 data->reports[i].periodicAdvertisingInterval;
584 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i].rssi =
585 data->reports[i].rssi;
586 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
587 .directAddressType = data->reports[i].directAddressType;
588
589 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
590 .directAddress.size = CHRE_BLE_ADDRESS_LEN;
591 std::memcpy(
592 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
593 .directAddress.bytes,
594 data->reports[i].directAddress, CHRE_BLE_ADDRESS_LEN);
595
596 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
597 .data.size = data->reports[i].dataLength;
598 std::memcpy(
599 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
600 .data.bytes,
601 data->reports[i].data, data->reports[i].dataLength);
602
603 gGeneralEventsMessage.data.chreBleAdvertisementEvent.reports[i]
604 .reserved = data->reports[i].reserved;
605 }
606
607 gGeneralEventsMessage.status = true;
608 gGeneralEventsMessage.which_data =
609 chre_rpc_GeneralEventsMessage_chreBleAdvertisementEvent_tag;
610 break;
611 }
612 case CHRE_EVENT_AUDIO_SAMPLING_CHANGE: {
613 const auto *data =
614 static_cast<const struct chreAudioSourceStatusEvent *>(eventData);
615 gGeneralEventsMessage.data.chreAudioSourceStatusEvent.handle =
616 data->handle;
617 gGeneralEventsMessage.data.chreAudioSourceStatusEvent.status.enabled =
618 data->status.enabled;
619 gGeneralEventsMessage.data.chreAudioSourceStatusEvent.status.suspended =
620 data->status.suspended;
621
622 gGeneralEventsMessage.status = true;
623 gGeneralEventsMessage.which_data =
624 chre_rpc_GeneralEventsMessage_chreAudioSourceStatusEvent_tag;
625 break;
626 }
627 case CHRE_EVENT_AUDIO_DATA: {
628 const auto *data =
629 static_cast<const struct chreAudioDataEvent *>(eventData);
630 messageSent = handleChreAudioDataEvent(data);
631 break;
632 }
633 default: {
634 LOGE("GatherEvents: event type: %" PRIu16 " not implemented", eventType);
635 }
636 }
637
638 // If we already sent the message, we have nothing else to send.
639 if (messageSent) {
640 return;
641 }
642
643 if (!gGeneralEventsMessage.status) {
644 LOGE("GatherEvents: unable to create message for event with type: %" PRIu16,
645 eventType);
646 return;
647 }
648
649 sendGeneralEventToHost(gGeneralEventsMessage);
650 }
651
handleTimerEvent(const void * cookie)652 void ChreApiTestService::handleTimerEvent(const void *cookie) {
653 if (mWriter.has_value() && cookie == &mSyncTimerHandle) {
654 sendFailureAndFinishCloseWriter(mWriter);
655 mSyncTimerHandle = CHRE_TIMER_INVALID;
656 LOGD("Active sync function: status: false (timeout)");
657 } else if (mEventWriter.has_value() && cookie == &mEventTimerHandle) {
658 finishAndCloseWriter(mEventWriter);
659 mEventTimerHandle = CHRE_TIMER_INVALID;
660 LOGD("Timeout for event collection");
661 }
662 }
663
startSyncTimer()664 bool ChreApiTestService::startSyncTimer() {
665 mSyncTimerHandle = chreTimerSet(
666 kSyncFunctionTimeout, &mSyncTimerHandle /* cookie */, true /* oneShot */);
667 return mSyncTimerHandle != CHRE_TIMER_INVALID;
668 }
669
670 // Start ChreApiTestManager functions
671
start()672 bool ChreApiTestManager::start() {
673 chre::RpcServer::Service service = {.service = mChreApiTestService,
674 .id = 0x61002d392de8430a,
675 .version = 0x01000000};
676 if (!mServer.registerServices(1, &service)) {
677 LOGE("Error while registering the service");
678 return false;
679 }
680
681 return true;
682 }
683
end()684 void ChreApiTestManager::end() {
685 mServer.close();
686 }
687
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)688 void ChreApiTestManager::handleEvent(uint32_t senderInstanceId,
689 uint16_t eventType,
690 const void *eventData) {
691 if (!mServer.handleEvent(senderInstanceId, eventType, eventData)) {
692 LOGE("An RPC error occurred");
693 }
694
695 mChreApiTestService.handleGatheringEvent(eventType, eventData);
696
697 switch (eventType) {
698 case CHRE_EVENT_BLE_ASYNC_RESULT:
699 mChreApiTestService.handleBleAsyncResult(
700 static_cast<const chreAsyncResult *>(eventData));
701 break;
702 case CHRE_EVENT_TIMER:
703 mChreApiTestService.handleTimerEvent(eventData);
704 break;
705 default: {
706 // ignore
707 }
708 }
709 }
710
setPermissionForNextMessage(uint32_t permission)711 void ChreApiTestManager::setPermissionForNextMessage(uint32_t permission) {
712 mServer.setPermissionForNextMessage(permission);
713 }
714
715 // End ChreApiTestManager functions
716