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