From 3bbadc5904234c6cf8392964c9efa82e3cce2643 Mon Sep 17 00:00:00 2001 From: zhouyan Date: Thu, 9 Jun 2022 15:44:45 +0800 Subject: [PATCH] =?UTF-8?q?tokensync=E5=8A=A8=E6=80=81=E6=8B=89=E8=B5=B7?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhouyan Change-Id: I1731acfe00375bf4386ceaa2207a4394582b6336 --- interfaces/innerkits/tokensync/BUILD.gn | 1 + .../src/token_sync_death_recipient.cpp | 37 +++++++++ .../src/token_sync_death_recipient.h | 36 +++++++++ .../src/token_sync_manager_client.cpp | 79 +++++++++++++++---- .../tokensync/src/token_sync_manager_client.h | 5 ++ .../src/device/atm_device_state_callback.cpp | 18 +++-- 6 files changed, 154 insertions(+), 22 deletions(-) create mode 100644 interfaces/innerkits/tokensync/src/token_sync_death_recipient.cpp create mode 100644 interfaces/innerkits/tokensync/src/token_sync_death_recipient.h diff --git a/interfaces/innerkits/tokensync/BUILD.gn b/interfaces/innerkits/tokensync/BUILD.gn index 24cb4826c..6f0225ca6 100644 --- a/interfaces/innerkits/tokensync/BUILD.gn +++ b/interfaces/innerkits/tokensync/BUILD.gn @@ -40,6 +40,7 @@ ohos_shared_library("libtokensync_sdk") { ] sources = [ + "src/token_sync_death_recipient.cpp", "src/token_sync_kit.cpp", "src/token_sync_load_callback.cpp", "src/token_sync_manager_client.cpp", diff --git a/interfaces/innerkits/tokensync/src/token_sync_death_recipient.cpp b/interfaces/innerkits/tokensync/src/token_sync_death_recipient.cpp new file mode 100644 index 000000000..aaa86fe08 --- /dev/null +++ b/interfaces/innerkits/tokensync/src/token_sync_death_recipient.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "token_sync_death_recipient.h" + +#include "token_sync_manager_client.h" +#include "accesstoken_log.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TokenSyncDeathRecipient"}; +} + +void TokenSyncDeathRecipient::OnRemoteDied(const wptr& onject) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "called"); + + TokenSyncManagerClient::GetInstance().OnRemoteDiedHandle(); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/interfaces/innerkits/tokensync/src/token_sync_death_recipient.h b/interfaces/innerkits/tokensync/src/token_sync_death_recipient.h new file mode 100644 index 000000000..4007d086e --- /dev/null +++ b/interfaces/innerkits/tokensync/src/token_sync_death_recipient.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOKEN_SYNC_DEATH_RECIPIENT_H +#define TOKEN_SYNC_DEATH_RECIPIENT_H + +#include "iremote_object.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class TokenSyncDeathRecipient : public IRemoteObject::DeathRecipient { +public: + TokenSyncDeathRecipient() + {} + + virtual ~TokenSyncDeathRecipient() = default; + void OnRemoteDied(const wptr& onject) override; +private: +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // TOKEN_SYNC_DEATH_RECIPIENT_H diff --git a/interfaces/innerkits/tokensync/src/token_sync_manager_client.cpp b/interfaces/innerkits/tokensync/src/token_sync_manager_client.cpp index 2295f5620..9df60ca00 100644 --- a/interfaces/innerkits/tokensync/src/token_sync_manager_client.cpp +++ b/interfaces/innerkits/tokensync/src/token_sync_manager_client.cpp @@ -19,6 +19,7 @@ #include "hap_token_info_for_sync_parcel.h" #include "native_token_info_for_sync_parcel.h" #include "iservice_registry.h" +#include "token_sync_death_recipient.h" #include "token_sync_load_callback.h" namespace OHOS { @@ -75,7 +76,10 @@ int TokenSyncManagerClient::UpdateRemoteHapTokenInfo(const HapTokenInfoForSync& void TokenSyncManagerClient::LoadTokenSync() { - ACCESSTOKEN_LOG_DEBUG(LABEL, "remoteObject_ is %{public}d", remoteObject_ == nullptr); + { + std::unique_lock lock(tokenSyncMutex_); + ready_ = false; + } auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (sam == nullptr) { @@ -97,25 +101,42 @@ void TokenSyncManagerClient::LoadTokenSync() return; } - std::unique_lock lock(tokenSyncMutex_); - // wait_for release lock and block until time out(60s) or match the condition with notice - auto waitStatus = tokenSyncCon_.wait_for(lock, std::chrono::milliseconds(TOKEN_SYNC_LOAD_SA_TIMEOUT_MS), - [this]() { return remoteObject_ != nullptr; }); - if (!waitStatus) { - // time out or loadcallback fail - ACCESSTOKEN_LOG_ERROR(LABEL, "tokensync load sa timeout"); + { + std::unique_lock lock(tokenSyncMutex_); + // wait_for release lock and block until time out(60s) or match the condition with notice + auto waitStatus = tokenSyncCon_.wait_for(lock, std::chrono::milliseconds(TOKEN_SYNC_LOAD_SA_TIMEOUT_MS), + [this]() { return ready_; }); + if (!waitStatus) { + // time out or loadcallback fail + ACCESSTOKEN_LOG_WARN(LABEL, "tokensync load sa timeout"); + return; + } + } + + if (GetRemoteObject() == nullptr) { + ACCESSTOKEN_LOG_WARN(LABEL, "remote object is null"); return; } + sptr ptrTokenSyncDeathRecipient = new (std::nothrow) TokenSyncDeathRecipient(); + if (ptrTokenSyncDeathRecipient == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "new TokenSyncDeathRecipient fail."); + return; + } + // add death recipient to reset token_sync + GetRemoteObject()->AddDeathRecipient(ptrTokenSyncDeathRecipient); } void TokenSyncManagerClient::FinishStartSASuccess(const sptr &remoteObject) { ACCESSTOKEN_LOG_DEBUG(LABEL, "get tokensync sa success."); - remoteObject_ = remoteObject; + SetRemoteObject(remoteObject); // get lock which wait_for release and send a notice so that wait_for can out of block - std::unique_lock lock(tokenSyncMutex_); + { + std::unique_lock lock(tokenSyncMutex_); + ready_ = true; + } tokenSyncCon_.notify_one(); } @@ -124,18 +145,48 @@ void TokenSyncManagerClient::FinishStartSAFailed() { ACCESSTOKEN_LOG_DEBUG(LABEL, "get tokensync sa failed."); + SetRemoteObject(nullptr); + // get lock which wait_for release and send a notice - std::unique_lock lock(tokenSyncMutex_); + { + std::unique_lock lock(tokenSyncMutex_); + ready_ = true; + } + tokenSyncCon_.notify_one(); } +void TokenSyncManagerClient::SetRemoteObject(const sptr &remoteObject) +{ + std::unique_lock lock(remoteMutex_); + remoteObject_ = remoteObject; +} + +sptr TokenSyncManagerClient::GetRemoteObject() +{ + std::unique_lock lock(remoteMutex_); + return remoteObject_; +} + +void TokenSyncManagerClient::OnRemoteDiedHandle() +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "Remote service died."); + + SetRemoteObject(nullptr); + + std::unique_lock lock(tokenSyncMutex_); + ready_ = false; +} + sptr TokenSyncManagerClient::GetProxy() { - LoadTokenSync(); + if (GetRemoteObject() == nullptr) { + LoadTokenSync(); + } - auto proxy = iface_cast(remoteObject_); + auto proxy = iface_cast(GetRemoteObject()); if (proxy == nullptr) { - ACCESSTOKEN_LOG_ERROR(LABEL, "iface_cast get null"); + ACCESSTOKEN_LOG_WARN(LABEL, "iface_cast get null"); return nullptr; } return proxy; diff --git a/interfaces/innerkits/tokensync/src/token_sync_manager_client.h b/interfaces/innerkits/tokensync/src/token_sync_manager_client.h index 4f615ca01..6736c8bf8 100644 --- a/interfaces/innerkits/tokensync/src/token_sync_manager_client.h +++ b/interfaces/innerkits/tokensync/src/token_sync_manager_client.h @@ -42,10 +42,15 @@ public: void LoadTokenSync(); void FinishStartSASuccess(const sptr &remoteObject); void FinishStartSAFailed(); + void SetRemoteObject(const sptr &remoteObject); + sptr GetRemoteObject(); + void OnRemoteDiedHandle(); private: std::condition_variable tokenSyncCon_; std::mutex tokenSyncMutex_; + std::mutex remoteMutex_; + bool ready_ = false; sptr remoteObject_ = nullptr; TokenSyncManagerClient(); diff --git a/services/accesstokenmanager/main/cpp/src/device/atm_device_state_callback.cpp b/services/accesstokenmanager/main/cpp/src/device/atm_device_state_callback.cpp index 0feac7b32..3f7db3a8f 100644 --- a/services/accesstokenmanager/main/cpp/src/device/atm_device_state_callback.cpp +++ b/services/accesstokenmanager/main/cpp/src/device/atm_device_state_callback.cpp @@ -51,17 +51,19 @@ void AtmDeviceStateCallback::OnDeviceOnline(const DmDeviceInfo &deviceInfo) { ACCESSTOKEN_LOG_DEBUG(LABEL, "device online"); - std::function runner = [&]() { - // when remote device online, start a thread to load tokensync - TokenSyncManagerClient::GetInstance().LoadTokenSync(); + // when remote device online and token sync remote object is null, start a thread to load token sync + if (TokenSyncManagerClient::GetInstance().GetRemoteObject() == nullptr) { + std::function runner = [&]() { + TokenSyncManagerClient::GetInstance().LoadTokenSync(); - ACCESSTOKEN_LOG_INFO(LABEL, "device state listenner register success."); + ACCESSTOKEN_LOG_INFO(LABEL, "load tokensync."); - return; - }; + return; + }; - std::thread initThread(runner); - initThread.detach(); + std::thread initThread(runner); + initThread.detach(); + } } void AtmDeviceStateCallback::OnDeviceOffline(const DmDeviceInfo &deviceInfo) -- Gitee