1/* 2 * Copyright (c) 2022 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 "admin_manager.h" 17 18#include <algorithm> 19#include <ctime> 20#include <fstream> 21#include <iostream> 22 23#include "directory_ex.h" 24#include "edm_constants.h" 25#include "edm_log.h" 26#include "permission_manager.h" 27#include "super_admin.h" 28 29namespace OHOS { 30namespace EDM { 31std::shared_ptr<AdminManager> AdminManager::instance_; 32std::mutex AdminManager::mutexLock_; 33 34std::shared_ptr<AdminManager> AdminManager::GetInstance() 35{ 36 if (instance_ == nullptr) { 37 std::lock_guard<std::mutex> autoLock(mutexLock_); 38 if (instance_ == nullptr) { 39 instance_.reset(new (std::nothrow) AdminManager()); 40 } 41 } 42 return instance_; 43} 44 45AdminManager::AdminManager() 46{ 47 EDMLOGI("AdminManager::AdminManager"); 48} 49 50AdminManager::~AdminManager() 51{ 52 EDMLOGI("AdminManager::~AdminManager"); 53 admins_.clear(); 54} 55 56ErrCode AdminManager::GetReqPermission(const std::vector<std::string> &permissions, 57 std::vector<EdmPermission> &reqPermissions) 58{ 59 EDMLOGD("AdminManager::GetReqPermission"); 60 PermissionManager::GetInstance()->GetReqPermission(permissions, reqPermissions); 61 return reqPermissions.empty() ? ERR_EDM_EMPTY_PERMISSIONS : ERR_OK; 62} 63 64bool AdminManager::GetAdminByUserId(int32_t userId, std::vector<std::shared_ptr<Admin>> &userAdmin) 65{ 66 userAdmin.clear(); 67 auto iter = admins_.find(userId); 68 if (iter == admins_.end()) { 69 EDMLOGW("GetAdminByUserId::get userId Admin failed. userId = %{public}d", userId); 70 return false; 71 } 72 userAdmin = iter->second; 73 return true; 74} 75 76void AdminManager::GetAdminBySubscribeEvent(ManagedEvent event, 77 std::unordered_map<int32_t, std::vector<std::shared_ptr<Admin>>> &subscribeAdmins) 78{ 79 for (const auto &adminItem : admins_) { 80 std::vector<std::shared_ptr<Admin>> subAdmin; 81 for (const auto &it : adminItem.second) { 82 std::vector<ManagedEvent> events = it->adminInfo_.managedEvents_; 83 if (std::find(events.begin(), events.end(), event) != events.end()) { 84 subAdmin.push_back(it); 85 } 86 } 87 if (!subAdmin.empty()) { 88 subscribeAdmins[adminItem.first] = subAdmin; 89 } 90 } 91} 92 93ErrCode AdminManager::SetAdminValue(int32_t userId, Admin &adminItem) 94{ 95 auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance(); 96 if (adminPoliciesStorageRdb == nullptr) { 97 EDMLOGE("AdminManager::SetAdminValue get adminPoliciesStorageRdb failed."); 98 return ERR_GET_STORAGE_RDB_FAILED; 99 } 100 std::vector<AdminPermission> reqPermission; 101 std::vector<std::string> permissionNames; 102 PermissionManager::GetInstance()->GetReqPermission(adminItem.adminInfo_.permission_, reqPermission); 103 if (reqPermission.empty()) { 104 EDMLOGW("SetAdminValue::the application is requesting useless permissions"); 105 } 106 for (const auto &it : reqPermission) { 107 if (adminItem.adminInfo_.adminType_ == AdminType::NORMAL && it.adminType == AdminType::ENT) { 108 return ERR_EDM_DENY_PERMISSION; 109 } 110 permissionNames.push_back(it.permissionName); 111 } 112 std::shared_ptr<Admin> getAdmin = GetAdminByPkgName(adminItem.adminInfo_.packageName_, userId); 113 if (getAdmin != nullptr) { 114 if (!adminPoliciesStorageRdb->UpdateAdmin(userId, adminItem)) { 115 EDMLOGE("AdminManager::SetAdminValue update failed."); 116 return ERR_EDM_ADD_ADMIN_FAILED; 117 } 118 getAdmin->adminInfo_.adminType_ = adminItem.adminInfo_.adminType_; 119 getAdmin->adminInfo_.entInfo_ = adminItem.adminInfo_.entInfo_; 120 getAdmin->adminInfo_.permission_ = permissionNames; 121 return ERR_OK; 122 } 123 if (!adminPoliciesStorageRdb->InsertAdmin(userId, adminItem)) { 124 EDMLOGE("AdminManager::SetAdminValue insert failed."); 125 return ERR_EDM_ADD_ADMIN_FAILED; 126 } 127 std::vector<std::shared_ptr<Admin>> admins; 128 GetAdminByUserId(userId, admins); 129 adminItem.adminInfo_.permission_ = permissionNames; 130 std::shared_ptr<Admin> admin = std::make_shared<Admin>(adminItem); 131 admins.emplace_back(admin); 132 admins_[userId] = admins; 133 return ERR_OK; 134} 135 136std::shared_ptr<Admin> AdminManager::GetAdminByPkgName(const std::string &packageName, int32_t userId) 137{ 138 std::shared_ptr<Admin> subOrSuperAdmin; 139 if (SUCCEEDED(GetSubOrSuperAdminByPkgName(packageName, subOrSuperAdmin))) { 140 EDMLOGD("GetAdminByPkgName::get sub-super or super admin: %{public}s", packageName.c_str()); 141 return subOrSuperAdmin; 142 } 143 std::vector<std::shared_ptr<Admin>> userAdmin; 144 if (!GetAdminByUserId(userId, userAdmin)) { 145 EDMLOGW("GetAdminByPkgName::get userId Admin failed. userId = %{public}d", userId); 146 return nullptr; 147 } 148 for (const auto &item : userAdmin) { 149 if (item->adminInfo_.packageName_ == packageName) { 150 return item; 151 } 152 } 153 EDMLOGD("GetAdminByPkgName::get admin failed. admin size = %{public}u, packageName = %{public}s", 154 (uint32_t)userAdmin.size(), packageName.c_str()); 155 return nullptr; 156} 157 158ErrCode AdminManager::DeleteAdmin(const std::string &packageName, int32_t userId) 159{ 160 auto iterMap = admins_.find(userId); 161 if (iterMap == admins_.end()) { 162 EDMLOGW("DeleteAdmin::get userId Admin failed. userId = %{public}d", userId); 163 return ERR_EDM_UNKNOWN_ADMIN; 164 } 165 auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance(); 166 if (adminPoliciesStorageRdb == nullptr) { 167 EDMLOGE("AdminManager::DeleteAdmin get adminPoliciesStorageRdb failed."); 168 return ERR_GET_STORAGE_RDB_FAILED; 169 } 170 if (!adminPoliciesStorageRdb->DeleteAdmin(userId, packageName)) { 171 EDMLOGW("delete admin (%{public}s) failed!", packageName.c_str()); 172 return ERR_EDM_DEL_ADMIN_FAILED; 173 } 174 auto iter = std::remove_if(iterMap->second.begin(), iterMap->second.end(), 175 [&](std::shared_ptr<Admin> admin) { return admin->adminInfo_.packageName_ == packageName; }); 176 iterMap->second.erase(iter, iterMap->second.end()); 177 if (iterMap->second.empty()) { 178 admins_.erase(iterMap); 179 } 180 return ERR_OK; 181} 182 183ErrCode AdminManager::GetGrantedPermission(std::vector<std::string> &permissions, AdminType type) 184{ 185 if (permissions.empty()) { 186 EDMLOGW("GetGrantedPermission::permissions is empty"); 187 return ERR_OK; 188 } 189 // filtering out non-edm permissions 190 std::vector<AdminPermission> reqPermission; 191 PermissionManager::GetInstance()->GetReqPermission(permissions, reqPermission); 192 if (reqPermission.empty()) { 193 EDMLOGW("GetGrantedPermission::edm permission is empty"); 194 return ERR_OK; 195 } 196 197 // filter out super permissions if admin is NORMAL 198 std::vector<std::string> permissionNameList; 199 for (const auto &it : reqPermission) { 200 if ((type == AdminType::NORMAL) && (it.adminType == AdminType::ENT)) { 201 continue; 202 } 203 permissionNameList.push_back(it.permissionName); 204 } 205 permissions.assign(permissionNameList.begin(), permissionNameList.end()); 206 return ERR_OK; 207} 208 209ErrCode AdminManager::UpdateAdmin(AppExecFwk::ExtensionAbilityInfo &abilityInfo, 210 const std::vector<std::string> &permissions, int32_t userId) 211{ 212 auto adminItem = GetAdminByPkgName(abilityInfo.bundleName, userId); 213 if (adminItem == nullptr) { 214 EDMLOGW("UpdateAdmin::get null admin, never get here"); 215 return ERR_EDM_UNKNOWN_ADMIN; 216 } 217 auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance(); 218 if (adminPoliciesStorageRdb == nullptr) { 219 EDMLOGE("AdminManager::UpdateAdmin get adminPoliciesStorageRdb failed."); 220 return ERR_GET_STORAGE_RDB_FAILED; 221 } 222 223 std::vector<std::string> combinePermission = permissions; 224 ErrCode ret = GetGrantedPermission(combinePermission, adminItem->adminInfo_.adminType_); 225 if (ret != ERR_OK) { 226 EDMLOGW("UpdateAdmin::GetGrantedPermission failed"); 227 return ret; 228 } 229 230 if (!adminPoliciesStorageRdb->UpdateAdmin(userId, abilityInfo.bundleName, abilityInfo.name, combinePermission)) { 231 EDMLOGW("UpdateAdmin::update admin failed."); 232 return ERR_EDM_UNKNOWN_ADMIN; 233 } 234 adminItem->adminInfo_.permission_ = combinePermission; 235 adminItem->adminInfo_.packageName_ = abilityInfo.bundleName; 236 adminItem->adminInfo_.className_ = abilityInfo.name; 237 return ERR_OK; 238} 239 240// success is returned as long as there is a super administrator 241bool AdminManager::IsSuperAdminExist() 242{ 243 std::vector<std::shared_ptr<Admin>> userAdmin; 244 bool ret = GetAdminByUserId(DEFAULT_USER_ID, userAdmin); 245 if (!ret) { 246 EDMLOGD("IsSuperAdminExist::not find super Admin"); 247 return false; 248 } 249 return std::any_of(userAdmin.begin(), userAdmin.end(), 250 [](const std::shared_ptr<Admin> &admin) { return admin->adminInfo_.adminType_ == AdminType::ENT; }); 251} 252 253bool AdminManager::IsSuperAdmin(const std::string &bundleName) 254{ 255 std::shared_ptr<Admin> admin = GetAdminByPkgName(bundleName, DEFAULT_USER_ID); 256 if (admin == nullptr) { 257 EDMLOGW("IsSuperAdmin: admin == nullptr."); 258 return false; 259 } 260 if (admin->adminInfo_.adminType_ == AdminType::ENT) { 261 EDMLOGW("IsSuperAdmin: admin->adminInfo_.adminType_ == AdminType::ENT."); 262 return true; 263 } 264 return false; 265} 266 267bool AdminManager::IsAdminExist() 268{ 269 return !admins_.empty(); 270} 271 272bool AdminManager::IsSuperOrSubSuperAdmin(const std::string &bundleName) 273{ 274 std::shared_ptr<Admin> superAdmin; 275 superAdmin = GetAdminByPkgName(bundleName, DEFAULT_USER_ID); 276 if (superAdmin == nullptr) { 277 return false; 278 } 279 return superAdmin->adminInfo_.adminType_ == AdminType::ENT || 280 superAdmin->adminInfo_.adminType_ == AdminType::SUB_SUPER_ADMIN; 281} 282 283/* 284 * There are different administrator types according to the input parameters. 285 * Returns a list of package names 286 */ 287void AdminManager::GetEnabledAdmin(AdminType role, std::vector<std::string> &packageNameList, int32_t userId) 288{ 289 packageNameList.clear(); 290 std::vector<std::shared_ptr<Admin>> userAdmin; 291 bool ret = GetAdminByUserId(userId, userAdmin); 292 if (!ret) { 293 EDMLOGW("GetEnabledAdmin::not find enabled Admin. userId = %{public}d", userId); 294 return; 295 } 296 EDMLOGD("AdminManager:GetEnabledAdmin adminType: %{public}d , admin size: %{public}zu", role, userAdmin.size()); 297 if (static_cast<int32_t>(role) >= static_cast<int32_t>(AdminType::UNKNOWN) || 298 static_cast<int32_t>(role) < static_cast<int32_t>(AdminType::NORMAL)) { 299 EDMLOGD("there is no admin(%{public}u) device manager package name list!", role); 300 return; 301 } 302 303 for (const auto &item : userAdmin) { 304 if (item->adminInfo_.adminType_ == role) { 305 std::string adminName = item->adminInfo_.packageName_ + "/" + item->adminInfo_.className_; 306 packageNameList.push_back(adminName); 307 } 308 } 309} 310 311ErrCode AdminManager::GetSubOrSuperAdminByPkgName(const std::string &subAdminName, 312 std::shared_ptr<Admin> &subOrSuperAdmin) 313{ 314 std::vector<std::shared_ptr<Admin>> userAdmin; 315 if (!GetAdminByUserId(DEFAULT_USER_ID, userAdmin)) { 316 EDMLOGW("GetSubOrSuperAdminByPkgName::not find Admin under default user id"); 317 return ERR_EDM_SUPER_ADMIN_NOT_FOUND; 318 } 319 auto adminItem = std::find_if(userAdmin.begin(), userAdmin.end(), [&](const std::shared_ptr<Admin> &admin) { 320 return admin->adminInfo_.packageName_ == subAdminName && (admin->adminInfo_.adminType_ == AdminType::ENT || 321 admin->adminInfo_.adminType_ == AdminType::SUB_SUPER_ADMIN); 322 }); 323 if (adminItem == userAdmin.end()) { 324 EDMLOGW("GetSubOrSuperAdminByPkgName::not find sub-super admin or super Admin"); 325 return ERR_EDM_SUPER_ADMIN_NOT_FOUND; 326 } 327 subOrSuperAdmin = *adminItem; 328 return ERR_OK; 329} 330 331ErrCode AdminManager::GetSubSuperAdminsByParentName(const std::string &parentName, std::vector<std::string> &subAdmins) 332{ 333 if (subAdmins.size() > 0) { 334 subAdmins.clear(); 335 } 336 std::vector<std::shared_ptr<Admin>> userAdmin; 337 if (!GetAdminByUserId(DEFAULT_USER_ID, userAdmin)) { 338 EDMLOGE("GetSubSuperAdminsByParentName::not find Admin under default user id."); 339 return ERR_EDM_SUPER_ADMIN_NOT_FOUND; 340 } 341 for (const auto &admin : userAdmin) { 342 if (admin->adminInfo_.adminType_ == AdminType::SUB_SUPER_ADMIN && 343 admin->adminInfo_.parentAdminName_ == parentName) { 344 subAdmins.push_back(admin->adminInfo_.packageName_); 345 } 346 } 347 return ERR_OK; 348} 349 350ErrCode AdminManager::GetEntInfo(const std::string &packageName, EntInfo &entInfo, int32_t userId) 351{ 352 std::vector<std::shared_ptr<Admin>> userAdmin; 353 bool ret = GetAdminByUserId(userId, userAdmin); 354 if (!ret) { 355 EDMLOGW("GetEntInfo::not find Admin. userId = %{public}d", userId); 356 return ERR_EDM_UNKNOWN_ADMIN; 357 } 358 for (const auto &item : userAdmin) { 359 if (item->adminInfo_.packageName_ == packageName) { 360 entInfo = item->adminInfo_.entInfo_; 361 return ERR_OK; 362 } 363 } 364 return ERR_EDM_UNKNOWN_ADMIN; 365} 366 367ErrCode AdminManager::SetEntInfo(const std::string &packageName, EntInfo &entInfo, int32_t userId) 368{ 369 std::vector<std::shared_ptr<Admin>> userAdmin; 370 bool ret = GetAdminByUserId(userId, userAdmin); 371 if (!ret) { 372 EDMLOGW("SetEntInfo::not find Admin. userId = %{public}d", userId); 373 return ERR_EDM_UNKNOWN_ADMIN; 374 } 375 auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance(); 376 if (adminPoliciesStorageRdb == nullptr) { 377 EDMLOGE("AdminManager::SetEntInfo get adminPoliciesStorageRdb failed."); 378 return ERR_GET_STORAGE_RDB_FAILED; 379 } 380 for (auto &item : userAdmin) { 381 if (item->adminInfo_.packageName_ == packageName && 382 adminPoliciesStorageRdb->UpdateEntInfo(userId, packageName, entInfo)) { 383 item->adminInfo_.entInfo_ = entInfo; 384 return ERR_OK; 385 } 386 } 387 return ERR_EDM_UNKNOWN_ADMIN; 388} 389 390ErrCode AdminManager::SaveSubscribeEvents(const std::vector<uint32_t> &events, const std::string &bundleName, 391 int32_t userId) 392{ 393 std::shared_ptr<Admin> admin = GetAdminByPkgName(bundleName, userId); 394 if (admin == nullptr) { 395 return ERR_EDM_UNKNOWN_ADMIN; 396 } 397 auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance(); 398 if (adminPoliciesStorageRdb == nullptr) { 399 EDMLOGE("AdminManager::SaveSubscribeEvents get adminPoliciesStorageRdb failed."); 400 return ERR_GET_STORAGE_RDB_FAILED; 401 } 402 std::vector<ManagedEvent> oldManagedEvents = admin->adminInfo_.managedEvents_; 403 size_t eventsNumber = admin->adminInfo_.managedEvents_.size(); 404 for (const auto &event : events) { 405 std::vector<ManagedEvent> managedEvents = admin->adminInfo_.managedEvents_; 406 ManagedEvent subEvent = static_cast<ManagedEvent>(event); 407 if (std::find(managedEvents.begin(), managedEvents.end(), subEvent) == managedEvents.end()) { 408 admin->adminInfo_.managedEvents_.push_back(subEvent); 409 } 410 } 411 if (admin->adminInfo_.managedEvents_.size() > eventsNumber && 412 !adminPoliciesStorageRdb->UpdateManagedEvents(userId, admin->adminInfo_.packageName_, 413 admin->adminInfo_.managedEvents_)) { 414 admin->adminInfo_.managedEvents_ = oldManagedEvents; 415 return ERR_EDM_UNKNOWN_ADMIN; 416 } 417 return ERR_OK; 418} 419 420ErrCode AdminManager::RemoveSubscribeEvents(const std::vector<uint32_t> &events, const std::string &bundleName, 421 int32_t userId) 422{ 423 std::shared_ptr<Admin> admin = GetAdminByPkgName(bundleName, userId); 424 if (admin == nullptr) { 425 return ERR_EDM_UNKNOWN_ADMIN; 426 } 427 auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance(); 428 if (adminPoliciesStorageRdb == nullptr) { 429 EDMLOGE("AdminManager::RemoveSubscribeEvents get adminPoliciesStorageRdb failed."); 430 return ERR_GET_STORAGE_RDB_FAILED; 431 } 432 433 std::vector<ManagedEvent> oldManagedEvents = admin->adminInfo_.managedEvents_; 434 size_t eventsNumber = admin->adminInfo_.managedEvents_.size(); 435 auto iter = std::remove_if(admin->adminInfo_.managedEvents_.begin(), admin->adminInfo_.managedEvents_.end(), 436 [&](ManagedEvent managedEvent) { 437 return std::find(events.begin(), events.end(), static_cast<uint32_t>(managedEvent)) != events.end(); 438 }); 439 admin->adminInfo_.managedEvents_.erase(iter, admin->adminInfo_.managedEvents_.end()); 440 441 if (admin->adminInfo_.managedEvents_.size() < eventsNumber && 442 !adminPoliciesStorageRdb->UpdateManagedEvents(userId, admin->adminInfo_.packageName_, 443 admin->adminInfo_.managedEvents_)) { 444 admin->adminInfo_.managedEvents_ = oldManagedEvents; 445 return ERR_EDM_UNKNOWN_ADMIN; 446 } 447 return ERR_OK; 448} 449 450ErrCode AdminManager::SaveAuthorizedAdmin(const std::string &bundleName, const std::vector<std::string> &permissions, 451 const std::string &parentName) 452{ 453 std::vector<std::shared_ptr<Admin>> admin; 454 if (!GetAdminByUserId(DEFAULT_USER_ID, admin)) { 455 return ERR_SAVE_AUTHORIZED_ADMIN_FAILED; 456 } 457 std::shared_ptr<Admin> adminItem = GetAdminByPkgName(bundleName, DEFAULT_USER_ID); 458 if (!adminItem && 459 !AdminPoliciesStorageRdb::GetInstance()->InsertAuthorizedAdmin(bundleName, permissions, parentName)) { 460 EDMLOGE("AdminManager::InsertAuthorizedAdmin save authorized failed."); 461 return ERR_SAVE_AUTHORIZED_ADMIN_FAILED; 462 } 463 if (adminItem) { 464 if (adminItem->GetAdminType() != AdminType::SUB_SUPER_ADMIN) { 465 EDMLOGE("AdminManager::UpdateAuthorizedAdmin can only update sub-super admin."); 466 return ERR_SAVE_AUTHORIZED_ADMIN_FAILED; 467 } 468 if (!AdminPoliciesStorageRdb::GetInstance()->UpdateAuthorizedAdmin(bundleName, permissions, parentName)) { 469 EDMLOGE("AdminManager::UpdateAuthorizedAdmin save authorized failed."); 470 return ERR_SAVE_AUTHORIZED_ADMIN_FAILED; 471 } 472 } 473 if (!adminItem) { 474 admin.emplace_back(std::make_shared<Admin>()); 475 admins_[DEFAULT_USER_ID] = admin; 476 adminItem = admin.back(); 477 adminItem->adminInfo_.adminType_ = AdminType::SUB_SUPER_ADMIN; 478 } 479 adminItem->adminInfo_.packageName_ = bundleName; 480 adminItem->adminInfo_.permission_ = permissions; 481 adminItem->adminInfo_.parentAdminName_ = parentName; 482 return ERR_OK; 483} 484 485std::shared_ptr<Admin> AdminManager::GetSuperAdmin() 486{ 487 if (admins_.find(DEFAULT_USER_ID) != admins_.end()) { 488 auto item = std::find_if(admins_[DEFAULT_USER_ID].begin(), admins_[DEFAULT_USER_ID].end(), 489 [&](const std::shared_ptr<Admin>& admin) { return admin->GetAdminType() == AdminType::ENT; }); 490 if (item != admins_[DEFAULT_USER_ID].end()) { 491 return *item; 492 } 493 } 494 return nullptr; 495} 496 497// init 498void AdminManager::Init() 499{ 500 auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance(); 501 if (adminPoliciesStorageRdb != nullptr) { 502 admins_ = adminPoliciesStorageRdb->QueryAllAdmin(); 503 } else { 504 EDMLOGE("AdminManager::Init failed."); 505 } 506} 507 508void AdminManager::Dump() 509{ 510 for (const auto &entry : admins_) { 511 EDMLOGI("AdminManager::Dump %{public}d.", entry.first); 512 for (const auto &admin : entry.second) { 513 EDMLOGI("AdminManager::Dump admin info adminType_ %{public}d.", 514 admin->adminInfo_.adminType_); 515 EDMLOGI("AdminManager::Dump admin info packageName_ %{public}s.", 516 admin->adminInfo_.packageName_.c_str()); 517 EDMLOGI("AdminManager::Dump admin info parentAdminName_ %{public}s.", 518 admin->adminInfo_.parentAdminName_.c_str()); 519 } 520 } 521} 522} // namespace EDM 523} // namespace OHOS 524