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/platform/platform_nanoapp.h" 18 19 #include <dlfcn.h> 20 #include <cinttypes> 21 22 #include "chre/platform/assert.h" 23 #include "chre/platform/log.h" 24 #include "chre/platform/shared/nanoapp_dso_util.h" 25 #include "chre_api/chre/version.h" 26 27 namespace chre { 28 29 PlatformNanoapp::~PlatformNanoapp() { 30 closeNanoapp(); 31 } 32 33 bool PlatformNanoapp::start() { 34 return openNanoapp() && mAppInfo->entryPoints.start(); 35 } 36 37 void PlatformNanoapp::handleEvent(uint32_t senderInstanceId, uint16_t eventType, 38 const void *eventData) { 39 mAppInfo->entryPoints.handleEvent(senderInstanceId, eventType, eventData); 40 } 41 42 void PlatformNanoapp::end() { 43 mAppInfo->entryPoints.end(); 44 closeNanoapp(); 45 } 46 47 uint64_t PlatformNanoapp::getAppId() const { 48 return (mAppInfo == nullptr) ? 0 : mAppInfo->appId; 49 } 50 51 uint32_t PlatformNanoapp::getAppVersion() const { 52 return mAppInfo->appVersion; 53 } 54 55 uint32_t PlatformNanoapp::getTargetApiVersion() const { 56 return CHRE_API_VERSION; 57 } 58 59 const char *PlatformNanoapp::getAppName() const { 60 return (mAppInfo != nullptr) ? mAppInfo->name : "Unknown"; 61 } 62 63 bool PlatformNanoapp::isSystemNanoapp() const { 64 return (mAppInfo != nullptr && mAppInfo->isSystemNanoapp); 65 } 66 67 void PlatformNanoapp::logStateToBuffer(DebugDumpWrapper &debugDump) const {} 68 69 void PlatformNanoappBase::loadFromFile(const std::string &filename) { 70 CHRE_ASSERT(!isLoaded()); 71 mFilename = filename; 72 } 73 74 void PlatformNanoappBase::loadStatic(const struct chreNslNanoappInfo *appInfo) { 75 CHRE_ASSERT(!isLoaded()); 76 mIsStatic = true; 77 mAppInfo = appInfo; 78 } 79 80 bool PlatformNanoappBase::isLoaded() const { 81 return (mIsStatic || mDsoHandle != nullptr); 82 } 83 84 bool PlatformNanoappBase::openNanoapp() { 85 bool success = false; 86 87 if (mIsStatic) { 88 success = true; 89 } else if (!mFilename.empty()) { 90 success = openNanoappFromFile(); 91 } else { 92 CHRE_ASSERT(false); 93 } 94 95 return success; 96 } 97 98 bool PlatformNanoappBase::openNanoappFromFile() { 99 CHRE_ASSERT(!mFilename.empty()); 100 CHRE_ASSERT_LOG(mDsoHandle == nullptr, "Re-opening nanoapp"); 101 bool success = false; 102 103 mDsoHandle = dlopen(mFilename.c_str(), RTLD_NOW | RTLD_GLOBAL); 104 if (mDsoHandle == nullptr) { 105 LOGE("Failed to load nanoapp from file %s: %s", mFilename.c_str(), 106 dlerror()); 107 } else { 108 mAppInfo = static_cast<const struct chreNslNanoappInfo *>( 109 dlsym(mDsoHandle, CHRE_NSL_DSO_NANOAPP_INFO_SYMBOL_NAME)); 110 if (mAppInfo == nullptr) { 111 LOGE("Failed to find app info symbol in %s: %s", mFilename.c_str(), 112 dlerror()); 113 } else { 114 // TODO(b/120778991): reenable this check after adding support for passing 115 // in the .napp_header to the simulator 116 // success = validateAppInfo(0 /* skip ID validation */, 0, mAppInfo); 117 success = true; 118 if (!success) { 119 mAppInfo = nullptr; 120 } else { 121 LOGI("Successfully loaded nanoapp %s (0x%016" PRIx64 122 ") version 0x%" PRIx32 " uimg %d system %d from file %s", 123 mAppInfo->name, mAppInfo->appId, mAppInfo->appVersion, 124 mAppInfo->isTcmNanoapp, mAppInfo->isSystemNanoapp, 125 mFilename.c_str()); 126 } 127 } 128 } 129 130 return success; 131 } 132 133 void PlatformNanoappBase::closeNanoapp() { 134 if (mDsoHandle != nullptr) { 135 mAppInfo = nullptr; 136 if (dlclose(mDsoHandle) != 0) { 137 LOGE("dlclose failed: %s", dlerror()); 138 } 139 mDsoHandle = nullptr; 140 } 141 } 142 143 } // namespace chre 144