1 /*
2 * Copyright (C) 2016 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 <cstdarg>
18 #include <cstdio>
19 #include <cstring>
20
21 #include "chre/core/event_loop_manager.h"
22 #include "chre/core/host_comms_manager.h"
23 #include "chre/core/host_endpoint_manager.h"
24 #include "chre/platform/fatal_error.h"
25 #include "chre/platform/log.h"
26 #include "chre/util/macros.h"
27 #include "chre/util/system/napp_permissions.h"
28 #include "chre_api/chre/event.h"
29 #include "chre_api/chre/re.h"
30
31 using ::chre::EventLoop;
32 using ::chre::EventLoopManager;
33 using ::chre::EventLoopManagerSingleton;
34 using ::chre::handleNanoappAbort;
35 using ::chre::HostCommsManager;
36 using ::chre::Nanoapp;
37
38 namespace {
39
40 /**
41 * Sends a message to the host.
42 *
43 * @param nanoapp The nanoapp sending the message.
44 * @param message A pointer to the message buffer.
45 * @param messageSize The size of the message.
46 * @param hostEndpoint The host endpoint to send the message to.
47 * @param messagePermissions Bitmasked CHRE_MESSAGE_PERMISSION_...
48 * @param freeCallback The callback that will be invoked to free the message
49 * buffer.
50 * @param isReliable Whether to send a reliable message.
51 * @param cookie The cookie used when reporting reliable message status. It is
52 * only used for reliable messages.
53 * @return Whether the message was accepted for transmission.
54 */
sendMessageToHost(Nanoapp * nanoapp,void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback,bool isReliable,const void * cookie)55 bool sendMessageToHost(Nanoapp *nanoapp, void *message, size_t messageSize,
56 uint32_t messageType, uint16_t hostEndpoint,
57 uint32_t messagePermissions,
58 chreMessageFreeFunction *freeCallback, bool isReliable,
59 const void *cookie) {
60 const EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
61 bool success = false;
62 if (eventLoop.currentNanoappIsStopping()) {
63 LOGW("Rejecting message to host from app instance %" PRIu16
64 " because it's stopping",
65 nanoapp->getInstanceId());
66 } else {
67 HostCommsManager &hostCommsManager =
68 EventLoopManagerSingleton::get()->getHostCommsManager();
69 success = hostCommsManager.sendMessageToHostFromNanoapp(
70 nanoapp, message, messageSize, messageType, hostEndpoint,
71 messagePermissions, freeCallback, isReliable, cookie);
72 }
73
74 if (!success && freeCallback != nullptr) {
75 freeCallback(message, messageSize);
76 }
77
78 return success;
79 }
80
81 } // namespace
82
chreAbort(uint32_t)83 DLL_EXPORT void chreAbort(uint32_t /* abortCode */) {
84 Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
85
86 // TODO: we should cleanly unload the nanoapp, release all of its resources,
87 // and send an abort notification to the host so as to localize the impact to
88 // the calling nanoapp
89 if (nanoapp == nullptr) {
90 FATAL_ERROR("chreAbort called in unknown context");
91 } else {
92 handleNanoappAbort(*nanoapp);
93 }
94 }
95
chreSendEvent(uint16_t eventType,void * eventData,chreEventCompleteFunction * freeCallback,uint32_t targetInstanceId)96 DLL_EXPORT bool chreSendEvent(uint16_t eventType, void *eventData,
97 chreEventCompleteFunction *freeCallback,
98 uint32_t targetInstanceId) {
99 Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
100
101 // Prevent an app that is in the process of being unloaded from generating new
102 // events
103 bool success = false;
104 EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
105 CHRE_ASSERT_LOG(targetInstanceId <= UINT16_MAX,
106 "Invalid instance ID %" PRIu32 " provided", targetInstanceId);
107 if (eventLoop.currentNanoappIsStopping()) {
108 LOGW("Rejecting event from app instance %" PRIu16 " because it's stopping",
109 nanoapp->getInstanceId());
110 } else if (targetInstanceId <= UINT16_MAX) {
111 success = eventLoop.postLowPriorityEventOrFree(
112 eventType, eventData, freeCallback, nanoapp->getInstanceId(),
113 static_cast<uint16_t>(targetInstanceId));
114 }
115 return success;
116 }
117
chreSendMessageToHost(void * message,uint32_t messageSize,uint32_t messageType,chreMessageFreeFunction * freeCallback)118 DLL_EXPORT bool chreSendMessageToHost(void *message, uint32_t messageSize,
119 uint32_t messageType,
120 chreMessageFreeFunction *freeCallback) {
121 return chreSendMessageToHostEndpoint(
122 message, static_cast<size_t>(messageSize), messageType,
123 CHRE_HOST_ENDPOINT_BROADCAST, freeCallback);
124 }
125
chreSendMessageWithPermissions(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback)126 DLL_EXPORT bool chreSendMessageWithPermissions(
127 void *message, size_t messageSize, uint32_t messageType,
128 uint16_t hostEndpoint, uint32_t messagePermissions,
129 chreMessageFreeFunction *freeCallback) {
130 Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
131 return sendMessageToHost(nanoapp, message, messageSize, messageType,
132 hostEndpoint, messagePermissions, freeCallback,
133 /*isReliable=*/false, /*cookie=*/nullptr);
134 }
135
chreSendReliableMessageAsync(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback,const void * cookie)136 DLL_EXPORT bool chreSendReliableMessageAsync(
137 void *message, size_t messageSize, uint32_t messageType,
138 uint16_t hostEndpoint, uint32_t messagePermissions,
139 chreMessageFreeFunction *freeCallback, const void *cookie) {
140 #ifdef CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED
141 Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
142 return sendMessageToHost(nanoapp, message, messageSize, messageType,
143 hostEndpoint, messagePermissions, freeCallback,
144 /*isReliable=*/true, cookie);
145 #else
146 UNUSED_VAR(message);
147 UNUSED_VAR(messageSize);
148 UNUSED_VAR(messageType);
149 UNUSED_VAR(hostEndpoint);
150 UNUSED_VAR(messagePermissions);
151 UNUSED_VAR(freeCallback);
152 UNUSED_VAR(cookie);
153 return false;
154 #endif // CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED
155 }
156
chreSendMessageToHostEndpoint(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,chreMessageFreeFunction * freeCallback)157 DLL_EXPORT bool chreSendMessageToHostEndpoint(
158 void *message, size_t messageSize, uint32_t messageType,
159 uint16_t hostEndpoint, chreMessageFreeFunction *freeCallback) {
160 return chreSendMessageWithPermissions(
161 message, messageSize, messageType, hostEndpoint,
162 static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_NONE),
163 freeCallback);
164 }
165
chreGetNanoappInfoByAppId(uint64_t appId,struct chreNanoappInfo * info)166 DLL_EXPORT bool chreGetNanoappInfoByAppId(uint64_t appId,
167 struct chreNanoappInfo *info) {
168 return EventLoopManagerSingleton::get()
169 ->getEventLoop()
170 .populateNanoappInfoForAppId(appId, info);
171 }
172
chreGetNanoappInfoByInstanceId(uint32_t instanceId,struct chreNanoappInfo * info)173 DLL_EXPORT bool chreGetNanoappInfoByInstanceId(uint32_t instanceId,
174 struct chreNanoappInfo *info) {
175 CHRE_ASSERT(instanceId <= UINT16_MAX);
176 if (instanceId <= UINT16_MAX) {
177 return EventLoopManagerSingleton::get()
178 ->getEventLoop()
179 .populateNanoappInfoForInstanceId(static_cast<uint16_t>(instanceId),
180 info);
181 }
182 return false;
183 }
184
chreConfigureNanoappInfoEvents(bool enable)185 DLL_EXPORT void chreConfigureNanoappInfoEvents(bool enable) {
186 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
187 nanoapp->configureNanoappInfoEvents(enable);
188 }
189
chreConfigureHostSleepStateEvents(bool enable)190 DLL_EXPORT void chreConfigureHostSleepStateEvents(bool enable) {
191 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
192 nanoapp->configureHostSleepEvents(enable);
193 }
194
chreIsHostAwake()195 DLL_EXPORT bool chreIsHostAwake() {
196 return EventLoopManagerSingleton::get()
197 ->getEventLoop()
198 .getPowerControlManager()
199 .hostIsAwake();
200 }
201
chreConfigureDebugDumpEvent(bool enable)202 DLL_EXPORT void chreConfigureDebugDumpEvent(bool enable) {
203 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
204 nanoapp->configureDebugDumpEvent(enable);
205 }
206
chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,bool enable)207 DLL_EXPORT bool chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,
208 bool enable) {
209 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
210 return nanoapp->configureHostEndpointNotifications(hostEndpointId, enable);
211 }
212
chrePublishRpcServices(struct chreNanoappRpcService * services,size_t numServices)213 DLL_EXPORT bool chrePublishRpcServices(struct chreNanoappRpcService *services,
214 size_t numServices) {
215 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
216 return nanoapp->publishRpcServices(services, numServices);
217 }
218
chreGetHostEndpointInfo(uint16_t hostEndpointId,struct chreHostEndpointInfo * info)219 DLL_EXPORT bool chreGetHostEndpointInfo(uint16_t hostEndpointId,
220 struct chreHostEndpointInfo *info) {
221 return EventLoopManagerSingleton::get()
222 ->getHostEndpointManager()
223 .getHostEndpointInfo(hostEndpointId, info);
224 }
225