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