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_notifications.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::Nanoapp;
35
chreAbort(uint32_t)36 DLL_EXPORT void chreAbort(uint32_t /* abortCode */) {
37 Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
38
39 // TODO: we should cleanly unload the nanoapp, release all of its resources,
40 // and send an abort notification to the host so as to localize the impact to
41 // the calling nanoapp
42 if (nanoapp == nullptr) {
43 FATAL_ERROR("chreAbort called in unknown context");
44 } else {
45 FATAL_ERROR("chreAbort called by app 0x%016" PRIx64, nanoapp->getAppId());
46 }
47 }
48
chreSendEvent(uint16_t eventType,void * eventData,chreEventCompleteFunction * freeCallback,uint32_t targetInstanceId)49 DLL_EXPORT bool chreSendEvent(uint16_t eventType, void *eventData,
50 chreEventCompleteFunction *freeCallback,
51 uint32_t targetInstanceId) {
52 Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
53
54 // Prevent an app that is in the process of being unloaded from generating new
55 // events
56 bool success = false;
57 EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
58 CHRE_ASSERT_LOG(targetInstanceId <= UINT16_MAX,
59 "Invalid instance ID %" PRIu32 " provided", targetInstanceId);
60 if (eventLoop.currentNanoappIsStopping()) {
61 LOGW("Rejecting event from app instance %" PRIu16 " because it's stopping",
62 nanoapp->getInstanceId());
63 } else if (targetInstanceId <= UINT16_MAX) {
64 success = eventLoop.postLowPriorityEventOrFree(
65 eventType, eventData, freeCallback, nanoapp->getInstanceId(),
66 static_cast<uint16_t>(targetInstanceId));
67 }
68 return success;
69 }
70
chreSendMessageToHost(void * message,uint32_t messageSize,uint32_t messageType,chreMessageFreeFunction * freeCallback)71 DLL_EXPORT bool chreSendMessageToHost(void *message, uint32_t messageSize,
72 uint32_t messageType,
73 chreMessageFreeFunction *freeCallback) {
74 return chreSendMessageToHostEndpoint(
75 message, static_cast<size_t>(messageSize), messageType,
76 CHRE_HOST_ENDPOINT_BROADCAST, freeCallback);
77 }
78
chreSendMessageWithPermissions(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,uint32_t messagePermissions,chreMessageFreeFunction * freeCallback)79 DLL_EXPORT bool chreSendMessageWithPermissions(
80 void *message, size_t messageSize, uint32_t messageType,
81 uint16_t hostEndpoint, uint32_t messagePermissions,
82 chreMessageFreeFunction *freeCallback) {
83 Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
84
85 bool success = false;
86 const EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
87 if (eventLoop.currentNanoappIsStopping()) {
88 LOGW("Rejecting message to host from app instance %" PRIu16
89 " because it's stopping",
90 nanoapp->getInstanceId());
91 } else {
92 auto &hostCommsManager =
93 EventLoopManagerSingleton::get()->getHostCommsManager();
94 success = hostCommsManager.sendMessageToHostFromNanoapp(
95 nanoapp, message, messageSize, messageType, hostEndpoint,
96 messagePermissions, freeCallback);
97 }
98
99 if (!success && freeCallback != nullptr) {
100 freeCallback(message, messageSize);
101 }
102
103 return success;
104 }
105
chreSendMessageToHostEndpoint(void * message,size_t messageSize,uint32_t messageType,uint16_t hostEndpoint,chreMessageFreeFunction * freeCallback)106 DLL_EXPORT bool chreSendMessageToHostEndpoint(
107 void *message, size_t messageSize, uint32_t messageType,
108 uint16_t hostEndpoint, chreMessageFreeFunction *freeCallback) {
109 return chreSendMessageWithPermissions(
110 message, messageSize, messageType, hostEndpoint,
111 static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_NONE),
112 freeCallback);
113 }
114
chreGetNanoappInfoByAppId(uint64_t appId,struct chreNanoappInfo * info)115 DLL_EXPORT bool chreGetNanoappInfoByAppId(uint64_t appId,
116 struct chreNanoappInfo *info) {
117 return EventLoopManagerSingleton::get()
118 ->getEventLoop()
119 .populateNanoappInfoForAppId(appId, info);
120 }
121
chreGetNanoappInfoByInstanceId(uint32_t instanceId,struct chreNanoappInfo * info)122 DLL_EXPORT bool chreGetNanoappInfoByInstanceId(uint32_t instanceId,
123 struct chreNanoappInfo *info) {
124 CHRE_ASSERT(instanceId <= UINT16_MAX);
125 if (instanceId <= UINT16_MAX) {
126 return EventLoopManagerSingleton::get()
127 ->getEventLoop()
128 .populateNanoappInfoForInstanceId(static_cast<uint16_t>(instanceId),
129 info);
130 }
131 return false;
132 }
133
chreConfigureNanoappInfoEvents(bool enable)134 DLL_EXPORT void chreConfigureNanoappInfoEvents(bool enable) {
135 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
136 nanoapp->configureNanoappInfoEvents(enable);
137 }
138
chreConfigureHostSleepStateEvents(bool enable)139 DLL_EXPORT void chreConfigureHostSleepStateEvents(bool enable) {
140 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
141 nanoapp->configureHostSleepEvents(enable);
142 }
143
chreIsHostAwake()144 DLL_EXPORT bool chreIsHostAwake() {
145 return EventLoopManagerSingleton::get()
146 ->getEventLoop()
147 .getPowerControlManager()
148 .hostIsAwake();
149 }
150
chreConfigureDebugDumpEvent(bool enable)151 DLL_EXPORT void chreConfigureDebugDumpEvent(bool enable) {
152 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
153 nanoapp->configureDebugDumpEvent(enable);
154 }
155
chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,bool enable)156 DLL_EXPORT bool chreConfigureHostEndpointNotifications(uint16_t hostEndpointId,
157 bool enable) {
158 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
159 return nanoapp->configureHostEndpointNotifications(hostEndpointId, enable);
160 }
161
chrePublishRpcServices(struct chreNanoappRpcService * services,size_t numServices)162 DLL_EXPORT bool chrePublishRpcServices(struct chreNanoappRpcService *services,
163 size_t numServices) {
164 chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
165 return nanoapp->publishRpcServices(services, numServices);
166 }
167
chreGetHostEndpointInfo(uint16_t hostEndpointId,struct chreHostEndpointInfo * info)168 DLL_EXPORT bool chreGetHostEndpointInfo(uint16_t hostEndpointId,
169 struct chreHostEndpointInfo *info) {
170 return chre::getHostEndpointInfo(hostEndpointId, info);
171 }
172