• 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     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