diff --git a/connected_nfc_tag/hdi_service/connected_nfc_tag_impl.cpp b/connected_nfc_tag/hdi_service/connected_nfc_tag_impl.cpp index b1b8378ac8..c054ebc911 100644 --- a/connected_nfc_tag/hdi_service/connected_nfc_tag_impl.cpp +++ b/connected_nfc_tag/hdi_service/connected_nfc_tag_impl.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "v1_1/connected_nfc_tag_service.h" #include "connected_nfc_tag_vendor_adapter.h" @@ -32,12 +33,12 @@ namespace ConnectedNfcTag { namespace V1_1 { static sptr g_callbackV1_1 = nullptr; -static std::mutex g_callbackMutex; +static std::mutex g_callbackMutex {}; static const int MAX_NDEF_LEN = 256; static int EventCallback(uint8_t event, uint8_t *buff, uint32_t buffLen) { - std::lock_guard lock(g_callbackMutex); + std::lock_guard guard(g_callbackMutex); if (g_callbackV1_1 != nullptr && buff != nullptr && buffLen > 0) { std::vector data(buff, buff + buffLen); g_callbackV1_1->OnChipEvent((ConnectedNfcTagEvent)event, data); @@ -50,10 +51,20 @@ extern "C" IConnectedNfcTag *ConnectedNfcTagImplGetInstance(void) return new (std::nothrow) ConnectedNfcTagImpl(); } +ConnectedNfcTagImpl::ConnectedNfcTagImpl() +{ + remoteDeathRecipient_ = + new RemoteDeathRecipient(std::bind(&ConnectedNfcTagImpl::OnRemoteDied, this, std::placeholders::_1)); +} + ConnectedNfcTagImpl::~ConnectedNfcTagImpl() { - HDF_LOGI("%{public}s", __func__); - adapter.UnInit(); + std::lock_guard guard(g_callbackMutex); + if (callbackObj_ != nullptr) { + RemoveDeathRecipient(callbackObj_); + callbackObj_ = nullptr; + } + g_callbackV1_1 = nullptr; } int32_t ConnectedNfcTagImpl::RegisterCallBack( @@ -61,15 +72,24 @@ int32_t ConnectedNfcTagImpl::RegisterCallBack( { HDF_LOGI("%{public}s", __func__); + { + std::lock_guard guard(g_callbackMutex); + if (callbackObj_ != nullptr) { + RemoveDeathRecipient(callbackObj_); + callbackObj_ = nullptr; + g_callbackV1_1 = nullptr; + } + } if (callbackObj == nullptr) { HDF_LOGW("%{public}s: callbackObj NULL", __func__); - std::lock_guard lock(g_callbackMutex); - g_callbackV1_1 = nullptr; - return HDF_SUCCESS; - } - { - std::lock_guard lock(g_callbackMutex); + } else { + callbackObj_ = callbackObj; g_callbackV1_1 = callbackObj; + AddDeathRecipient(callbackObj_); + } + + if (callbackObj == nullptr) { + return adapter.RegisterCallBack(nullptr); } return adapter.RegisterCallBack(EventCallback); } @@ -117,6 +137,62 @@ int32_t ConnectedNfcTagImpl::WriteNdefTag(const std::string &ndefData) return -1; } +void ConnectedNfcTagImpl::OnRemoteDied(const wptr &object) +{ + HDF_LOGW("%{public}s: callback process died, cleaning up", __func__); + { + std::lock_guard guard(g_callbackMutex); + if (callbackObj_ != nullptr) { + RemoteDeathRecipient(callbackObj_); + callbackObj_ = nullptr; + } + g_callbackV1_1 = nullptr; + } + adapter.RegisterCallBack(nullptr); +} + +int32_t ConnectedNfcTagImpl::AddDeathRecipient( + const sptr& callbackObj) +{ + if (callbackObj == nullptr) { + HDF_LOGE("%{public}s: callbackObj nullptr", __func__); + return HDF_FAILURE; + } + const stpr &remote = + OHOS::HDI::hdi_objcast(callbackObj); + if (remote == nullptr) { + HDF_LOGE("%{public}s: remote nullptr", __func__); + return HDF_FAILURE; + } + bool result = remote->AddDeathRecipient(remoteDeathRecipient_); + if (!result) { + HDF_LOGE("%{public}s: AddDeathRecipient failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t ConnectedNfcTagImpl::RemoveDeathRecipient( + const sptr& callbackObj) +{ + if (callbackObj == nullptr) { + HDF_LOGE("%{public}s: callbackObj nullptr", __func__); + return HDF_FAILURE; + } + const stpr &remote = + OHOS::HDI::hdi_objcast(callbackObj); + if (remote == nullptr) { + HDF_LOGE("%{public}s: remote nullptr", __func__); + return HDF_FAILURE; + } + bool result = remote->RemoveDeathRecipient(remoteDeathRecipient_); + if (!result) { + HDF_LOGE("%{public}s: RemoveDeathRecipient failed", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + } // namespace V1_1 } // namespace ConnectedNfcTag } // namespace HDI diff --git a/connected_nfc_tag/hdi_service/connected_nfc_tag_impl.h b/connected_nfc_tag/hdi_service/connected_nfc_tag_impl.h index 9a53c4c9c4..1104a9d3d3 100644 --- a/connected_nfc_tag/hdi_service/connected_nfc_tag_impl.h +++ b/connected_nfc_tag/hdi_service/connected_nfc_tag_impl.h @@ -17,10 +17,12 @@ #define CONNECTED_NFC_TAG_IMPL_H #include +#include #include #include "v1_1/iconnected_nfc_tag.h" #include "connected_nfc_tag_vendor_adapter.h" +#include "remote_death_recipient.h" namespace OHOS { namespace HDI { @@ -40,8 +42,15 @@ public: int32_t ReadNdefTag(std::string &ndefData) override; int32_t WriteNdefTag(const std::string &ndefData) override; +private: + void OnRemoteDied(const wptr &object); + int32_t AddDeathRecipient(const sptr& callbackObj); + int32_t RemoveDeathRecipient(const sptr& callbackObj); + private: ConnectedNfcTagVendorAdapter adapter; + sptr callbackObj_ = nullptr; + sptr remote_death_recipient_ = nullptr; }; } // namespace V1_1 } // namespace ConnectedNfcTag diff --git a/connected_nfc_tag/hdi_service/remote_death_recipient.h b/connected_nfc_tag/hdi_service/remote_death_recipient.h new file mode 100644 index 0000000000..3aa77459f4 --- /dev/null +++ b/connected_nfc_tag/hdi_service/remote_death_recipient.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024 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 OHOS_HDI_CONNECTED_NFC_TAG_REMOTE_DEATH_RECIPIENT_H +#define OHOS_HDI_CONNECTED_NFC_TAG_REMOTE_DEATH_RECIPIENT_H + +#include + +#include "iremote_object.h" +#include "refbase.h" + +namespace OHOS { +namespace HDI { +namespace ConnectedNfcTag { +class RemoteDeathRecipient : public IRemoteObject::DeathRecipient { +public: + explicit RemoteDeathRecipient(std::function &)> callback) + { + callback_ = callback; + } + ~RemoteDeathRecipient() + { + callback_ = nullptr; + } + + void OnRemoteDied(const wptr &object) + { + if (callback_ != nullptr) { + callback_(object); + } + } + +private: + std::function &)> callback_; +}; +} // ConnectedNfcTag +} // HDI +} // OHOS + +#endif // OHOS_HDI_CONNECTED_NFC_TAG_REMOTE_DEATH_RECIPIENT_H