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", ¶metersVal) == 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