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 <dlfcn.h>
17 #include <map>
18 #include <thread>
19
20 #include "../include/module_log.h"
21 #include "../include/module_manager.h"
22
23 namespace OHOS {
24 namespace UpdateEngine {
25 std::map<uint32_t, RequestFuncType> ModuleManager::onRemoteRequestFuncMap_;
26 std::map<std::string, LifeCycleFuncType> ModuleManager::onStartOnStopFuncMap_;
27 std::map<std::string, LifeCycleFuncReturnType> ModuleManager::onIdleFuncMap_;
28
29 bool ModuleManager::isLoaded = false;
30
LoadModule(std::string libPath)31 void ModuleManager::LoadModule(std::string libPath)
32 {
33 std::string prefix = "/system/lib64/updateext";
34 std::string suffix = ".so";
35 if ((libPath.substr(0, prefix.length()) != prefix) ||
36 (libPath.substr(libPath.length() - suffix.length(), suffix.length()) != suffix)) {
37 UTILS_LOGE("LoadModule lib path invalid");
38 return;
39 }
40 UTILS_LOGD("LoadModule so path: %{public}s", libPath.c_str());
41 if (dueModuleHandler == nullptr) {
42 constexpr int32_t maxRetryTimes = 1;
43 int32_t retryTimes = 0;
44 do {
45 dueModuleHandler = dlopen(libPath.c_str(), RTLD_LAZY);
46 if (dueModuleHandler != nullptr) {
47 isLoaded = true;
48 break;
49 }
50 UTILS_LOGE("openSo path: %{public}s fail", libPath.c_str());
51 retryTimes++;
52 if (retryInterval_ > 0 && retryTimes <= maxRetryTimes) {
53 std::this_thread::sleep_for(std::chrono::milliseconds(retryInterval_));
54 }
55 } while (retryTimes <= maxRetryTimes);
56 } else {
57 isLoaded = true;
58 UTILS_LOGD("openSo ok");
59 }
60 }
61
GetInstance()62 ModuleManager& ModuleManager::GetInstance()
63 {
64 static ModuleManager moduleManager;
65 return moduleManager;
66 }
67
HookFunc(std::vector<uint32_t> codes,RequestFuncType handleRemoteRequest)68 void ModuleManager::HookFunc(std::vector<uint32_t> codes, RequestFuncType handleRemoteRequest)
69 {
70 for (int code : codes) {
71 if (onRemoteRequestFuncMap_.find(code) == onRemoteRequestFuncMap_.end()) {
72 UTILS_LOGE("code not exist %{public}d onRemoteRequestFuncMap_", code);
73 onRemoteRequestFuncMap_.insert(std::make_pair(code, handleRemoteRequest));
74 } else {
75 UTILS_LOGD("add code %{public}d to onRemoteRequestFuncMap_", code);
76 onRemoteRequestFuncMap_[code] = handleRemoteRequest;
77 }
78 }
79 }
80
HandleFunc(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)81 int32_t ModuleManager::HandleFunc(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
82 {
83 if (onRemoteRequestFuncMap_.find(code) == onRemoteRequestFuncMap_.end()) {
84 UTILS_LOGE("HandleFunc code %{public}d not exist", code);
85 } else {
86 UTILS_LOGD("HandleFunc code %{public}d exist", code);
87 return ((RequestFuncType)onRemoteRequestFuncMap_[code])(code, data, reply, option);
88 }
89 return 0;
90 }
91
ModuleManager()92 ModuleManager::ModuleManager() {}
93
IsModuleLoaded()94 bool ModuleManager::IsModuleLoaded()
95 {
96 return isLoaded;
97 }
98
HookOnStartOnStopFunc(std::string phase,LifeCycleFuncType handleSAOnStartOnStop)99 void ModuleManager::HookOnStartOnStopFunc(std::string phase, LifeCycleFuncType handleSAOnStartOnStop)
100 {
101 if (onStartOnStopFuncMap_.find(phase) == onStartOnStopFuncMap_.end()) {
102 UTILS_LOGE("phase exist already %{public}s onStartOnStopFuncMap_", phase.c_str());
103 onStartOnStopFuncMap_.insert(std::make_pair(phase, handleSAOnStartOnStop));
104 } else {
105 UTILS_LOGD("add phase %{public}s to onStartOnStopFuncMap_", phase.c_str());
106 onStartOnStopFuncMap_[phase] = handleSAOnStartOnStop;
107 }
108 }
109
HandleOnStartOnStopFunc(std::string phase,const OHOS::SystemAbilityOnDemandReason & reason)110 void ModuleManager::HandleOnStartOnStopFunc(std::string phase, const OHOS::SystemAbilityOnDemandReason &reason)
111 {
112 if (onStartOnStopFuncMap_.find(phase) == onStartOnStopFuncMap_.end()) {
113 UTILS_LOGE("HandleOnStartOnStopFunc phase %{public}s not exist", phase.c_str());
114 } else {
115 UTILS_LOGD("HandleOnStartOnStopFunc phase %{public}s exist", phase.c_str());
116 ((LifeCycleFuncType)onStartOnStopFuncMap_[phase])(reason);
117 }
118 }
119
HookOnIdleFunc(std::string phase,LifeCycleFuncReturnType handleSAOnIdle)120 void ModuleManager::HookOnIdleFunc(std::string phase, LifeCycleFuncReturnType handleSAOnIdle)
121 {
122 if (onIdleFuncMap_.find(phase) == onIdleFuncMap_.end()) {
123 UTILS_LOGE("phase exist already %{public}s onIdleFuncMap_", phase.c_str());
124 onIdleFuncMap_.insert(std::make_pair(phase, handleSAOnIdle));
125 } else {
126 UTILS_LOGD("add phase %{public}s to onIdleFuncMap_", phase.c_str());
127 onIdleFuncMap_[phase] = handleSAOnIdle;
128 }
129 }
130
HandleOnIdleFunc(std::string phase,const OHOS::SystemAbilityOnDemandReason & reason)131 int32_t ModuleManager::HandleOnIdleFunc(std::string phase, const OHOS::SystemAbilityOnDemandReason &reason)
132 {
133 if (onIdleFuncMap_.find(phase) == onIdleFuncMap_.end()) {
134 UTILS_LOGE("HandleOnIdleFunc phase %{public}s not exist", phase.c_str());
135 } else {
136 UTILS_LOGI("HandleOnIdleFunc phase %{public}s exist", phase.c_str());
137 return ((LifeCycleFuncReturnType)onIdleFuncMap_[phase])(reason);
138 }
139 return 0;
140 }
141 } // namespace UpdateEngine
142 } // namespace OHOS
143