Home | History | Annotate | Download | only in shared
      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_api/chre/event.h"
     22 #include "chre_api/chre/re.h"
     23 #include "chre/core/event_loop_manager.h"
     24 #include "chre/core/host_comms_manager.h"
     25 #include "chre/platform/fatal_error.h"
     26 #include "chre/platform/log.h"
     27 #include "chre/util/macros.h"
     28 
     29 using chre::EventLoop;
     30 using chre::EventLoopManager;
     31 using chre::EventLoopManagerSingleton;
     32 using chre::Nanoapp;
     33 
     34 DLL_EXPORT void chreAbort(uint32_t abortCode) {
     35   Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
     36 
     37   // TODO: we should cleanly unload the nanoapp, release all of its resources,
     38   // and send an abort notification to the host so as to localize the impact to
     39   // the calling nanoapp
     40   if (nanoapp == nullptr) {
     41     FATAL_ERROR("chreAbort called in unknown context");
     42   } else {
     43     FATAL_ERROR("chreAbort called by app 0x%016" PRIx64, nanoapp->getAppId());
     44   }
     45 }
     46 
     47 DLL_EXPORT bool chreSendEvent(uint16_t eventType, void *eventData,
     48                               chreEventCompleteFunction *freeCallback,
     49                               uint32_t targetInstanceId) {
     50   Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
     51 
     52   // Prevent an app that is in the process of being unloaded from generating new
     53   // events
     54   bool success = false;
     55   EventLoop& eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
     56   if (eventLoop.currentNanoappIsStopping()) {
     57     LOGW("Rejecting event from app instance %" PRIu32 " because it's stopping",
     58          nanoapp->getInstanceId());
     59   } else {
     60     success = eventLoop.postEvent(eventType, eventData, freeCallback,
     61                                   nanoapp->getInstanceId(), targetInstanceId);
     62   }
     63 
     64   if (!success && freeCallback != nullptr) {
     65     freeCallback(eventType, eventData);
     66   }
     67   return success;
     68 }
     69 
     70 DLL_EXPORT bool chreSendMessageToHost(void *message, uint32_t messageSize,
     71                                       uint32_t messageType,
     72                                       chreMessageFreeFunction *freeCallback) {
     73   return chreSendMessageToHostEndpoint(
     74       message, static_cast<size_t>(messageSize), messageType,
     75       CHRE_HOST_ENDPOINT_BROADCAST, freeCallback);
     76 }
     77 
     78 DLL_EXPORT bool chreSendMessageToHostEndpoint(
     79     void *message, size_t messageSize, uint32_t messageType,
     80     uint16_t hostEndpoint, chreMessageFreeFunction *freeCallback) {
     81   Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
     82 
     83   bool success = false;
     84   const EventLoop& eventLoop = EventLoopManagerSingleton::get()
     85       ->getEventLoop();
     86   if (eventLoop.currentNanoappIsStopping()) {
     87     LOGW("Rejecting message to host from app instance %" PRIu32 " because it's "
     88          "stopping", nanoapp->getInstanceId());
     89   } else {
     90     auto& hostCommsManager =
     91         EventLoopManagerSingleton::get()->getHostCommsManager();
     92     success = hostCommsManager.sendMessageToHostFromNanoapp(
     93         nanoapp, message, messageSize, messageType, hostEndpoint, freeCallback);
     94   }
     95 
     96   if (!success && freeCallback != nullptr) {
     97     freeCallback(message, messageSize);
     98   }
     99 
    100   return success;
    101 }
    102 
    103 DLL_EXPORT bool chreGetNanoappInfoByAppId(uint64_t appId,
    104                                           struct chreNanoappInfo *info) {
    105   return EventLoopManagerSingleton::get()->getEventLoop()
    106       .populateNanoappInfoForAppId(appId, info);
    107 }
    108 
    109 DLL_EXPORT bool chreGetNanoappInfoByInstanceId(uint32_t instanceId,
    110                                                struct chreNanoappInfo *info) {
    111   return EventLoopManagerSingleton::get()->getEventLoop()
    112       .populateNanoappInfoForInstanceId(instanceId, info);
    113 }
    114 
    115 DLL_EXPORT void chreConfigureNanoappInfoEvents(bool enable) {
    116   chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
    117   nanoapp->configureNanoappInfoEvents(enable);
    118 }
    119 
    120 DLL_EXPORT void chreConfigureHostSleepStateEvents(bool enable) {
    121   chre::Nanoapp *nanoapp = EventLoopManager::validateChreApiCall(__func__);
    122   nanoapp->configureHostSleepEvents(enable);
    123 }
    124 
    125 DLL_EXPORT bool chreIsHostAwake() {
    126   return EventLoopManagerSingleton::get()->getEventLoop()
    127       .getPowerControlManager().hostIsAwake();
    128 }
    129