xref: /aosp_15_r20/system/chre/apps/test/common/chre_api_test/src/chre_api_test_manager.cc (revision 84e339476a462649f82315436d70fd732297a399)
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