1190978c3Sopenharmony_ci/* 2190978c3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3190978c3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4190978c3Sopenharmony_ci * you may not use this file except in compliance with the License. 5190978c3Sopenharmony_ci * You may obtain a copy of the License at 6190978c3Sopenharmony_ci * 7190978c3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8190978c3Sopenharmony_ci * 9190978c3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10190978c3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11190978c3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12190978c3Sopenharmony_ci * See the License for the specific language governing permissions and 13190978c3Sopenharmony_ci * limitations under the License. 14190978c3Sopenharmony_ci */ 15190978c3Sopenharmony_ci 16190978c3Sopenharmony_ci#include <climits> 17190978c3Sopenharmony_ci#include <dlfcn.h> 18190978c3Sopenharmony_ci#include <map> 19190978c3Sopenharmony_ci#include <thread> 20190978c3Sopenharmony_ci 21190978c3Sopenharmony_ci#include "../include/module_log.h" 22190978c3Sopenharmony_ci#include "../include/module_manager.h" 23190978c3Sopenharmony_ci 24190978c3Sopenharmony_cinamespace OHOS { 25190978c3Sopenharmony_cinamespace UpdateEngine { 26190978c3Sopenharmony_cistd::map<uint32_t, RequestFuncType> ModuleManager::onRemoteRequestFuncMap_; 27190978c3Sopenharmony_cistd::map<std::string, LifeCycleFuncType> ModuleManager::onStartOnStopFuncMap_; 28190978c3Sopenharmony_cistd::map<std::string, LifeCycleFuncReturnType> ModuleManager::onIdleFuncMap_; 29190978c3Sopenharmony_cistd::map<std::string, LifeCycleFuncDumpType> ModuleManager::onDumpFuncMap_; 30190978c3Sopenharmony_cistd::mutex ModuleManager::onRemoteRequestFuncMapMutex_; 31190978c3Sopenharmony_cistd::mutex ModuleManager::onStartOnStopFuncMapMutex_; 32190978c3Sopenharmony_cistd::mutex ModuleManager::onIdleFuncMapMutex_; 33190978c3Sopenharmony_cistd::mutex ModuleManager::onDumpFuncMapMutex_; 34190978c3Sopenharmony_ci 35190978c3Sopenharmony_cibool ModuleManager::isLoaded = false; 36190978c3Sopenharmony_ci 37190978c3Sopenharmony_civoid ModuleManager::LoadModule(std::string libPath) 38190978c3Sopenharmony_ci{ 39190978c3Sopenharmony_ci std::string prefix = "/system/lib64/updateext"; 40190978c3Sopenharmony_ci std::string modulePrefix = "/module_update/3006/lib64/updateext"; 41190978c3Sopenharmony_ci std::string suffix = ".so"; 42190978c3Sopenharmony_ci if ((libPath.substr(0, prefix.length()) != prefix && 43190978c3Sopenharmony_ci libPath.substr(0, modulePrefix.length()) != modulePrefix) || 44190978c3Sopenharmony_ci (libPath.substr(libPath.length() - suffix.length(), suffix.length()) != suffix)) { 45190978c3Sopenharmony_ci UTILS_LOGE("LoadModule lib path invalid"); 46190978c3Sopenharmony_ci return; 47190978c3Sopenharmony_ci } 48190978c3Sopenharmony_ci UTILS_LOGD("LoadModule so path: %{public}s", libPath.c_str()); 49190978c3Sopenharmony_ci if (dueModuleHandler == nullptr) { 50190978c3Sopenharmony_ci constexpr int32_t maxRetryTimes = 1; 51190978c3Sopenharmony_ci int32_t retryTimes = 0; 52190978c3Sopenharmony_ci char dealPath[PATH_MAX] = {}; 53190978c3Sopenharmony_ci if (realpath(libPath.c_str(), dealPath) == nullptr) { 54190978c3Sopenharmony_ci UTILS_LOGE("soPath %{private}s is not exist or invalid", libPath.c_str()); 55190978c3Sopenharmony_ci return; 56190978c3Sopenharmony_ci } 57190978c3Sopenharmony_ci do { 58190978c3Sopenharmony_ci dueModuleHandler = dlopen(dealPath, RTLD_LAZY); 59190978c3Sopenharmony_ci if (dueModuleHandler != nullptr) { 60190978c3Sopenharmony_ci isLoaded = true; 61190978c3Sopenharmony_ci break; 62190978c3Sopenharmony_ci } 63190978c3Sopenharmony_ci UTILS_LOGE("openSo path: %{public}s fail", libPath.c_str()); 64190978c3Sopenharmony_ci retryTimes++; 65190978c3Sopenharmony_ci if (retryInterval_ > 0 && retryTimes <= maxRetryTimes) { 66190978c3Sopenharmony_ci std::this_thread::sleep_for(std::chrono::milliseconds(retryInterval_)); 67190978c3Sopenharmony_ci } 68190978c3Sopenharmony_ci } while (retryTimes <= maxRetryTimes); 69190978c3Sopenharmony_ci } else { 70190978c3Sopenharmony_ci isLoaded = true; 71190978c3Sopenharmony_ci UTILS_LOGD("openSo ok"); 72190978c3Sopenharmony_ci } 73190978c3Sopenharmony_ci} 74190978c3Sopenharmony_ci 75190978c3Sopenharmony_ciModuleManager& ModuleManager::GetInstance() 76190978c3Sopenharmony_ci{ 77190978c3Sopenharmony_ci static ModuleManager moduleManager; 78190978c3Sopenharmony_ci return moduleManager; 79190978c3Sopenharmony_ci} 80190978c3Sopenharmony_ci 81190978c3Sopenharmony_civoid ModuleManager::HookFunc(std::vector<uint32_t> codes, RequestFuncType handleRemoteRequest) 82190978c3Sopenharmony_ci{ 83190978c3Sopenharmony_ci std::lock_guard<std::mutex> guard(onRemoteRequestFuncMapMutex_); 84190978c3Sopenharmony_ci for (const uint32_t code : codes) { 85190978c3Sopenharmony_ci if (!IsMapFuncExist(code)) { 86190978c3Sopenharmony_ci UTILS_LOGI("add code %{public}d", code); 87190978c3Sopenharmony_ci onRemoteRequestFuncMap_.insert(std::make_pair(code, handleRemoteRequest)); 88190978c3Sopenharmony_ci } else { 89190978c3Sopenharmony_ci UTILS_LOGI("code %{public}d already exist", code); 90190978c3Sopenharmony_ci } 91190978c3Sopenharmony_ci } 92190978c3Sopenharmony_ci} 93190978c3Sopenharmony_ci 94190978c3Sopenharmony_ciint32_t ModuleManager::HandleFunc(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) 95190978c3Sopenharmony_ci{ 96190978c3Sopenharmony_ci if (!IsMapFuncExist(code)) { 97190978c3Sopenharmony_ci UTILS_LOGI("code %{public}d not exist", code); 98190978c3Sopenharmony_ci } else { 99190978c3Sopenharmony_ci UTILS_LOGI("code %{public}d called", code); 100190978c3Sopenharmony_ci return ((RequestFuncType)onRemoteRequestFuncMap_[code])(code, data, reply, option); 101190978c3Sopenharmony_ci } 102190978c3Sopenharmony_ci return 0; 103190978c3Sopenharmony_ci} 104190978c3Sopenharmony_ci 105190978c3Sopenharmony_ciModuleManager::ModuleManager() {} 106190978c3Sopenharmony_ci 107190978c3Sopenharmony_cibool ModuleManager::IsModuleLoaded() 108190978c3Sopenharmony_ci{ 109190978c3Sopenharmony_ci return isLoaded; 110190978c3Sopenharmony_ci} 111190978c3Sopenharmony_ci 112190978c3Sopenharmony_civoid ModuleManager::HookOnStartOnStopFunc(std::string phase, LifeCycleFuncType handleSAOnStartOnStop) 113190978c3Sopenharmony_ci{ 114190978c3Sopenharmony_ci std::lock_guard<std::mutex> guard(onStartOnStopFuncMapMutex_); 115190978c3Sopenharmony_ci if (onStartOnStopFuncMap_.find(phase) == onStartOnStopFuncMap_.end()) { 116190978c3Sopenharmony_ci UTILS_LOGI("add phase %{public}s", phase.c_str()); 117190978c3Sopenharmony_ci onStartOnStopFuncMap_.insert(std::make_pair(phase, handleSAOnStartOnStop)); 118190978c3Sopenharmony_ci } else { 119190978c3Sopenharmony_ci UTILS_LOGI("phase %{public}s exist", phase.c_str()); 120190978c3Sopenharmony_ci onStartOnStopFuncMap_[phase] = handleSAOnStartOnStop; 121190978c3Sopenharmony_ci } 122190978c3Sopenharmony_ci} 123190978c3Sopenharmony_ci 124190978c3Sopenharmony_civoid ModuleManager::HandleOnStartOnStopFunc(std::string phase, const OHOS::SystemAbilityOnDemandReason &reason) 125190978c3Sopenharmony_ci{ 126190978c3Sopenharmony_ci if (onStartOnStopFuncMap_.find(phase) == onStartOnStopFuncMap_.end()) { 127190978c3Sopenharmony_ci UTILS_LOGI("phase %{public}s not exist", phase.c_str()); 128190978c3Sopenharmony_ci return; 129190978c3Sopenharmony_ci } 130190978c3Sopenharmony_ci UTILS_LOGI("HandleOnStartOnStopFunc phase %{public}s exist", phase.c_str()); 131190978c3Sopenharmony_ci ((LifeCycleFuncType)onStartOnStopFuncMap_[phase])(reason); 132190978c3Sopenharmony_ci} 133190978c3Sopenharmony_ci 134190978c3Sopenharmony_civoid ModuleManager::HookOnIdleFunc(std::string phase, LifeCycleFuncReturnType handleSAOnIdle) 135190978c3Sopenharmony_ci{ 136190978c3Sopenharmony_ci std::lock_guard<std::mutex> guard(onIdleFuncMapMutex_); 137190978c3Sopenharmony_ci if (onIdleFuncMap_.find(phase) == onIdleFuncMap_.end()) { 138190978c3Sopenharmony_ci UTILS_LOGI("add phase %{public}s", phase.c_str()); 139190978c3Sopenharmony_ci onIdleFuncMap_.insert(std::make_pair(phase, handleSAOnIdle)); 140190978c3Sopenharmony_ci } else { 141190978c3Sopenharmony_ci UTILS_LOGI("phase %{public}s already exist", phase.c_str()); 142190978c3Sopenharmony_ci onIdleFuncMap_[phase] = handleSAOnIdle; 143190978c3Sopenharmony_ci } 144190978c3Sopenharmony_ci} 145190978c3Sopenharmony_ci 146190978c3Sopenharmony_ciint32_t ModuleManager::HandleOnIdleFunc(std::string phase, const OHOS::SystemAbilityOnDemandReason &reason) 147190978c3Sopenharmony_ci{ 148190978c3Sopenharmony_ci if (onIdleFuncMap_.find(phase) == onIdleFuncMap_.end()) { 149190978c3Sopenharmony_ci UTILS_LOGI("phase %{public}s not exist", phase.c_str()); 150190978c3Sopenharmony_ci } else { 151190978c3Sopenharmony_ci UTILS_LOGI("phase %{public}s already exist", phase.c_str()); 152190978c3Sopenharmony_ci return ((LifeCycleFuncReturnType)onIdleFuncMap_[phase])(reason); 153190978c3Sopenharmony_ci } 154190978c3Sopenharmony_ci return 0; 155190978c3Sopenharmony_ci} 156190978c3Sopenharmony_ci 157190978c3Sopenharmony_civoid ModuleManager::HookDumpFunc(std::string phase, LifeCycleFuncDumpType handleSADump) 158190978c3Sopenharmony_ci{ 159190978c3Sopenharmony_ci std::lock_guard<std::mutex> guard(onDumpFuncMapMutex_); 160190978c3Sopenharmony_ci if (onDumpFuncMap_.find(phase) == onDumpFuncMap_.end()) { 161190978c3Sopenharmony_ci UTILS_LOGI("add phase %{public}s", phase.c_str()); 162190978c3Sopenharmony_ci onDumpFuncMap_.insert(std::make_pair(phase, handleSADump)); 163190978c3Sopenharmony_ci } else { 164190978c3Sopenharmony_ci UTILS_LOGI("phase %{public}s already exist", phase.c_str()); 165190978c3Sopenharmony_ci onDumpFuncMap_[phase] = handleSADump; 166190978c3Sopenharmony_ci } 167190978c3Sopenharmony_ci} 168190978c3Sopenharmony_ci 169190978c3Sopenharmony_ciint ModuleManager::HandleDumpFunc(std::string phase, int fd, const std::vector<std::u16string> &args) 170190978c3Sopenharmony_ci{ 171190978c3Sopenharmony_ci if (onDumpFuncMap_.find(phase) == onDumpFuncMap_.end()) { 172190978c3Sopenharmony_ci UTILS_LOGI("phase %{public}s not exist", phase.c_str()); 173190978c3Sopenharmony_ci } else { 174190978c3Sopenharmony_ci UTILS_LOGI("phase %{public}s already exist", phase.c_str()); 175190978c3Sopenharmony_ci return ((LifeCycleFuncDumpType)onDumpFuncMap_[phase])(fd, args); 176190978c3Sopenharmony_ci } 177190978c3Sopenharmony_ci return 0; 178190978c3Sopenharmony_ci} 179190978c3Sopenharmony_ci 180190978c3Sopenharmony_cibool ModuleManager::IsMapFuncExist(uint32_t code) 181190978c3Sopenharmony_ci{ 182190978c3Sopenharmony_ci return onRemoteRequestFuncMap_.count(code); 183190978c3Sopenharmony_ci} 184190978c3Sopenharmony_ci} // namespace UpdateEngine 185190978c3Sopenharmony_ci} // namespace OHOS 186