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