• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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