diff --git a/frameworks/js/napi/include/napi_bluetooth_a2dp_snk_observer.h b/frameworks/js/napi/include/napi_bluetooth_a2dp_snk_observer.h index 06761559d1ae2a63321960a30e662463fb8be457..a3afb4d3d508ed7e1f714c818002b390e615a776 100644 --- a/frameworks/js/napi/include/napi_bluetooth_a2dp_snk_observer.h +++ b/frameworks/js/napi/include/napi_bluetooth_a2dp_snk_observer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. + * Copyright (C) 2021-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 @@ -16,11 +16,13 @@ #ifndef NAPI_BLUETOOTH_A2DP_SNK_OBSERVER_H_ #define NAPI_BLUETOOTH_A2DP_SNK_OBSERVER_H_ +#include #include "bluetooth_a2dp_snk.h" #include "napi_bluetooth_utils.h" namespace OHOS { namespace Bluetooth { +static std::shared_mutex g_a2dpSinkCallbackInfosMutex; const std::string STR_BT_A2DP_SINK_CONNECTION_STATE_CHANGE = "connectionStateChange"; class NapiA2dpSinkObserver : public A2dpSinkObserver{ diff --git a/frameworks/js/napi/include/napi_bluetooth_a2dp_src_observer.h b/frameworks/js/napi/include/napi_bluetooth_a2dp_src_observer.h index 6d682399a38e00e05baba9fa2389376dc1eadbff..be85e900a54473a04c1457ebfde5c1193901695f 100644 --- a/frameworks/js/napi/include/napi_bluetooth_a2dp_src_observer.h +++ b/frameworks/js/napi/include/napi_bluetooth_a2dp_src_observer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. + * Copyright (C) 2021-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 @@ -16,11 +16,13 @@ #ifndef NAPI_BLUETOOTH_A2DP_SRC_OBSERVER_H_ #define NAPI_BLUETOOTH_A2DP_SRC_OBSERVER_H_ +#include #include "bluetooth_a2dp_src.h" #include "napi_bluetooth_utils.h" namespace OHOS { namespace Bluetooth { +static std::shared_mutex g_a2dpSrcCallbackInfosMutex; const std::string STR_BT_A2DP_SOURCE_CONNECTION_STATE_CHANGE = "connectionStateChange"; class NapiA2dpSourceObserver : public A2dpSourceObserver{ diff --git a/frameworks/js/napi/include/napi_bluetooth_utils.h b/frameworks/js/napi/include/napi_bluetooth_utils.h index 32fc38d969bd97ffebc4e120aa92c1d96e7edc80..3542236a7972327b241b3cfa8788a05152279d01 100644 --- a/frameworks/js/napi/include/napi_bluetooth_utils.h +++ b/frameworks/js/napi/include/napi_bluetooth_utils.h @@ -56,6 +56,8 @@ constexpr int ASYNC_START = 1; constexpr int ASYNC_DONE = 2; constexpr int32_t THREAD_WAIT_TIMEOUT = 5; +constexpr uint32_t INVALID_REF_COUNT = 0xFF; + struct ServerResponse { std::string deviceId = ""; int transId = 0; diff --git a/frameworks/js/napi/src/napi_bluetooth_a2dp_snk.cpp b/frameworks/js/napi/src/napi_bluetooth_a2dp_snk.cpp index 5c3908a01ca70c89fe638ef6ecec90474d644020..d2bdfe1bc73b5fc4b3841bda31e5e5057e224a84 100644 --- a/frameworks/js/napi/src/napi_bluetooth_a2dp_snk.cpp +++ b/frameworks/js/napi/src/napi_bluetooth_a2dp_snk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. + * Copyright (C) 2021-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 @@ -54,6 +54,7 @@ napi_value NapiA2dpSink::A2dpSinkConstructor(napi_env env, napi_callback_info in napi_value NapiA2dpSink::On(napi_env env, napi_callback_info info) { HILOGI("enter"); + std::unique_lock guard(g_a2dpSinkCallbackInfosMutex); size_t expectedArgsCount = ARGS_SIZE_TWO; size_t argc = expectedArgsCount; napi_value argv[ARGS_SIZE_TWO] = {0}; @@ -96,6 +97,7 @@ napi_value NapiA2dpSink::On(napi_env env, napi_callback_info info) napi_value NapiA2dpSink::Off(napi_env env, napi_callback_info info) { HILOGI("enter"); + std::unique_lock guard(g_a2dpSinkCallbackInfosMutex); size_t expectedArgsCount = ARGS_SIZE_ONE; size_t argc = expectedArgsCount; napi_value argv[ARGS_SIZE_ONE] = {0}; @@ -114,6 +116,12 @@ napi_value NapiA2dpSink::Off(napi_env env, napi_callback_info info) HILOGE("string expected."); return ret; } + uint32_t refCount = INVALID_REF_COUNT; + napi_reference_unref(env, observer_.callbackInfos_[type]->callback_, &refCount); + HILOGI("decrements the refernce count, refCount: %{public}d", refCount); + if (refCount == 0) { + napi_delete_reference(env, observer_.callbackInfos_[type]->callback_); + } observer_.callbackInfos_[type] = nullptr; HILOGI("%{public}s is unregistered", type.c_str()); return ret; diff --git a/frameworks/js/napi/src/napi_bluetooth_a2dp_snk_observer.cpp b/frameworks/js/napi/src/napi_bluetooth_a2dp_snk_observer.cpp index ad0727aad65bcc7dd0e94332eaa3d7e5e81d2120..0a0e18174a32f81c9d887c886fc456020f943f37 100644 --- a/frameworks/js/napi/src/napi_bluetooth_a2dp_snk_observer.cpp +++ b/frameworks/js/napi/src/napi_bluetooth_a2dp_snk_observer.cpp @@ -21,18 +21,24 @@ namespace Bluetooth { void NapiA2dpSinkObserver::OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state) { HILOGI("enter, remote device address: %{public}s, state: %{public}d", GET_ENCRYPT_ADDR(device), state); - if (!callbackInfos_[STR_BT_A2DP_SINK_CONNECTION_STATE_CHANGE]) { + std::unique_lock guard(g_a2dpSinkCallbackInfosMutex); + + std::map>::iterator it = + callbackInfos_.find(STR_BT_A2DP_SINK_CONNECTION_STATE_CHANGE); + if (it == callbackInfos_.end() || it->second == nullptr) { HILOGW("This callback is not registered by ability."); return; } - std::shared_ptr callbackInfo = - callbackInfos_[STR_BT_A2DP_SINK_CONNECTION_STATE_CHANGE]; + std::shared_ptr callbackInfo = it->second; callbackInfo->state_ = state; callbackInfo->deviceId_ = device.GetDeviceAddr(); uv_loop_s *loop = nullptr; napi_get_uv_event_loop(callbackInfo->env_, &loop); uv_work_t *work = new uv_work_t; + uint32_t refCount = INVALID_REF_COUNT; + napi_reference_ref(callbackInfo->env_, callbackInfo->callback_, &refCount); + HILOGI("increments the reference count, refCount: %{public}d", refCount); work->data = (void*)callbackInfo.get(); uv_queue_work( @@ -49,7 +55,16 @@ void NapiA2dpSinkObserver::OnConnectionStateChanged(const BluetoothRemoteDevice napi_value callResult = nullptr; napi_get_undefined(callbackInfo->env_, &undefined); napi_get_reference_value(callbackInfo->env_, callbackInfo->callback_, &callback); - napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult); + if (callback != nullptr) { + HILOGI("a2dp snk napi_call_function called"); + napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult); + } + uint32_t refCount = INVALID_REF_COUNT; + napi_reference_unref(callbackInfo->env_, callbackInfo->callback_, &refCount); + HILOGI("uv_queue_work unref, refCount: %{public}d", refCount); + if (refCount == 0) { + napi_delete_reference(callbackInfo->env_, callbackInfo->callback_); + } delete work; work = nullptr; } diff --git a/frameworks/js/napi/src/napi_bluetooth_a2dp_src.cpp b/frameworks/js/napi/src/napi_bluetooth_a2dp_src.cpp index 1fae82111ca768a9bdee92637120fba6ee1ef124..b682b0147fca17e6af5e1066d977106e07ca3e70 100644 --- a/frameworks/js/napi/src/napi_bluetooth_a2dp_src.cpp +++ b/frameworks/js/napi/src/napi_bluetooth_a2dp_src.cpp @@ -55,6 +55,7 @@ napi_value NapiA2dpSource::A2dpSourceConstructor(napi_env env, napi_callback_inf napi_value NapiA2dpSource::On(napi_env env, napi_callback_info info) { HILOGI("enter"); + std::unique_lock guard(g_a2dpSrcCallbackInfosMutex); size_t expectedArgsCount = ARGS_SIZE_TWO; size_t argc = expectedArgsCount; napi_value argv[ARGS_SIZE_TWO] = {0}; @@ -98,6 +99,7 @@ napi_value NapiA2dpSource::On(napi_env env, napi_callback_info info) napi_value NapiA2dpSource::Off(napi_env env, napi_callback_info info) { HILOGI("enter"); + std::unique_lock guard(g_a2dpSrcCallbackInfosMutex); size_t expectedArgsCount = ARGS_SIZE_ONE; size_t argc = expectedArgsCount; napi_value argv[ARGS_SIZE_ONE] = {0}; @@ -116,6 +118,12 @@ napi_value NapiA2dpSource::Off(napi_env env, napi_callback_info info) HILOGE("string expected."); return ret; } + uint32_t refCount = INVALID_REF_COUNT; + napi_reference_unref(env, observer_.callbackInfos_[type]->callback_, &refCount); + HILOGI("decrements the refernce count, refCount: %{public}d", refCount); + if (refCount == 0) { + napi_delete_reference(env, observer_.callbackInfos_[type]->callback_); + } observer_.callbackInfos_[type] = nullptr; HILOGI("%{public}s is unregistered", type.c_str()); diff --git a/frameworks/js/napi/src/napi_bluetooth_a2dp_src_observer.cpp b/frameworks/js/napi/src/napi_bluetooth_a2dp_src_observer.cpp index 4c25f43ee84926a9d87711c196fb2424de06175e..87218f9aeb9f573b5e144c01c397889986b0859b 100644 --- a/frameworks/js/napi/src/napi_bluetooth_a2dp_src_observer.cpp +++ b/frameworks/js/napi/src/napi_bluetooth_a2dp_src_observer.cpp @@ -21,18 +21,25 @@ namespace Bluetooth { void NapiA2dpSourceObserver::OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state) { HILOGI("enter, remote device address: %{public}s, state: %{public}d", GET_ENCRYPT_ADDR(device), state); - if (!callbackInfos_[STR_BT_A2DP_SOURCE_CONNECTION_STATE_CHANGE]) { + std::unique_lock guard(g_a2dpSrcCallbackInfosMutex); + + std::map>::iterator it = + callbackInfos_.find(STR_BT_A2DP_SOURCE_CONNECTION_STATE_CHANGE); + if (it == callbackInfos_.end() || it->second == nullptr) { HILOGW("This callback is not registered by ability."); return; } - std::shared_ptr callbackInfo = - callbackInfos_[STR_BT_A2DP_SOURCE_CONNECTION_STATE_CHANGE]; + + std::shared_ptr callbackInfo = it->second; callbackInfo->state_ = state; callbackInfo->deviceId_ = device.GetDeviceAddr(); uv_loop_s *loop = nullptr; napi_get_uv_event_loop(callbackInfo->env_, &loop); uv_work_t *work = new uv_work_t; + uint32_t refCount = INVALID_REF_COUNT; + napi_reference_ref(callbackInfo->env_, callbackInfo->callback_, &refCount); + HILOGI("increments the reference count, refCount: %{public}d", refCount); work->data = (void*)callbackInfo.get(); uv_queue_work( @@ -49,7 +56,16 @@ void NapiA2dpSourceObserver::OnConnectionStateChanged(const BluetoothRemoteDevic napi_value callResult = nullptr; napi_get_undefined(callbackInfo->env_, &undefined); napi_get_reference_value(callbackInfo->env_, callbackInfo->callback_, &callback); - napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult); + if (callback != nullptr) { + HILOGI("a2dp src napi_call_function called"); + napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult); + } + uint32_t refCount = INVALID_REF_COUNT; + napi_reference_unref(callbackInfo->env_, callbackInfo->callback_, &refCount); + HILOGI("uv_queue_work unref, refCount: %{public}d", refCount); + if (refCount == 0) { + napi_delete_reference(callbackInfo->env_, callbackInfo->callback_); + } delete work; work = nullptr; }