diff --git a/frameworks/js/napi/BUILD.gn b/frameworks/js/napi/BUILD.gn index f085dcf80738dc9b1c7ba33df935f68702be103a..7df927638774c2da8affe024bdc4c7c0ad019640 100644 --- a/frameworks/js/napi/BUILD.gn +++ b/frameworks/js/napi/BUILD.gn @@ -73,6 +73,7 @@ ohos_shared_library("audio") { "../../../services/audio_service:audio_client", "../../native/audiocapturer:audio_capturer", "../../native/audiorenderer:audio_renderer", + "../../native/audioutils:audio_utils", ] defines = [] diff --git a/frameworks/js/napi/audio_manager/src/audio_volume_group_manager_napi.cpp b/frameworks/js/napi/audio_manager/src/audio_volume_group_manager_napi.cpp index b37ce396a40dbb5c0b2b9ca4347aab90890b0bb3..c2948a3c693c75f2347fd693e24c22e2a475f35a 100755 --- a/frameworks/js/napi/audio_manager/src/audio_volume_group_manager_napi.cpp +++ b/frameworks/js/napi/audio_manager/src/audio_volume_group_manager_napi.cpp @@ -18,6 +18,7 @@ #include "audio_errors.h" #include "hilog/log.h" #include "audio_log.h" +#include "audio_utils.h" #include "xpower_event_js.h" using namespace std; @@ -289,19 +290,22 @@ napi_value AudioVolumeGroupManagerNapi::Construct(napi_env env, napi_callback_in HiLog::Info(LABEL, "Construct() %{public}d", groupId); if (status == napi_ok) { - unique_ptr groupmanagerNapi = make_unique(); - if (groupmanagerNapi != nullptr) { - groupmanagerNapi->audioGroupMngr_ = AudioSystemManager::GetInstance()->GetGroupManager(groupId); - if (groupmanagerNapi->audioGroupMngr_ == nullptr) { + unique_ptr objectInfo = make_unique(); + if (objectInfo != nullptr) { + ObjectRefMap::Insert(objectInfo.get()); + objectInfo->audioGroupMngr_ = AudioSystemManager::GetInstance()->GetGroupManager(groupId); + if (objectInfo->audioGroupMngr_ == nullptr) { HiLog::Error(LABEL, "Failed in AudioVolumeGroupManagerNapi::Construct()!"); AudioVolumeGroupManagerNapi::isConstructSuccess_ = NAPI_ERR_SYSTEM; } - groupmanagerNapi->cachedClientId_ = getpid(); - status = napi_wrap(env, jsThis, static_cast(groupmanagerNapi.get()), + objectInfo->cachedClientId_ = getpid(); + status = napi_wrap(env, jsThis, static_cast(objectInfo.get()), AudioVolumeGroupManagerNapi::Destructor, nullptr, nullptr); if (status == napi_ok) { - groupmanagerNapi.release(); + objectInfo.release(); return jsThis; + } else { + ObjectRefMap::Erase(objectInfo.get()); } } } @@ -317,8 +321,7 @@ void AudioVolumeGroupManagerNapi::Destructor(napi_env env, void *nativeObject, v if (nativeObject != nullptr) { auto obj = static_cast(nativeObject); - delete obj; - obj = nullptr; + ObjectRefMap::DecreaseRef(obj); AUDIO_DEBUG_LOG("AudioVolumeGroupManagerNapi::Destructor delete AudioVolumeGroupManagerNapi obj done"); } } @@ -1040,8 +1043,10 @@ napi_value AudioVolumeGroupManagerNapi::GetRingerMode(napi_env env, napi_callbac env, nullptr, resource, [](napi_env env, void *data) { auto context = static_cast(data); - if (context->status == SUCCESS) { - context->ringMode = GetJsAudioRingMode(context->objectInfo->audioGroupMngr_->GetRingerMode()); + ObjectRefMap objectGuard(context->objectInfo); + AudioVolumeGroupManagerNapi *object = objectGuard.GetPtr(); + if (context->status == SUCCESS && object != nullptr) { + context->ringMode = GetJsAudioRingMode(object->audioGroupMngr_->GetRingerMode()); context->intValue = context->ringMode; context->status = 0; } diff --git a/frameworks/native/audioutils/include/audio_utils.h b/frameworks/native/audioutils/include/audio_utils.h index 0c7879b8a704cd4056c1113d70ef769c60474ddd..08d1ba36cfbb33fada38aad85ebfc94c77228b78 100644 --- a/frameworks/native/audioutils/include/audio_utils.h +++ b/frameworks/native/audioutils/include/audio_utils.h @@ -18,6 +18,7 @@ #include #include #include +#include #define AUDIO_MS_PER_SECOND 1000 #define AUDIO_US_PER_SECOND 1000000 @@ -96,6 +97,91 @@ private: static FILE *OpenDumpFileInner(std::string para, std::string fileName, AudioDumpFileType fileType); static void ChangeDumpFileState(std::string para, FILE **dumpFile, std::string fileName); }; + +template +class ObjectRefMap { +public: + static std::mutex allObjLock; + static std::map refMap; + static void Insert(T *obj); + static void Erase(T *obj); + static T *IncreaseRef(T *obj); + static void DecreaseRef(T *obj); + + ObjectRefMap(T *obj); + ~ObjectRefMap(); + T *GetPtr(); + +private: + T *obj_ = nullptr; +}; + +template +std::mutex ObjectRefMap::allObjLock; + +template +std::map ObjectRefMap::refMap; + +template +void ObjectRefMap::Insert(T *obj) +{ + std::lock_guard lock(allObjLock); + refMap[obj] = 1; +} + +template +void ObjectRefMap::Erase(T *obj) +{ + std::lock_guard lock(allObjLock); + auto it = refMap.find(obj); + if (it != refMap.end()) { + refMap.erase(it); + } +} + +template +T *ObjectRefMap::IncreaseRef(T *obj) +{ + std::lock_guard lock(allObjLock); + if (refMap.count(obj)) { + refMap[obj]++; + return obj; + } else { + return nullptr; + } +} + +template +void ObjectRefMap::DecreaseRef(T *obj) +{ + std::lock_guard lock(allObjLock); + if (refMap.count(obj) && --refMap[obj] == 0) { + delete obj; + refMap.erase(obj); + } +} + +template +ObjectRefMap::ObjectRefMap(T *obj) +{ + if (obj != nullptr) { + obj_ = ObjectRefMap::IncreaseRef(obj); + } +} + +template +ObjectRefMap::~ObjectRefMap() +{ + if (obj_ != nullptr) { + ObjectRefMap::DecreaseRef(obj_); + } +} + +template +T *ObjectRefMap::GetPtr() +{ + return obj_; +} } // namespace AudioStandard } // namespace OHOS #endif // AUDIO_UTILS_H