• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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_ability_connection_manager.h"
17 
18 #include <algorithm>
19 #include <memory>
20 #include <string>
21 #include <vector>
22 
23 #include "ability_connection_manager.h"
24 #include "app_event.h"
25 #include "app_event_processor_mgr.h"
26 #include "dtbcollabmgr_log.h"
27 #include "ipc_skeleton.h"
28 #include "js_runtime_utils.h"
29 #include "napi_common_util.h"
30 #include "napi_base_context.h"
31 #include "native_avcapability.h"
32 #include "native_avcodec_base.h"
33 #include "native_avformat.h"
34 #include "native_avcodec_videoencoder.h"
35 #include "native_avcodec_videodecoder.h"
36 #include "string_wrapper.h"
37 #include "tokenid_kit.h"
38 #include "ui_extension_context.h"
39 
40 namespace OHOS {
41 namespace DistributedCollab {
42 using namespace OHOS::AbilityRuntime;
43 using namespace OHOS::AppExecFwk;
44 using namespace OHOS::MediaAVCodec;
45 using namespace OHOS::HiviewDFX;
46 namespace {
47 #define GET_PARAMS(env, info, num)    \
48     size_t argc = num;                \
49     napi_value argv[num] = {nullptr}; \
50     napi_value thisVar = nullptr;     \
51     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr))
52 
53 const std::string TAG = "JsAbilityConnectionManager";
54 constexpr int32_t ARG_INDEX_ZERO = 0;
55 constexpr int32_t ARG_INDEX_ONE = 1;
56 constexpr int32_t ARG_INDEX_TWO = 2;
57 constexpr int32_t ARG_INDEX_THREE = 3;
58 constexpr int32_t ARG_COUNT_ONE = 1;
59 constexpr int32_t ARG_COUNT_TWO = 2;
60 constexpr int32_t ARG_COUNT_THREE = 3;
61 constexpr int32_t ARG_COUNT_FOUR = 4;
62 constexpr int32_t NAPI_BUF_LENGTH = 1024;
63 constexpr int32_t SOURCE = 0;
64 constexpr int32_t SINK = 1;
65 constexpr int32_t UNKNOWN = -1;
66 constexpr int32_t NV12 = 0;
67 constexpr int32_t NV21 = 1;
68 constexpr int32_t IMAGE_COMPRESSION_QUALITY = 30;
69 constexpr int32_t EVENT_RESULT_SUCCESS = 0;
70 constexpr int32_t EVENT_RESULT_FAIL = 1;
71 
72 const std::string EVENT_CONNECT = "connect";
73 const std::string EVENT_DISCONNECT = "disconnect";
74 const std::string EVENT_RECEIVE_MESSAGE = "receiveMessage";
75 const std::string EVENT_RECEIVE_DATA = "receiveData";
76 const std::string EVENT_RECEIVE_IMAGE = "receiveImage";
77 const std::string EVENT_COLLABORATE = "collaborateEvent";
78 const std::vector<std::string> REGISTER_EVENT_TYPES = {
79     EVENT_CONNECT, EVENT_DISCONNECT, EVENT_RECEIVE_MESSAGE, EVENT_RECEIVE_DATA,
80     EVENT_RECEIVE_IMAGE, EVENT_COLLABORATE
81 };
82 const std::vector<std::string> SYSTEM_APP_EVENT_TYPES = {
83     EVENT_RECEIVE_IMAGE, EVENT_COLLABORATE
84 };
85 
86 const std::string ERR_MESSAGE_NO_PERMISSION =
87     "Permission verification failed. The application does not have the permission required to call the API.";
88 const std::string ERR_MESSAGE_INVALID_PARAMS = "Parameter error.";
89 const std::string ERR_MESSAGE_FAILED = "Failed to execute the function.";
90 const std::string ERR_MESSAGE_ONE_STREAM = "Only one stream can be created for the current session.";
91 const std::string ERR_MESSAGE_RECEIVE_NOT_START = "The stream at the receive end is not started.";
92 const std::string ERR_MESSAGE_NOT_SUPPORTED_BITATE = "Bitrate not supported.";
93 const std::string ERR_MESSAGE_NOT_SUPPORTED_COLOR_SPACE = "Color space not supported.";
94 const std::string KEY_START_OPTION = "ohos.collabrate.key.start.option";
95 const std::string VALUE_START_OPTION_FOREGROUND = "ohos.collabrate.value.forefround";
96 const std::string VALUE_START_OPTION_BACKGROUND = "ohos.collabrate.value.background";
97 const std::string COLLABORATE_KEYS_PEER_INFO  = "ohos.collaboration.key.peerInfo";
98 const std::string COLLABORATE_KEYS_CONNECT_OPTIONS = "ohos.collaboration.key.connectOptions";
99 const std::string COLLABORATE_KEYS_COLLABORATE_TYPE = "ohos.collaboration.key.abilityCollaborateType";
100 const std::string ABILITY_COLLABORATION_TYPE_DEFAULT  = "ohos.collaboration.value.abilityCollab";
101 const std::string ABILITY_COLLABORATION_TYPE_CONNECT_PROXY = "ohos.collaboration.value.connectProxy";
102 }
103 
JsToInt32(const napi_env & env,const napi_value & value,const std::string & valueName,int32_t & strValue)104 bool JsAbilityConnectionManager::JsToInt32(const napi_env &env, const napi_value &value,
105     const std::string &valueName, int32_t &strValue)
106 {
107     HILOGD("called.");
108     napi_valuetype valueType = napi_undefined;
109     if (napi_typeof(env, value, &valueType) != napi_ok) {
110         HILOGE("Failed to get argument type");
111         return false;
112     }
113 
114     if (valueType != napi_number) {
115         HILOGE("Argument must be a number");
116         return false;
117     }
118 
119     if (napi_get_value_int32(env, value, &strValue) != napi_ok) {
120         HILOGE("Failed to get number value");
121         return false;
122     }
123     return true;
124 }
125 
JsToString(const napi_env & env,const napi_value & value,const std::string & valueName,std::string & strValue)126 bool JsAbilityConnectionManager::JsToString(const napi_env &env, const napi_value &value, const std::string &valueName,
127     std::string &strValue)
128 {
129     napi_valuetype valueType = napi_undefined;
130     if (napi_typeof(env, value, &valueType) != napi_ok) {
131         HILOGE("Failed to get argument type");
132         return false;
133     }
134 
135     if (valueType != napi_string) {
136         HILOGE("Argument must be a string");
137         return false;
138     }
139 
140     size_t valueLen = 0;
141     if (napi_get_value_string_utf8(env, value, nullptr, 0, &valueLen) != napi_ok) {
142         HILOGE("Failed to get string length");
143         return false;
144     }
145 
146     if (valueLen >= NAPI_BUF_LENGTH) {
147         HILOGE("string length mast < %{public}d", NAPI_BUF_LENGTH);
148         return false;
149     }
150 
151     std::vector<char> buf(NAPI_BUF_LENGTH, 0);
152     if (napi_get_value_string_utf8(env, value, buf.data(), valueLen + 1, &valueLen) != napi_ok) {
153         HILOGE("Failed to read string value");
154         return false;
155     }
156     strValue.assign(buf.begin(), buf.begin() + valueLen);
157     return true;
158 }
159 
JsObjectToString(const napi_env & env,const napi_value & object,const std::string & fieldStr,std::string & fieldRef)160 bool JsAbilityConnectionManager::JsObjectToString(const napi_env &env, const napi_value &object,
161     const std::string &fieldStr, std::string& fieldRef)
162 {
163     bool hasProperty = false;
164     if (napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty) != napi_ok) {
165         HILOGE("check object has named property failed.");
166         return false;
167     }
168 
169     if (!hasProperty) {
170         HILOGE("napi js to str no property: %{public}s", fieldStr.c_str());
171         return false;
172     }
173 
174     napi_value field = nullptr;
175     if (napi_get_named_property(env, object, fieldStr.c_str(), &field) != napi_ok) {
176         HILOGE("get property failed, property is %{public}s.", fieldStr.c_str());
177         return false;
178     }
179     return JsToString(env, field, fieldStr, fieldRef);
180 }
181 
JsObjectToBool(const napi_env & env,const napi_value & object,const std::string & fieldStr,bool & fieldRef)182 bool JsAbilityConnectionManager::JsObjectToBool(const napi_env &env, const napi_value &object,
183     const std::string &fieldStr, bool &fieldRef)
184 {
185     bool hasProperty = false;
186     if (napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty) != napi_ok) {
187         HILOGE("check object has named property failed.");
188         return false;
189     }
190 
191     if (!hasProperty) {
192         HILOGE("napi js to str no property: %{public}s", fieldStr.c_str());
193         return false;
194     }
195 
196     napi_value field = nullptr;
197     if (napi_get_named_property(env, object, fieldStr.c_str(), &field) != napi_ok) {
198         HILOGE("get property failed, property is %{public}s.", fieldStr.c_str());
199         return false;
200     }
201 
202     napi_valuetype valueType = napi_undefined;
203     if (napi_typeof(env, field, &valueType) != napi_ok) {
204         HILOGE("Failed to get argument type");
205         return false;
206     }
207 
208     if (valueType != napi_boolean) {
209         return false;
210     }
211 
212     if (napi_get_value_bool(env, field, &fieldRef) != napi_ok) {
213         HILOGE("Failed to read bool value");
214         return false;
215     }
216     return true;
217 }
218 
JsObjectToInt(const napi_env & env,const napi_value & object,const std::string & fieldStr,int32_t & fieldRef)219 bool JsAbilityConnectionManager::JsObjectToInt(const napi_env &env, const napi_value &object,
220     const std::string &fieldStr, int32_t &fieldRef)
221 {
222     bool hasProperty = false;
223     if (napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty) != napi_ok) {
224         HILOGE("check object has named property failed.");
225         return false;
226     }
227 
228     if (!hasProperty) {
229         HILOGE("napi js to str no property: %{public}s", fieldStr.c_str());
230         return false;
231     }
232 
233     napi_value field = nullptr;
234     if (napi_get_named_property(env, object, fieldStr.c_str(), &field) != napi_ok) {
235         HILOGE("get property failed, property is %{public}s.", fieldStr.c_str());
236         return false;
237     }
238     return JsToInt32(env, field, fieldStr, fieldRef);
239 }
240 
IsSystemApp()241 bool JsAbilityConnectionManager::IsSystemApp()
242 {
243     static bool isSystemApp = []() {
244         uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
245         return OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId);
246     }();
247     return isSystemApp;
248 }
249 
GenerateBusinessError(napi_env env,int32_t err,const std::string & msg)250 napi_value GenerateBusinessError(napi_env env,
251     int32_t err, const std::string &msg)
252 {
253     napi_value businessError = nullptr;
254     NAPI_CALL(env, napi_create_object(env, &businessError));
255     napi_value errorCode = nullptr;
256     NAPI_CALL(env, napi_create_int32(env, err, &errorCode));
257     napi_value errorMsg = nullptr;
258     NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), NAPI_AUTO_LENGTH, &errorMsg));
259     NAPI_CALL(env, napi_set_named_property(env, businessError, "code", errorCode));
260     NAPI_CALL(env, napi_set_named_property(env, businessError, "message", errorMsg));
261 
262     return businessError;
263 }
264 
CreateErrorForCall(napi_env env,int32_t code,const std::string & errMsg,bool isAsync=true)265 napi_value CreateErrorForCall(napi_env env, int32_t code, const std::string &errMsg, bool isAsync = true)
266 {
267     HILOGI("CreateErrorForCall code:%{public}d, message:%{public}s", code, errMsg.c_str());
268     napi_value error = nullptr;
269     if (isAsync) {
270         napi_throw_error(env, std::to_string(code).c_str(), errMsg.c_str());
271     } else {
272         error = GenerateBusinessError(env, code, errMsg);
273     }
274     return error;
275 }
276 
CreateBusinessError(napi_env env,int32_t errCode,bool isAsync=true)277 napi_value CreateBusinessError(napi_env env, int32_t errCode, bool isAsync = true)
278 {
279     napi_value error = nullptr;
280     switch (errCode) {
281         case ERR_IS_NOT_SYSTEM_APP:
282             error = CreateErrorForCall(env, static_cast<int32_t>(BussinessErrorCode::ERR_NOT_SYSTEM_APP),
283                 ERR_MESSAGE_NO_PERMISSION, isAsync);
284             break;
285         case ERR_INVALID_PARAMETERS:
286             error = CreateErrorForCall(env, static_cast<int32_t>(BussinessErrorCode::ERR_INVALID_PARAMS),
287                 ERR_MESSAGE_INVALID_PARAMS, isAsync);
288             break;
289         case ONLY_SUPPORT_ONE_STREAM:
290             error = CreateErrorForCall(env, static_cast<int32_t>(BussinessErrorCode::ERR_ONLY_SUPPORT_ONE_STREAM),
291                 ERR_MESSAGE_ONE_STREAM, isAsync);
292             break;
293         case RECEIVE_STREAM_NOT_START:
294             error = CreateErrorForCall(env, static_cast<int32_t>(BussinessErrorCode::ERR_RECEIVE_STREAM_NOT_START),
295                 ERR_MESSAGE_RECEIVE_NOT_START, isAsync);
296             break;
297         case NOT_SUPPORTED_BITATE:
298             error = CreateErrorForCall(env, static_cast<int32_t>(BussinessErrorCode::ERR_BITATE_NOT_SUPPORTED),
299                 ERR_MESSAGE_NOT_SUPPORTED_BITATE, isAsync);
300             break;
301         case NOT_SUPPORTED_COLOR_SPACE:
302             error = CreateErrorForCall(env, static_cast<int32_t>(BussinessErrorCode::ERR_COLOR_SPACE_NOT_SUPPORTED),
303                 ERR_MESSAGE_NOT_SUPPORTED_COLOR_SPACE, isAsync);
304             break;
305         case ERR_EXECUTE_FUNCTION:
306             error = CreateErrorForCall(env, static_cast<int32_t>(BussinessErrorCode::ERR_INVALID_PARAMS),
307                 ERR_MESSAGE_FAILED, isAsync);
308             break;
309         case COLLAB_PERMISSION_DENIED:
310             error = CreateErrorForCall(env, static_cast<int32_t>(BussinessErrorCode::ERR_INVALID_PERMISSION),
311                 ERR_MESSAGE_NO_PERMISSION, isAsync);
312             break;
313         case INVALID_PARAMETERS_ERR:
314             error = CreateErrorForCall(env, static_cast<int32_t>(BussinessErrorCode::ERR_INVALID_PARAMS),
315                 ERR_MESSAGE_INVALID_PARAMS, isAsync);
316             break;
317         default:
318             error = CreateErrorForCall(env, static_cast<int32_t>(BussinessErrorCode::ERR_INVALID_PARAMS),
319                 ERR_MESSAGE_FAILED, isAsync);
320             break;
321     }
322     return error;
323 }
324 
CreateAbilityConnectionSession(napi_env env,napi_callback_info info)325 napi_value JsAbilityConnectionManager::CreateAbilityConnectionSession(napi_env env, napi_callback_info info)
326 {
327     HILOGI("called.");
328     GET_PARAMS(env, info, ARG_COUNT_FOUR);
329     napi_value result = nullptr;
330     if (argc != ARG_COUNT_FOUR) {
331         HILOGE("CheckArgsCount failed.");
332         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
333         return result;
334     }
335 
336     std::string serviceName = "";
337     if (!JsToServiceName(env, argv[ARG_INDEX_ZERO], serviceName)) {
338         HILOGE("Failed to unwrap service name/id");
339         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
340         return result;
341     }
342 
343     std::shared_ptr<AbilityInfo> abilityInfo = nullptr;
344     if (!JsToAbilityInfo(env, argv[ARG_INDEX_ONE], abilityInfo)) {
345         HILOGE("Failed to unwrap abilityInfo.");
346         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
347         return result;
348     }
349 
350     PeerInfo peerInfo;
351     if (!JsToPeerInfo(env, argv[ARG_INDEX_TWO], peerInfo)) {
352         HILOGE("Failed to unwrap PeerInfo.");
353         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
354         return result;
355     }
356     if (peerInfo.serverId.empty()) {
357         peerInfo.serverId = serviceName;
358         peerInfo.serviceName = serviceName;
359     }
360 
361     ConnectOption connectOption;
362     int32_t ret = JSToConnectOption(env, argv[ARG_INDEX_THREE], connectOption);
363     if (ret != ERR_OK) {
364         HILOGE("Failed to unwrap ConnectOption.");
365         CreateBusinessError(env, ret);
366         return result;
367     }
368 
369     return ExecuteCreateSession(serviceName, abilityInfo, peerInfo, connectOption, env);
370 }
371 
ExecuteCreateSession(const std::string & serviceName,std::shared_ptr<AbilityInfo> & abilityInfo,PeerInfo & peerInfo,ConnectOption & connectOption,const napi_env & env)372 napi_value JsAbilityConnectionManager::ExecuteCreateSession(
373     const std::string& serviceName, std::shared_ptr<AbilityInfo>& abilityInfo,
374     PeerInfo& peerInfo, ConnectOption& connectOption, const napi_env& env)
375 {
376     napi_value result = nullptr;
377     int32_t sessionId = -1;
378     int32_t ret = AbilityConnectionManager::GetInstance().CreateSession(
379         serviceName, abilityInfo, peerInfo, connectOption, sessionId);
380     if (ret == COLLAB_PERMISSION_DENIED || ret == INVALID_PARAMETERS_ERR) {
381         HILOGE("create session failed due to param or permission valid");
382         CreateBusinessError(env, ret);
383         return result;
384     } else if (ret != ERR_OK) {
385         HILOGE("create session failed due to function err");
386         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
387         return result;
388     }
389     NAPI_CALL(env, napi_create_int32(env, sessionId, &result));
390     return result;
391 }
392 
JsToServiceName(const napi_env & env,const napi_value & jsValue,std::string & serviceName)393 bool JsAbilityConnectionManager::JsToServiceName(const napi_env &env, const napi_value &jsValue,
394     std::string& serviceName)
395 {
396     HILOGI("parse serviceName");
397     // no serviceName
398     if (!JsToString(env, jsValue, "serviceName", serviceName)) {
399         HILOGW("Failed to unwrap serviceName.");
400     } else {
401         return true;
402     }
403     // neither exist
404     if (!JsToString(env, jsValue, "serverId", serviceName)) {
405         HILOGE("Failed to unwrap serverId and serviceName.");
406         return false;
407     }
408     return true;
409 }
410 
JsToAbilityInfo(const napi_env & env,const napi_value & jsValue,std::shared_ptr<AbilityInfo> & abilityInfo)411 bool JsAbilityConnectionManager::JsToAbilityInfo(const napi_env &env, const napi_value &jsValue,
412     std::shared_ptr<AbilityInfo>& abilityInfo)
413 {
414     HILOGI("parse abilityInfo");
415     bool stageMode = false;
416     napi_status status = OHOS::AbilityRuntime::IsStageContext(env, jsValue, stageMode);
417     if (status != napi_ok || !stageMode) {
418         auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
419         if (!ability) {
420             HILOGE("get current ability failed!");
421             return false;
422         }
423         auto abilityContext = ability->GetAbilityContext();
424         if (!abilityContext) {
425             HILOGE("get ability context failed!");
426             return false;
427         }
428         abilityInfo = abilityContext->GetAbilityInfo();
429     } else {
430         auto context = AbilityRuntime::GetStageModeContext(env, jsValue);
431         if (!context) {
432             HILOGE("get stage mode context failed!");
433             return false;
434         }
435         auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
436         if (abilityContext == nullptr) {
437             HILOGW("convertTo AbilityContext failed! try convertTo UIExtensionContext");
438             auto extensionContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::UIExtensionContext>(context);
439             if (extensionContext == nullptr) {
440                 HILOGE("convertTo UIExtensionContext failed!");
441                 return false;
442             }
443             abilityInfo = extensionContext->GetAbilityInfo();
444         } else {
445             abilityInfo = abilityContext->GetAbilityInfo();
446         }
447     }
448     return true;
449 }
450 
JsToPeerInfo(const napi_env & env,const napi_value & jsValue,PeerInfo & peerInfo)451 bool JsAbilityConnectionManager::JsToPeerInfo(const napi_env &env, const napi_value &jsValue, PeerInfo &peerInfo)
452 {
453     HILOGI("parse PeerInfo");
454     napi_valuetype argvType = napi_undefined;
455     NAPI_CALL_BASE(env, napi_typeof(env, jsValue, &argvType), false);
456     if (argvType != napi_object) {
457         HILOGE("Parameter verification failed.");
458         return false;
459     }
460 
461     if (!JsObjectToString(env, jsValue, "deviceId", peerInfo.deviceId)) {
462         HILOGE("Failed to unwrap deviceId.");
463         return false;
464     }
465 
466     if (!JsObjectToString(env, jsValue, "bundleName", peerInfo.bundleName)) {
467         HILOGE("Failed to unwrap bundleName.");
468         return false;
469     }
470 
471     if (!JsObjectToString(env, jsValue, "moduleName", peerInfo.moduleName)) {
472         HILOGE("Failed to unwrap moduleName.");
473         return false;
474     }
475 
476     if (!JsObjectToString(env, jsValue, "abilityName", peerInfo.abilityName)) {
477         HILOGE("Failed to unwrap abilityName.");
478         return false;
479     }
480 
481     if (!JsObjectToString(env, jsValue, "serviceName", peerInfo.serverId)) {
482         HILOGW("Failed to unwrap serviceName.");
483     }
484     if (!JsObjectToString(env, jsValue, "serverId", peerInfo.serverId)) {
485         HILOGW("Failed to unwrap serverId.");
486     }
487     peerInfo.serviceName = peerInfo.serverId;
488     return true;
489 }
490 
JSToConnectOption(const napi_env & env,const napi_value & jsValue,ConnectOption & option)491 int32_t JsAbilityConnectionManager::JSToConnectOption(const napi_env &env, const napi_value &jsValue,
492     ConnectOption &option)
493 {
494     HILOGI("parse ConnectOption");
495     napi_valuetype argvType = napi_undefined;
496     NAPI_CALL_BASE(env, napi_typeof(env, jsValue, &argvType), false);
497     if (argvType != napi_object) {
498         HILOGE("Parameter verification failed.");
499         return ERR_INVALID_PARAMETERS;
500     }
501     if (!JsObjectToBool(env, jsValue, "needSendData", option.needSendData)) {
502         HILOGW("Failed to unwrap needSendData.");
503     }
504     if (!JsObjectToBool(env, jsValue, "needSendStream", option.needSendStream)) {
505         HILOGW("Failed to unwrap needSendStream.");
506     }
507 
508     if (!JsObjectToBool(env, jsValue, "needReceiveStream", option.needReceiveStream)) {
509         HILOGW("Failed to unwrap needSendStream.");
510     }
511     // check start option/options
512     napi_value startOptionsVal;
513     if (napi_get_named_property(env, jsValue, "startOptions", &startOptionsVal) == napi_ok) {
514         UnwrapStartOptions(env, startOptionsVal, option);
515     }
516     napi_value optionsVal;
517     if (napi_get_named_property(env, jsValue, "options", &optionsVal) == napi_ok) {
518         UnwrapOptions(env, optionsVal, option);
519     }
520     // set default
521     if (option.options.IsEmpty()) {
522         option.options.SetParam(KEY_START_OPTION, AAFwk::String::Box(VALUE_START_OPTION_FOREGROUND));
523     }
524 
525     napi_value parametersVal;
526     if (napi_get_named_property(env, jsValue, "parameters", &parametersVal) == napi_ok) {
527         UnwrapParameters(env, parametersVal, option);
528     }
529 
530     return CheckConnectOption(option);
531 }
532 
UnwrapStartOptions(napi_env env,napi_value startOptionsVal,ConnectOption & connectOption)533 bool JsAbilityConnectionManager::UnwrapStartOptions(napi_env env, napi_value startOptionsVal,
534     ConnectOption &connectOption)
535 {
536     HILOGI("unwrap StartOptions");
537     if (startOptionsVal == nullptr) {
538         HILOGE("start options is nullptr");
539         return false;
540     }
541     napi_valuetype argvType = napi_undefined;
542     if (napi_typeof(env, startOptionsVal, &argvType) != napi_ok) {
543         return false;
544     }
545     if (argvType != napi_number) {
546         HILOGW("start options verification failed.");
547         return false;
548     }
549     int32_t startOption = 0;
550     napi_get_value_int32(env, startOptionsVal, &startOption);
551     if (startOption < static_cast<int32_t>(StartOptionParams::START_IN_FOREGROUND) ||
552             startOption > static_cast<int32_t>(StartOptionParams::START_IN_BACKGROUND)) {
553             HILOGE("invalid start option");
554             return false;
555     }
556     if (startOption == static_cast<int32_t>(StartOptionParams::START_IN_FOREGROUND)) {
557         connectOption.options.SetParam(KEY_START_OPTION, AAFwk::String::Box(VALUE_START_OPTION_FOREGROUND));
558     } else if (startOption == static_cast<int32_t>(StartOptionParams::START_IN_BACKGROUND)) {
559         connectOption.options.SetParam(KEY_START_OPTION, AAFwk::String::Box(VALUE_START_OPTION_BACKGROUND));
560     } else {
561         HILOGE("Invalid startOptions value.");
562         return false;
563     }
564     return true;
565 }
566 
UnwrapOptions(napi_env env,napi_value options,ConnectOption & connectOption)567 bool JsAbilityConnectionManager::UnwrapOptions(napi_env env, napi_value options, ConnectOption &connectOption)
568 {
569     HILOGI("unwrap Options");
570     if (options == nullptr) {
571         HILOGI("options is nullptr");
572         return false;
573     }
574 
575     napi_valuetype argvType = napi_undefined;
576     if (napi_typeof(env, options, &argvType) != napi_ok) {
577         return false;
578     }
579 
580     if (argvType != napi_object) {
581         HILOGW("options verification failed.");
582         return false;
583     }
584 
585     napi_value jsProNameList = nullptr;
586     NAPI_CALL_BASE(env, napi_get_property_names(env, options, &jsProNameList), false);
587 
588     uint32_t jsProCount = 0;
589     NAPI_CALL_BASE(env, napi_get_array_length(env, jsProNameList, &jsProCount), false);
590 
591     napi_value jsProName = nullptr;
592     napi_value jsProValue = nullptr;
593     for (uint32_t index = 0; index < jsProCount; index++) {
594         NAPI_CALL_BASE(env, napi_get_element(env, jsProNameList, index, &jsProName), false);
595 
596         std::string strProName;
597         if (!JsToString(env, jsProName, "options key", strProName)) {
598             HILOGE("options get key failed");
599             return false;
600         }
601 
602         NAPI_CALL_BASE(env, napi_get_named_property(env, options, strProName.c_str(), &jsProValue), false);
603         std::string natValue;
604         if (!JsToString(env, jsProValue, "options value", natValue)) {
605             HILOGE("options get value failed");
606             return false;
607         }
608         connectOption.options.SetParam(strProName, AAFwk::String::Box(natValue));
609     }
610     return true;
611 }
612 
CheckConnectOption(const ConnectOption & connectOption)613 int32_t JsAbilityConnectionManager::CheckConnectOption(const ConnectOption &connectOption)
614 {
615     // check background
616     if (connectOption.options.GetStringParam(KEY_START_OPTION) == VALUE_START_OPTION_BACKGROUND &&
617             !IsSystemApp()) {
618             HILOGE("normal app background denied");
619             return ERR_IS_NOT_SYSTEM_APP;
620     }
621     if (connectOption.needSendStream && !IsSystemApp()) {
622         HILOGE("normal app stream denied");
623         return ERR_IS_NOT_SYSTEM_APP;
624     }
625     if (connectOption.needReceiveStream && !IsSystemApp()) {
626         HILOGE("normal app stream denied");
627         return ERR_IS_NOT_SYSTEM_APP;
628     }
629     return ERR_OK;
630 }
631 
UnwrapParameters(napi_env env,napi_value parameters,ConnectOption & option)632 bool JsAbilityConnectionManager::UnwrapParameters(napi_env env, napi_value parameters, ConnectOption &option)
633 {
634     HILOGI("Unwrap Parameters");
635     if (parameters == nullptr) {
636         HILOGI("parameters is nullptr");
637         return false;
638     }
639 
640     napi_valuetype argvType = napi_undefined;
641     if (napi_typeof(env, parameters, &argvType) != napi_ok) {
642         return false;
643     }
644 
645     if (argvType != napi_object) {
646         HILOGE("parameters verification failed.");
647         return false;
648     }
649 
650     napi_value jsProNameList = nullptr;
651     NAPI_CALL_BASE(env, napi_get_property_names(env, parameters, &jsProNameList), false);
652 
653     uint32_t jsProCount = 0;
654     NAPI_CALL_BASE(env, napi_get_array_length(env, jsProNameList, &jsProCount), false);
655 
656     napi_value jsProName = nullptr;
657     napi_value jsProValue = nullptr;
658     for (uint32_t index = 0; index < jsProCount; index++) {
659         NAPI_CALL_BASE(env, napi_get_element(env, jsProNameList, index, &jsProName), false);
660 
661         std::string strProName;
662         if (!JsToString(env, jsProName, "parameters key", strProName)) {
663             HILOGE("parameters get key failed");
664             return false;
665         }
666 
667         NAPI_CALL_BASE(env, napi_get_named_property(env, parameters, strProName.c_str(), &jsProValue), false);
668         std::string natValue;
669         if (!JsToString(env, jsProValue, "parameters value", natValue)) {
670             HILOGE("parameters get value failed");
671             return false;
672         }
673         option.parameters.SetParam(strProName, AAFwk::String::Box(natValue));
674     }
675     return true;
676 }
677 
DestroyAbilityConnectionSession(napi_env env,napi_callback_info info)678 napi_value JsAbilityConnectionManager::DestroyAbilityConnectionSession(napi_env env, napi_callback_info info)
679 {
680     HILOGI("called.");
681     GET_PARAMS(env, info, ARG_COUNT_ONE);
682     if (argc != ARG_COUNT_ONE) {
683         HILOGE("CheckArgsCount failed.");
684         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
685         return nullptr;
686     }
687 
688     int32_t sessionId = -1;
689     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "sessionId", sessionId)) {
690         HILOGE("Failed to unwrap sessionId.");
691         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
692         return nullptr;
693     }
694 
695     int32_t ret = AbilityConnectionManager::GetInstance().DestroySession(sessionId);
696     if (ret != ERR_OK) {
697         HILOGE("destroy session failed!");
698         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
699     }
700     return nullptr;
701 }
702 
GetPeerInfoById(napi_env env,napi_callback_info info)703 napi_value JsAbilityConnectionManager::GetPeerInfoById(napi_env env, napi_callback_info info)
704 {
705     HILOGD("called.");
706     GET_PARAMS(env, info, ARG_COUNT_ONE);
707     napi_value result = nullptr;
708     if (argc != ARG_COUNT_ONE) {
709         HILOGE("CheckArgsCount failed.");
710         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
711         return result;
712     }
713     int32_t sessionId = -1;
714     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "sessionId", sessionId)) {
715         HILOGE("Failed to unwrap sessionId.");
716         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
717         return result;
718     }
719 
720     PeerInfo peerInfo;
721     int32_t ret = AbilityConnectionManager::GetInstance().getPeerInfoBySessionId(sessionId, peerInfo);
722     if (ret != ERR_OK) {
723         HILOGE("get peerInfo failed!");
724         napi_value undefinedValue;
725         napi_get_undefined(env, &undefinedValue);
726         return undefinedValue;
727     }
728 
729     return WrapPeerInfo(env, peerInfo);
730 }
731 
WrapPeerInfo(napi_env & env,const PeerInfo & peerInfo)732 napi_value JsAbilityConnectionManager::WrapPeerInfo(napi_env& env,
733     const PeerInfo& peerInfo)
734 {
735     napi_value peerInfoObj;
736     napi_create_object(env, &peerInfoObj);
737 
738     // empty peerInfo return undefined
739     if (peerInfo.deviceId.empty()) {
740         napi_value undefinedValue;
741         napi_get_undefined(env, &undefinedValue);
742         return undefinedValue;
743     }
744 
745     napi_value deviceId;
746     napi_create_string_utf8(env, peerInfo.deviceId.c_str(), NAPI_AUTO_LENGTH, &deviceId);
747     napi_set_named_property(env, peerInfoObj, "deviceId", deviceId);
748 
749     napi_value bundleName;
750     napi_create_string_utf8(env, peerInfo.bundleName.c_str(), NAPI_AUTO_LENGTH, &bundleName);
751     napi_set_named_property(env, peerInfoObj, "bundleName", bundleName);
752 
753     napi_value moduleName;
754     napi_create_string_utf8(env, peerInfo.moduleName.c_str(), NAPI_AUTO_LENGTH, &moduleName);
755     napi_set_named_property(env, peerInfoObj, "moduleName", moduleName);
756 
757     napi_value abilityName;
758     napi_create_string_utf8(env, peerInfo.abilityName.c_str(), NAPI_AUTO_LENGTH, &abilityName);
759     napi_set_named_property(env, peerInfoObj, "abilityName", abilityName);
760 
761     napi_value serviceName;
762     napi_create_string_utf8(env, peerInfo.serverId.c_str(), NAPI_AUTO_LENGTH, &serviceName);
763     napi_set_named_property(env, peerInfoObj, "serviceName", serviceName);
764 
765     return peerInfoObj;
766 }
767 
CheckEventType(const std::string & eventType)768 int32_t JsAbilityConnectionManager::CheckEventType(const std::string& eventType)
769 {
770     bool isExist = (std::find(REGISTER_EVENT_TYPES.begin(),
771         REGISTER_EVENT_TYPES.end(), eventType) != REGISTER_EVENT_TYPES.end());
772     if (!isExist) {
773         HILOGE("invalid event type not exist: %{public}s", eventType.c_str());
774         return ERR_INVALID_PARAMETERS;
775     }
776 
777     bool isCallSystemApi = (std::find(SYSTEM_APP_EVENT_TYPES.begin(),
778         SYSTEM_APP_EVENT_TYPES.end(), eventType) != SYSTEM_APP_EVENT_TYPES.end());
779     if (isCallSystemApi && !IsSystemApp()) {
780         HILOGE("event type %{public}s only allow system app", eventType.c_str());
781         return ERR_IS_NOT_SYSTEM_APP;
782     }
783     return ERR_OK;
784 }
785 
RegisterAbilityConnectionSessionCallback(napi_env env,napi_callback_info info)786 napi_value JsAbilityConnectionManager::RegisterAbilityConnectionSessionCallback(napi_env env, napi_callback_info info)
787 {
788     HILOGD("called.");
789     GET_PARAMS(env, info, ARG_COUNT_THREE);
790     if (argc != ARG_COUNT_THREE) {
791         HILOGE("CheckArgsCount failed.");
792         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
793         return nullptr;
794     }
795 
796     std::string eventType;
797     if (!JsToString(env, argv[ARG_INDEX_ZERO], "eventType", eventType)) {
798         HILOGE("Failed to unwrap type.");
799         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
800         return nullptr;
801     }
802 
803     int32_t ret = CheckEventType(eventType);
804     if (ret != ERR_OK) {
805         HILOGE("The type error. eventType is %{public}s", eventType.c_str());
806         CreateBusinessError(env, ret);
807         return nullptr;
808     }
809 
810     int32_t sessionId = -1;
811     if (!JsToInt32(env, argv[ARG_INDEX_ONE], "sessionId", sessionId)) {
812         HILOGE("Failed to unwrap sessionId.");
813         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
814         return nullptr;
815     }
816 
817     napi_value listenerObj = argv[ARG_INDEX_TWO];
818     if (listenerObj == nullptr) {
819         HILOGE("listenerObj is nullptr");
820         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
821         return nullptr;
822     }
823 
824     bool isCallable = false;
825     napi_status status = napi_is_callable(env, listenerObj, &isCallable);
826     if (status != napi_ok || !isCallable) {
827         HILOGE("Failed to check listenerObj is callable");
828         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
829         return nullptr;
830     }
831 
832     std::shared_ptr<JsAbilityConnectionSessionListener> listener =
833         std::make_shared<JsAbilityConnectionSessionListener>(env);
834 
835     listener->SetCallback(listenerObj);
836     ret = AbilityConnectionManager::GetInstance().RegisterEventCallback(
837         sessionId, eventType, listener);
838     if (ret != ERR_OK) {
839         HILOGE("Register event callback failed!");
840         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
841     }
842     return nullptr;
843 }
844 
UnregisterAbilityConnectionSessionCallback(napi_env env,napi_callback_info info)845 napi_value JsAbilityConnectionManager::UnregisterAbilityConnectionSessionCallback(napi_env env,
846     napi_callback_info info)
847 {
848     HILOGD("called.");
849     GET_PARAMS(env, info, ARG_COUNT_THREE);
850     if (argc < ARG_COUNT_TWO || argc > ARG_COUNT_THREE) {
851         HILOGE("CheckArgsCount failed.");
852         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
853         return nullptr;
854     }
855 
856     std::string eventType;
857     if (!JsToString(env, argv[ARG_INDEX_ZERO], "eventType", eventType)) {
858         HILOGE("Failed to unwrap type.");
859         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
860         return nullptr;
861     }
862 
863     int32_t ret = CheckEventType(eventType);
864     if (ret != ERR_OK) {
865         HILOGE("The type error. eventType is %{public}s", eventType.c_str());
866         CreateBusinessError(env, ret);
867         return nullptr;
868     }
869 
870     int32_t sessionId = -1;
871     if (!JsToInt32(env, argv[ARG_INDEX_ONE], "sessionId", sessionId)) {
872         HILOGE("Failed to unwrap sessionId.");
873         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
874         return nullptr;
875     }
876 
877     ret = AbilityConnectionManager::GetInstance().UnregisterEventCallback(sessionId, eventType);
878     if (ret != ERR_OK) {
879         HILOGE("Unregister event callback failed!");
880         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
881     }
882     return nullptr;
883 }
884 
AddProcessor()885 static int64_t AddProcessor()
886 {
887     HiAppEvent::ReportConfig config;
888     config.name = "ha_app_event";
889     config.configName = "SDK_OCG";
890     return HiAppEvent::AppEventProcessorMgr::AddProcessor(config);
891 }
892 
WriteEndEvent(const std::string & transId,const int result,const int errCode,const time_t beginTime,int64_t processorId)893 static void WriteEndEvent(const std::string& transId, const int result, const int errCode, const time_t beginTime,
894     int64_t processorId)
895 {
896     HiAppEvent::Event event("api_diagnostic", "api_exec_end", HiAppEvent::BEHAVIOR);
897     event.AddParam("transId", transId);
898     event.AddParam("result", result);
899     event.AddParam("error_code", errCode);
900     event.AddParam("api_name", std::string("connect"));
901     event.AddParam("sdk_name", std::string("DistributedServiceKit"));
902     event.AddParam("begin_time", beginTime);
903     event.AddParam("end_time", time(nullptr));
904     if (processorId > 0) {
905         Write(event);
906     }
907 }
908 
Connect(napi_env env,napi_callback_info info)909 napi_value JsAbilityConnectionManager::Connect(napi_env env, napi_callback_info info)
910 {
911     HILOGI("called.");
912     int64_t processorId = -1;
913     processorId = AddProcessor();
914     if (processorId <= 0) {
915         HILOGE("Add processor fail.Error code is %{public}" PRId64"", processorId);
916     }
917     time_t beginTime = time(nullptr);
918     std::string transId = std::string("transId_") + std::to_string(std::rand());
919     int32_t sessionId = -1;
920     GET_PARAMS(env, info, ARG_COUNT_ONE);
921     if (argc != ARG_COUNT_ONE || !JsToInt32(env, argv[ARG_INDEX_ZERO], "sessionId", sessionId)) {
922         HILOGE("CheckArgsCount failed or Failed to unwrap sessionId.");
923         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
924         WriteEndEvent(transId, EVENT_RESULT_FAIL, ERR_INVALID_PARAMETERS, beginTime, processorId);
925         return nullptr;
926     }
927     return ConnectInner(env, sessionId, transId, beginTime, processorId);
928 }
929 
ConnectInner(napi_env env,int32_t sessionId,const std::string & transId,time_t beginTime,int64_t processorId)930 napi_value JsAbilityConnectionManager::ConnectInner(
931     napi_env env, int32_t sessionId, const std::string &transId, time_t beginTime, int64_t processorId)
932 {
933     napi_deferred deferred;
934     napi_value promise = nullptr;
935     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
936 
937     AsyncConnectCallbackInfo* asyncCallbackInfo = new AsyncConnectCallbackInfo();
938     asyncCallbackInfo->deferred = deferred;
939     asyncCallbackInfo->sessionId = sessionId;
940 
941     napi_threadsafe_function tsfn;
942     if (CreateConnectThreadsafeFunction(env, nullptr, &tsfn) != napi_ok || tsfn == nullptr) {
943         HILOGE("Failed to create connect function.");
944         delete asyncCallbackInfo;
945         napi_release_threadsafe_function(tsfn, napi_tsfn_release);
946         napi_reject_deferred(env, deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
947         WriteEndEvent(transId, EVENT_RESULT_FAIL, ERR_EXECUTE_FUNCTION, beginTime, processorId);
948         return promise;
949     }
950     asyncCallbackInfo->tsfn = tsfn;
951 
952     napi_value asyncResourceName;
953     NAPI_CALL(env, napi_create_string_utf8(env, "connectAsync", NAPI_AUTO_LENGTH, &asyncResourceName));
954 
955     napi_status status = napi_create_async_work(
956         env, nullptr, asyncResourceName, ExecuteConnect, CompleteAsyncConnectWork,
957         static_cast<void *>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
958     if (status != napi_ok) {
959         HILOGE("Failed to create async work.");
960         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
961         delete asyncCallbackInfo;
962         napi_release_threadsafe_function(tsfn, napi_tsfn_release);
963         napi_reject_deferred(env, deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
964         WriteEndEvent(transId, EVENT_RESULT_FAIL, ERR_EXECUTE_FUNCTION, beginTime, processorId);
965         return promise;
966     }
967 
968     if (napi_queue_async_work(env, asyncCallbackInfo->asyncWork) != napi_ok) {
969         HILOGE("Failed to queue async work.");
970         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
971         delete asyncCallbackInfo;
972         napi_release_threadsafe_function(tsfn, napi_tsfn_release);
973         napi_reject_deferred(env, deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
974         WriteEndEvent(transId, EVENT_RESULT_FAIL, ERR_EXECUTE_FUNCTION, beginTime, processorId);
975         return promise;
976     }
977 
978     WriteEndEvent(transId, EVENT_RESULT_SUCCESS, EVENT_RESULT_SUCCESS, beginTime, processorId);
979     return promise;
980 }
981 
CreateConnectThreadsafeFunction(napi_env env,napi_value js_func,napi_threadsafe_function * tsfn)982 napi_status JsAbilityConnectionManager::CreateConnectThreadsafeFunction(napi_env env,
983     napi_value js_func, napi_threadsafe_function* tsfn)
984 {
985     napi_value async_resource = nullptr;
986     napi_value async_resource_name = nullptr;
987     napi_create_string_utf8(env, "connectAsync", NAPI_AUTO_LENGTH, &async_resource_name);
988 
989     return napi_create_threadsafe_function(
990         env, js_func, async_resource, async_resource_name,
991         0, 1, nullptr, nullptr, nullptr,
992         ConnectThreadsafeFunctionCallback, tsfn);
993 }
994 
ConnectThreadsafeFunctionCallback(napi_env env,napi_value js_callback,void * context,void * data)995 void JsAbilityConnectionManager::ConnectThreadsafeFunctionCallback(napi_env env, napi_value js_callback,
996     void* context, void* data)
997 {
998     HILOGI("called real connect callback.");
999     if (data == nullptr) {
1000         HILOGE("Async data is null");
1001         return;
1002     }
1003 
1004     AsyncConnectCallbackInfo* asyncData = static_cast<AsyncConnectCallbackInfo*>(data);
1005     napi_deferred deferred = asyncData->deferred;
1006     napi_threadsafe_function tsfn = asyncData->tsfn;
1007     ConnectResult result = asyncData->result;
1008     // reset
1009     asyncData->deferred = nullptr;
1010     asyncData->tsfn = nullptr;
1011 
1012     if (!result.isConnected && result.errorCode == ConnectErrorCode::INVALID_SESSION_ID) {
1013         napi_status ret = napi_reject_deferred(env, deferred,
1014             CreateBusinessError(env, ERR_INVALID_PARAMETERS, false));
1015         if (ret != napi_ok) {
1016             HILOGE("Failed to throw error. status is %{public}d", static_cast<int32_t>(ret));
1017         }
1018         CleanupConnectionResources(env, asyncData, tsfn);
1019         return;
1020     }
1021 
1022     napi_value connectResultObj;
1023     napi_create_object(env, &connectResultObj);
1024 
1025     napi_value isConnected;
1026     napi_get_boolean(env, result.isConnected, &isConnected);
1027     napi_set_named_property(env, connectResultObj, "isConnected", isConnected);
1028 
1029     napi_value reason;
1030     napi_create_string_utf8(env, result.reason.c_str(), NAPI_AUTO_LENGTH, &reason);
1031     napi_set_named_property(env, connectResultObj, "reason", reason);
1032 
1033     if (!result.isConnected) {
1034         napi_value errorCode;
1035         napi_create_int32(env, static_cast<int32_t>(result.errorCode), &errorCode);
1036         napi_set_named_property(env, connectResultObj, "errorCode", errorCode);
1037     }
1038     napi_resolve_deferred(env, deferred, connectResultObj);
1039     HILOGI("resolve defer");
1040     AbilityConnectionManager::GetInstance().FinishSessionConnect(result.sessionId);
1041     CleanupConnectionResources(env, asyncData, tsfn);
1042 }
1043 
CleanupConnectionResources(napi_env env,AsyncConnectCallbackInfo * asyncData,napi_threadsafe_function tsfn)1044 void JsAbilityConnectionManager::CleanupConnectionResources(napi_env env, AsyncConnectCallbackInfo* asyncData,
1045     napi_threadsafe_function tsfn)
1046 {
1047     HILOGI("called.");
1048     if (env == nullptr) {
1049         HILOGE("env is nullptr");
1050         return;
1051     }
1052     if (tsfn != nullptr) {
1053         napi_release_threadsafe_function(tsfn, napi_tsfn_release);
1054         HILOGI("release tsfn");
1055     }
1056     asyncData->connectCallbackExecuted = true;
1057     // The later of ConnectThreadsafeFunctionCallback/CompleteAsyncConnectWork frees asyncData
1058     if (asyncData->completeAsyncworkExecuted) {
1059         delete asyncData;
1060         HILOGI("release async data");
1061     }
1062 }
1063 
ExecuteConnect(napi_env env,void * data)1064 void JsAbilityConnectionManager::ExecuteConnect(napi_env env, void *data)
1065 {
1066     HILOGI("called.");
1067     AsyncConnectCallbackInfo* asyncData = static_cast<AsyncConnectCallbackInfo*>(data);
1068     if (asyncData == nullptr) {
1069         HILOGE("asyncData is nullptr");
1070         return;
1071     }
1072     AbilityConnectionManager::ConnectCallback connectCallback = [env, asyncData](ConnectResult result) mutable {
1073         HILOGI("called.");
1074         if (asyncData == nullptr || env == nullptr) {
1075             HILOGE("asyncData or env is nullptr");
1076             return;
1077         }
1078         asyncData->result = result;
1079         napi_threadsafe_function tsfn = asyncData->tsfn;
1080         if (tsfn == nullptr) {
1081             HILOGE("tsfn is nullptr");
1082             return;
1083         }
1084         napi_status status = napi_call_threadsafe_function(tsfn, asyncData, napi_tsfn_nonblocking);
1085         if (status != napi_ok) {
1086             HILOGE("Failed to create async work. status is %{public}d", static_cast<int32_t>(status));
1087         }
1088         HILOGI("clear asyncData to prevent secondary calls.");
1089         asyncData = nullptr;
1090     };
1091     AbilityConnectionManager::GetInstance().ConnectSession(asyncData->sessionId, connectCallback);
1092 }
1093 
CompleteAsyncConnectWork(napi_env env,napi_status status,void * data)1094 void JsAbilityConnectionManager::CompleteAsyncConnectWork(napi_env env, napi_status status, void* data)
1095 {
1096     HILOGI("called.");
1097     if (data == nullptr) {
1098         HILOGE("Async data is null");
1099         return;
1100     }
1101 
1102     AsyncConnectCallbackInfo* asyncData = static_cast<AsyncConnectCallbackInfo*>(data);
1103     napi_async_work asyncWork = asyncData->asyncWork;
1104     // reset
1105     asyncData->asyncWork = nullptr;
1106     if (asyncWork != nullptr) {
1107         napi_delete_async_work(env, asyncWork);
1108         HILOGI("release asyncWork");
1109     }
1110     asyncData->completeAsyncworkExecuted = true;
1111     // The later of ConnectThreadsafeFunctionCallback/CompleteAsyncConnectWork frees asyncData
1112     if (asyncData->connectCallbackExecuted) {
1113         delete asyncData;
1114         HILOGI("release async data");
1115     }
1116 }
1117 
DisConnect(napi_env env,napi_callback_info info)1118 napi_value JsAbilityConnectionManager::DisConnect(napi_env env, napi_callback_info info)
1119 {
1120     HILOGI("called.");
1121     GET_PARAMS(env, info, ARG_COUNT_ONE);
1122     if (argc != ARG_COUNT_ONE) {
1123         HILOGE("CheckArgsCount failed.");
1124         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1125         return nullptr;
1126     }
1127 
1128     int32_t sessionId = -1;
1129     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "sessionId", sessionId)) {
1130         HILOGE("Failed to unwrap sessionId.");
1131         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1132         return nullptr;
1133     }
1134 
1135     int32_t ret = AbilityConnectionManager::GetInstance().DisconnectSession(sessionId);
1136     if (ret != ERR_OK) {
1137         HILOGE("disconnect session failed!");
1138         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
1139     }
1140     return nullptr;
1141 }
1142 
CompleteAsyncWork(napi_env env,napi_status status,void * data)1143 void JsAbilityConnectionManager::CompleteAsyncWork(napi_env env, napi_status status, void* data)
1144 {
1145     HILOGI("called.");
1146     if (data == nullptr) {
1147         HILOGE("Async data is null");
1148         return;
1149     }
1150 
1151     AsyncCallbackInfo* asyncData = static_cast<AsyncCallbackInfo*>(data);
1152     if (asyncData->result == ERR_OK) {
1153         napi_value result;
1154         napi_get_undefined(env, &result);
1155         napi_resolve_deferred(env, asyncData->deferred, result);
1156     } else {
1157         napi_reject_deferred(env, asyncData->deferred,
1158             CreateBusinessError(env, asyncData->result, false));
1159     }
1160     napi_delete_async_work(env, asyncData->asyncWork);
1161     delete asyncData;
1162 }
1163 
AcceptConnect(napi_env env,napi_callback_info info)1164 napi_value JsAbilityConnectionManager::AcceptConnect(napi_env env, napi_callback_info info)
1165 {
1166     HILOGI("called.");
1167     GET_PARAMS(env, info, ARG_COUNT_TWO);
1168     if (argc != ARG_COUNT_TWO) {
1169         HILOGE("CheckArgsCount failed.");
1170         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1171         return nullptr;
1172     }
1173 
1174     int32_t sessionId = -1;
1175     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "sessionId", sessionId)) {
1176         HILOGE("Failed to unwrap sessionId.");
1177         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1178         return nullptr;
1179     }
1180 
1181     std::string token;
1182     if (!JsToString(env, argv[ARG_INDEX_ONE], "token", token)) {
1183         HILOGE("Failed to unwrap token.");
1184         return nullptr;
1185     }
1186 
1187     napi_deferred deferred;
1188     napi_value promise = nullptr;
1189     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1190 
1191     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo();
1192     asyncCallbackInfo->deferred = deferred;
1193     asyncCallbackInfo->sessionId = sessionId;
1194     asyncCallbackInfo->token = token;
1195 
1196     napi_value asyncResourceName;
1197     NAPI_CALL(env, napi_create_string_utf8(env, "acceptConnectAsync", NAPI_AUTO_LENGTH, &asyncResourceName));
1198 
1199     napi_status status = napi_create_async_work(
1200         env, nullptr, asyncResourceName, ExecuteAcceptConnect, CompleteAsyncWork,
1201         static_cast<void *>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
1202     if (status != napi_ok) {
1203         HILOGE("Failed to create async work.");
1204         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1205         delete asyncCallbackInfo;
1206         napi_reject_deferred(env, deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
1207         return promise;
1208     }
1209 
1210     if (napi_queue_async_work(env, asyncCallbackInfo->asyncWork) != napi_ok) {
1211         HILOGE("Failed to queue async work.");
1212         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1213         delete asyncCallbackInfo;
1214         napi_reject_deferred(env, deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
1215         return promise;
1216     }
1217     return promise;
1218 }
1219 
ExecuteAcceptConnect(napi_env env,void * data)1220 void JsAbilityConnectionManager::ExecuteAcceptConnect(napi_env env, void *data)
1221 {
1222     HILOGI("called.");
1223     AsyncCallbackInfo* asyncData = static_cast<AsyncCallbackInfo*>(data);
1224     asyncData->result = AbilityConnectionManager::GetInstance().AcceptConnect(asyncData->sessionId, asyncData->token);
1225 }
1226 
Reject(napi_env env,napi_callback_info info)1227 napi_value JsAbilityConnectionManager::Reject(napi_env env, napi_callback_info info)
1228 {
1229     HILOGI("called.");
1230     GET_PARAMS(env, info, ARG_COUNT_TWO);
1231     if (argc != ARG_COUNT_TWO) {
1232         HILOGE("CheckArgsCount failed.");
1233         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1234         return nullptr;
1235     }
1236 
1237     std::string token;
1238     if (!JsToString(env, argv[ARG_INDEX_ZERO], "token", token)) {
1239         HILOGE("Failed to unwrap token.");
1240         return nullptr;
1241     }
1242 
1243     std::string reason;
1244     if (!JsToString(env, argv[ARG_INDEX_ONE], "reason", reason)) {
1245         HILOGE("Failed to unwrap reason.");
1246         return nullptr;
1247     }
1248 
1249     int32_t ret = AbilityConnectionManager::GetInstance().Reject(token, reason);
1250     if (ret != ERR_OK) {
1251         HILOGE("Reject session failed!");
1252         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
1253     }
1254     return nullptr;
1255 }
1256 
SendMessage(napi_env env,napi_callback_info info)1257 napi_value JsAbilityConnectionManager::SendMessage(napi_env env, napi_callback_info info)
1258 {
1259     HILOGI("called.");
1260     napi_deferred deferred;
1261     napi_value promise = nullptr;
1262     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1263 
1264     GET_PARAMS(env, info, ARG_COUNT_TWO);
1265     if (argc != ARG_COUNT_TWO) {
1266         HILOGE("CheckArgsCount failed.");
1267         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1268         return promise;
1269     }
1270 
1271     int32_t sessionId = -1;
1272     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "sessionId", sessionId)) {
1273         HILOGE("Failed to unwrap sessionId.");
1274         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1275         return promise;
1276     }
1277 
1278     std::string msg;
1279     if (!JsToString(env, argv[ARG_INDEX_ONE], "msg", msg)) {
1280         HILOGE("Failed to unwrap msg.");
1281         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1282         return promise;
1283     }
1284 
1285     HILOGI("start send message.");
1286     int32_t ret = AbilityConnectionManager::GetInstance().SendMessage(sessionId, msg);
1287     HILOGI("notify sendMessage event.");
1288     if (ret == ERR_OK) {
1289         napi_value result;
1290         napi_get_undefined(env, &result);
1291         napi_resolve_deferred(env, deferred, result);
1292     } else {
1293         napi_reject_deferred(env, deferred,
1294             CreateBusinessError(env, ret, false));
1295     }
1296 
1297     HILOGI("end.");
1298     return promise;
1299 }
1300 
ExecuteSendMessage(napi_env env,void * data)1301 void JsAbilityConnectionManager::ExecuteSendMessage(napi_env env, void *data)
1302 {
1303     AsyncCallbackInfo* asyncData = static_cast<AsyncCallbackInfo*>(data);
1304     asyncData->result = AbilityConnectionManager::GetInstance().SendMessage(asyncData->sessionId, asyncData->msg);
1305 }
1306 
SendData(napi_env env,napi_callback_info info)1307 napi_value JsAbilityConnectionManager::SendData(napi_env env, napi_callback_info info)
1308 {
1309     HILOGI("called.");
1310     napi_deferred deferred;
1311     napi_value promise = nullptr;
1312     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1313 
1314     GET_PARAMS(env, info, ARG_COUNT_TWO);
1315     if (argc != ARG_COUNT_TWO) {
1316         HILOGE("CheckArgsCount failed.");
1317         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1318         return promise;
1319     }
1320 
1321     int32_t sessionId = -1;
1322     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "sessionId", sessionId)) {
1323         HILOGE("Failed to unwrap sessionId.");
1324         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1325         return promise;
1326     }
1327 
1328     void *data;
1329     size_t length;
1330     if (napi_get_arraybuffer_info(env, argv[ARG_INDEX_ONE], &data, &length) != napi_ok) {
1331         HILOGE("get arraybuffer info failed.");
1332         napi_throw_error(env, nullptr, ERR_MESSAGE_FAILED.c_str());
1333         return nullptr;
1334     }
1335 
1336     std::shared_ptr<AVTransDataBuffer> buffer = std::make_shared<AVTransDataBuffer>(length);
1337     if (memcpy_s(buffer->Data(), buffer->Size(), data, length) != ERR_OK) {
1338         HILOGE("pack recv data failed");
1339         napi_throw_error(env, nullptr, ERR_MESSAGE_FAILED.c_str());
1340         return nullptr;
1341     }
1342 
1343     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo();
1344     asyncCallbackInfo->deferred = deferred;
1345     asyncCallbackInfo->sessionId = sessionId;
1346     asyncCallbackInfo->buffer = buffer;
1347     CreateSendDataAsyncWork(env, asyncCallbackInfo);
1348     return promise;
1349 }
1350 
CreateSendDataAsyncWork(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)1351 void JsAbilityConnectionManager::CreateSendDataAsyncWork(napi_env env, AsyncCallbackInfo* asyncCallbackInfo)
1352 {
1353     if (asyncCallbackInfo == nullptr) {
1354         return;
1355     }
1356     napi_value asyncResourceName;
1357     napi_create_string_utf8(env, "sendDataAsync", NAPI_AUTO_LENGTH, &asyncResourceName);
1358 
1359     napi_status status = napi_create_async_work(
1360         env, nullptr, asyncResourceName, ExecuteSendData, CompleteAsyncWork,
1361         static_cast<void *>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
1362     if (status != napi_ok) {
1363         HILOGE("Failed to create async work.");
1364         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1365         napi_reject_deferred(env, asyncCallbackInfo->deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
1366         delete asyncCallbackInfo;
1367         return;
1368     }
1369 
1370     if (napi_queue_async_work(env, asyncCallbackInfo->asyncWork) != napi_ok) {
1371         HILOGE("Failed to queue async work.");
1372         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1373         napi_reject_deferred(env, asyncCallbackInfo->deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
1374         delete asyncCallbackInfo;
1375         return;
1376     }
1377 }
1378 
ExecuteSendData(napi_env env,void * data)1379 void JsAbilityConnectionManager::ExecuteSendData(napi_env env, void *data)
1380 {
1381     AsyncCallbackInfo* asyncData = static_cast<AsyncCallbackInfo*>(data);
1382     asyncData->result = AbilityConnectionManager::GetInstance().SendData(asyncData->sessionId, asyncData->buffer);
1383 }
1384 
SendImage(napi_env env,napi_callback_info info)1385 napi_value JsAbilityConnectionManager::SendImage(napi_env env, napi_callback_info info)
1386 {
1387     HILOGI("called.");
1388     if (!IsSystemApp()) {
1389         HILOGE("Permission verification failed.");
1390         CreateBusinessError(env, ERR_IS_NOT_SYSTEM_APP);
1391     }
1392 
1393     napi_deferred deferred;
1394     napi_value promise = nullptr;
1395     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1396 
1397     GET_PARAMS(env, info, ARG_COUNT_THREE);
1398     if (argc < ARG_COUNT_TWO || argc > ARG_COUNT_THREE) {
1399         HILOGE("CheckArgsCount failed.");
1400         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1401         return promise;
1402     }
1403 
1404     int32_t sessionId = -1;
1405     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "sessionId", sessionId)) {
1406         HILOGE("Failed to unwrap sessionId.");
1407         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1408         return promise;
1409     }
1410 
1411     int32_t quality = IMAGE_COMPRESSION_QUALITY;
1412     if (argc == ARG_COUNT_THREE) {
1413         if (!JsToInt32(env, argv[ARG_INDEX_TWO], "quality", quality)) {
1414             HILOGE("Failed to unwrap quality.");
1415             CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1416             return promise;
1417         }
1418     }
1419 
1420     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo();
1421     asyncCallbackInfo->deferred = deferred;
1422     asyncCallbackInfo->sessionId = sessionId;
1423     asyncCallbackInfo->image = Media::PixelMapNapi::GetPixelMap(env, argv[ARG_INDEX_ONE]);
1424     if (!asyncCallbackInfo->image) {
1425         HILOGE("Failed to unwrap image.");
1426         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1427         delete asyncCallbackInfo;
1428         return promise;
1429     }
1430     asyncCallbackInfo->imageQuality = quality;
1431     return CreateSendImageAsyncWork(env, asyncCallbackInfo);
1432 }
1433 
CreateSendImageAsyncWork(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)1434 napi_value JsAbilityConnectionManager::CreateSendImageAsyncWork(napi_env env, AsyncCallbackInfo* asyncCallbackInfo)
1435 {
1436     napi_value promise = nullptr;
1437     if (asyncCallbackInfo == nullptr) {
1438         return promise;
1439     }
1440     napi_value asyncResourceName;
1441     NAPI_CALL(env, napi_create_string_utf8(env, "sendImageAsync", NAPI_AUTO_LENGTH, &asyncResourceName));
1442 
1443     napi_status status = napi_create_async_work(
1444         env, nullptr, asyncResourceName, ExecuteSendImage, CompleteAsyncWork,
1445         static_cast<void *>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
1446     if (status != napi_ok) {
1447         HILOGE("Failed to create async work.");
1448         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1449         napi_reject_deferred(env, asyncCallbackInfo->deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
1450         delete asyncCallbackInfo;
1451         return promise;
1452     }
1453 
1454     if (napi_queue_async_work(env, asyncCallbackInfo->asyncWork) != napi_ok) {
1455         HILOGE("Failed to queue async work.");
1456         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1457         napi_reject_deferred(env, asyncCallbackInfo->deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
1458         delete asyncCallbackInfo;
1459         return promise;
1460     }
1461 
1462     return promise;
1463 }
1464 
ExecuteSendImage(napi_env env,void * data)1465 void JsAbilityConnectionManager::ExecuteSendImage(napi_env env, void *data)
1466 {
1467     AsyncCallbackInfo* asyncData = static_cast<AsyncCallbackInfo*>(data);
1468     asyncData->result = AbilityConnectionManager::GetInstance().SendImage(asyncData->sessionId,
1469         asyncData->image, asyncData->imageQuality);
1470 }
1471 
CreateStream(napi_env env,napi_callback_info info)1472 napi_value JsAbilityConnectionManager::CreateStream(napi_env env, napi_callback_info info)
1473 {
1474     HILOGD("called.");
1475     if (!IsSystemApp()) {
1476         HILOGE("Permission verification failed.");
1477         CreateBusinessError(env, ERR_IS_NOT_SYSTEM_APP);
1478     }
1479 
1480     napi_deferred deferred;
1481     napi_value promise = nullptr;
1482     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1483 
1484     GET_PARAMS(env, info, ARG_COUNT_TWO);
1485     if (argc != ARG_COUNT_TWO) {
1486         HILOGE("CheckArgsCount failed.");
1487         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1488         return promise;
1489     }
1490 
1491     int32_t sessionId = -1;
1492     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "sessionId", sessionId)) {
1493         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1494         return promise;
1495     }
1496 
1497     HILOGI("StreamParam.");
1498     StreamParams streamParam;
1499     if (!JsToStreamParam(env, argv[ARG_INDEX_ONE], streamParam)) {
1500         HILOGE("Failed to unwrap streamParam.");
1501         return promise;
1502     }
1503 
1504     AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo();
1505     asyncCallbackInfo->deferred = deferred;
1506     asyncCallbackInfo->sessionId = sessionId;
1507     asyncCallbackInfo->streamParam = streamParam;
1508     CreateStreamAsyncWork(env, asyncCallbackInfo);
1509 
1510     return promise;
1511 }
1512 
CreateStreamAsyncWork(napi_env env,AsyncCallbackInfo * asyncCallbackInfo)1513 void JsAbilityConnectionManager::CreateStreamAsyncWork(napi_env env, AsyncCallbackInfo* asyncCallbackInfo)
1514 {
1515     napi_value asyncResourceName;
1516     napi_create_string_utf8(env, "createStreamAsync", NAPI_AUTO_LENGTH, &asyncResourceName);
1517 
1518     napi_status status = napi_create_async_work(
1519         env, nullptr, asyncResourceName, ExecuteCreateStream, CompleteAsyncCreateStreamWork,
1520         static_cast<void *>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
1521     if (status != napi_ok) {
1522         HILOGE("Failed to create async work.");
1523         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1524         napi_reject_deferred(env, asyncCallbackInfo->deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
1525         delete asyncCallbackInfo;
1526         return;
1527     }
1528 
1529     if (napi_queue_async_work(env, asyncCallbackInfo->asyncWork) != napi_ok) {
1530         HILOGE("Failed to queue async work.");
1531         napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1532         napi_reject_deferred(env, asyncCallbackInfo->deferred, CreateBusinessError(env, ERR_EXECUTE_FUNCTION, false));
1533         delete asyncCallbackInfo;
1534         return;
1535     }
1536 }
1537 
JsToStreamParam(const napi_env & env,const napi_value & jsValue,StreamParams & streamParam)1538 bool JsAbilityConnectionManager::JsToStreamParam(const napi_env &env, const napi_value &jsValue,
1539     StreamParams &streamParam)
1540 {
1541     napi_valuetype argvType = napi_undefined;
1542     NAPI_CALL_BASE(env, napi_typeof(env, jsValue, &argvType), false);
1543     if (argvType != napi_object) {
1544         HILOGE("Parameter verification failed.");
1545         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1546         return false;
1547     }
1548 
1549     if (!JsObjectToString(env, jsValue, "name", streamParam.name)) {
1550         HILOGE("name parameter parsing failed.");
1551         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1552         return false;
1553     }
1554 
1555     int32_t role = -1;
1556     if (!JsObjectToInt(env, jsValue, "role", role)) {
1557         HILOGE("role verification failed.");
1558         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1559         return false;
1560     }
1561 
1562     if (role < static_cast<int32_t>(StreamRole::SOURCE) ||
1563         role > static_cast<int32_t>(StreamRole::SINK)) {
1564         HILOGE("Invalid role value: %{public}d", role);
1565         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1566         return false;
1567     }
1568     streamParam.role = static_cast<StreamRole>(role);
1569     if (!GetStreamParamBitrate(env, jsValue, streamParam)) {
1570         return false;
1571     }
1572     if (!UnwrapColorSpace(env, jsValue, streamParam)) {
1573         return false;
1574     }
1575     return true;
1576 }
1577 
GetStreamParamBitrate(const napi_env & env,const napi_value & jsValue,StreamParams & streamParam)1578 bool JsAbilityConnectionManager::GetStreamParamBitrate(const napi_env &env, const napi_value &jsValue,
1579     StreamParams &streamParam)
1580 {
1581     bool hasProperty = false;
1582     if (napi_has_named_property(env, jsValue, "bitrate", &hasProperty) != napi_ok || !hasProperty) {
1583         HILOGW("no bitrate propertys");
1584         return true;
1585     }
1586 
1587     int32_t bitrate = -1;
1588     if (!JsObjectToInt(env, jsValue, "bitrate", bitrate)) {
1589         HILOGE("bitrate verification failed.");
1590         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1591         return false;
1592     }
1593 
1594     if (!IsVaildBitrate(bitrate)) {
1595         HILOGE("not support bitrate: %{public}d.", bitrate);
1596         CreateBusinessError(env, NOT_SUPPORTED_BITATE);
1597         return false;
1598     }
1599     HILOGI("bitrate is %{public}d.", bitrate);
1600     streamParam.bitrate = bitrate;
1601     return true;
1602 }
1603 
IsVaildBitrate(int32_t bitrate)1604 bool JsAbilityConnectionManager::IsVaildBitrate(int32_t bitrate)
1605 {
1606     OH_BitrateMode bitrateMode = BITRATE_MODE_CBR;
1607     OH_AVCapability *capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
1608     if (capability == nullptr) {
1609         HILOGE("GetCapability failed, it's nullptr");
1610         return false;
1611     }
1612     bool isSupported = OH_AVCapability_IsEncoderBitrateModeSupported(capability, bitrateMode);
1613     if (!isSupported) {
1614         HILOGE("BITRATE_MODE_CBR is not support.");
1615         return false;
1616     }
1617     OH_AVRange bitrateRange = {-1, -1};
1618     int32_t ret = OH_AVCapability_GetEncoderBitrateRange(capability, &bitrateRange);
1619     if (ret != AV_ERR_OK || bitrateRange.maxVal <= 0) {
1620         HILOGE("bitrate range query failed. ret: %{public}d; maxVal: %{public}d;", ret, bitrateRange.maxVal);
1621         return false;
1622     }
1623     if (bitrate < bitrateRange.minVal || bitrate > bitrateRange.maxVal) {
1624         HILOGE("Bitrate is not supported, it should be between %{public}d and %{public}d", bitrateRange.minVal,
1625             bitrateRange.maxVal);
1626         return false;
1627     }
1628     return true;
1629 }
1630 
UnwrapColorSpace(const napi_env & env,const napi_value & jsValue,StreamParams & streamParam)1631 bool JsAbilityConnectionManager::UnwrapColorSpace(const napi_env &env, const napi_value &jsValue,
1632     StreamParams &streamParam)
1633 {
1634     bool hasProperty = false;
1635     if (napi_has_named_property(env, jsValue, "colorSpaceConversionTarget", &hasProperty) != napi_ok || !hasProperty) {
1636         HILOGW("no colorSpaceConversionTarget propertys");
1637         return true;
1638     }
1639 
1640     int32_t colorSpace = -1;
1641     if (!JsObjectToInt(env, jsValue, "colorSpaceConversionTarget", colorSpace)) {
1642         HILOGE("colorSpace verification failed.");
1643         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1644         return false;
1645     }
1646 
1647     // only BT709_LIMIT is supported
1648     if (colorSpace != static_cast<int32_t>(ColorSpace::BT709_LIMIT)) {
1649         HILOGE("colorSpace not BT709_LIMIT.");
1650         CreateBusinessError(env, NOT_SUPPORTED_COLOR_SPACE);
1651         return false;
1652     }
1653     streamParam.colorSpace = static_cast<ColorSpace>(colorSpace);
1654     return true;
1655 }
1656 
ExecuteCreateStream(napi_env env,void * data)1657 void JsAbilityConnectionManager::ExecuteCreateStream(napi_env env, void *data)
1658 {
1659     AsyncCallbackInfo* asyncData = static_cast<AsyncCallbackInfo*>(data);
1660 
1661     asyncData->result = AbilityConnectionManager::GetInstance().CreateStream(asyncData->sessionId,
1662         asyncData->streamParam, asyncData->streamId);
1663 }
1664 
CompleteAsyncCreateStreamWork(napi_env env,napi_status status,void * data)1665 void JsAbilityConnectionManager::CompleteAsyncCreateStreamWork(napi_env env, napi_status status, void* data)
1666 {
1667     HILOGI("called.");
1668     if (data == nullptr) {
1669         HILOGE("Async data is null");
1670         return;
1671     }
1672 
1673     AsyncCallbackInfo* asyncData = static_cast<AsyncCallbackInfo*>(data);
1674     if (asyncData->result == ERR_OK) {
1675         napi_value result;
1676         napi_create_int32(env, asyncData->streamId, &result);
1677         napi_resolve_deferred(env, asyncData->deferred, result);
1678     } else {
1679         napi_reject_deferred(env, asyncData->deferred,
1680             CreateBusinessError(env, asyncData->result, false));
1681     }
1682     napi_delete_async_work(env, asyncData->asyncWork);
1683     delete asyncData;
1684 }
1685 
SetSurfaceId(napi_env env,napi_callback_info info)1686 napi_value JsAbilityConnectionManager::SetSurfaceId(napi_env env, napi_callback_info info)
1687 {
1688     HILOGI("called.");
1689     if (!IsSystemApp()) {
1690         HILOGE("Permission verification failed.");
1691         CreateBusinessError(env, ERR_IS_NOT_SYSTEM_APP);
1692     }
1693 
1694     GET_PARAMS(env, info, ARG_COUNT_THREE);
1695     if (argc != ARG_COUNT_THREE) {
1696         HILOGE("CheckArgsCount failed.");
1697         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1698         return nullptr;
1699     }
1700 
1701     int32_t streamId = -1;
1702     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "streamId", streamId)) {
1703         HILOGE("Parameter parsing failed.");
1704         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1705         return nullptr;
1706     }
1707 
1708     std::string surfaceId;
1709     if (!JsToString(env, argv[ARG_INDEX_ONE], "surfaceId", surfaceId)) {
1710         HILOGE("surfaceId parsing failed.");
1711         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1712         return nullptr;
1713     }
1714 
1715     SurfaceParams surfaceParam;
1716     if (!JsToSurfaceParam(env, argv[ARG_INDEX_TWO], surfaceParam)) {
1717         HILOGE("Failed to unwrap surfaceParam.");
1718         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1719         return nullptr;
1720     }
1721 
1722     int32_t ret = AbilityConnectionManager::GetInstance().SetSurfaceId(streamId,
1723         surfaceId, surfaceParam);
1724     if (ret != ERR_OK) {
1725         HILOGE("SetSurfaceId failed.");
1726         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
1727     }
1728     return nullptr;
1729 }
1730 
JsToSurfaceParam(const napi_env & env,const napi_value & jsValue,SurfaceParams & surfaceParam)1731 bool JsAbilityConnectionManager::JsToSurfaceParam(const napi_env &env, const napi_value &jsValue,
1732     SurfaceParams &surfaceParam)
1733 {
1734     napi_valuetype argvType = napi_undefined;
1735     NAPI_CALL_BASE(env, napi_typeof(env, jsValue, &argvType), false);
1736     if (argvType != napi_object) {
1737         HILOGE("Parameter verification failed.");
1738         return false;
1739     }
1740 
1741     if (!JsObjectToInt(env, jsValue, "width", surfaceParam.width)) {
1742         HILOGE("Unable to get width parameter.");
1743         return false;
1744     }
1745 
1746     if (!JsObjectToInt(env, jsValue, "height", surfaceParam.height)) {
1747         HILOGE("Unable to get height parameter.");
1748         return false;
1749     }
1750 
1751     int32_t format = -1;
1752     if (JsObjectToInt(env, jsValue, "format", format)) {
1753         if (format < static_cast<int32_t>(VideoPixelFormat::UNKNOWN) ||
1754             format > static_cast<int32_t>(VideoPixelFormat::NV21)) {
1755             HILOGE("Invalid format value: %{public}d", format);
1756             return false;
1757         }
1758         surfaceParam.format = static_cast<VideoPixelFormat>(format);
1759     }
1760 
1761     int32_t flip = -1;
1762     if (JsObjectToInt(env, jsValue, "flip", flip)) {
1763         if (flip < static_cast<int32_t>(FlipOptions::HORIZONTAL) ||
1764             flip > static_cast<int32_t>(FlipOptions::VERTICAL)) {
1765             HILOGE("Invalid flip value: %{public}d", flip);
1766             return false;
1767         }
1768         surfaceParam.flip = static_cast<FlipOptions>(flip);
1769     }
1770 
1771     if (!JsObjectToInt(env, jsValue, "rotation", surfaceParam.rotation)) {
1772         HILOGW("Unable to get rotation parameter.");
1773     }
1774 
1775     return true;
1776 }
1777 
GetSurfaceId(napi_env env,napi_callback_info info)1778 napi_value JsAbilityConnectionManager::GetSurfaceId(napi_env env, napi_callback_info info)
1779 {
1780     HILOGI("called.");
1781     if (!IsSystemApp()) {
1782         HILOGE("Permission verification failed.");
1783         CreateBusinessError(env, ERR_IS_NOT_SYSTEM_APP);
1784     }
1785 
1786     GET_PARAMS(env, info, ARG_COUNT_TWO);
1787     if (argc != ARG_COUNT_TWO) {
1788         HILOGE("CheckArgsCount failed.");
1789         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1790         return nullptr;
1791     }
1792 
1793     int32_t streamId = -1;
1794     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "streamId", streamId)) {
1795         HILOGE("Parameter parsing failed.");
1796         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1797         return nullptr;
1798     }
1799 
1800     SurfaceParams surfaceParam;
1801     if (!JsToSurfaceParam(env, argv[ARG_INDEX_ONE], surfaceParam)) {
1802         HILOGE("Failed to unwrap surfaceParam.");
1803         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1804         return nullptr;
1805     }
1806 
1807     std::string surfaceId;
1808     int32_t ret = AbilityConnectionManager::GetInstance().GetSurfaceId(streamId, surfaceParam, surfaceId);
1809     if (ret != ERR_OK) {
1810         HILOGE("SetSurfaceId failed.");
1811         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
1812         return nullptr;
1813     }
1814 
1815     napi_value result;
1816     napi_create_string_utf8(env, surfaceId.c_str(), surfaceId.size(), &result);
1817     return result;
1818 }
1819 
UpdateSurfaceParam(napi_env env,napi_callback_info info)1820 napi_value JsAbilityConnectionManager::UpdateSurfaceParam(napi_env env, napi_callback_info info)
1821 {
1822     HILOGI("called.");
1823     if (!IsSystemApp()) {
1824         HILOGE("Permission verification failed.");
1825         CreateBusinessError(env, ERR_IS_NOT_SYSTEM_APP);
1826     }
1827 
1828     GET_PARAMS(env, info, ARG_COUNT_TWO);
1829     if (argc != ARG_COUNT_TWO) {
1830         HILOGE("CheckArgsCount failed.");
1831         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1832         return nullptr;
1833     }
1834 
1835     int32_t streamId = -1;
1836     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "streamId", streamId)) {
1837         HILOGE("streamId parsing failed.");
1838         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1839         return nullptr;
1840     }
1841 
1842     SurfaceParams surfaceParam;
1843     if (!JsToSurfaceParam(env, argv[ARG_INDEX_ONE], surfaceParam)) {
1844         HILOGE("Failed to unwrap surfaceParam.");
1845         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1846         return nullptr;
1847     }
1848 
1849     int32_t ret = AbilityConnectionManager::GetInstance().UpdateSurfaceParam(streamId, surfaceParam);
1850     if (ret != ERR_OK) {
1851         HILOGE("SetSurfaceId failed.");
1852         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
1853     }
1854     return nullptr;
1855 }
1856 
DestroyStream(napi_env env,napi_callback_info info)1857 napi_value JsAbilityConnectionManager::DestroyStream(napi_env env, napi_callback_info info)
1858 {
1859     HILOGI("called.");
1860     if (!IsSystemApp()) {
1861         HILOGE("Permission verification failed.");
1862         CreateBusinessError(env, ERR_IS_NOT_SYSTEM_APP);
1863     }
1864 
1865     GET_PARAMS(env, info, ARG_COUNT_ONE);
1866     if (argc != ARG_COUNT_ONE) {
1867         HILOGE("CheckArgsCount failed.");
1868         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1869         return nullptr;
1870     }
1871 
1872     int32_t streamId = -1;
1873     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "streamId", streamId)) {
1874         HILOGE("Parameter parsing failed.");
1875         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1876         return nullptr;
1877     }
1878 
1879     int32_t ret = AbilityConnectionManager::GetInstance().DestroyStream(streamId);
1880     if (ret != ERR_OK) {
1881         HILOGE("DestroyStream failed.");
1882         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
1883     }
1884     return nullptr;
1885 }
1886 
StartStream(napi_env env,napi_callback_info info)1887 napi_value JsAbilityConnectionManager::StartStream(napi_env env, napi_callback_info info)
1888 {
1889     HILOGI("called.");
1890     if (!IsSystemApp()) {
1891         HILOGE("Permission verification failed.");
1892         CreateBusinessError(env, ERR_IS_NOT_SYSTEM_APP);
1893     }
1894 
1895     GET_PARAMS(env, info, ARG_COUNT_ONE);
1896     if (argc != ARG_COUNT_ONE) {
1897         HILOGE("CheckArgsCount failed.");
1898         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1899         return nullptr;
1900     }
1901 
1902     int32_t streamId = -1;
1903     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "streamId", streamId)) {
1904         HILOGE("Parameter parsing failed.");
1905         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1906         return nullptr;
1907     }
1908 
1909     int32_t ret = AbilityConnectionManager::GetInstance().StartStream(streamId);
1910     if (ret != ERR_OK) {
1911         HILOGE("StartStream failed.");
1912         CreateBusinessError(env, ret);
1913     }
1914     return nullptr;
1915 }
1916 
StopStream(napi_env env,napi_callback_info info)1917 napi_value JsAbilityConnectionManager::StopStream(napi_env env, napi_callback_info info)
1918 {
1919     HILOGI("called.");
1920     if (!IsSystemApp()) {
1921         HILOGE("Permission verification failed.");
1922         CreateBusinessError(env, ERR_IS_NOT_SYSTEM_APP);
1923     }
1924 
1925     GET_PARAMS(env, info, ARG_COUNT_ONE);
1926     if (argc != ARG_COUNT_ONE) {
1927         HILOGE("CheckArgsCount failed.");
1928         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1929         return nullptr;
1930     }
1931 
1932     int32_t streamId = -1;
1933     if (!JsToInt32(env, argv[ARG_INDEX_ZERO], "streamId", streamId)) {
1934         HILOGE("Parameter parsing failed.");
1935         CreateBusinessError(env, ERR_INVALID_PARAMETERS);
1936         return nullptr;
1937     }
1938 
1939     int32_t ret = AbilityConnectionManager::GetInstance().StopStream(streamId);
1940     if (ret != ERR_OK) {
1941         HILOGE("StopStream failed.");
1942         CreateBusinessError(env, ERR_EXECUTE_FUNCTION);
1943     }
1944     return nullptr;
1945 }
1946 
InitConnectOptionParams(napi_env & env,napi_value & exports)1947 void InitConnectOptionParams(napi_env& env, napi_value& exports)
1948 {
1949     char propertyName[] = "ConnectOptionParams";
1950     napi_value startOptionKey = nullptr;
1951     napi_value startToForeground = nullptr;
1952     napi_value startTobackground = nullptr;
1953     napi_create_string_utf8(env, KEY_START_OPTION.c_str(), KEY_START_OPTION.size(), &startOptionKey);
1954     napi_create_string_utf8(env, VALUE_START_OPTION_FOREGROUND.c_str(),
1955         VALUE_START_OPTION_FOREGROUND.size(), &startToForeground);
1956     napi_create_string_utf8(env, VALUE_START_OPTION_BACKGROUND.c_str(),
1957         VALUE_START_OPTION_BACKGROUND.size(), &startTobackground);
1958 
1959     napi_property_descriptor desc[] = {
1960         DECLARE_NAPI_STATIC_PROPERTY("KEY_START_OPTION", startOptionKey),
1961         DECLARE_NAPI_STATIC_PROPERTY("VALUE_START_OPTION_FOREGROUND", startToForeground),
1962         DECLARE_NAPI_STATIC_PROPERTY("VALUE_START_OPTION_BACKGROUND", startTobackground),
1963     };
1964     napi_value obj = nullptr;
1965     napi_create_object(env, &obj);
1966     napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc);
1967     napi_set_named_property(env, exports, propertyName, obj);
1968 }
1969 
InitDisconnectReason(napi_env & env,napi_value & exports)1970 void InitDisconnectReason(napi_env& env, napi_value& exports)
1971 {
1972     char propertyName[] = "DisconnectReason";
1973     napi_value peerAppExit = nullptr;
1974     napi_value peerAppCloseCollab = nullptr;
1975     napi_value networkDisconnected = nullptr;
1976     napi_create_int32(env,
1977         static_cast<int32_t>(DisconnectReason::PEER_APP_CLOSE_COLLABORATION), &peerAppCloseCollab);
1978     napi_create_int32(env,
1979         static_cast<int32_t>(DisconnectReason::PEER_APP_EXIT), &peerAppExit);
1980     napi_create_int32(env,
1981         static_cast<int32_t>(DisconnectReason::NETWORK_DISCONNECTED), &networkDisconnected);
1982 
1983     napi_property_descriptor desc[] = {
1984         DECLARE_NAPI_STATIC_PROPERTY("PEER_APP_CLOSE_COLLABORATION", peerAppCloseCollab),
1985         DECLARE_NAPI_STATIC_PROPERTY("PEER_APP_EXIT", peerAppExit),
1986         DECLARE_NAPI_STATIC_PROPERTY("NETWORK_DISCONNECTED", networkDisconnected),
1987     };
1988     napi_value obj = nullptr;
1989     napi_create_object(env, &obj);
1990     napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc);
1991     napi_set_named_property(env, exports, propertyName, obj);
1992 }
1993 
InitFlipOptions(napi_env & env,napi_value & exports)1994 void InitFlipOptions(napi_env& env, napi_value& exports)
1995 {
1996     char propertyName[] = "FlipOptions";
1997     char propertyNameOld[] = "FlipOption";
1998     napi_value horizontal = nullptr;
1999     napi_value vertical = nullptr;
2000     napi_create_int32(env, static_cast<int32_t>(FlipOptions::HORIZONTAL), &horizontal);
2001     napi_create_int32(env, static_cast<int32_t>(FlipOptions::VERTICAL), &vertical);
2002 
2003     napi_property_descriptor desc[] = {
2004         DECLARE_NAPI_STATIC_PROPERTY("HORIZONTAL", horizontal),
2005         DECLARE_NAPI_STATIC_PROPERTY("VERTICAL", vertical),
2006     };
2007     napi_value obj = nullptr;
2008     napi_create_object(env, &obj);
2009     napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc);
2010     napi_set_named_property(env, exports, propertyName, obj);
2011     napi_set_named_property(env, exports, propertyNameOld, obj);
2012 }
2013 
InitStreamRole(napi_env & env,napi_value & exports)2014 void InitStreamRole(napi_env& env, napi_value& exports)
2015 {
2016     char propertyName[] = "StreamRole";
2017     napi_value source = nullptr;
2018     napi_value sink = nullptr;
2019     napi_create_int32(env, SOURCE, &source);
2020     napi_create_int32(env, SINK, &sink);
2021 
2022     napi_property_descriptor desc[] = {
2023         DECLARE_NAPI_STATIC_PROPERTY("SOURCE", source),
2024         DECLARE_NAPI_STATIC_PROPERTY("SINK", sink),
2025     };
2026     napi_value obj = nullptr;
2027     napi_create_object(env, &obj);
2028     napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc);
2029     napi_set_named_property(env, exports, propertyName, obj);
2030 }
2031 
InitVideoPixelFormat(napi_env & env,napi_value & exports)2032 void InitVideoPixelFormat(napi_env& env, napi_value& exports)
2033 {
2034     char propertyName[] = "VideoPixelFormat";
2035     napi_value unknown = nullptr;
2036     napi_value nv12 = nullptr;
2037     napi_value nv21 = nullptr;
2038     napi_create_int32(env, UNKNOWN, &unknown);
2039     napi_create_int32(env, NV12, &nv12);
2040     napi_create_int32(env, NV21, &nv21);
2041 
2042     napi_property_descriptor desc[] = {
2043         DECLARE_NAPI_STATIC_PROPERTY("UNKNOWN", unknown),
2044         DECLARE_NAPI_STATIC_PROPERTY("NV12", nv12),
2045         DECLARE_NAPI_STATIC_PROPERTY("NV21", nv21),
2046     };
2047     napi_value obj = nullptr;
2048     napi_create_object(env, &obj);
2049     napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc);
2050     napi_set_named_property(env, exports, propertyName, obj);
2051 }
2052 
InitStartOptionParams(napi_env & env,napi_value & exports)2053 void InitStartOptionParams(napi_env& env, napi_value& exports)
2054 {
2055     char propertyName[] = "StartOptionParams";
2056     napi_value startInForeground = nullptr;
2057     napi_value startInBackground = nullptr;
2058     napi_create_int32(env, static_cast<int32_t>(StartOptionParams::START_IN_FOREGROUND),
2059         &startInForeground);
2060     napi_create_int32(env, static_cast<int32_t>(StartOptionParams::START_IN_BACKGROUND),
2061         &startInBackground);
2062 
2063     napi_property_descriptor desc[] = {
2064         DECLARE_NAPI_STATIC_PROPERTY("START_IN_FOREGROUND", startInForeground),
2065         DECLARE_NAPI_STATIC_PROPERTY("START_IN_BACKGROUND", startInBackground),
2066     };
2067     napi_value obj = nullptr;
2068     napi_create_object(env, &obj);
2069     napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc);
2070     napi_set_named_property(env, exports, propertyName, obj);
2071 }
2072 
InitCollaborateEventType(napi_env & env,napi_value & exports)2073 void InitCollaborateEventType(napi_env& env, napi_value& exports)
2074 {
2075     char propertyName[] = "CollaborateEventType";
2076     napi_value sendFailure = nullptr;
2077     napi_value colorSpaceConversionFailure = nullptr;
2078     napi_create_int32(env, static_cast<int32_t>(CollaborateEventType::SEND_FAILURE),
2079         &sendFailure);
2080     napi_create_int32(env, static_cast<int32_t>(CollaborateEventType::COLOR_SPACE_CONVERSION_FAILURE),
2081         &colorSpaceConversionFailure);
2082 
2083     napi_property_descriptor desc[] = {
2084         DECLARE_NAPI_STATIC_PROPERTY("SEND_FAILURE", sendFailure),
2085         DECLARE_NAPI_STATIC_PROPERTY("COLOR_SPACE_CONVERSION_FAILURE", colorSpaceConversionFailure),
2086     };
2087     napi_value obj = nullptr;
2088     napi_create_object(env, &obj);
2089     napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc);
2090     napi_set_named_property(env, exports, propertyName, obj);
2091 }
2092 
InitConnectErrorCode(napi_env env,napi_value exports)2093 void InitConnectErrorCode(napi_env env, napi_value exports)
2094 {
2095     char propertyName[] = "ConnectErrorCode";
2096     napi_value connectedSessionExists = nullptr;
2097     napi_value peerAppRejected = nullptr;
2098     napi_value localWifiNotOpen = nullptr;
2099     napi_value peerWifiNotOpen = nullptr;
2100     napi_value peerAbilityNoOncollaborate = nullptr;
2101     napi_value systemInternalError = nullptr;
2102 
2103     napi_create_int32(env,
2104         static_cast<int32_t>(ConnectErrorCode::CONNECTED_SESSION_EXISTS), &connectedSessionExists);
2105     napi_create_int32(env,
2106         static_cast<int32_t>(ConnectErrorCode::PEER_APP_REJECTED), &peerAppRejected);
2107     napi_create_int32(env,
2108         static_cast<int32_t>(ConnectErrorCode::LOCAL_WIFI_NOT_OPEN), &localWifiNotOpen);
2109     napi_create_int32(env,
2110         static_cast<int32_t>(ConnectErrorCode::PEER_WIFI_NOT_OPEN), &peerWifiNotOpen);
2111     napi_create_int32(env,
2112         static_cast<int32_t>(ConnectErrorCode::PEER_ABILITY_NO_ONCOLLABORATE), &peerAbilityNoOncollaborate);
2113     napi_create_int32(env,
2114         static_cast<int32_t>(ConnectErrorCode::SYSTEM_INTERNAL_ERROR), &systemInternalError);
2115 
2116     napi_property_descriptor desc[] = {
2117         DECLARE_NAPI_STATIC_PROPERTY("CONNECTED_SESSION_EXISTS", connectedSessionExists),
2118         DECLARE_NAPI_STATIC_PROPERTY("PEER_APP_REJECTED", peerAppRejected),
2119         DECLARE_NAPI_STATIC_PROPERTY("LOCAL_WIFI_NOT_OPEN", localWifiNotOpen),
2120         DECLARE_NAPI_STATIC_PROPERTY("PEER_WIFI_NOT_OPEN", peerWifiNotOpen),
2121         DECLARE_NAPI_STATIC_PROPERTY("PEER_ABILITY_NO_ONCOLLABORATE", peerAbilityNoOncollaborate),
2122         DECLARE_NAPI_STATIC_PROPERTY("SYSTEM_INTERNAL_ERROR", systemInternalError),
2123     };
2124 
2125     napi_value obj = nullptr;
2126     napi_create_object(env, &obj);
2127     napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc);
2128     napi_set_named_property(env, exports, propertyName, obj);
2129 }
2130 
InitCollaborationKeys(napi_env & env,napi_value & exports)2131 void InitCollaborationKeys(napi_env& env, napi_value& exports)
2132 {
2133     char propertyName[] = "CollaborationKeys";
2134     napi_value peerInfo = nullptr;
2135     napi_value connectOptions = nullptr;
2136     napi_value collaborateType = nullptr;
2137 
2138     napi_create_string_utf8(env, COLLABORATE_KEYS_PEER_INFO.c_str(),
2139         COLLABORATE_KEYS_PEER_INFO.size(), &peerInfo);
2140     napi_create_string_utf8(env, COLLABORATE_KEYS_CONNECT_OPTIONS.c_str(),
2141         COLLABORATE_KEYS_CONNECT_OPTIONS.size(), &connectOptions);
2142     napi_create_string_utf8(env, COLLABORATE_KEYS_COLLABORATE_TYPE.c_str(),
2143         COLLABORATE_KEYS_COLLABORATE_TYPE.size(), &collaborateType);
2144 
2145     napi_property_descriptor desc[] = {
2146         DECLARE_NAPI_STATIC_PROPERTY("PEER_INFO", peerInfo),
2147         DECLARE_NAPI_STATIC_PROPERTY("CONNECT_OPTIONS", connectOptions),
2148         DECLARE_NAPI_STATIC_PROPERTY("COLLABORATE_TYPE", collaborateType),
2149     };
2150     napi_value obj = nullptr;
2151     napi_create_object(env, &obj);
2152     napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc);
2153     napi_set_named_property(env, exports, propertyName, obj);
2154 }
2155 
InitCollaborationValues(napi_env & env,napi_value & exports)2156 void InitCollaborationValues(napi_env& env, napi_value& exports)
2157 {
2158     char propertyName[] = "CollaborationValues";
2159     napi_value abilityCollab = nullptr;
2160     napi_value connectProxy = nullptr;
2161 
2162     napi_create_string_utf8(env, ABILITY_COLLABORATION_TYPE_DEFAULT.c_str(),
2163         ABILITY_COLLABORATION_TYPE_DEFAULT.size(), &abilityCollab);
2164     napi_create_string_utf8(env, ABILITY_COLLABORATION_TYPE_CONNECT_PROXY.c_str(),
2165         ABILITY_COLLABORATION_TYPE_CONNECT_PROXY.size(), &connectProxy);
2166 
2167     napi_property_descriptor desc[] = {
2168         DECLARE_NAPI_STATIC_PROPERTY("ABILITY_COLLABORATION_TYPE_DEFAULT", abilityCollab),
2169         DECLARE_NAPI_STATIC_PROPERTY("ABILITY_COLLABORATION_TYPE_CONNECT_PROXY", connectProxy),
2170     };
2171     napi_value obj = nullptr;
2172     napi_create_object(env, &obj);
2173     napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc);
2174     napi_set_named_property(env, exports, propertyName, obj);
2175 }
2176 
InitFunction(napi_env env,napi_value exports)2177 void InitFunction(napi_env env, napi_value exports)
2178 {
2179     static napi_property_descriptor desc[] = {
2180         DECLARE_NAPI_FUNCTION("createAbilityConnectionSession",
2181             JsAbilityConnectionManager::CreateAbilityConnectionSession),
2182         DECLARE_NAPI_FUNCTION("destroyAbilityConnectionSession",
2183             JsAbilityConnectionManager::DestroyAbilityConnectionSession),
2184         DECLARE_NAPI_FUNCTION("getPeerInfoById", JsAbilityConnectionManager::GetPeerInfoById),
2185         DECLARE_NAPI_FUNCTION("on", JsAbilityConnectionManager::RegisterAbilityConnectionSessionCallback),
2186         DECLARE_NAPI_FUNCTION("off", JsAbilityConnectionManager::UnregisterAbilityConnectionSessionCallback),
2187         DECLARE_NAPI_FUNCTION("connect", JsAbilityConnectionManager::Connect),
2188         DECLARE_NAPI_FUNCTION("disconnect", JsAbilityConnectionManager::DisConnect),
2189         DECLARE_NAPI_FUNCTION("acceptConnect", JsAbilityConnectionManager::AcceptConnect),
2190         DECLARE_NAPI_FUNCTION("reject", JsAbilityConnectionManager::Reject),
2191         DECLARE_NAPI_FUNCTION("sendMessage", JsAbilityConnectionManager::SendMessage),
2192         DECLARE_NAPI_FUNCTION("sendData", JsAbilityConnectionManager::SendData),
2193         DECLARE_NAPI_FUNCTION("sendImage", JsAbilityConnectionManager::SendImage),
2194         DECLARE_NAPI_FUNCTION("createStream", JsAbilityConnectionManager::CreateStream),
2195         DECLARE_NAPI_FUNCTION("setSurfaceId", JsAbilityConnectionManager::SetSurfaceId),
2196         DECLARE_NAPI_FUNCTION("getSurfaceId", JsAbilityConnectionManager::GetSurfaceId),
2197         DECLARE_NAPI_FUNCTION("updateSurfaceParam", JsAbilityConnectionManager::UpdateSurfaceParam),
2198         DECLARE_NAPI_FUNCTION("destroyStream", JsAbilityConnectionManager::DestroyStream),
2199         DECLARE_NAPI_FUNCTION("startStream", JsAbilityConnectionManager::StartStream),
2200         DECLARE_NAPI_FUNCTION("stopStream", JsAbilityConnectionManager::StopStream),
2201     };
2202     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
2203 }
2204 
JsAbilityConnectionManagerInit(napi_env env,napi_value exports)2205 napi_value JsAbilityConnectionManagerInit(napi_env env, napi_value exports)
2206 {
2207     HILOGD("called.");
2208     if (env == nullptr || exports == nullptr) {
2209         HILOGE("Invalid input parameters");
2210         return nullptr;
2211     }
2212     InitConnectOptionParams(env, exports);
2213     InitDisconnectReason(env, exports);
2214     InitFlipOptions(env, exports);
2215     InitStreamRole(env, exports);
2216     InitVideoPixelFormat(env, exports);
2217     InitStartOptionParams(env, exports);
2218     InitCollaborateEventType(env, exports);
2219     InitConnectErrorCode(env, exports);
2220     InitCollaborationKeys(env, exports);
2221     InitCollaborationValues(env, exports);
2222     InitFunction(env, exports);
2223 
2224     HILOGI("napi_define_properties end");
2225     return exports;
2226 }
2227 }  // namespace DistributedCollab
2228 }  // namespace OHOS