xref: /aosp_15_r20/system/chre/apps/test/common/shared/src/send_message.cc (revision 84e339476a462649f82315436d70fd732297a399)
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 "send_message.h"
18 
19 #include <pb_encode.h>
20 
21 #include "chre/util/nanoapp/callbacks.h"
22 #include "chre/util/nanoapp/log.h"
23 #include "chre/util/system/napp_permissions.h"
24 #include "chre_api/chre.h"
25 
26 #ifndef LOG_TAG
27 #define LOG_TAG "[TestShared]"
28 #endif
29 
30 namespace chre::test_shared {
31 namespace {
32 
encodeErrorMessage(pb_ostream_t * stream,const pb_field_t *,void * const * arg)33 bool encodeErrorMessage(pb_ostream_t *stream, const pb_field_t * /*field*/,
34                         void *const *arg) {
35   const char *str = static_cast<const char *>(const_cast<const void *>(*arg));
36   size_t len = strlen(str);
37   return pb_encode_tag_for_field(
38              stream, &chre_test_common_TestResult_fields
39                          [chre_test_common_TestResult_errorMessage_tag - 1]) &&
40          pb_encode_string(stream, reinterpret_cast<const pb_byte_t *>(str),
41                           len);
42 }
43 
44 }  // namespace
45 
makeTestResultProtoMessage(bool success,const char * errMessage)46 chre_test_common_TestResult makeTestResultProtoMessage(bool success,
47                                                        const char *errMessage) {
48   chre_test_common_TestResult testResult =
49       chre_test_common_TestResult_init_default;
50   testResult.has_code = true;
51   testResult.code = success ? chre_test_common_TestResult_Code_PASSED
52                             : chre_test_common_TestResult_Code_FAILED;
53   if (!success && errMessage != nullptr) {
54     testResult.errorMessage = {.funcs = {.encode = encodeErrorMessage},
55                                .arg = const_cast<char *>(errMessage)};
56     LOGE("%s", errMessage);
57   }
58   return testResult;
59 }
60 
sendTestResultWithMsgToHost(uint16_t hostEndpointId,uint32_t messageType,bool success,const char * errMessage,bool abortOnFailure)61 void sendTestResultWithMsgToHost(uint16_t hostEndpointId, uint32_t messageType,
62                                  bool success, const char *errMessage,
63                                  bool abortOnFailure) {
64   // Unspecified endpoint is not allowed in chreSendMessageToHostEndpoint.
65   if (hostEndpointId == CHRE_HOST_ENDPOINT_UNSPECIFIED) {
66     hostEndpointId = CHRE_HOST_ENDPOINT_BROADCAST;
67     LOGE("Unspecified endpoint ID is not allowed");
68     success = false;
69   }
70 
71   chre_test_common_TestResult result =
72       makeTestResultProtoMessage(success, errMessage);
73 
74   sendMessageToHost(hostEndpointId, &result, chre_test_common_TestResult_fields,
75                     messageType);
76 
77   if (!success && abortOnFailure) {
78     chreAbort(0);
79   }
80 }
81 
sendTestResultToHost(uint16_t hostEndpointId,uint32_t messageType,bool success,bool abortOnFailure)82 void sendTestResultToHost(uint16_t hostEndpointId, uint32_t messageType,
83                           bool success, bool abortOnFailure) {
84   sendTestResultWithMsgToHost(hostEndpointId, messageType, success,
85                               nullptr /* errMessage */, abortOnFailure);
86 }
87 
sendEmptyMessageToHost(uint16_t hostEndpointId,uint32_t messageType)88 void sendEmptyMessageToHost(uint16_t hostEndpointId, uint32_t messageType) {
89   // Unspecified endpoint is not allowed in chreSendMessageToHostEndpoint.
90   if (hostEndpointId == CHRE_HOST_ENDPOINT_UNSPECIFIED) {
91     hostEndpointId = CHRE_HOST_ENDPOINT_BROADCAST;
92     LOGE("Unspecified endpoint ID is not allowed");
93     // TODO: Send failure message to host
94     return;
95   }
96 
97   chreSendMessageToHostEndpoint(nullptr /* message */, 0 /* messageSize */,
98                                 messageType, hostEndpointId,
99                                 nullptr /* freeCallback */);
100 }
101 
sendMessageToHost(uint16_t hostEndpointId,const void * message,const pb_field_t * fields,uint32_t messageType)102 void sendMessageToHost(uint16_t hostEndpointId, const void *message,
103                        const pb_field_t *fields, uint32_t messageType) {
104   sendMessageToHostWithPermissions(hostEndpointId, message, fields, messageType,
105                                    chre::NanoappPermissions::CHRE_PERMS_NONE);
106 }
107 
sendMessageToHostWithPermissions(uint16_t hostEndpointId,const void * message,const pb_field_t * fields,uint32_t messageType,chre::NanoappPermissions perms)108 void sendMessageToHostWithPermissions(uint16_t hostEndpointId,
109                                       const void *message,
110                                       const pb_field_t *fields,
111                                       uint32_t messageType,
112                                       chre::NanoappPermissions perms) {
113   size_t size;
114   if (!pb_get_encoded_size(&size, fields, message)) {
115     LOGE("Failed to get message size");
116   } else {
117     pb_byte_t *bytes = static_cast<pb_byte_t *>(chreHeapAlloc(size));
118     if (size > 0 && bytes == nullptr) {
119       LOG_OOM();
120     } else {
121       pb_ostream_t stream = pb_ostream_from_buffer(bytes, size);
122       if (!pb_encode(&stream, fields, message)) {
123         LOGE("Failed to encode message error %s", PB_GET_ERROR(&stream));
124         chreHeapFree(bytes);
125       } else if (!chreSendMessageWithPermissions(
126                      bytes, size, messageType, hostEndpointId,
127                      static_cast<uint32_t>(perms), heapFreeMessageCallback)) {
128         LOGE("Failed to send message to host");
129       }
130     }
131   }
132 }
133 
134 }  // namespace chre::test_shared
135