• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_context.h"
17 
18 #include "devicestatus_define.h"
19 #include "drag_data.h"
20 #include "napi_constants.h"
21 #include "util_napi_error.h"
22 
23 namespace OHOS {
24 namespace Msdp {
25 namespace DeviceStatus {
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "JsDragContext" };
28 const char* DRAG_CLASS { "drag_class" };
29 const char* DRAG { "drag" };
30 inline constexpr size_t MAX_STRING_LEN { 1024 };
31 } // namespace
32 
JsDragContext()33 JsDragContext::JsDragContext()
34     : mgr_(std::make_shared<JsDragManager>()) {}
35 
~JsDragContext()36 JsDragContext::~JsDragContext()
37 {
38     std::lock_guard<std::mutex> guard(mutex_);
39     if (mgr_ != nullptr) {
40         mgr_->ResetEnv();
41         mgr_ = nullptr;
42     }
43 }
44 
GetJsDragMgr()45 std::shared_ptr<JsDragManager> JsDragContext::GetJsDragMgr()
46 {
47     std::lock_guard<std::mutex> guard(mutex_);
48     return mgr_;
49 }
50 
CreateInstance(napi_env env)51 napi_value JsDragContext::CreateInstance(napi_env env)
52 {
53     CALL_INFO_TRACE;
54     napi_value global = nullptr;
55     CHKRP(napi_get_global(env, &global), GET_GLOBAL);
56 
57     constexpr char className[] = "JsDragContext";
58     napi_value jsClass = nullptr;
59     napi_property_descriptor desc[] = {};
60     napi_status status = napi_define_class(env, className, sizeof(className),
61         JsDragContext::JsConstructor, nullptr, sizeof(desc) / sizeof(desc[0]), nullptr, &jsClass);
62     CHKRP(status, DEFINE_CLASS);
63 
64     status = napi_set_named_property(env, global, DRAG_CLASS, jsClass);
65     CHKRP(status, SET_NAMED_PROPERTY);
66 
67     napi_value jsInstance = nullptr;
68     CHKRP(napi_new_instance(env, jsClass, 0, nullptr, &jsInstance), NEW_INSTANCE);
69     CHKRP(napi_set_named_property(env, global, DRAG, jsInstance),
70         SET_NAMED_PROPERTY);
71 
72     JsDragContext *jsContext = nullptr;
73     CHKRP(napi_unwrap(env, jsInstance, reinterpret_cast<void**>(&jsContext)), UNWRAP);
74     CHKPP(jsContext);
75     CHKRP(napi_create_reference(env, jsInstance, 1, &(jsContext->contextRef_)), CREATE_REFERENCE);
76 
77     uint32_t refCount = 0;
78     status = napi_reference_ref(env, jsContext->contextRef_, &refCount);
79     if (status != napi_ok) {
80         FI_HILOGE("ref is nullptr");
81         napi_delete_reference(env, jsContext->contextRef_);
82         return nullptr;
83     }
84     return jsInstance;
85 }
86 
JsConstructor(napi_env env,napi_callback_info info)87 napi_value JsDragContext::JsConstructor(napi_env env, napi_callback_info info)
88 {
89     CALL_INFO_TRACE;
90     napi_value thisVar = nullptr;
91     void *data = nullptr;
92     CHKRP(napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data), GET_CB_INFO);
93 
94     JsDragContext *jsContext = new (std::nothrow) JsDragContext();
95     CHKPP(jsContext);
96     napi_status status = napi_wrap(env, thisVar, jsContext, [](napi_env env, void *data, void *hin) {
97         FI_HILOGI("Jsvm ends");
98         JsDragContext *context = static_cast<JsDragContext*>(data);
99         delete context;
100     }, nullptr, nullptr);
101     if (status != napi_ok) {
102         delete jsContext;
103         FI_HILOGE("%{public}s failed", std::string(WRAP).c_str());
104         auto errInfoTemp = std::string(__FUNCTION__) + ": " + std::string(WRAP) + " failed";
105         napi_throw_error(env, nullptr, errInfoTemp.c_str());
106         return nullptr;
107     }
108     return thisVar;
109 }
110 
GetInstance(napi_env env)111 JsDragContext *JsDragContext::GetInstance(napi_env env)
112 {
113     CALL_INFO_TRACE;
114     napi_value global = nullptr;
115     CHKRP(napi_get_global(env, &global), GET_GLOBAL);
116 
117     bool result = false;
118     CHKRP(napi_has_named_property(env, global, DRAG, &result), HAS_NAMED_PROPERTY);
119     if (!result) {
120         FI_HILOGE("Drag was not found");
121         return nullptr;
122     }
123 
124     napi_handle_scope scope = nullptr;
125     napi_open_handle_scope(env, &scope);
126     if (scope == nullptr) {
127         FI_HILOGE("scope is nullptr");
128         return nullptr;
129     }
130     napi_value object = nullptr;
131     CHKRP_SCOPE(env, napi_get_named_property(env, global, DRAG, &object), GET_NAMED_PROPERTY, scope);
132     if (object == nullptr) {
133         napi_close_handle_scope(env, scope);
134         FI_HILOGE("object is nullptr");
135         return nullptr;
136     }
137 
138     JsDragContext *instance = nullptr;
139     CHKRP_SCOPE(env, napi_unwrap(env, object, reinterpret_cast<void**>(&instance)), UNWRAP, scope);
140     if (instance == nullptr) {
141         napi_close_handle_scope(env, scope);
142         FI_HILOGE("instance is nullptr");
143         return nullptr;
144     }
145     napi_close_handle_scope(env, scope);
146     return instance;
147 }
148 
On(napi_env env,napi_callback_info info)149 napi_value JsDragContext::On(napi_env env, napi_callback_info info)
150 {
151     CALL_INFO_TRACE;
152     size_t argc = 2;
153     napi_value argv[2] = { nullptr };
154     CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
155     if (argc < 2) {
156         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Wrong number of parameters");
157         return nullptr;
158     }
159     JsDragContext *jsDev = JsDragContext::GetInstance(env);
160     CHKPP(jsDev);
161     auto jsDragMgr = jsDev->GetJsDragMgr();
162     CHKPP(jsDragMgr);
163     if (!UtilNapi::TypeOf(env, argv[0], napi_string)) {
164         THROWERR(env, COMMON_PARAMETER_ERROR, "type", "string");
165         return nullptr;
166     }
167     char type[MAX_STRING_LEN] = { 0 };
168     size_t strLength = 0;
169     CHKRP(napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &strLength), CREATE_STRING_UTF8);
170     if ((DRAG_TYPE.compare(type)) != 0) {
171         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Type must be drag");
172         return nullptr;
173     }
174     if (!UtilNapi::TypeOf(env, argv[1], napi_function)) {
175         THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
176         return nullptr;
177     }
178     jsDragMgr->RegisterListener(env, argv[1]);
179     return nullptr;
180 }
181 
Off(napi_env env,napi_callback_info info)182 napi_value JsDragContext::Off(napi_env env, napi_callback_info info)
183 {
184     CALL_INFO_TRACE;
185     size_t argc = 2;
186     napi_value argv[2] = { nullptr };
187     CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
188 
189     JsDragContext *jsDev = JsDragContext::GetInstance(env);
190     CHKPP(jsDev);
191     auto jsDragMgr = jsDev->GetJsDragMgr();
192     CHKPP(jsDragMgr);
193     if ((argc == 0) || (!UtilNapi::TypeOf(env, argv[0], napi_string))) {
194         THROWERR(env, COMMON_PARAMETER_ERROR, "type", "string");
195         return nullptr;
196     }
197     char type[MAX_STRING_LEN] = { 0 };
198     size_t length = 0;
199     CHKRP(napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &length), CREATE_STRING_UTF8);
200     if ((DRAG_TYPE.compare(type)) != 0) {
201         THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Type must be drag");
202         return nullptr;
203     }
204     if (argc == 1) {
205         jsDragMgr->UnregisterListener(env);
206         return nullptr;
207     }
208     if (UtilNapi::TypeOf(env, argv[1], napi_undefined) || UtilNapi::TypeOf(env, argv[1], napi_null)) {
209         jsDragMgr->UnregisterListener(env);
210         return nullptr;
211     }
212     if (!UtilNapi::TypeOf(env, argv[1], napi_function)) {
213         THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
214         return nullptr;
215     }
216     jsDragMgr->UnregisterListener(env, argv[1]);
217     return nullptr;
218 }
219 
GetDataSummary(napi_env env,napi_callback_info info)220 napi_value JsDragContext::GetDataSummary(napi_env env, napi_callback_info info)
221 {
222     CALL_INFO_TRACE;
223     JsDragContext *jsDev = JsDragContext::GetInstance(env);
224     CHKPP(jsDev);
225     auto jsDragMgr = jsDev->GetJsDragMgr();
226     CHKPP(jsDragMgr);
227     return jsDragMgr->GetDataSummary(env);
228 }
229 
DeclareDragData(napi_env env,napi_value exports)230 void JsDragContext::DeclareDragData(napi_env env, napi_value exports)
231 {
232     napi_value startMsg = nullptr;
233     CHKRV(napi_create_int32(env, static_cast<int32_t>(DragState::START), &startMsg),
234         CREATE_INT32);
235     napi_value stopMsg = nullptr;
236     CHKRV(napi_create_int32(env, static_cast<int32_t>(DragState::STOP), &stopMsg),
237         CREATE_INT32);
238     napi_value cancelMsg = nullptr;
239     CHKRV(napi_create_int32(env, static_cast<int32_t>(DragState::CANCEL), &cancelMsg),
240         CREATE_INT32);
241 
242     napi_property_descriptor msg[] = {
243         DECLARE_NAPI_STATIC_PROPERTY("MSG_DRAG_STATE_START", startMsg),
244         DECLARE_NAPI_STATIC_PROPERTY("MSG_DRAG_STATE_STOP", stopMsg),
245         DECLARE_NAPI_STATIC_PROPERTY("MSG_DRAG_STATE_CANCEL", cancelMsg)
246     };
247 
248     napi_value eventMsg = nullptr;
249     CHKRV(napi_define_class(env, "DragState", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr,
250         sizeof(msg) / sizeof(*msg), msg, &eventMsg), DEFINE_CLASS);
251     CHKRV(napi_set_named_property(env, exports, "DragState", eventMsg), SET_NAMED_PROPERTY);
252 }
253 
DeclareDragInterface(napi_env env,napi_value exports)254 void JsDragContext::DeclareDragInterface(napi_env env, napi_value exports)
255 {
256     napi_property_descriptor functions[] = {
257         DECLARE_NAPI_STATIC_FUNCTION("on", On),
258         DECLARE_NAPI_STATIC_FUNCTION("off", Off),
259         DECLARE_NAPI_STATIC_FUNCTION("getDataSummary", GetDataSummary)
260     };
261     CHKRV(napi_define_properties(env, exports,
262         sizeof(functions) / sizeof(*functions), functions), DEFINE_PROPERTIES);
263 }
264 
EnumClassConstructor(napi_env env,napi_callback_info info)265 napi_value JsDragContext::EnumClassConstructor(napi_env env, napi_callback_info info)
266 {
267     size_t argc = 0;
268     napi_value args[1] = { nullptr };
269     napi_value result = nullptr;
270     void *data = nullptr;
271     CHKRP(napi_get_cb_info(env, info, &argc, args, &result, &data), GET_CB_INFO);
272     return result;
273 }
274 
Export(napi_env env,napi_value exports)275 napi_value JsDragContext::Export(napi_env env, napi_value exports)
276 {
277     CALL_INFO_TRACE;
278     auto instance = CreateInstance(env);
279     CHKPP(instance);
280     DeclareDragData(env, exports);
281     DeclareDragInterface(env, exports);
282     return exports;
283 }
284 } // namespace DeviceStatus
285 } // namespace Msdp
286 } // namespace OHOS
287