1e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie/* 2e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Copyright (C) 2016 The Android Open Source Project 3e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 4e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Licensed under the Apache License, Version 2.0 (the "License"); 5e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * you may not use this file except in compliance with the License. 6e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * You may obtain a copy of the License at 7e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 8e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * http://www.apache.org/licenses/LICENSE-2.0 9e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * 10e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Unless required by applicable law or agreed to in writing, software 11e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * distributed under the License is distributed on an "AS IS" BASIS, 12e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * See the License for the specific language governing permissions and 14e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * limitations under the License. 15e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */ 16e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 17e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/platform/platform_nanoapp.h" 18e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 19fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol#include <cinttypes> 20fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol#include <dlfcn.h> 21fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 22fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol#include "chre_api/chre/version.h" 23fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol#include "chre/platform/assert.h" 24fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol#include "chre/platform/log.h" 25fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol#include "chre/platform/shared/nanoapp_dso_util.h" 26fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 27e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddienamespace chre { 28e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 29fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew RossignolPlatformNanoapp::~PlatformNanoapp() { 30fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol closeNanoapp(); 31fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol} 329d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie 33e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddiebool PlatformNanoapp::start() { 34fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol return openNanoapp() && mAppInfo->entryPoints.start(); 35e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie} 36e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 37e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddievoid PlatformNanoapp::handleEvent(uint32_t senderInstanceId, 38e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie uint16_t eventType, 39e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie const void *eventData) { 40fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mAppInfo->entryPoints.handleEvent(senderInstanceId, eventType, eventData); 41e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie} 42e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 432b9d71a9f6a9e8cc0e787957d022154231f29962Brian Duddievoid PlatformNanoapp::end() { 44fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mAppInfo->entryPoints.end(); 45fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol closeNanoapp(); 46e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie} 47e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie 489d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddieuint64_t PlatformNanoapp::getAppId() const { 491a436aa2739b13c4f5625fa1fca75c7a964068adAndrew Rossignol return (mAppInfo == nullptr) ? 0 : mAppInfo->appId; 509d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie} 519d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie 529d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddieuint32_t PlatformNanoapp::getAppVersion() const { 53fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol return mAppInfo->appVersion; 549d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie} 559d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie 569d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddieuint32_t PlatformNanoapp::getTargetApiVersion() const { 579d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie return CHRE_API_VERSION; 589d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie} 599d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie 609d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddiebool PlatformNanoapp::isSystemNanoapp() const { 611a436aa2739b13c4f5625fa1fca75c7a964068adAndrew Rossignol return (mAppInfo != nullptr && mAppInfo->isSystemNanoapp); 629d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie} 639d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie 64d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishigurobool PlatformNanoapp::logStateToBuffer(char *buffer, size_t *bufferPos, 65d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro size_t bufferSize) const { 66d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro return true; 67d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro} 68d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro 69fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignolvoid PlatformNanoappBase::loadFromFile(const std::string& filename) { 70fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol CHRE_ASSERT(!isLoaded()); 71fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mFilename = filename; 72fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol} 73fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 74fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignolvoid PlatformNanoappBase::loadStatic(const struct chreNslNanoappInfo *appInfo) { 75fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol CHRE_ASSERT(!isLoaded()); 76fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mIsStatic = true; 77fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mAppInfo = appInfo; 78fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol} 79fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 80fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignolbool PlatformNanoappBase::isLoaded() const { 81fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol return (mIsStatic || mDsoHandle != nullptr); 82fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol} 83fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 84fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignolbool PlatformNanoappBase::openNanoapp() { 85fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol bool success = false; 86fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 87fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol if (mIsStatic) { 88fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol success = true; 89fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } else if (!mFilename.empty()) { 90fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol success = openNanoappFromFile(); 91fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } else { 92fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol CHRE_ASSERT(false); 93fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } 94fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 95fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol return success; 96fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol} 97fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 98fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignolbool PlatformNanoappBase::openNanoappFromFile() { 99fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol CHRE_ASSERT(!mFilename.empty()); 100fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol CHRE_ASSERT_LOG(mDsoHandle == nullptr, "Re-opening nanoapp"); 101fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol bool success = false; 102fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 103fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mDsoHandle = dlopen(mFilename.c_str(), RTLD_NOW | RTLD_GLOBAL); 104fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol if (mDsoHandle == nullptr) { 105fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol LOGE("Failed to load nanoapp from file %s: %s", 106fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mFilename.c_str(), dlerror()); 107fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } else { 108fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mAppInfo = static_cast<const struct chreNslNanoappInfo *>( 109fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol dlsym(mDsoHandle, CHRE_NSL_DSO_NANOAPP_INFO_SYMBOL_NAME)); 110fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol if (mAppInfo == nullptr) { 111fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol LOGE("Failed to find app info symbol in %s: %s", 112fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mFilename.c_str(), dlerror()); 113fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } else { 114fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol success = validateAppInfo(0 /* skip ID validation */, 0, mAppInfo, 115fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol true /* ignoreAppVersion */); 116fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol if (!success) { 117fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mAppInfo = nullptr; 118fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } else { 119fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol LOGI("Successfully loaded nanoapp %s (0x%016" PRIx64 ") version 0x%" 120fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol PRIx32 " uimg %d system %d from file %s", mAppInfo->name, 121fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mAppInfo->appId, mAppInfo->appVersion, mAppInfo->isTcmNanoapp, 122fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mAppInfo->isSystemNanoapp, mFilename.c_str()); 123fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } 124fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } 125fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } 126fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 127fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol return success; 128fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol} 129fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 130fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignolvoid PlatformNanoappBase::closeNanoapp() { 131fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol if (mDsoHandle != nullptr) { 132fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol if (dlclose(mDsoHandle) != 0) { 133fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol LOGE("dlclose failed: %s", dlerror()); 134fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } 135fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol mDsoHandle = nullptr; 136fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol } 137fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol} 138fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol 139e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie} // namespace chre 140