diff --git a/interfaces/innerkits/sandbox_manager/include/sandbox_manager_client.h b/interfaces/innerkits/sandbox_manager/include/sandbox_manager_client.h index 9c9f0c58824713bde3cbde60a80aca92a0c986cb..dc04319fd89e979a3e2b27528a3d1c8ac23a3cec 100644 --- a/interfaces/innerkits/sandbox_manager/include/sandbox_manager_client.h +++ b/interfaces/innerkits/sandbox_manager/include/sandbox_manager_client.h @@ -31,10 +31,17 @@ #include "policy_info.h" #include "refbase.h" #include "sandbox_manager_death_recipient.h" +#include "system_ability_status_change_stub.h" namespace OHOS { namespace AccessControl { namespace SandboxManager { +class SandboxManagerStatusListener : public SystemAbilityStatusChangeStub { +public: + void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override {}; + void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; +}; + class SandboxManagerClient final { public: static SandboxManagerClient &GetInstance(); @@ -62,6 +69,9 @@ public: void FinishStartSASuccess(const sptr &remoteObject); void FinishStartSAFail(); void OnRemoteDiedHandle(); + void OnRemoteRemovedHandle(); + bool RegisterListener(); + bool UnRegisterListener(); private: SandboxManagerClient(); @@ -80,6 +90,7 @@ private: std::condition_variable sandboxManagerCon_; std::mutex proxyMutex_; sptr serviceDeathObserver_ = nullptr; + sptr listener_ = nullptr; }; } // SandboxManager } // AccessControl diff --git a/interfaces/innerkits/sandbox_manager/src/sandbox_manager_client.cpp b/interfaces/innerkits/sandbox_manager/src/sandbox_manager_client.cpp index dd870e4a29e58c25dec3d1b0ff5155a8eced98ca..5ad72ebbff52839b77eace718ca4ad7b69b26351 100644 --- a/interfaces/innerkits/sandbox_manager/src/sandbox_manager_client.cpp +++ b/interfaces/innerkits/sandbox_manager/src/sandbox_manager_client.cpp @@ -32,6 +32,77 @@ static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { }; static const int32_t SANDBOX_MANAGER_LOAD_SA_TIMEOUT_MS = 4000; +void SandboxManagerStatusListener::OnRemoveSystemAbility( + int32_t systemAbilityId, const std::string &deviceId) +{ + if (systemAbilityId == ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE) { + SandboxManagerClient::GetInstance().OnRemoteDiedHandle(); + } +} + +void SandboxManagerClient::OnRemoteRemovedHandle() +{ + SANDBOXMANAGER_LOG_WARN(LABEL, "Remote is removed, clean proxy."); + { + std::unique_lock lock(cvLock_); + readyFlag_ = false; + } + { + std::unique_lock lock(proxyMutex_); + if ((serviceDeathObserver_ != nullptr) && (proxy_ != nullptr)) { + proxy_->AsObject()->RemoveDeathRecipient(serviceDeathObserver_); + } + serviceDeathObserver_ = nullptr; + proxy_ = nullptr; + } +} + +bool SandboxManagerClient::RegisterListener() +{ + if (listener_ != nullptr) { + SANDBOXMANAGER_LOG_INFO(LABEL, "Listener is already registered."); + return true; + } + sptr listener = sptr::MakeSptr(); + if (listener == nullptr) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Make listener failed."); + return false; + } + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Get system ability manager failed."); + return false; + } + int32_t ret = samgr->SubscribeSystemAbility(ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE, + listener); + if (ret != ERR_OK) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Subscribe system ability failed, ret = %{public}d.", ret); + return false; + } + listener_ = listener; + return true; +} + +bool SandboxManagerClient::UnRegisterListener() +{ + if (listener_ == nullptr) { + return true; + } + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Get system ability manager failed."); + return false; + } + int32_t ret = samgr->UnSubscribeSystemAbility(ISandboxManager::SA_ID_SANDBOX_MANAGER_SERVICE, + listener_); + if (ret != ERR_OK) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Unsubscribe system ability failed, ret = %{public}d.", ret); + return false; + } + listener_ = nullptr; + return true; +} + SandboxManagerClient& SandboxManagerClient::GetInstance() { static SandboxManagerClient instance; @@ -39,10 +110,18 @@ SandboxManagerClient& SandboxManagerClient::GetInstance() } SandboxManagerClient::SandboxManagerClient() -{} +{ + if (!RegisterListener()) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Register listener failed."); + } +} SandboxManagerClient::~SandboxManagerClient() -{} +{ + if (!UnRegisterListener()) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Unregister listener failed."); + } +} int32_t SandboxManagerClient::CleanPersistPolicyByPath(const std::vector& filePathList) { @@ -272,9 +351,14 @@ void SandboxManagerClient::LoadSandboxManagerSa() void SandboxManagerClient::OnRemoteDiedHandle() { SANDBOXMANAGER_LOG_ERROR(LABEL, "Remote service died"); - std::unique_lock lock(proxyMutex_); - proxy_ = nullptr; - serviceDeathObserver_ = nullptr; + { + std::unique_lock lock(proxyMutex_); + if ((serviceDeathObserver_ != nullptr) && (proxy_ != nullptr)) { + proxy_->AsObject()->RemoveDeathRecipient(serviceDeathObserver_); + } + serviceDeathObserver_ = nullptr; + proxy_ = nullptr; + } { std::unique_lock lock1(cvLock_); readyFlag_ = false; @@ -337,6 +421,9 @@ sptr SandboxManagerClient::GetProxy(bool doLoadSa) { { std::unique_lock lock(proxyMutex_); + if (!RegisterListener()) { + SANDBOXMANAGER_LOG_ERROR(LABEL, "Subscribe system ability listener failed."); + } if (proxy_ != nullptr) { return proxy_; }