1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <climits>
17 #include <dlfcn.h>
18 #include <map>
19 #include <thread>
20
21 #include "../include/module_log.h"
22 #include "../include/module_manager.h"
23
24 namespace OHOS {
25 namespace UpdateEngine {
26 std::map<uint32_t, RequestFuncType> ModuleManager::onRemoteRequestFuncMap_;
27 std::map<std::string, LifeCycleFuncType> ModuleManager::onStartOnStopFuncMap_;
28 std::map<std::string, LifeCycleFuncReturnType> ModuleManager::onIdleFuncMap_;
29 std::mutex ModuleManager::onRemoteRequestFuncMapMutex_;
30 std::mutex ModuleManager::onStartOnStopFuncMapMutex_;
31 std::mutex ModuleManager::onIdleFuncMapMutex_;
32
33 bool ModuleManager::isLoaded = false;
34
LoadModule(std::string libPath)35 void ModuleManager::LoadModule(std::string libPath)
36 {
37 std::string prefix = "/system/lib64/updateext";
38 std::string modulePrefix = "/module_update/3006/lib64/updateext";
39 std::string suffix = ".so";
40 if ((libPath.substr(0, prefix.length()) != prefix &&
41 libPath.substr(0, modulePrefix.length()) != modulePrefix) ||
42 (libPath.substr(libPath.length() - suffix.length(), suffix.length()) != suffix)) {
43 UTILS_LOGE("LoadModule lib path invalid");
44 return;
45 }
46 UTILS_LOGD("LoadModule so path: %{public}s", libPath.c_str());
47 if (dueModuleHandler == nullptr) {
48 constexpr int32_t maxRetryTimes = 1;
49 int32_t retryTimes = 0;
50 char dealPath[PATH_MAX] = {};
51 if (realpath(libPath.c_str(), dealPath) == nullptr) {
52 UTILS_LOGE("soPath %{private}s is not exist or invalid", libPath.c_str());
53 return;
54 }
55 do {
56 dueModuleHandler = dlopen(dealPath, RTLD_LAZY);
57 if (dueModuleHandler != nullptr) {
58 isLoaded = true;
59 break;
60 }
61 UTILS_LOGE("openSo path: %{public}s fail", libPath.c_str());
62 retryTimes++;
63 if (retryInterval_ > 0 && retryTimes <= maxRetryTimes) {
64 std::this_thread::sleep_for(std::chrono::milliseconds(retryInterval_));
65 }
66 } while (retryTimes <= maxRetryTimes);
67 } else {
68 isLoaded = true;
69 UTILS_LOGD("openSo ok");
70 }
71 }
72
GetInstance()73 ModuleManager& ModuleManager::GetInstance()
74 {
75 static ModuleManager moduleManager;
76 return moduleManager;
77 }
78
HookFunc(std::vector<uint32_t> codes,RequestFuncType handleRemoteRequest)79 void ModuleManager::HookFunc(std::vector<uint32_t> codes, RequestFuncType handleRemoteRequest)
80 {
81 std::lock_guard<std::mutex> guard(onRemoteRequestFuncMapMutex_);
82 for (const uint32_t code : codes) {
83 if (!IsMapFuncExist(code)) {
84 UTILS_LOGI("add code %{public}d", code);
85 onRemoteRequestFuncMap_.insert(std::make_pair(code, handleRemoteRequest));
86 } else {
87 UTILS_LOGI("code %{public}d already exist", code);
88 }
89 }
90 }
91
HandleFunc(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)92 int32_t ModuleManager::HandleFunc(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
93 {
94 if (!IsMapFuncExist(code)) {
95 UTILS_LOGI("code %{public}d not exist", code);
96 } else {
97 UTILS_LOGI("code %{public}d called", code);
98 return ((RequestFuncType)onRemoteRequestFuncMap_[code])(code, data, reply, option);
99 }
100 return 0;
101 }
102
ModuleManager()103 ModuleManager::ModuleManager() {}
104
IsModuleLoaded()105 bool ModuleManager::IsModuleLoaded()
106 {
107 return isLoaded;
108 }
109
HookOnStartOnStopFunc(std::string phase,LifeCycleFuncType handleSAOnStartOnStop)110 void ModuleManager::HookOnStartOnStopFunc(std::string phase, LifeCycleFuncType handleSAOnStartOnStop)
111 {
112 std::lock_guard<std::mutex> guard(onStartOnStopFuncMapMutex_);
113 if (onStartOnStopFuncMap_.find(phase) == onStartOnStopFuncMap_.end()) {
114 UTILS_LOGI("add phase %{public}s", phase.c_str());
115 onStartOnStopFuncMap_.insert(std::make_pair(phase, handleSAOnStartOnStop));
116 } else {
117 UTILS_LOGI("phase %{public}s exist", phase.c_str());
118 onStartOnStopFuncMap_[phase] = handleSAOnStartOnStop;
119 }
120 }
121
HandleOnStartOnStopFunc(std::string phase,const OHOS::SystemAbilityOnDemandReason & reason)122 void ModuleManager::HandleOnStartOnStopFunc(std::string phase, const OHOS::SystemAbilityOnDemandReason &reason)
123 {
124 if (onStartOnStopFuncMap_.find(phase) == onStartOnStopFuncMap_.end()) {
125 UTILS_LOGI("phase %{public}s not exist", phase.c_str());
126 return;
127 }
128 UTILS_LOGI("HandleOnStartOnStopFunc phase %{public}s exist", phase.c_str());
129 ((LifeCycleFuncType)onStartOnStopFuncMap_[phase])(reason);
130 }
131
HookOnIdleFunc(std::string phase,LifeCycleFuncReturnType handleSAOnIdle)132 void ModuleManager::HookOnIdleFunc(std::string phase, LifeCycleFuncReturnType handleSAOnIdle)
133 {
134 std::lock_guard<std::mutex> guard(onIdleFuncMapMutex_);
135 if (onIdleFuncMap_.find(phase) == onIdleFuncMap_.end()) {
136 UTILS_LOGI("add phase %{public}s", phase.c_str());
137 onIdleFuncMap_.insert(std::make_pair(phase, handleSAOnIdle));
138 } else {
139 UTILS_LOGI("phase %{public}s already exist", phase.c_str());
140 onIdleFuncMap_[phase] = handleSAOnIdle;
141 }
142 }
143
HandleOnIdleFunc(std::string phase,const OHOS::SystemAbilityOnDemandReason & reason)144 int32_t ModuleManager::HandleOnIdleFunc(std::string phase, const OHOS::SystemAbilityOnDemandReason &reason)
145 {
146 if (onIdleFuncMap_.find(phase) == onIdleFuncMap_.end()) {
147 UTILS_LOGI("phase %{public}s not exist", phase.c_str());
148 } else {
149 UTILS_LOGI("phase %{public}s already exist", phase.c_str());
150 return ((LifeCycleFuncReturnType)onIdleFuncMap_[phase])(reason);
151 }
152 return 0;
153 }
154
IsMapFuncExist(uint32_t code)155 bool ModuleManager::IsMapFuncExist(uint32_t code)
156 {
157 return onRemoteRequestFuncMap_.count(code);
158 }
159 } // namespace UpdateEngine
160 } // namespace OHOS
161