1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "listener_base.h"
16
17 #include <uv.h>
18
19 #include "camera_log.h"
20 #include "js_native_api.h"
21 #include "js_native_api_types.h"
22
23 namespace OHOS {
24 namespace CameraStandard {
ListenerBase(napi_env env)25 ListenerBase::ListenerBase(napi_env env) : env_(env)
26 {
27 MEDIA_DEBUG_LOG("ListenerBase is called.");
28 }
29
~ListenerBase()30 ListenerBase::~ListenerBase()
31 {
32 MEDIA_DEBUG_LOG("~ListenerBase is called.");
33 }
34
SaveCallbackReference(const std::string eventName,napi_value callback,bool isOnce)35 void ListenerBase::SaveCallbackReference(const std::string eventName, napi_value callback, bool isOnce)
36 {
37 if (callback == nullptr) {
38 MEDIA_ERR_LOG("SaveCallbackReference:%s js callback is nullptr, save nothing", eventName.c_str());
39 return;
40 }
41 napi_valuetype valueType = napi_undefined;
42 napi_typeof(env_, callback, &valueType);
43 if (valueType != napi_function) {
44 MEDIA_ERR_LOG("SaveCallbackReference:%s js callback valueType is not function", eventName.c_str());
45 return;
46 }
47 auto& callbackList = GetCallbackList(eventName);
48 std::lock_guard<std::mutex> lock(callbackList.listMutex);
49 for (auto it = callbackList.refList.begin(); it != callbackList.refList.end(); ++it) {
50 bool isSameCallback = CameraNapiUtils::IsSameNapiValue(env_, callback, it->GetCallbackFunction());
51 CHECK_AND_RETURN_LOG(!isSameCallback, "SaveCallbackReference: has same callback, nothing to do");
52 }
53 callbackList.refList.emplace_back(AutoRef(env_, callback, isOnce));
54 MEDIA_DEBUG_LOG("Save callback reference success, %s callback list size [%{public}zu]", eventName.c_str(),
55 callbackList.refList.size());
56 }
57
RemoveCallbackRef(const std::string eventName,napi_value callback)58 void ListenerBase::RemoveCallbackRef(const std::string eventName, napi_value callback)
59 {
60 if (callback == nullptr) {
61 MEDIA_INFO_LOG("RemoveCallbackReference: js callback is nullptr, remove all callback reference");
62 RemoveAllCallbacks(eventName);
63 return;
64 }
65 auto& callbackList = GetCallbackList(eventName);
66 std::lock_guard<std::mutex> lock(callbackList.listMutex);
67 for (auto it = callbackList.refList.begin(); it != callbackList.refList.end(); ++it) {
68 bool isSameCallback = CameraNapiUtils::IsSameNapiValue(env_, callback, it->GetCallbackFunction());
69 if (isSameCallback) {
70 MEDIA_INFO_LOG("RemoveCallbackReference: find %s callback, delete it", eventName.c_str());
71 callbackList.refList.erase(it);
72 return;
73 }
74 }
75 MEDIA_INFO_LOG("RemoveCallbackReference: %s callback not find", eventName.c_str());
76 }
77
ExecuteCallback(const std::string eventName,const ExecuteCallbackNapiPara & callbackPara) const78 void ListenerBase::ExecuteCallback(const std::string eventName, const ExecuteCallbackNapiPara& callbackPara) const
79 {
80 MEDIA_DEBUG_LOG("ListenerBase::ExecuteCallback is called");
81 auto& callbackList = GetCallbackList(eventName);
82 std::lock_guard<std::mutex> lock(callbackList.listMutex);
83 for (auto it = callbackList.refList.begin(); it != callbackList.refList.end();) {
84 napi_call_function(env_, callbackPara.recv, it->GetCallbackFunction(), callbackPara.argc, callbackPara.argv,
85 callbackPara.result);
86 if (it->isOnce_) {
87 callbackList.refList.erase(it);
88 } else {
89 it++;
90 }
91 }
92 MEDIA_DEBUG_LOG("ListenerBase::ExecuteCallback, %s callback list size [%{public}zu]", eventName.c_str(),
93 callbackList.refList.size());
94 }
95
RemoveAllCallbacks(const std::string eventName)96 void ListenerBase::RemoveAllCallbacks(const std::string eventName)
97 {
98 auto& callbackList = GetCallbackList(eventName);
99 std::lock_guard<std::mutex> lock(callbackList.listMutex);
100 callbackList.refList.clear();
101 MEDIA_INFO_LOG("RemoveAllCallbacks: remove all js callbacks success");
102 }
103
IsEmpty(const std::string eventName) const104 bool ListenerBase::IsEmpty(const std::string eventName) const
105 {
106 auto& callbackList = GetCallbackList(eventName);
107 std::lock_guard<std::mutex> lock(callbackList.listMutex);
108 return callbackList.refList.empty();
109 }
110 } // namespace CameraStandard
111 } // namespace OHOS
112