1 /*
2 * Copyright (c) 2022-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_coordination_context.h"
17
18 #include "devicestatus_define.h"
19 #include "napi_constants.h"
20 #include "util_napi_error.h"
21 #include "utility.h"
22
23 #undef LOG_TAG
24 #define LOG_TAG "JsCoordinationContext"
25
26 namespace OHOS {
27 namespace Msdp {
28 namespace DeviceStatus {
29 namespace {
30 const char* COORDINATION_CLASS { "Coordination_class" };
31 const char* COORDINATION { "Coordination" };
32 inline constexpr std::string_view GET_VALUE_BOOL { "napi_get_value_bool" };
33 inline constexpr std::string_view GET_VALUE_INT32 { "napi_get_value_int32" };
34 inline constexpr std::string_view GET_VALUE_STRING_UTF8 { "napi_get_value_string_utf8" };
35 inline constexpr size_t MAX_STRING_LEN { 1024 };
36 inline constexpr size_t MAX_ARGC { 3 };
37 inline constexpr size_t ARGV_TWO { 2 };
38 } // namespace
39
JsCoordinationContext()40 JsCoordinationContext::JsCoordinationContext()
41 : mgr_(std::make_shared<JsCoordinationManager>()) {}
42
~JsCoordinationContext()43 JsCoordinationContext::~JsCoordinationContext()
44 {
45 std::lock_guard<std::mutex> guard(mutex_);
46 auto jsCoordinationMgr = mgr_;
47 mgr_.reset();
48 if (jsCoordinationMgr != nullptr) {
49 jsCoordinationMgr->ResetEnv();
50 }
51 }
52
Export(napi_env env,napi_value exports)53 napi_value JsCoordinationContext::Export(napi_env env, napi_value exports)
54 {
55 CALL_INFO_TRACE;
56 auto instance = CreateInstance(env);
57 CHKPP(instance);
58 DeclareDeviceCoordinationInterface(env, exports);
59 DeclareDeviceCoordinationData(env, exports);
60 DeclareDeviceCooperateData(env, exports);
61 return exports;
62 }
63
Prepare(napi_env env,napi_callback_info info)64 napi_value JsCoordinationContext::Prepare(napi_env env, napi_callback_info info)
65 {
66 CALL_INFO_TRACE;
67 return PrepareCompatible(env, info);
68 }
69
PrepareCooperate(napi_env env,napi_callback_info info)70 napi_value JsCoordinationContext::PrepareCooperate(napi_env env, napi_callback_info info)
71 {
72 CALL_INFO_TRACE;
73 return PrepareCompatible(env, info, true);
74 }
75
PrepareCompatible(napi_env env,napi_callback_info info,bool isCompatible)76 napi_value JsCoordinationContext::PrepareCompatible(napi_env env, napi_callback_info info, bool isCompatible)
77 {
78 size_t argc = 1;
79 napi_value argv[1] = { nullptr };
80 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
81
82 JsCoordinationContext *jsDev = JsCoordinationContext::GetInstance(env);
83 CHKPP(jsDev);
84 std::shared_ptr<JsCoordinationManager> jsCoordinationMgr = jsDev->GetJsCoordinationMgr();
85 CHKPP(jsCoordinationMgr);
86 if (argc == 0) {
87 return jsCoordinationMgr->Prepare(env, isCompatible);
88 }
89 if (!UtilNapi::TypeOf(env, argv[0], napi_function)) {
90 THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
91 return nullptr;
92 }
93 return jsCoordinationMgr->Prepare(env, isCompatible, argv[0]);
94 }
95
Unprepare(napi_env env,napi_callback_info info)96 napi_value JsCoordinationContext::Unprepare(napi_env env, napi_callback_info info)
97 {
98 CALL_INFO_TRACE;
99 return UnprepareCompatible(env, info);
100 }
101
UnprepareCooperate(napi_env env,napi_callback_info info)102 napi_value JsCoordinationContext::UnprepareCooperate(napi_env env, napi_callback_info info)
103 {
104 CALL_INFO_TRACE;
105 return UnprepareCompatible(env, info, true);
106 }
107
UnprepareCompatible(napi_env env,napi_callback_info info,bool isCompatible)108 napi_value JsCoordinationContext::UnprepareCompatible(napi_env env, napi_callback_info info, bool isCompatible)
109 {
110 size_t argc = 1;
111 napi_value argv[1] = { nullptr };
112 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
113
114 JsCoordinationContext *jsDev = JsCoordinationContext::GetInstance(env);
115 CHKPP(jsDev);
116 std::shared_ptr<JsCoordinationManager> jsCoordinationMgr = jsDev->GetJsCoordinationMgr();
117 CHKPP(jsCoordinationMgr);
118 if (argc == 0) {
119 return jsCoordinationMgr->Unprepare(env, isCompatible);
120 }
121 if (!UtilNapi::TypeOf(env, argv[0], napi_function)) {
122 THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
123 return nullptr;
124 }
125 return jsCoordinationMgr->Unprepare(env, isCompatible, argv[0]);
126 }
127
Activate(napi_env env,napi_callback_info info)128 napi_value JsCoordinationContext::Activate(napi_env env, napi_callback_info info)
129 {
130 CALL_INFO_TRACE;
131 return ActivateCompatible(env, info);
132 }
133
ActivateCooperate(napi_env env,napi_callback_info info)134 napi_value JsCoordinationContext::ActivateCooperate(napi_env env, napi_callback_info info)
135 {
136 CALL_INFO_TRACE;
137 return ActivateCompatible(env, info, true);
138 }
139
ActivateCompatible(napi_env env,napi_callback_info info,bool isCompatible)140 napi_value JsCoordinationContext::ActivateCompatible(napi_env env, napi_callback_info info, bool isCompatible)
141 {
142 size_t argc = 3;
143 napi_value argv[3] = { nullptr };
144 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
145
146 if (argc < 2) {
147 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Wrong number of parameters");
148 return nullptr;
149 }
150 if (!UtilNapi::TypeOf(env, argv[0], napi_string)) {
151 THROWERR(env, COMMON_PARAMETER_ERROR, "targetNetworkId", "string");
152 return nullptr;
153 }
154 if (!UtilNapi::TypeOf(env, argv[1], napi_number)) {
155 THROWERR(env, COMMON_PARAMETER_ERROR, "inputDeviceId", "number");
156 return nullptr;
157 }
158 char remoteNetworkId[MAX_STRING_LEN] = { 0 };
159 int32_t startDeviceId = 0;
160 size_t length = 0;
161 CHKRP(napi_get_value_string_utf8(env, argv[0], remoteNetworkId,
162 sizeof(remoteNetworkId), &length), GET_VALUE_STRING_UTF8);
163 CHKRP(napi_get_value_int32(env, argv[1], &startDeviceId), GET_VALUE_INT32);
164
165 JsCoordinationContext *jsDev = JsCoordinationContext::GetInstance(env);
166 CHKPP(jsDev);
167 std::shared_ptr<JsCoordinationManager> jsCoordinationMgr = jsDev->GetJsCoordinationMgr();
168 CHKPP(jsCoordinationMgr);
169 if (argc == 2) {
170 return jsCoordinationMgr->Activate(env, remoteNetworkId, startDeviceId, isCompatible);
171 }
172 if (!UtilNapi::TypeOf(env, argv[2], napi_function)) {
173 THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
174 return nullptr;
175 }
176 return jsCoordinationMgr->Activate(env, std::string(remoteNetworkId), startDeviceId, isCompatible, argv[2]);
177 }
178
GetCooperationsData(napi_env env,CooperateOptions & cooperateOptions,napi_value optionsHandle)179 CooperateOptions JsCoordinationContext::GetCooperationsData(napi_env env, CooperateOptions &cooperateOptions,
180 napi_value optionsHandle)
181 {
182 cooperateOptions.displayX = JsUtil::GetNamePropertyInt32(env, optionsHandle, "displayX");
183 cooperateOptions.displayY = JsUtil::GetNamePropertyInt32(env, optionsHandle, "displayY");
184 cooperateOptions.displayId = JsUtil::GetNamePropertyInt32(env, optionsHandle, "displayId");
185 FI_HILOGI("Start cooperate,displayX:%{private}d,displayY:%{private}d,displayId:%{public}d",
186 cooperateOptions.displayX, cooperateOptions.displayY, cooperateOptions.displayId);
187 return cooperateOptions;
188 }
189
ActivateCooperateWithOptions(napi_env env,napi_callback_info info)190 napi_value JsCoordinationContext::ActivateCooperateWithOptions(napi_env env, napi_callback_info info)
191 {
192 size_t argc = MAX_ARGC;
193 napi_value argv[3] = { nullptr };
194 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
195
196 if (argc < MAX_ARGC) {
197 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Wrong number of parameters");
198 return nullptr;
199 }
200 if (!UtilNapi::TypeOf(env, argv[0], napi_string)) {
201 THROWERR(env, COMMON_PARAMETER_ERROR, "targetNetworkId", "string");
202 return nullptr;
203 }
204 if (!UtilNapi::TypeOf(env, argv[1], napi_number)) {
205 THROWERR(env, COMMON_PARAMETER_ERROR, "inputDeviceId", "number");
206 return nullptr;
207 }
208 char remoteNetworkId[MAX_STRING_LEN] = { 0 };
209 int32_t startDeviceId = 0;
210 size_t length = 0;
211 CHKRP(napi_get_value_string_utf8(env, argv[0], remoteNetworkId, sizeof(remoteNetworkId), &length),
212 GET_VALUE_STRING_UTF8);
213 CHKRP(napi_get_value_int32(env, argv[1], &startDeviceId), GET_VALUE_INT32);
214 JsCoordinationContext *jsDev = JsCoordinationContext::GetInstance(env);
215 CHKPP(jsDev);
216 std::shared_ptr<JsCoordinationManager> jsCoordinationMgr = jsDev->GetJsCoordinationMgr();
217 CHKPP(jsCoordinationMgr);
218 if (!UtilNapi::TypeOf(env, argv[ARGV_TWO], napi_object)) {
219 FI_HILOGI("CooperateOptions is not assigned, call ActivateCooperate");
220 return jsCoordinationMgr->Activate(env, remoteNetworkId, startDeviceId, true);
221 }
222 CooperateOptions cooperateOptions = GetCooperationsData(env, cooperateOptions, argv[2]);
223 return jsCoordinationMgr->ActivateCooperateWithOptions(env, remoteNetworkId, startDeviceId, cooperateOptions);
224 }
225
Deactivate(napi_env env,napi_callback_info info)226 napi_value JsCoordinationContext::Deactivate(napi_env env, napi_callback_info info)
227 {
228 CALL_INFO_TRACE;
229 return DeactivateCompatible(env, info);
230 }
231
DeactivateCooperate(napi_env env,napi_callback_info info)232 napi_value JsCoordinationContext::DeactivateCooperate(napi_env env, napi_callback_info info)
233 {
234 CALL_INFO_TRACE;
235 return DeactivateCompatible(env, info, true);
236 }
237
DeactivateCompatible(napi_env env,napi_callback_info info,bool isCompatible)238 napi_value JsCoordinationContext::DeactivateCompatible(napi_env env, napi_callback_info info, bool isCompatible)
239 {
240 size_t argc = 2;
241 napi_value argv[2] = { nullptr };
242 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
243
244 if (argc == 0) {
245 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Wrong number of parameters");
246 return nullptr;
247 }
248 if (!UtilNapi::TypeOf(env, argv[0], napi_boolean)) {
249 THROWERR(env, COMMON_PARAMETER_ERROR, "isUnchained", "boolean");
250 return nullptr;
251 }
252 bool isUnchained = false;
253 CHKRP(napi_get_value_bool(env, argv[0], &isUnchained), GET_VALUE_BOOL);
254
255 JsCoordinationContext *jsDev = JsCoordinationContext::GetInstance(env);
256 CHKPP(jsDev);
257 std::shared_ptr<JsCoordinationManager> jsCoordinationMgr = jsDev->GetJsCoordinationMgr();
258 CHKPP(jsCoordinationMgr);
259 if (argc == 1) {
260 return jsCoordinationMgr->Deactivate(env, isUnchained, isCompatible);
261 }
262 if (!UtilNapi::TypeOf(env, argv[1], napi_function)) {
263 THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
264 return nullptr;
265 }
266 return jsCoordinationMgr->Deactivate(env, isUnchained, isCompatible, argv[1]);
267 }
268
GetCrossingSwitchState(napi_env env,napi_callback_info info)269 napi_value JsCoordinationContext::GetCrossingSwitchState(napi_env env, napi_callback_info info)
270 {
271 CALL_INFO_TRACE;
272 return GetCrossingSwitchStateCompatible(env, info);
273 }
274
GetCooperateSwitchState(napi_env env,napi_callback_info info)275 napi_value JsCoordinationContext::GetCooperateSwitchState(napi_env env, napi_callback_info info)
276 {
277 CALL_INFO_TRACE;
278 return GetCrossingSwitchStateCompatible(env, info, true);
279 }
280
GetCrossingSwitchStateCompatible(napi_env env,napi_callback_info info,bool isCompatible)281 napi_value JsCoordinationContext::GetCrossingSwitchStateCompatible(napi_env env,
282 napi_callback_info info, bool isCompatible)
283 {
284 size_t argc = 2;
285 napi_value argv[2] = { nullptr };
286 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
287
288 if (argc == 0) {
289 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Incorrect parameter count");
290 return nullptr;
291 }
292 if (!UtilNapi::TypeOf(env, argv[0], napi_string)) {
293 THROWERR(env, COMMON_PARAMETER_ERROR, "networkId", "string");
294 return nullptr;
295 }
296 char networkId[MAX_STRING_LEN] = { 0 };
297 size_t length = 0;
298 CHKRP(napi_get_value_string_utf8(env, argv[0], networkId,
299 sizeof(networkId), &length), GET_VALUE_STRING_UTF8);
300 std::string networkIdTemp = networkId;
301
302 JsCoordinationContext *jsDev = JsCoordinationContext::GetInstance(env);
303 CHKPP(jsDev);
304 std::shared_ptr<JsCoordinationManager> jsCoordinationMgr = jsDev->GetJsCoordinationMgr();
305 CHKPP(jsCoordinationMgr);
306 if (argc == 1) {
307 return jsCoordinationMgr->GetCrossingSwitchState(env, networkIdTemp, isCompatible);
308 }
309 if (!UtilNapi::TypeOf(env, argv[1], napi_function)) {
310 THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
311 return nullptr;
312 }
313 return jsCoordinationMgr->GetCrossingSwitchState(env, networkIdTemp, isCompatible, argv[1]);
314 }
315
On(napi_env env,napi_callback_info info)316 napi_value JsCoordinationContext::On(napi_env env, napi_callback_info info)
317 {
318 CALL_INFO_TRACE;
319 size_t argc = 1;
320 napi_value argv[1] = { nullptr };
321 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
322
323 if (argc < 1) {
324 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Parameter mismatch error");
325 return nullptr;
326 }
327 if (!UtilNapi::TypeOf(env, argv[0], napi_string)) {
328 THROWERR(env, COMMON_PARAMETER_ERROR, "type", "string");
329 return nullptr;
330 }
331
332 char type[MAX_STRING_LEN] = { 0 };
333 size_t length = 0;
334 CHKRP(napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &length), GET_VALUE_STRING_UTF8);
335
336 if ((COOPERATE_NAME.compare(type)) == 0 || (COOPERATE_MESSAGE_NAME.compare(type)) == 0) {
337 return RegisterCooperateListener(env, type, info);
338 }
339 if ((COOPERATE_MOUSE_NAME.compare(type)) == 0) {
340 return RegisterMouseListener(env, info);
341 }
342 FI_HILOGE("Unknow type:%{public}s", std::string(type).c_str());
343 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Type must be cooperate, cooperateMessage or cooperateMouse");
344 return nullptr;
345 }
346
Off(napi_env env,napi_callback_info info)347 napi_value JsCoordinationContext::Off(napi_env env, napi_callback_info info)
348 {
349 CALL_INFO_TRACE;
350 napi_value argv[1] = { nullptr };
351 size_t argc = 1;
352 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
353 if (argc < 1) {
354 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Wrong number of parameters");
355 return nullptr;
356 }
357 if (!UtilNapi::TypeOf(env, argv[0], napi_string)) {
358 THROWERR(env, COMMON_PARAMETER_ERROR, "type", "string");
359 return nullptr;
360 }
361 size_t length = 0;
362 char type[MAX_STRING_LEN] = { 0 };
363 CHKRP(napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &length), GET_VALUE_STRING_UTF8);
364
365 if ((COOPERATE_NAME.compare(type)) == 0 || (COOPERATE_MESSAGE_NAME.compare(type)) == 0) {
366 return UnregisterCooperateListener(env, type, info);
367 }
368 if ((COOPERATE_MOUSE_NAME.compare(type)) == 0) {
369 return UnregisterMouseListener(env, info);
370 }
371 FI_HILOGE("Unknow type:%{public}s", std::string(type).c_str());
372 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Type must be cooperate, cooperateMessage or cooperateMouse");
373 return nullptr;
374 }
375
RegisterCooperateListener(napi_env env,const std::string & type,napi_callback_info info)376 napi_value JsCoordinationContext::RegisterCooperateListener(
377 napi_env env, const std::string &type, napi_callback_info info)
378 {
379 CALL_INFO_TRACE;
380 size_t argc = 2;
381 napi_value argv[2] = { nullptr };
382 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
383 if (argc < 2) {
384 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Wrong number of parameters");
385 return nullptr;
386 }
387 JsCoordinationContext *jsDev = JsCoordinationContext::GetInstance(env);
388 CHKPP(jsDev);
389 std::shared_ptr<JsCoordinationManager> jsCoordinationMgr = jsDev->GetJsCoordinationMgr();
390 CHKPP(jsCoordinationMgr);
391 if (!UtilNapi::TypeOf(env, argv[1], napi_function)) {
392 THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
393 return nullptr;
394 }
395 jsCoordinationMgr->RegisterListener(env, type, argv[1]);
396 return nullptr;
397 }
398
UnregisterCooperateListener(napi_env env,const std::string & type,napi_callback_info info)399 napi_value JsCoordinationContext::UnregisterCooperateListener(
400 napi_env env, const std::string &type, napi_callback_info info)
401 {
402 CALL_INFO_TRACE;
403 size_t argc = 2;
404 napi_value argv[2] = { nullptr };
405 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
406 if (argc < 1) {
407 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Wrong number of parameters");
408 return nullptr;
409 }
410 JsCoordinationContext *jsDev = JsCoordinationContext::GetInstance(env);
411 CHKPP(jsDev);
412 std::shared_ptr<JsCoordinationManager> jsCoordinationMgr = jsDev->GetJsCoordinationMgr();
413 CHKPP(jsCoordinationMgr);
414 if (argc < 2) {
415 jsCoordinationMgr->UnregisterListener(env, type);
416 return nullptr;
417 }
418 if (UtilNapi::TypeOf(env, argv[1], napi_undefined) || UtilNapi::TypeOf(env, argv[1], napi_null)) {
419 FI_HILOGW("Undefined callback, unregister all listener of type:%{public}s", type.c_str());
420 jsCoordinationMgr->UnregisterListener(env, type);
421 return nullptr;
422 }
423 if (UtilNapi::TypeOf(env, argv[1], napi_function)) {
424 jsCoordinationMgr->UnregisterListener(env, type, argv[1]);
425 return nullptr;
426 }
427 THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
428 FI_HILOGE("UnregisterCooperateListener failed, invalid parameter");
429 return nullptr;
430 }
431
RegisterMouseListener(napi_env env,napi_callback_info info)432 napi_value JsCoordinationContext::RegisterMouseListener(napi_env env, napi_callback_info info)
433 {
434 CALL_INFO_TRACE;
435 size_t argc = 3;
436 napi_value argv[3] = { nullptr };
437 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
438 if (argc < 3) {
439 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Wrong number of parameters");
440 return nullptr;
441 }
442 char type[MAX_STRING_LEN] = { 0 };
443 size_t length = 0;
444 CHKRP(napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &length), GET_VALUE_STRING_UTF8);
445 if ((COOPERATE_MOUSE_NAME.compare(type)) != 0) {
446 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Type must be cooperateMouse");
447 return nullptr;
448 }
449
450 char networkId[MAX_STRING_LEN] = { 0 };
451 size_t len = 0;
452 CHKRP(napi_get_value_string_utf8(env, argv[1], networkId, sizeof(networkId), &len), GET_VALUE_STRING_UTF8);
453
454 if (!UtilNapi::TypeOf(env, argv[2], napi_function)) {
455 THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
456 return nullptr;
457 }
458
459 JsCoordinationContext *jsDev = JsCoordinationContext::GetInstance(env);
460 CHKPP(jsDev);
461 std::shared_ptr<JsCoordinationManager> jsCoordinationMgr = jsDev->GetJsCoordinationMgr();
462 CHKPP(jsCoordinationMgr);
463 jsCoordinationMgr->RegisterListener(env, type, networkId, argv[2]);
464 return nullptr;
465 }
466
UnregisterMouseListener(napi_env env,napi_callback_info info)467 napi_value JsCoordinationContext::UnregisterMouseListener(napi_env env, napi_callback_info info)
468 {
469 CALL_INFO_TRACE;
470 napi_value argv[3] = { nullptr };
471 size_t argc = 3;
472 CHKRP(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr), GET_CB_INFO);
473 if (argc < 2) {
474 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Wrong number of parameters");
475 return nullptr;
476 }
477 char type[MAX_STRING_LEN] = { 0 };
478 size_t length = 0;
479 CHKRP(napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &length), GET_VALUE_STRING_UTF8);
480 if ((COOPERATE_MOUSE_NAME.compare(type)) != 0) {
481 THROWERR_CUSTOM(env, COMMON_PARAMETER_ERROR, "Type must be cooperateMouse");
482 return nullptr;
483 }
484
485 char networkId[MAX_STRING_LEN] = { 0 };
486 size_t len = 0;
487 CHKRP(napi_get_value_string_utf8(env, argv[1], networkId, sizeof(networkId), &len), GET_VALUE_STRING_UTF8);
488
489 JsCoordinationContext *jsDev = JsCoordinationContext::GetInstance(env);
490 CHKPP(jsDev);
491 std::shared_ptr<JsCoordinationManager> jsCoordinationMgr = jsDev->GetJsCoordinationMgr();
492 CHKPP(jsCoordinationMgr);
493
494 if (argc == 2) {
495 jsCoordinationMgr->UnregisterListener(env, type, networkId);
496 return nullptr;
497 }
498 if (UtilNapi::TypeOf(env, argv[2], napi_undefined) || UtilNapi::TypeOf(env, argv[2], napi_null)) {
499 FI_HILOGW("Undefined callback, unregister all listener of networkId: %{public}s",
500 Utility::Anonymize(networkId).c_str());
501 jsCoordinationMgr->UnregisterListener(env, type, networkId);
502 return nullptr;
503 }
504 if (UtilNapi::TypeOf(env, argv[2], napi_function)) {
505 jsCoordinationMgr->UnregisterListener(env, type, networkId, argv[2]);
506 return nullptr;
507 }
508 THROWERR(env, COMMON_PARAMETER_ERROR, "callback", "function");
509 FI_HILOGE("UnregisterMouseListener failed, invalid parameter");
510 return nullptr;
511 }
512
GetJsCoordinationMgr()513 std::shared_ptr<JsCoordinationManager> JsCoordinationContext::GetJsCoordinationMgr()
514 {
515 std::lock_guard<std::mutex> guard(mutex_);
516 return mgr_;
517 }
518
CreateInstance(napi_env env)519 napi_value JsCoordinationContext::CreateInstance(napi_env env)
520 {
521 CALL_INFO_TRACE;
522 napi_value global = nullptr;
523 CHKRP(napi_get_global(env, &global), GET_GLOBAL);
524
525 constexpr char className[] = "JsCoordinationContext";
526 napi_value jsClass = nullptr;
527 napi_property_descriptor desc[] = {};
528 napi_status status = napi_define_class(env, className, sizeof(className),
529 JsCoordinationContext::JsConstructor, nullptr, sizeof(desc) / sizeof(desc[0]), nullptr, &jsClass);
530 CHKRP(status, DEFINE_CLASS);
531
532 status = napi_set_named_property(env, global, COORDINATION_CLASS, jsClass);
533 CHKRP(status, SET_NAMED_PROPERTY);
534
535 napi_value jsInstance = nullptr;
536 CHKRP(napi_new_instance(env, jsClass, 0, nullptr, &jsInstance), NEW_INSTANCE);
537 CHKRP(napi_set_named_property(env, global, COORDINATION, jsInstance),
538 SET_NAMED_PROPERTY);
539
540 JsCoordinationContext *jsContext = nullptr;
541 CHKRP(napi_unwrap(env, jsInstance, reinterpret_cast<void**>(&jsContext)), UNWRAP);
542 CHKPP(jsContext);
543 CHKRP(napi_create_reference(env, jsInstance, 1, &(jsContext->contextRef_)), CREATE_REFERENCE);
544
545 uint32_t refCount = 0;
546 status = napi_reference_ref(env, jsContext->contextRef_, &refCount);
547 if (status != napi_ok) {
548 FI_HILOGE("Reference to nullptr");
549 napi_delete_reference(env, jsContext->contextRef_);
550 return nullptr;
551 }
552 return jsInstance;
553 }
554
JsConstructor(napi_env env,napi_callback_info info)555 napi_value JsCoordinationContext::JsConstructor(napi_env env, napi_callback_info info)
556 {
557 CALL_INFO_TRACE;
558 napi_value thisVar = nullptr;
559 void *data = nullptr;
560 CHKRP(napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data), GET_CB_INFO);
561
562 JsCoordinationContext *jsContext = new (std::nothrow) JsCoordinationContext();
563 CHKPP(jsContext);
564 napi_status status = napi_wrap(env, thisVar, jsContext, [](napi_env env, void *data, void *hin) {
565 FI_HILOGI("Jsvm ends");
566 JsCoordinationContext *context = static_cast<JsCoordinationContext*>(data);
567 delete context;
568 }, nullptr, nullptr);
569 if (status != napi_ok) {
570 delete jsContext;
571 FI_HILOGE("%{public}s failed", std::string(WRAP).c_str());
572 auto infoTemp = std::string(__FUNCTION__) + ": " + std::string(WRAP) + " failed";
573 napi_throw_error(env, nullptr, infoTemp.c_str());
574 return nullptr;
575 }
576 return thisVar;
577 }
578
GetInstance(napi_env env)579 JsCoordinationContext *JsCoordinationContext::GetInstance(napi_env env)
580 {
581 CALL_INFO_TRACE;
582 napi_value napiGlobal = nullptr;
583 CHKRP(napi_get_global(env, &napiGlobal), GET_GLOBAL);
584
585 bool result = false;
586 CHKRP(napi_has_named_property(env, napiGlobal, COORDINATION, &result), HAS_NAMED_PROPERTY);
587 if (!result) {
588 FI_HILOGE("Coordination was not found");
589 return nullptr;
590 }
591
592 napi_handle_scope handleScope = nullptr;
593 napi_open_handle_scope(env, &handleScope);
594 CHKPP(handleScope);
595 napi_value object = nullptr;
596 CHKRP_SCOPE(env, napi_get_named_property(env, napiGlobal, COORDINATION, &object),
597 GET_NAMED_PROPERTY, handleScope);
598 if (object == nullptr) {
599 napi_close_handle_scope(env, handleScope);
600 FI_HILOGE("object is nullptr");
601 return nullptr;
602 }
603
604 JsCoordinationContext *instance = nullptr;
605 CHKRP_SCOPE(env, napi_unwrap(env, object, reinterpret_cast<void**>(&instance)), UNWRAP, handleScope);
606 if (instance == nullptr) {
607 napi_close_handle_scope(env, handleScope);
608 FI_HILOGE("instance is nullptr");
609 return nullptr;
610 }
611 napi_close_handle_scope(env, handleScope);
612 return instance;
613 }
614
DeclareDeviceCoordinationData(napi_env env,napi_value exports)615 void JsCoordinationContext::DeclareDeviceCoordinationData(napi_env env, napi_value exports)
616 {
617 napi_value prepare = nullptr;
618 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::PREPARE), &prepare),
619 CREATE_INT32);
620 napi_value unprepare = nullptr;
621 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::UNPREPARE), &unprepare),
622 CREATE_INT32);
623 napi_value activate = nullptr;
624 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::ACTIVATE), &activate),
625 CREATE_INT32);
626 napi_value activateSuccess = nullptr;
627 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::ACTIVATE_SUCCESS), &activateSuccess),
628 CREATE_INT32);
629 napi_value activateFail = nullptr;
630 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::ACTIVATE_FAIL), &activateFail),
631 CREATE_INT32);
632 napi_value deactivateSuccess = nullptr;
633 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::DEACTIVATE_SUCCESS), &deactivateSuccess),
634 CREATE_INT32);
635 napi_value deactivateFail = nullptr;
636 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::DEACTIVATE_FAIL), &deactivateFail),
637 CREATE_INT32);
638 napi_value sessionClosed = nullptr;
639 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::SESSION_CLOSED), &sessionClosed),
640 CREATE_INT32);
641
642 napi_property_descriptor msg[] = {
643 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_PREPARE", prepare),
644 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_UNPREPARE", unprepare),
645 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_ACTIVATE", activate),
646 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_ACTIVATE_SUCCESS", activateSuccess),
647 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_ACTIVATE_FAIL", activateFail),
648 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_DEACTIVATE_SUCCESS", deactivateSuccess),
649 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_DEACTIVATE_FAIL", deactivateFail),
650 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_SESSION_DISCONNECTED", sessionClosed)
651 };
652
653 napi_value cooperateMsg = nullptr;
654 CHKRV(napi_define_class(env, "CooperateMsg", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr,
655 sizeof(msg) / sizeof(*msg), msg, &cooperateMsg), DEFINE_CLASS);
656 CHKRV(napi_set_named_property(env, exports, "CooperateMsg", cooperateMsg), SET_NAMED_PROPERTY);
657 }
658
DeclareDeviceCooperateData(napi_env env,napi_value exports)659 void JsCoordinationContext::DeclareDeviceCooperateData(napi_env env, napi_value exports)
660 {
661 napi_value prepare = nullptr;
662 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::PREPARE), &prepare),
663 CREATE_INT32);
664 napi_value unprepare = nullptr;
665 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::UNPREPARE), &unprepare),
666 CREATE_INT32);
667 napi_value activate = nullptr;
668 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::ACTIVATE), &activate),
669 CREATE_INT32);
670 napi_value activateSuccess = nullptr;
671 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::ACTIVATE_SUCCESS), &activateSuccess),
672 CREATE_INT32);
673 napi_value activateFail = nullptr;
674 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::ACTIVATE_FAIL), &activateFail),
675 CREATE_INT32);
676 napi_value deactivateSuccess = nullptr;
677 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::DEACTIVATE_SUCCESS), &deactivateSuccess),
678 CREATE_INT32);
679 napi_value deactivateFail = nullptr;
680 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::DEACTIVATE_FAIL), &deactivateFail),
681 CREATE_INT32);
682 napi_value sessionClosed = nullptr;
683 CHKRV(napi_create_int32(env, static_cast<int32_t>(CoordinationMessage::SESSION_CLOSED), &sessionClosed),
684 CREATE_INT32);
685
686 napi_property_descriptor msg[] = {
687 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_PREPARE", prepare),
688 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_UNPREPARE", unprepare),
689 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_ACTIVATE", activate),
690 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_ACTIVATE_SUCCESS", activateSuccess),
691 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_ACTIVATE_FAILURE", activateFail),
692 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_DEACTIVATE_SUCCESS", deactivateSuccess),
693 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_DEACTIVATE_FAILURE", deactivateFail),
694 DECLARE_NAPI_STATIC_PROPERTY("COOPERATE_SESSION_DISCONNECTED", sessionClosed)
695 };
696
697 napi_value cooperateMsg = nullptr;
698 CHKRV(napi_define_class(env, "CooperateState", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr,
699 sizeof(msg) / sizeof(*msg), msg, &cooperateMsg), DEFINE_CLASS);
700 CHKRV(napi_set_named_property(env, exports, "CooperateState", cooperateMsg), SET_NAMED_PROPERTY);
701 }
702
DeclareDeviceCoordinationInterface(napi_env env,napi_value exports)703 void JsCoordinationContext::DeclareDeviceCoordinationInterface(napi_env env, napi_value exports)
704 {
705 napi_property_descriptor functions[] = {
706 DECLARE_NAPI_STATIC_FUNCTION("prepare", Prepare),
707 DECLARE_NAPI_STATIC_FUNCTION("prepareCooperate", PrepareCooperate),
708 DECLARE_NAPI_STATIC_FUNCTION("unprepare", Unprepare),
709 DECLARE_NAPI_STATIC_FUNCTION("unprepareCooperate", UnprepareCooperate),
710 DECLARE_NAPI_STATIC_FUNCTION("activate", Activate),
711 DECLARE_NAPI_STATIC_FUNCTION("activateCooperateWithOptions", ActivateCooperateWithOptions),
712 DECLARE_NAPI_STATIC_FUNCTION("activateCooperate", ActivateCooperate),
713 DECLARE_NAPI_STATIC_FUNCTION("deactivate", Deactivate),
714 DECLARE_NAPI_STATIC_FUNCTION("deactivateCooperate", DeactivateCooperate),
715 DECLARE_NAPI_STATIC_FUNCTION("getCrossingSwitchState", GetCrossingSwitchState),
716 DECLARE_NAPI_STATIC_FUNCTION("getCooperateSwitchState", GetCooperateSwitchState),
717 DECLARE_NAPI_STATIC_FUNCTION("on", On),
718 DECLARE_NAPI_STATIC_FUNCTION("off", Off)
719 };
720 CHKRV(napi_define_properties(env, exports,
721 sizeof(functions) / sizeof(*functions), functions), DEFINE_PROPERTIES);
722 }
723
EnumClassConstructor(napi_env env,napi_callback_info info)724 napi_value JsCoordinationContext::EnumClassConstructor(napi_env env, napi_callback_info info)
725 {
726 size_t argc = 0;
727 napi_value args[1] = { nullptr };
728 napi_value result = nullptr;
729 void *data = nullptr;
730 CHKRP(napi_get_cb_info(env, info, &argc, args, &result, &data), GET_CB_INFO);
731 return result;
732 }
733 } // namespace DeviceStatus
734 } // namespace Msdp
735 } // namespace OHOS
736