1 /*
2 * Copyright (c) 2023 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 "js_drag_manager.h"
17
18 #include "devicestatus_define.h"
19 #include "interaction_manager.h"
20 #include "napi_constants.h"
21 #include "util_napi.h"
22
23 #undef LOG_TAG
24 #define LOG_TAG "JsDragManager"
25
26 namespace OHOS {
27 namespace Msdp {
28 namespace DeviceStatus {
29
ResetEnv()30 void JsDragManager::ResetEnv()
31 {
32 CALL_INFO_TRACE;
33 std::lock_guard<std::mutex> guard(mutex_);
34 listeners_.clear();
35 }
36
IsSameHandle(napi_env env,napi_value handle,napi_ref ref)37 bool JsDragManager::IsSameHandle(napi_env env, napi_value handle, napi_ref ref)
38 {
39 CALL_INFO_TRACE;
40 napi_handle_scope scope = nullptr;
41 napi_open_handle_scope(env, &scope);
42 CHKPF(scope);
43 napi_value handlerTemp = nullptr;
44 CHKRF_SCOPE(env, napi_get_reference_value(env, ref, &handlerTemp), GET_REFERENCE_VALUE, scope);
45 bool isEqual = false;
46 CHKRF_SCOPE(env, napi_strict_equals(env, handle, handlerTemp, &isEqual), STRICT_EQUALS, scope);
47 napi_close_handle_scope(env, scope);
48 return isEqual;
49 }
50
GetDataSummary(napi_env env)51 napi_value JsDragManager::GetDataSummary(napi_env env)
52 {
53 CALL_INFO_TRACE;
54 napi_value arr = nullptr;
55 CHKRP(napi_create_array(env, &arr), CREATE_ARRAY);
56 std::map<std::string, int64_t> summarys;
57 if (INTERACTION_MGR->GetDragSummary(summarys, true) != RET_OK) {
58 FI_HILOGE("Failed to GetDragSummary");
59 return arr;
60 }
61 uint32_t index = 0;
62 for (const auto &summary : summarys) {
63 napi_value dataType = nullptr;
64 CHKRP(napi_create_string_utf8(env, summary.first.c_str(), NAPI_AUTO_LENGTH, &dataType), CREATE_STRING_UTF8);
65 napi_value dataSize = nullptr;
66 CHKRP(napi_create_int64(env, summary.second, &dataSize), CREATE_INT64);
67 napi_value object = nullptr;
68 CHKRP(napi_create_object(env, &object), CREATE_OBJECT);
69 CHKRP(napi_set_named_property(env, object, "dataType", dataType), SET_NAMED_PROPERTY);
70 CHKRP(napi_set_named_property(env, object, "dataSize", dataSize), SET_NAMED_PROPERTY);
71 CHKRP(napi_set_element(env, arr, index, object), SET_ELEMENT);
72 ++index;
73 }
74 return arr;
75 }
76
SetDragSwitchState(napi_env env,bool enable)77 int32_t JsDragManager::SetDragSwitchState(napi_env env, bool enable)
78 {
79 CALL_INFO_TRACE;
80 std::lock_guard<std::mutex> guard(mutex_);
81 return INTERACTION_MGR->SetDragSwitchState(enable, true);
82 }
83
SetAppDragSwitchState(napi_env env,bool enable,const std::string & pkgName)84 int32_t JsDragManager::SetAppDragSwitchState(napi_env env, bool enable, const std::string &pkgName)
85 {
86 CALL_INFO_TRACE;
87 std::lock_guard<std::mutex> guard(mutex_);
88 if (pkgName.empty()) {
89 FI_HILOGE("The pkgName is empty");
90 return COMMON_PARAMETER_ERROR;
91 }
92 return INTERACTION_MGR->SetAppDragSwitchState(enable, pkgName, true);
93 }
94
RegisterListener(napi_env env,napi_value handle)95 void JsDragManager::RegisterListener(napi_env env, napi_value handle)
96 {
97 CALL_INFO_TRACE;
98 std::lock_guard<std::mutex> guard(mutex_);
99 for (const auto &item : listeners_) {
100 CHKPC(item);
101 if (item->env == env && IsSameHandle(env, handle, item->ref)) {
102 FI_HILOGE("The handle already exists");
103 return;
104 }
105 }
106 napi_ref ref = nullptr;
107 CHKRV(napi_create_reference(env, handle, 1, &ref), CREATE_REFERENCE);
108 sptr<CallbackInfo> monitor = new (std::nothrow) CallbackInfo();
109 CHKPV(monitor);
110 monitor->env = env;
111 monitor->ref = ref;
112 listeners_.push_back(std::move(monitor));
113 if (!hasRegistered_) {
114 hasRegistered_ = true;
115 INTERACTION_MGR->AddDraglistener(shared_from_this(), true);
116 }
117 }
118
UnregisterListener(napi_env env,napi_value handle)119 void JsDragManager::UnregisterListener(napi_env env, napi_value handle)
120 {
121 CALL_INFO_TRACE;
122 std::lock_guard<std::mutex> guard(mutex_);
123 if (listeners_.empty()) {
124 FI_HILOGE("The listener list is empty");
125 return;
126 }
127 for (auto iter = listeners_.begin(); iter != listeners_.end();) {
128 if (handle == nullptr) {
129 RELEASE_CALLBACKINFO((*iter)->env, (*iter)->ref);
130 iter = listeners_.erase(iter);
131 } else {
132 if ((*iter)->env == env && IsSameHandle(env, handle, (*iter)->ref)) {
133 FI_HILOGD("Removing monitor successfully");
134 RELEASE_CALLBACKINFO((*iter)->env, (*iter)->ref);
135 iter = listeners_.erase(iter);
136 break;
137 }
138 ++iter;
139 }
140 }
141 if (hasRegistered_ && listeners_.empty()) {
142 hasRegistered_ = false;
143 INTERACTION_MGR->RemoveDraglistener(shared_from_this(), true);
144 }
145 }
146
OnDragMessage(DragState state)147 void JsDragManager::OnDragMessage(DragState state)
148 {
149 CALL_DEBUG_ENTER;
150 std::lock_guard<std::mutex> guard(mutex_);
151 if (listeners_.empty()) {
152 FI_HILOGE("The listener list is empty");
153 return;
154 }
155 for (auto &item : listeners_) {
156 CHKPC(item);
157 CHKPC(item->env);
158 item->state = state;
159 item->IncStrongRef(nullptr);
160
161 auto task = [item]() {
162 FI_HILOGI("Execute lamdba");
163 CallDragMsg(item);
164 };
165 if (napi_status::napi_ok != napi_send_event(item->env, task, napi_eprio_immediate)) {
166 FI_HILOGE("Failed to SendEvent");
167 }
168 }
169 }
170
CallDragMsg(sptr<CallbackInfo> cb)171 void JsDragManager::CallDragMsg(sptr<CallbackInfo> cb)
172 {
173 CALL_DEBUG_ENTER;
174 if (cb == nullptr) {
175 FI_HILOGE("Check data is nullptr");
176 return;
177 }
178 std::lock_guard<std::mutex> guard(mutex_);
179 if (listeners_.empty()) {
180 FI_HILOGE("The listener list is empty");
181 return;
182 }
183 for (const auto &item : listeners_) {
184 CHKPC(item->env);
185 if (item->ref != cb->ref) {
186 continue;
187 }
188 napi_handle_scope scope = nullptr;
189 napi_open_handle_scope(item->env, &scope);
190 CHKPC(scope);
191 napi_value stateMsg = nullptr;
192 CHKRV_SCOPE(item->env, napi_create_int32(item->env, static_cast<int32_t>(item->state), &stateMsg),
193 CREATE_INT32, scope);
194 napi_value handler = nullptr;
195 CHKRV_SCOPE(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE, scope);
196 napi_value ret = nullptr;
197 CHKRV_SCOPE(item->env,
198 napi_call_function(item->env, nullptr, handler, 1, &stateMsg, &ret), CALL_FUNCTION, scope);
199 napi_close_handle_scope(item->env, scope);
200 }
201 }
202 } // namespace DeviceStatus
203 } // namespace Msdp
204 } // namespace OHOS
205