1 /*
2  * Copyright (C) 2024 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 
16 #include "listener_list.h"
17 
18 namespace OHOS::Request {
19 
AddListenerInner(napi_value cb)20 napi_status ListenerList::AddListenerInner(napi_value cb)
21 {
22     std::lock_guard<std::recursive_mutex> lock(allCbMutex_);
23     if (this->IsListenerAdded(cb)) {
24         return napi_ok;
25     }
26 
27     napi_ref ref;
28     napi_status status = napi_create_reference(env_, cb, 1, &ref);
29     if (status != napi_ok) {
30         return status;
31     }
32 
33     this->allCb_.push_back(std::make_pair(true, ref));
34     ++this->validCbNum;
35 
36     return napi_ok;
37 }
38 
RemoveListenerInner(napi_value cb)39 napi_status ListenerList::RemoveListenerInner(napi_value cb)
40 {
41     std::lock_guard<std::recursive_mutex> lock(allCbMutex_);
42     if (this->validCbNum == 0) {
43         return napi_ok;
44     }
45 
46     if (cb == nullptr) {
47         for (auto it = this->allCb_.begin(); it != this->allCb_.end(); it++) {
48             it->first = false;
49         }
50         this->validCbNum = 0;
51         return napi_ok;
52     }
53 
54     for (auto it = this->allCb_.begin(); it != this->allCb_.end(); it++) {
55         napi_value copyValue = nullptr;
56         napi_get_reference_value(this->env_, it->second, &copyValue);
57 
58         bool isEquals = false;
59         napi_strict_equals(this->env_, cb, copyValue, &isEquals);
60         if (isEquals) {
61             if (it->first == true) {
62                 it->first = false;
63                 --this->validCbNum;
64             }
65             break;
66         }
67     }
68     return napi_ok;
69 }
70 
OnMessageReceive(napi_value * value,uint32_t paramNumber)71 void ListenerList::OnMessageReceive(napi_value *value, uint32_t paramNumber)
72 {
73     std::lock_guard<std::recursive_mutex> lock(allCbMutex_);
74     for (auto it = this->allCb_.begin(); it != this->allCb_.end();) {
75         if (it->first == false) {
76             napi_delete_reference(this->env_, it->second);
77             it = this->allCb_.erase(it);
78             continue;
79         }
80         napi_value callbackFunc = nullptr;
81         napi_get_reference_value(this->env_, it->second, &callbackFunc);
82         napi_value callbackResult = nullptr;
83         napi_call_function(this->env_, nullptr, callbackFunc, paramNumber, value, &callbackResult);
84         it++;
85     }
86 }
87 
IsListenerAdded(napi_value cb)88 bool ListenerList::IsListenerAdded(napi_value cb)
89 {
90     if (cb == nullptr) {
91         return true;
92     }
93     for (auto it = this->allCb_.begin(); it != this->allCb_.end(); it++) {
94         napi_value copyValue = nullptr;
95         napi_get_reference_value(this->env_, it->second, &copyValue);
96 
97         bool isEquals = false;
98         napi_strict_equals(this->env_, cb, copyValue, &isEquals);
99         if (isEquals) {
100             return it->first;
101         }
102     }
103 
104     return false;
105 }
106 
HasListener()107 bool ListenerList::HasListener()
108 {
109     return this->validCbNum != 0;
110 }
111 
DeleteAllListenerRef()112 void ListenerList::DeleteAllListenerRef()
113 {
114     std::lock_guard<std::recursive_mutex> lock(allCbMutex_);
115     for (auto it = this->allCb_.begin(); it != this->allCb_.end();) {
116         it->first = false;
117         napi_delete_reference(this->env_, it->second);
118         it = this->allCb_.erase(it);
119     }
120     this->validCbNum = 0;
121     return;
122 }
123 
124 } // namespace OHOS::Request