• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "event_agent.h"
17 
18 #include "securec.h"
19 #include "utils_log.h"
20 
21 namespace OHOS {
22 namespace Storage {
23 namespace DistributedFile {
EventAgent(napi_env env,napi_value thisVar)24 EventAgent::EventAgent(napi_env env, napi_value thisVar)
25     : env_(env), thisVarRef_(nullptr), first_(nullptr), last_(nullptr)
26 {
27     napi_create_reference(env, thisVar, 1, &thisVarRef_);
28 }
29 
~EventAgent()30 EventAgent::~EventAgent()
31 {
32     EventListener* temp = nullptr;
33     for (EventListener* iter = first_; iter != nullptr; iter = temp) {
34         temp = iter->next;
35         if (iter == first_) {
36             first_ = first_->next;
37         } else if (iter == last_) {
38             last_ = last_->back;
39         } else {
40             iter->next->back = iter->back;
41             iter->back->next = iter->next;
42         }
43         napi_delete_reference(env_, iter->handlerRef);
44         delete iter;
45     }
46     napi_delete_reference(env_, thisVarRef_);
47 }
48 
On(const char * type,napi_value handler)49 void EventAgent::On(const char* type, napi_value handler)
50 {
51     auto tmp = new EventListener();
52 
53     LOGD("EventAgent::On: JS callback register.\n");
54     if (strncpy_s(tmp->type, LISTENER_TYPTE_MAX_LENGTH, type, strlen(type)) == -1) {
55         delete tmp;
56         tmp = nullptr;
57         return;
58     }
59 
60     if (first_ == nullptr) {
61         first_ = last_ = tmp;
62     } else {
63         last_->next = tmp;
64         last_->next->back = last_;
65         last_ = last_->next;
66     }
67     last_->isOnce = false;
68     napi_create_reference(env_, handler, 1, &last_->handlerRef);
69 }
70 
Off(const char * type)71 void EventAgent::Off(const char* type)
72 {
73     EventListener* temp = nullptr;
74     LOGD("EventAgent::Off: JS callback unregister.\n");
75     for (EventListener* eventListener = first_; eventListener != nullptr; eventListener = temp) {
76         temp = eventListener->next;
77         if (strcmp(eventListener->type, type) == 0) {
78             if (eventListener == first_) {
79                 first_ = first_->next;
80             } else if (eventListener == last_) {
81                 last_ = last_->back;
82             } else {
83                 eventListener->next->back = eventListener->back;
84                 eventListener->back->next = eventListener->next;
85             }
86             napi_delete_reference(env_, eventListener->handlerRef);
87             delete eventListener;
88             eventListener = nullptr;
89         }
90     }
91 }
92 
Emit(const char * type,Event * event)93 void EventAgent::Emit(const char* type, Event* event)
94 {
95     napi_handle_scope scope = nullptr;
96     napi_open_handle_scope(env_, &scope);
97 
98     napi_value thisVar = nullptr;
99     napi_get_reference_value(env_, thisVarRef_, &thisVar);
100     for (EventListener* eventListener = first_; eventListener != nullptr; eventListener = eventListener->next) {
101         if (strcmp(eventListener->type, type) == 0) {
102             napi_value jsEvent = event ? event->ToJsObject(env_) : nullptr;
103             napi_value handler = nullptr;
104             napi_value callbackResult = nullptr;
105             napi_value result = nullptr;
106             napi_get_undefined(env_, &result);
107             napi_value callbackValues[2] = {0};
108             callbackValues[0] = result;
109             callbackValues[1] = jsEvent;
110             napi_get_reference_value(env_, eventListener->handlerRef, &handler);
111             napi_call_function(env_, thisVar, handler, std::size(callbackValues), callbackValues, &callbackResult);
112             if (eventListener->isOnce) {
113                 Off(type);
114             }
115         }
116     }
117 
118     LOGD("EventAgent::Emit: [%{public}s]\n", type);
119     napi_close_handle_scope(env_, scope);
120 }
121 
InsertDevice(const std::string & deviceId)122 void EventAgent::InsertDevice(const std::string& deviceId)
123 {
124     if (deviceList_.find(deviceId) == deviceList_.end()) {
125         std::unique_lock<std::mutex> lock(deviceListMut_);
126         deviceList_.insert(deviceId);
127     }
128 }
129 
RemoveDevice(const std::string & deviceId)130 void EventAgent::RemoveDevice(const std::string& deviceId)
131 {
132     if (deviceList_.find(deviceId) != deviceList_.end()) {
133         std::unique_lock<std::mutex> lock(deviceListMut_);
134         deviceList_.erase(deviceId);
135     }
136 }
137 
FindDevice(const std::string & deviceId)138 bool EventAgent::FindDevice(const std::string& deviceId)
139 {
140     return (deviceList_.find(deviceId) != deviceList_.end());
141 }
142 
ClearDevice()143 void EventAgent::ClearDevice()
144 {
145     deviceList_.clear();
146 }
147 } // namespace DistributedFile
148 } // namespace Storage
149 } // namespace OHOS