diff --git a/interfaces/innerkits/sandbox_manager/include/sandbox_manager_client.h b/interfaces/innerkits/sandbox_manager/include/sandbox_manager_client.h index 9c9f0c58824713bde3cbde60a80aca92a0c986cb..46c1efc29957fd68f2fba6221fe0190bf6ac5f65 100644 --- a/interfaces/innerkits/sandbox_manager/include/sandbox_manager_client.h +++ b/interfaces/innerkits/sandbox_manager/include/sandbox_manager_client.h @@ -66,22 +66,14 @@ public: private: SandboxManagerClient(); DISALLOW_COPY_AND_MOVE(SandboxManagerClient); - sptr proxy_ = nullptr; - sptr GetProxy(bool doLoadSa); - void GetProxyFromRemoteObject(const sptr &remoteObject); + sptr GetProxy(); - bool StartLoadSandboxManagerSa(); - void WaitForSandboxManagerSa(); - void LoadSandboxManagerSa(); - void GetSandboxManagerSa(); - - std::mutex cvLock_; - bool readyFlag_ = false; - std::condition_variable sandboxManagerCon_; std::mutex proxyMutex_; - sptr serviceDeathObserver_ = nullptr; + int32_t CallProxyWithRetry(const std::function &)> &func, + const char *funcName); + bool IsRequestNeedRetry(int32_t ret); }; } // SandboxManager } // AccessControl } // OHOS -#endif //SANDBOXMANAGER_CLIENT_H \ No newline at end of file +#endif // SANDBOXMANAGER_CLIENT_H \ No newline at end of file diff --git a/interfaces/innerkits/sandbox_manager/src/sandbox_manager_client.cpp b/interfaces/innerkits/sandbox_manager/src/sandbox_manager_client.cpp index dd870e4a29e58c25dec3d1b0ff5155a8eced98ca..628d87569549238de41cdeafe67ae0706df50ee4 100644 --- a/interfaces/innerkits/sandbox_manager/src/sandbox_manager_client.cpp +++ b/interfaces/innerkits/sandbox_manager/src/sandbox_manager_client.cpp @@ -16,21 +16,31 @@ #include "sandbox_manager_client.h" #include -#include "iservice_registry.h" +#include #include "i_sandbox_manager.h" +#include "iservice_registry.h" #include "refbase.h" #include "sandbox_manager_death_recipient.h" #include "sandbox_manager_err_code.h" #include "sandbox_manager_load_callback.h" #include "sandbox_manager_log.h" +#include "sys_binder.h" namespace OHOS { namespace AccessControl { namespace SandboxManager { +namespace { static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, ACCESSCONTROL_DOMAIN_SANDBOXMANAGER, "SandboxManagerClient" }; -static const int32_t SANDBOX_MANAGER_LOAD_SA_TIMEOUT_MS = 4000; +static const int32_t SANDBOX_MANAGER_LOAD_SA_TIMEOUT_SEC = 4; +static const int32_t SANDBOX_MANAGER_LOAD_SA_TRY_TIMES = 2; +static const int32_t SA_REQUEST_RETRY_TIMES = 1; + +static const int32_t SENDREQ_FAIL_ERR = 32; +static const std::vector RETRY_CODE_LIST = { + BR_DEAD_REPLY, BR_FAILED_REPLY, SENDREQ_FAIL_ERR }; +} SandboxManagerClient& SandboxManagerClient::GetInstance() { @@ -46,308 +56,189 @@ SandboxManagerClient::~SandboxManagerClient() int32_t SandboxManagerClient::CleanPersistPolicyByPath(const std::vector& filePathList) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "Proxy is null"); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->CleanPersistPolicyByPath(filePathList); + std::function &)> func = + [&](sptr &proxy) { return proxy->CleanPersistPolicyByPath(filePathList); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::PersistPolicy(const std::vector &policy, std::vector &result) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "proxy is null"); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->PersistPolicy(policy, result); + std::function &)> func = + [&](sptr &proxy) { return proxy->PersistPolicy(policy, result); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::UnPersistPolicy(const std::vector &policy, std::vector &result) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "proxy is null"); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->UnPersistPolicy(policy, result); + std::function &)> func = + [&](sptr &proxy) { return proxy->UnPersistPolicy(policy, result); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::PersistPolicyByTokenId( uint32_t tokenId, const std::vector &policy, std::vector &result) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "proxy is null"); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->PersistPolicyByTokenId(tokenId, policy, result); + std::function &)> func = + [&](sptr &proxy) { return proxy->PersistPolicyByTokenId(tokenId, policy, result); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::UnPersistPolicyByTokenId( uint32_t tokenId, const std::vector &policy, std::vector &result) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "proxy is null"); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->UnPersistPolicyByTokenId(tokenId, policy, result); + std::function &)> func = + [&](sptr &proxy) { return proxy->UnPersistPolicyByTokenId(tokenId, policy, result); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::SetPolicy(uint32_t tokenId, const std::vector &policy, uint64_t policyFlag, std::vector &result) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "Proxy is null."); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->SetPolicy(tokenId, policy, policyFlag, result); + std::function &)> func = + [&](sptr &proxy) { return proxy->SetPolicy(tokenId, policy, policyFlag, result); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::UnSetPolicy(uint32_t tokenId, const PolicyInfo &policy) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "Proxy is null."); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->UnSetPolicy(tokenId, policy); + std::function &)> func = + [&](sptr &proxy) { return proxy->UnSetPolicy(tokenId, policy); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::SetPolicyAsync(uint32_t tokenId, const std::vector &policy, uint64_t policyFlag) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "Proxy is null."); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->SetPolicyAsync(tokenId, policy, policyFlag); + std::function &)> func = + [&](sptr &proxy) { return proxy->SetPolicyAsync(tokenId, policy, policyFlag); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::UnSetPolicyAsync(uint32_t tokenId, const PolicyInfo &policy) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "Proxy is null."); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->UnSetPolicyAsync(tokenId, policy); + std::function &)> func = + [&](sptr &proxy) { return proxy->UnSetPolicyAsync(tokenId, policy); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::CheckPolicy(uint32_t tokenId, const std::vector &policy, std::vector &result) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "Proxy is null."); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->CheckPolicy(tokenId, policy, result); + std::function &)> func = + [&](sptr &proxy) { return proxy->CheckPolicy(tokenId, policy, result); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::StartAccessingPolicy( const std::vector &policy, std::vector &result) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "proxy is null"); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->StartAccessingPolicy(policy, result); + std::function &)> func = + [&](sptr &proxy) { return proxy->StartAccessingPolicy(policy, result); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::StopAccessingPolicy(const std::vector &policy, std::vector &result) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "proxy is null"); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->StopAccessingPolicy(policy, result); + std::function &)> func = + [&](sptr &proxy) { return proxy->StopAccessingPolicy(policy, result); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::CheckPersistPolicy( uint32_t tokenId, const std::vector &policy, std::vector &result) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "proxy is null"); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->CheckPersistPolicy(tokenId, policy, result); + std::function &)> func = + [&](sptr &proxy) { return proxy->CheckPersistPolicy(tokenId, policy, result); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::StartAccessingByTokenId(uint32_t tokenId) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "Proxy is null"); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->StartAccessingByTokenId(tokenId); + std::function &)> func = + [&](sptr &proxy) { return proxy->StartAccessingByTokenId(tokenId); }; + return CallProxyWithRetry(func, __FUNCTION__); } int32_t SandboxManagerClient::UnSetAllPolicyByToken(uint32_t tokenId) { - auto proxy = GetProxy(true); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "Proxy is null"); - return SANDBOX_MANAGER_SERVICE_NOT_EXIST; - } - return proxy->UnSetAllPolicyByToken(tokenId); + std::function &)> func = + [&](sptr &proxy) { return proxy->UnSetAllPolicyByToken(tokenId); }; + return CallProxyWithRetry(func, __FUNCTION__); } -bool SandboxManagerClient::StartLoadSandboxManagerSa() +sptr SandboxManagerClient::GetProxy() { - { - std::unique_lock lock(cvLock_); - readyFlag_ = false; - } - auto sam = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (sam == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "GetSystemAbilityManager is null"); - return false; - } - sptr ptrSandboxManagerLoadCallback = new (std::nothrow) SandboxManagerLoadCallback(); - if (ptrSandboxManagerLoadCallback == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "New ptrSandboxManagerLoadCallback fail."); - return false; - } - - int32_t result = sam->LoadSystemAbility(ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE, - ptrSandboxManagerLoadCallback); - if (result != SANDBOX_MANAGER_OK) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "LoadSystemAbility %{public}d failed", - ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE); - return false; - } - SANDBOXMANAGER_LOG_INFO(LABEL, "Notify samgr load sa %{public}d success", - ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE); - return true; -} - -void SandboxManagerClient::WaitForSandboxManagerSa() -{ - // wait_for release lock and block until time out(1s) or match the condition with notice - std::unique_lock lock(cvLock_); - auto waitStatus = sandboxManagerCon_.wait_for( - lock, std::chrono::milliseconds(SANDBOX_MANAGER_LOAD_SA_TIMEOUT_MS), [this]() { return readyFlag_; }); - if (!waitStatus) { - // time out or loadcallback fail - SANDBOXMANAGER_LOG_ERROR(LABEL, "Sandbox manager load sa timeout"); - return; - } -} - -void SandboxManagerClient::GetSandboxManagerSa() -{ - auto sam = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (sam == nullptr) { + std::unique_lock lock(proxyMutex_); + auto samgr = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { SANDBOXMANAGER_LOG_ERROR(LABEL, "GetSystemAbilityManager return null"); - return; - } - - auto sa = sam->GetSystemAbility(ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE); - if (sa == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "GetSystemAbility %{public}d is null", - ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE); - return; + return nullptr; } - - GetProxyFromRemoteObject(sa); -} - -void SandboxManagerClient::LoadSandboxManagerSa() -{ - if (!StartLoadSandboxManagerSa()) { - return; + auto remoteObject = samgr->CheckSystemAbility(ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE); + if (remoteObject != nullptr) { + auto proxy = iface_cast(remoteObject); + if (proxy != nullptr) { + return proxy; + } } - WaitForSandboxManagerSa(); -} - -void SandboxManagerClient::OnRemoteDiedHandle() -{ - SANDBOXMANAGER_LOG_ERROR(LABEL, "Remote service died"); - std::unique_lock lock(proxyMutex_); - proxy_ = nullptr; - serviceDeathObserver_ = nullptr; - { - std::unique_lock lock1(cvLock_); - readyFlag_ = false; + for (int32_t i = 0; i < SANDBOX_MANAGER_LOAD_SA_TRY_TIMES; i++) { + remoteObject = samgr->LoadSystemAbility(ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE, + SANDBOX_MANAGER_LOAD_SA_TIMEOUT_SEC); + if (remoteObject == nullptr) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "LoadSystemAbility failed."); + return nullptr; + } + auto proxy = iface_cast(remoteObject); + if (proxy != nullptr) { + return proxy; + } + SANDBOXMANAGER_LOG_WARN(LABEL, "Try to load SandboxManager Sa failed, times %{public}d / %{public}d", + i, SANDBOX_MANAGER_LOAD_SA_TRY_TIMES); } + SANDBOXMANAGER_LOG_ERROR(LABEL, "Get proxy retry failed %{public}d times.", + SANDBOX_MANAGER_LOAD_SA_TRY_TIMES); + return nullptr; } -void SandboxManagerClient::FinishStartSASuccess(const sptr &remoteObject) -{ - SANDBOXMANAGER_LOG_INFO(LABEL, "Get sandbox_manager sa success."); - - GetProxyFromRemoteObject(remoteObject); - - // get lock which wait_for release and send a notice so that wait_for can out of block - std::unique_lock lock(cvLock_); - readyFlag_ = true; - sandboxManagerCon_.notify_one(); -} - -void SandboxManagerClient::FinishStartSAFail() -{ - SANDBOXMANAGER_LOG_ERROR(LABEL, "get sandbox_manager sa failed."); - - // get lock which wait_for release and send a notice - std::unique_lock lock(cvLock_); - readyFlag_ = true; - sandboxManagerCon_.notify_one(); -} - -void SandboxManagerClient::GetProxyFromRemoteObject(const sptr &remoteObject) +int32_t SandboxManagerClient::CallProxyWithRetry( + const std::function &)> &func, const char *funcName) { - if (remoteObject == nullptr) { - return; - } - - sptr serviceDeathObserver = new (std::nothrow) SandboxManagerDeathRecipient(); - if (serviceDeathObserver == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "Alloc service death observer fail"); - return; + auto proxy = GetProxy(); + int32_t ret = -1; + if (proxy != nullptr) { + int32_t ret = func(proxy); + if (!IsRequestNeedRetry(ret)) { + return ret; + } + } else { + SANDBOXMANAGER_LOG_WARN(LABEL,"First try call %{public}s failed, proxy is NULL begin retry", funcName); } - - if (!remoteObject->AddDeathRecipient(serviceDeathObserver)) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "Add service death observer fail"); - return; + if (ret != -1) { + SANDBOXMANAGER_LOG_WARN(LABEL,"First try call %{public}s failed, err = %{public}d begin retry", funcName, ret); } - - auto proxy = iface_cast(remoteObject); - if (proxy == nullptr) { - SANDBOXMANAGER_LOG_ERROR(LABEL, "iface_cast get null"); - return; + // begin retry + for (int32_t i = 0; i < SA_REQUEST_RETRY_TIMES; i++) { + proxy = GetProxy(); + if (proxy == nullptr) { + SANDBOXMANAGER_LOG_WARN(LABEL, "Get proxy %{public}s failed, retry time = %{public}d." , funcName, i); + continue; + } + ret = func(proxy); + if (!IsRequestNeedRetry(ret)) { + return ret; + } + SANDBOXMANAGER_LOG_WARN(LABEL, "Call %{public}s failed, retry time = %{public}d, " \ + "result = %{public}d.", funcName, i, ret); } - std::unique_lock lock(proxyMutex_); - proxy_ = proxy; - serviceDeathObserver_ = serviceDeathObserver; - SANDBOXMANAGER_LOG_INFO(LABEL, "GetSystemAbility %{public}d success", - ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE); - return; + SANDBOXMANAGER_LOG_ERROR(LABEL, "Retry call service %{public}s error, tried %{public}d times.", + funcName, SA_REQUEST_RETRY_TIMES); + return SANDBOX_MANAGER_SERVICE_REMOTE_ERR; } -sptr SandboxManagerClient::GetProxy(bool doLoadSa) +bool SandboxManagerClient::IsRequestNeedRetry(int32_t ret) { - { - std::unique_lock lock(proxyMutex_); - if (proxy_ != nullptr) { - return proxy_; - } - } - if (doLoadSa) { - LoadSandboxManagerSa(); - } else { - GetSandboxManagerSa(); - } - std::unique_lock lock(proxyMutex_); - return proxy_; + auto it = std::find(RETRY_CODE_LIST.begin(), RETRY_CODE_LIST.end(), ret); + return it != RETRY_CODE_LIST.end(); } } // SandboxManager } // AccessControl