1 /*
2 * Copyright (c) 2022-2024 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 "plugin_manager.h"
17
18 #include <dirent.h>
19 #include <dlfcn.h>
20 #include <string_ex.h>
21 #include <unistd.h>
22
23 #include <cstring>
24 #include <iostream>
25
26 #include "edm_ipc_interface_code.h"
27 #include "edm_log.h"
28 #include "func_code_utils.h"
29 #include "permission_manager.h"
30
31 namespace OHOS {
32 namespace EDM {
33 #if defined(_ARM64_) || defined(_X86_64_)
34 const char* const PLUGIN_DIR = "/system/lib64/edm_plugin/";
35 #else
36 const char* const PLUGIN_DIR = "/system/lib/edm_plugin/";
37 #endif
38
39 std::shared_ptr<PluginManager> PluginManager::instance_;
40 std::shared_timed_mutex PluginManager::mutexLock_;
41 constexpr int32_t TIMER_TIMEOUT = 180000; // 3 * 60 * 1000;
42 constexpr int32_t MUTEX_TIMEOUT = 10;;
43
44 std::vector<uint32_t> PluginManager::deviceCoreSoCodes_ = {
45 EdmInterfaceCode::DISALLOW_ADD_LOCAL_ACCOUNT, EdmInterfaceCode::ALLOWED_INSTALL_BUNDLES,
46 EdmInterfaceCode::DISALLOW_MODIFY_DATETIME, EdmInterfaceCode::DISALLOWED_INSTALL_BUNDLES,
47 EdmInterfaceCode::SCREEN_OFF_TIME, EdmInterfaceCode::DISALLOWED_UNINSTALL_BUNDLES,
48 EdmInterfaceCode::UNINSTALL, EdmInterfaceCode::DISABLED_PRINTER,
49 EdmInterfaceCode::DISABLED_HDC, EdmInterfaceCode::INSTALL,
50 EdmInterfaceCode::POWER_POLICY, EdmInterfaceCode::NTP_SERVER,
51 EdmInterfaceCode::LOCK_SCREEN, EdmInterfaceCode::SHUTDOWN,
52 EdmInterfaceCode::REBOOT, EdmInterfaceCode::DISALLOW_ADD_OS_ACCOUNT_BY_USER,
53 EdmInterfaceCode::ADD_OS_ACCOUNT, EdmInterfaceCode::GET_BLUETOOTH_INFO,
54 EdmInterfaceCode::DISABLE_MICROPHONE, EdmInterfaceCode::DISABLE_BLUETOOTH,
55 EdmInterfaceCode::ALLOWED_BLUETOOTH_DEVICES, EdmInterfaceCode::INACTIVE_USER_FREEZE,
56 EdmInterfaceCode::SNAPSHOT_SKIP, EdmInterfaceCode::WATERMARK_IMAGE,
57 EdmInterfaceCode::DISABLE_CAMERA, EdmInterfaceCode::DOMAIN_ACCOUNT_POLICY,
58 EdmInterfaceCode::DISABLE_MAINTENANCE_MODE, EdmInterfaceCode::SWITCH_BLUETOOTH,
59 EdmInterfaceCode::GET_BUNDLE_INFO_LIST, EdmInterfaceCode::DISABLE_BACKUP_AND_RESTORE,
60 EdmInterfaceCode::DISALLOWED_BLUETOOTH_DEVICES, EdmInterfaceCode::DISABLE_USER_MTP_CLIENT,
61 EdmInterfaceCode::DISABLE_MTP_CLIENT, EdmInterfaceCode::DISABLE_MTP_SERVER,
62 EdmInterfaceCode::SET_KIOSK_FEATURE, EdmInterfaceCode::DISALLOWED_BLUETOOTH_PROTOCOLS,
63 EdmInterfaceCode::DISABLE_REMOTE_DESK, EdmInterfaceCode::DISABLE_REMOTE_DIAGNOSIS,
64 EdmInterfaceCode::DISALLOW_POWER_LONG_PRESS, EdmInterfaceCode::DISABLE_SET_BIOMETRICS_AND_SCREENLOCK,
65 EdmInterfaceCode::DISABLE_SET_DEVICE_NAME, EdmInterfaceCode::SET_AUTO_UNLOCK_AFTER_REBOOT,
66 EdmInterfaceCode::ALLOWED_KIOSK_APPS, EdmInterfaceCode::DISALLOWED_SUDO,
67 EdmInterfaceCode::ALLOWED_INSTALL_APP_TYPE, EdmInterfaceCode::DISABLE_PRIVATE_SPACE,
68 EdmInterfaceCode::SET_INSTALL_LOCAL_ENTERPRISE_APP_ENABLED, EdmInterfaceCode::DISALLOWED_NEARLINK_PROTOCOLS,
69 EdmInterfaceCode::DISALLOWED_EXPORT_RECOVERY_KEY, EdmInterfaceCode::DISALLOWED_USB_STORAGE_DEVICE_WRITE,
70 EdmInterfaceCode::DISABLED_PRINT, EdmInterfaceCode::DISALLOWED_DISTRIBUTED_TRANSMISSION
71 };
72
73 std::vector<uint32_t> PluginManager::communicationSoCodes_ = {
74 EdmInterfaceCode::IS_WIFI_ACTIVE, EdmInterfaceCode::GET_NETWORK_INTERFACES,
75 EdmInterfaceCode::GET_IP_ADDRESS, EdmInterfaceCode::GET_MAC,
76 EdmInterfaceCode::SET_WIFI_PROFILE, EdmInterfaceCode::DISABLED_NETWORK_INTERFACE,
77 EdmInterfaceCode::IPTABLES_RULE, EdmInterfaceCode::SET_BROWSER_POLICIES,
78 EdmInterfaceCode::GLOBAL_PROXY, EdmInterfaceCode::USB_READ_ONLY,
79 EdmInterfaceCode::FIREWALL_RULE, EdmInterfaceCode::DOMAIN_FILTER_RULE,
80 EdmInterfaceCode::DISABLE_USB, EdmInterfaceCode::ALLOWED_USB_DEVICES,
81 EdmInterfaceCode::DISABLE_WIFI, EdmInterfaceCode::DISALLOWED_TETHERING,
82 EdmInterfaceCode::DISALLOWED_USB_DEVICES, EdmInterfaceCode::MANAGED_BROWSER_POLICY,
83 EdmInterfaceCode::ALLOWED_WIFI_LIST, EdmInterfaceCode::DISALLOWED_WIFI_LIST,
84 EdmInterfaceCode::DISALLOWED_SMS, EdmInterfaceCode::DISALLOWED_MMS,
85 EdmInterfaceCode::SWITCH_WIFI, EdmInterfaceCode::DISALLOW_MODIFY_APN,
86 EdmInterfaceCode::DISABLE_SAMBA_CLIENT, EdmInterfaceCode::DISABLE_SAMBA_SERVER,
87 EdmInterfaceCode::TURNONOFF_MOBILE_DATA, EdmInterfaceCode::SET_APN_INFO,
88 EdmInterfaceCode::DISALLOWED_SIM, EdmInterfaceCode::DISALLOWED_MOBILE_DATA,
89 EdmInterfaceCode::DISALLOW_MODIFY_ETHERNET_IP, EdmInterfaceCode::DISALLOWED_AIRPLANE_MODE,
90 EdmInterfaceCode::TELEPHONY_CALL_POLICY, EdmInterfaceCode::DISALLOWED_TELEPHONY_CALL,
91 EdmInterfaceCode::DISALLOW_VPN,
92 };
93
94 std::vector<uint32_t> PluginManager::sysServiceSoCodes_ = {
95 EdmInterfaceCode::SET_DATETIME, EdmInterfaceCode::RESET_FACTORY,
96 EdmInterfaceCode::DISALLOW_RUNNING_BUNDLES, EdmInterfaceCode::INSTALL_CERTIFICATE,
97 EdmInterfaceCode::LOCATION_POLICY, EdmInterfaceCode::MANAGE_AUTO_START_APPS,
98 EdmInterfaceCode::FINGERPRINT_AUTH, EdmInterfaceCode::PASSWORD_POLICY,
99 EdmInterfaceCode::CLIPBOARD_POLICY, EdmInterfaceCode::MANAGE_KEEP_ALIVE_APPS,
100 EdmInterfaceCode::CLEAR_UP_APPLICATION_DATA, EdmInterfaceCode::DISALLOWED_NOTIFICATION,
101 EdmInterfaceCode::PERMISSION_MANAGED_STATE
102 };
103
104 std::vector<uint32_t> PluginManager::needExtraSoCodes_ = {
105 EdmInterfaceCode::GET_DEVICE_SERIAL, EdmInterfaceCode::GET_DEVICE_NAME,
106 EdmInterfaceCode::GET_DEVICE_INFO, EdmInterfaceCode::OPERATE_DEVICE,
107 EdmInterfaceCode::SET_OTA_UPDATE_POLICY, EdmInterfaceCode::NOTIFY_UPGRADE_PACKAGES,
108 EdmInterfaceCode::GET_ADMINPROVISION_INFO, EdmInterfaceCode::SET_WALL_PAPER
109 };
110
PluginManager()111 PluginManager::PluginManager()
112 {
113 EDMLOGI("PluginManager::PluginManager.");
114 }
115
~PluginManager()116 PluginManager::~PluginManager()
117 {
118 EDMLOGI("PluginManager::~PluginManager.");
119 #ifndef EDM_FUZZ_TEST
120 NotifyUnloadAllPlugin();
121 #endif
122 }
123
GetInstance()124 std::shared_ptr<PluginManager> PluginManager::GetInstance()
125 {
126 if (instance_ == nullptr) {
127 std::unique_lock<std::shared_timed_mutex> autoLock(mutexLock_);
128 if (instance_ == nullptr) {
129 instance_.reset(new (std::nothrow) PluginManager());
130 }
131 }
132
133 IPluginManager::pluginManagerInstance_ = instance_.get();
134 return instance_;
135 }
136
GetPluginByFuncCode(std::uint32_t funcCode)137 std::shared_ptr<IPlugin> PluginManager::GetPluginByFuncCode(std::uint32_t funcCode)
138 {
139 FuncCodeUtils::PrintFuncCode(funcCode);
140 FuncFlag flag = FuncCodeUtils::GetSystemFlag(funcCode);
141 if (flag == FuncFlag::POLICY_FLAG) {
142 std::uint32_t code = FuncCodeUtils::GetPolicyCode(funcCode);
143 EDMLOGD("PluginManager::code %{public}u", code);
144 auto it = pluginsCode_.find(code);
145 if (it != pluginsCode_.end()) {
146 return it->second;
147 }
148 }
149 EDMLOGD("GetPluginByFuncCode::return nullptr");
150 return nullptr;
151 }
152
GetPluginByPolicyName(const std::string & policyName)153 std::shared_ptr<IPlugin> PluginManager::GetPluginByPolicyName(const std::string &policyName)
154 {
155 auto it = pluginsName_.find(policyName);
156 if (it != pluginsName_.end()) {
157 return it->second;
158 }
159 return nullptr;
160 }
161
GetPluginByCode(std::uint32_t code)162 std::shared_ptr<IPlugin> PluginManager::GetPluginByCode(std::uint32_t code)
163 {
164 EDMLOGD("PluginManager::code %{public}u", code);
165 auto it = pluginsCode_.find(code);
166 if (it != pluginsCode_.end()) {
167 return it->second;
168 }
169 EDMLOGI("GetPluginByCode::return nullptr");
170 return nullptr;
171 }
172
CreateExecuteStrategy(ExecuteStrategy strategy)173 std::shared_ptr<IPluginExecuteStrategy> PluginManager::CreateExecuteStrategy(ExecuteStrategy strategy)
174 {
175 if (strategy == ExecuteStrategy::ENHANCE) {
176 return enhanceStrategy_;
177 }
178 if (strategy == ExecuteStrategy::REPLACE) {
179 return replaceStrategy_;
180 }
181 return singleStrategy_;
182 }
183
AddPlugin(std::shared_ptr<IPlugin> plugin)184 bool PluginManager::AddPlugin(std::shared_ptr<IPlugin> plugin)
185 {
186 if (plugin == nullptr) {
187 return false;
188 }
189 EDMLOGD("AddPlugin %{public}d", plugin->GetCode());
190 return AddPluginInner(plugin);
191 }
192
AddPluginInner(std::shared_ptr<IPlugin> plugin)193 bool PluginManager::AddPluginInner(std::shared_ptr<IPlugin> plugin)
194 {
195 if (plugin == nullptr) {
196 return false;
197 }
198 EDMLOGD("AddPlugin %{public}d", plugin->GetCode());
199 std::vector<IPlugin::PolicyPermissionConfig> configs = plugin->GetAllPermission();
200 if (configs.empty()) {
201 return false;
202 }
203 for (auto &config : configs) {
204 for (auto &typePermission : config.typePermissions) {
205 PermissionManager::GetInstance()->AddPermission(typePermission.second,
206 typePermission.first, plugin->GetCode());
207 }
208 for (auto &tagPermission : config.tagPermissions) {
209 for (auto &typePermission : tagPermission.second) {
210 PermissionManager::GetInstance()->AddPermission(typePermission.second,
211 typePermission.first, plugin->GetCode());
212 }
213 }
214 }
215 pluginsCode_.insert(std::make_pair(plugin->GetCode(), plugin));
216 pluginsName_.insert(std::make_pair(plugin->GetPolicyName(), plugin));
217 if (extensionPluginMap_.find(plugin->GetCode()) != extensionPluginMap_.end()) {
218 EDMLOGD("PluginManager::AddPlugin %{public}d add extension plugin %{public}d", plugin->GetCode(),
219 extensionPluginMap_[plugin->GetCode()]);
220 plugin->SetExtensionPlugin(GetPluginByCode(extensionPluginMap_[plugin->GetCode()]));
221 }
222 if (executeStrategyMap_.find(plugin->GetCode()) != executeStrategyMap_.end()) {
223 plugin->SetExecuteStrategy(CreateExecuteStrategy(executeStrategyMap_[plugin->GetCode()]));
224 } else {
225 plugin->SetExecuteStrategy(CreateExecuteStrategy(ExecuteStrategy::SINGLE));
226 }
227 return true;
228 }
229
AddExtensionPlugin(std::shared_ptr<IPlugin> extensionPlugin,uint32_t basicPluginCode,ExecuteStrategy strategy)230 bool PluginManager::AddExtensionPlugin(std::shared_ptr<IPlugin> extensionPlugin, uint32_t basicPluginCode,
231 ExecuteStrategy strategy)
232 {
233 if (AddPlugin(extensionPlugin)) {
234 auto basicPlugin = GetPluginByCode(basicPluginCode);
235 if (basicPlugin != nullptr) {
236 EDMLOGD("PluginManager::AddExtensionPlugin %{public}d add extension plugin %{public}d", basicPluginCode,
237 extensionPlugin->GetCode());
238 basicPlugin->SetExtensionPlugin(extensionPlugin);
239 basicPlugin->SetExecuteStrategy(CreateExecuteStrategy(strategy));
240 }
241 extensionPlugin->SetBasicPluginCode(basicPluginCode);
242 extensionPlugin->SetPluginType(IPlugin::PluginType::EXTENSION);
243 extensionPluginMap_.insert(std::make_pair(basicPluginCode, extensionPlugin->GetCode()));
244 executeStrategyMap_.insert(std::make_pair(basicPluginCode, strategy));
245 return true;
246 }
247 return false;
248 }
249
LoadAllPlugin()250 void PluginManager::LoadAllPlugin()
251 {
252 LoadPlugin(SONAME::DEVICE_CORE_PLUGIN_SO);
253 LoadPlugin(SONAME::COMMUNICATION_PLUGIN_SO);
254 LoadPlugin(SONAME::SYS_SERVICE_PLUGIN_SO);
255 LoadPlugin(SONAME::NEED_EXTRA_PLUGIN_SO);
256 LoadExtraPlugin();
257 }
258
LoadExtraPlugin()259 void PluginManager::LoadExtraPlugin()
260 {
261 EDMLOGI("PluginManager::LoadExtraPlugin start.");
262 DIR *dir = opendir(PLUGIN_DIR);
263 if (dir == nullptr) {
264 EDMLOGE("PluginManager::LoadPlugin open edm_plugin dir fail.");
265 return;
266 }
267 struct dirent *entry;
268 while ((entry = readdir(dir)) != nullptr) {
269 if (entry->d_type == DT_REG && IsExtraPlugin(entry->d_name)) {
270 LoadPlugin(entry->d_name);
271 }
272 }
273 closedir(dir);
274 }
275
IsExtraPlugin(const std::string & soName)276 bool PluginManager::IsExtraPlugin(const std::string &soName)
277 {
278 return soName != SONAME::DEVICE_CORE_PLUGIN_SO
279 && soName != SONAME::COMMUNICATION_PLUGIN_SO
280 && soName != SONAME::SYS_SERVICE_PLUGIN_SO
281 && soName != SONAME::NEED_EXTRA_PLUGIN_SO
282 && soName != SONAME::OLD_EDM_PLUGIN_SO;
283 }
284
LoadPluginByFuncCode(uint32_t funcCode)285 ErrCode PluginManager::LoadPluginByFuncCode(uint32_t funcCode)
286 {
287 std::uint32_t code = FuncCodeUtils::GetPolicyCode(funcCode);
288 return LoadPluginByCode(code);
289 }
290
LoadPluginByCode(uint32_t code)291 ErrCode PluginManager::LoadPluginByCode(uint32_t code)
292 {
293 if (code > EdmInterfaceCode::POLICY_CODE_END) {
294 LoadExtraPlugin();
295 return ERR_OK;
296 }
297 std::string soName;
298 if (!GetSoNameByCode(code, soName)) {
299 EDMLOGE("PluginManager::LoadPluginByCode soname not found");
300 return EdmReturnErrCode::INTERFACE_UNSUPPORTED;
301 }
302 if (soName == SONAME::NEED_EXTRA_PLUGIN_SO) {
303 LoadExtraPlugin();
304 }
305 LoadPlugin(soName);
306 return ERR_OK;
307 }
308
LoadPlugin(const std::string & soName)309 void PluginManager::LoadPlugin(const std::string &soName)
310 {
311 if (soName.empty()) {
312 EDMLOGE("PluginManager::LoadPlugin soName empty");
313 return;
314 }
315 std::unique_lock<std::shared_timed_mutex> lock(mutexLock_, std::chrono::seconds(MUTEX_TIMEOUT));
316 if (!lock) {
317 EDMLOGE("PluginManager::UnloadPlugin mutex timeout.");
318 return;
319 }
320 EDMLOGI("PluginManager::LoadPlugin soName %{public}s", soName.c_str());
321 auto soLoadIter = soLoadStateMap_.find(soName);
322 if (soLoadIter == soLoadStateMap_.end()) {
323 soLoadStateMap_[soName] = std::make_shared<SoLoadState>();
324 }
325 std::shared_ptr<SoLoadState> loadStatePtr = soLoadStateMap_[soName];
326 loadStatePtr->lastCallTime = std::chrono::system_clock::now();
327 if (loadStatePtr->pluginHasInit) {
328 std::unique_lock<std::mutex> lock(loadStatePtr->waitMutex);
329 loadStatePtr->notifySignal = true;
330 loadStatePtr->waitSignal.notify_one();
331 } else {
332 EDMLOGI("PluginManager::DlopenPlugin soName %{public}s", soName.c_str());
333 DlopenPlugin(PLUGIN_DIR + soName, loadStatePtr);
334 loadStatePtr->pluginHasInit = true;
335 std::thread timerThread([=]() {
336 this->UnloadPluginTask(soName, loadStatePtr);
337 });
338 timerThread.detach();
339 }
340 }
341
UnloadPluginTask(const std::string & soName,std::shared_ptr<SoLoadState> loadStatePtr)342 void PluginManager::UnloadPluginTask(const std::string &soName, std::shared_ptr<SoLoadState> loadStatePtr)
343 {
344 while (loadStatePtr->pluginHasInit) {
345 {
346 std::unique_lock<std::mutex> lock(loadStatePtr->waitMutex);
347 loadStatePtr->notifySignal = false;
348 loadStatePtr->waitSignal.wait_for(lock, std::chrono::milliseconds(TIMER_TIMEOUT), [=] {
349 return loadStatePtr->notifySignal;
350 });
351 }
352 std::unique_lock<std::shared_timed_mutex> lock(mutexLock_);
353 auto now = std::chrono::system_clock::now();
354 auto diffTime = std::chrono::duration_cast<std::chrono::milliseconds>(now - loadStatePtr->lastCallTime).count();
355 if (diffTime >= std::chrono::milliseconds(TIMER_TIMEOUT).count()) {
356 UnloadPlugin(soName);
357 loadStatePtr->pluginHasInit = false;
358 }
359 }
360 }
361
DlopenPlugin(const std::string & pluginPath,std::shared_ptr<SoLoadState> loadStatePtr)362 void PluginManager::DlopenPlugin(const std::string &pluginPath, std::shared_ptr<SoLoadState> loadStatePtr)
363 {
364 void *handle = dlopen(pluginPath.c_str(), RTLD_LAZY);
365 if (!handle) {
366 EDMLOGE("PluginManager::open plugin so fail. %{public}s.", dlerror());
367 return;
368 }
369 loadStatePtr->pluginHandles = handle;
370 }
371
GetSoNameByCode(std::uint32_t code,std::string & soName)372 bool PluginManager::GetSoNameByCode(std::uint32_t code, std::string &soName)
373 {
374 auto deviceCoreIter = std::find(deviceCoreSoCodes_.begin(), deviceCoreSoCodes_.end(), code);
375 if (deviceCoreIter != deviceCoreSoCodes_.end()) {
376 soName = SONAME::DEVICE_CORE_PLUGIN_SO;
377 return true;
378 }
379 auto communicationIter = std::find(communicationSoCodes_.begin(), communicationSoCodes_.end(), code);
380 if (communicationIter != communicationSoCodes_.end()) {
381 soName = SONAME::COMMUNICATION_PLUGIN_SO;
382 return true;
383 }
384 auto sysServiceIter = std::find(sysServiceSoCodes_.begin(), sysServiceSoCodes_.end(), code);
385 if (sysServiceIter != sysServiceSoCodes_.end()) {
386 soName = SONAME::SYS_SERVICE_PLUGIN_SO;
387 return true;
388 }
389 auto needExtraIter = std::find(needExtraSoCodes_.begin(), needExtraSoCodes_.end(), code);
390 if (needExtraIter != needExtraSoCodes_.end()) {
391 soName = SONAME::NEED_EXTRA_PLUGIN_SO;
392 return true;
393 }
394 return false;
395 }
396
UnloadPlugin(const std::string & soName)397 void PluginManager::UnloadPlugin(const std::string &soName)
398 {
399 EDMLOGI("PluginManager::UnloadPlugin soName: %{public}s.", soName.c_str());
400 std::vector<uint32_t>* targetVec = nullptr;
401 std::vector<uint32_t> extraPluginCodeList;
402 if (soName == SONAME::DEVICE_CORE_PLUGIN_SO) {
403 targetVec = &deviceCoreSoCodes_;
404 } else if (soName == SONAME::COMMUNICATION_PLUGIN_SO) {
405 targetVec = &communicationSoCodes_;
406 } else if (soName == SONAME::SYS_SERVICE_PLUGIN_SO) {
407 targetVec = &sysServiceSoCodes_;
408 } else if (soName == SONAME::NEED_EXTRA_PLUGIN_SO) {
409 targetVec = &needExtraSoCodes_;
410 } else {
411 targetVec = &extraPluginCodeList;
412 GetExtraPluginCodeList(targetVec);
413 extensionPluginMap_.clear();
414 executeStrategyMap_.clear();
415 }
416 for (const auto& code : *targetVec) {
417 RemovePlugin(GetPluginByCode(code));
418 }
419 if (soLoadStateMap_.find(soName) == soLoadStateMap_.end()) {
420 EDMLOGE("PluginManager::UnloadPlugin this so:%{public}s not find", soName.c_str());
421 return;
422 }
423 std::shared_ptr<SoLoadState> loadStatePtr = soLoadStateMap_[soName];
424 if (loadStatePtr == nullptr || loadStatePtr->pluginHandles == nullptr) {
425 EDMLOGE("PluginManager::UnloadPlugin %{public}s handle nullptr", soName.c_str());
426 return;
427 }
428 int result = dlclose(loadStatePtr->pluginHandles);
429 if (result != 0) {
430 EDMLOGE("PluginManager::UnloadPlugin %{public}s close lib failed: %{public}s.", soName.c_str(), dlerror());
431 } else {
432 EDMLOGI("PluginManager::UnloadPlugin %{public}s close lib success", soName.c_str());
433 }
434 soLoadStateMap_.erase(soName);
435 }
436
GetExtraPluginCodeList(std::vector<uint32_t> * targetVec)437 void PluginManager::GetExtraPluginCodeList(std::vector<uint32_t>* targetVec)
438 {
439 for (const auto& it : pluginsCode_) {
440 if (it.first > EdmInterfaceCode::POLICY_CODE_END) {
441 targetVec->push_back(it.first);
442 }
443 }
444 for (const auto& it : extensionPluginMap_) {
445 targetVec->push_back(it.second);
446 }
447 }
448
RemovePlugin(std::shared_ptr<IPlugin> plugin)449 void PluginManager::RemovePlugin(std::shared_ptr<IPlugin> plugin)
450 {
451 if (plugin == nullptr) {
452 return;
453 }
454 extensionPluginMap_.erase(plugin->GetCode());
455 plugin->ResetExtensionPlugin();
456 std::vector<IPlugin::PolicyPermissionConfig> configs = plugin->GetAllPermission();
457 if (configs.empty()) {
458 return;
459 }
460 pluginsCode_.erase(plugin->GetCode());
461 pluginsName_.erase(plugin->GetPolicyName());
462 auto basicPlugin = GetPluginByCode(plugin->GetBasicPluginCode());
463 if (basicPlugin != nullptr) {
464 basicPlugin->ResetExtensionPlugin();
465 }
466 }
467
NotifyUnloadAllPlugin()468 void PluginManager::NotifyUnloadAllPlugin()
469 {
470 std::unique_lock<std::shared_timed_mutex> lock(mutexLock_);
471 for (const auto& it : soLoadStateMap_) {
472 auto state = it.second;
473 if (state->pluginHasInit) {
474 state->pluginHasInit = false;
475 std::unique_lock<std::mutex> lock(state->waitMutex);
476 state->notifySignal = true;
477 state->lastCallTime = std::chrono::system_clock::time_point(std::chrono::milliseconds(0));
478 state->waitSignal.notify_one();
479 }
480 }
481 }
482
DumpPluginConfig(IPlugin::PolicyPermissionConfig config)483 void PluginManager::DumpPluginConfig(IPlugin::PolicyPermissionConfig config)
484 {
485 std::string permissionStr;
486 permissionStr.append("Type Permissions:");
487 for (const auto &typePermission : config.typePermissions) {
488 permissionStr.append("PermissionType: ");
489 if (typePermission.first == IPlugin::PermissionType::NORMAL_DEVICE_ADMIN) {
490 permissionStr.append("NORMAL_DEVICE_ADMIN:");
491 }
492 if (typePermission.first == IPlugin::PermissionType::SUPER_DEVICE_ADMIN) {
493 permissionStr.append("SUPER_DEVICE_ADMIN:");
494 }
495 if (typePermission.first == IPlugin::PermissionType::BYOD_DEVICE_ADMIN) {
496 permissionStr.append("BYOD_DEVICE_ADMIN:");
497 }
498 permissionStr.append(typePermission.second);
499 }
500 permissionStr.append("Tag Permissions:");
501 for (const auto &tagPermission : config.tagPermissions) {
502 permissionStr.append("ApiTag: ");
503 permissionStr.append(tagPermission.first);
504 for (const auto &tag : tagPermission.second) {
505 if (tag.first == IPlugin::PermissionType::NORMAL_DEVICE_ADMIN) {
506 permissionStr.append("NORMAL_DEVICE_ADMIN:");
507 }
508 if (tag.first == IPlugin::PermissionType::SUPER_DEVICE_ADMIN) {
509 permissionStr.append("SUPER_DEVICE_ADMIN:");
510 }
511 if (tag.first == IPlugin::PermissionType::BYOD_DEVICE_ADMIN) {
512 permissionStr.append("BYOD_DEVICE_ADMIN:");
513 }
514 permissionStr.append(tag.second);
515 }
516 }
517 EDMLOGD("Config permission:%{public}s", permissionStr.c_str());
518 }
519
DumpPlugin()520 void PluginManager::DumpPlugin()
521 {
522 DumpPluginInner(pluginsCode_, pluginsName_);
523 }
524
DumpPluginInner(std::map<std::uint32_t,std::shared_ptr<IPlugin>> pluginsCode,std::map<std::string,std::shared_ptr<IPlugin>> pluginsName)525 void PluginManager::DumpPluginInner(std::map<std::uint32_t, std::shared_ptr<IPlugin>> pluginsCode,
526 std::map<std::string, std::shared_ptr<IPlugin>> pluginsName)
527 {
528 for (auto it = pluginsCode.begin(); it != pluginsCode.end(); it++) {
529 std::vector<IPlugin::PolicyPermissionConfig> configs = it->second->GetAllPermission();
530 EDMLOGD("PluginManager::Dump plugins_code.code:%{public}u,name:%{public}s", it->first,
531 it->second->GetPolicyName().c_str());
532 for (auto &config : configs) {
533 DumpPluginConfig(config);
534 }
535 }
536 for (auto it = pluginsName.begin(); it != pluginsName.end(); it++) {
537 std::vector<IPlugin::PolicyPermissionConfig> configs = it->second->GetAllPermission();
538 EDMLOGD("PluginManager::Dump plugins_name.name:%{public}s,code:%{public}u", it->first.c_str(),
539 it->second->GetCode());
540 for (auto &config : configs) {
541 DumpPluginConfig(config);
542 }
543 }
544 }
545 } // namespace EDM
546 } // namespace OHOS
547