1 /*
2 * Copyright (c) 2022-2025 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 "napi_avsession_manager.h"
17 #include "avcontrol_command.h"
18 #include "avplayback_state.h"
19 #include "avsession_errors.h"
20 #include "key_event.h"
21 #include "ability.h"
22 #include "napi_base_context.h"
23 #include "napi_utils.h"
24 #include "napi_async_work.h"
25 #include "napi_avsession.h"
26 #include "napi_avsession_controller.h"
27 #include "napi_control_command.h"
28 #include "avsession_trace.h"
29 #include "avsession_sysevent.h"
30 #include "ipc_skeleton.h"
31 #include "tokenid_kit.h"
32 #include "avsession_radar.h"
33 #include "permission_checker.h"
34
35 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
36 #include "napi_avcast_controller.h"
37 #endif
38
39 namespace OHOS::AVSession {
40 using namespace Security::AccessToken;
41 std::map<std::string, std::pair<NapiAVSessionManager::OnEventHandlerType, NapiAVSessionManager::OffEventHandlerType>>
42 NapiAVSessionManager::eventHandlers_ = {
43 { "sessionCreate", { OnSessionCreate, OffSessionCreate } },
44 { "sessionDestroy", { OnSessionDestroy, OffSessionDestroy } },
45 { "topSessionChange", { OnTopSessionChange, OffTopSessionChange } },
46 { "sessionServiceDie", { OnServiceDie, OffServiceDie } },
47 { "deviceAvailable", { OnDeviceAvailable, OffDeviceAvailable } },
48 { "deviceLogEvent", { OnDeviceLogEvent, OffDeviceLogEvent } },
49 { "deviceOffline", { OnDeviceOffline, OffDeviceOffline } },
50 { "deviceStateChanged", { OnDeviceStateChanged, OffDeviceStateChanged } },
51 };
52
53 std::map<DistributedSessionType, std::pair<NapiAVSessionManager::OnEventHandlerType,
54 NapiAVSessionManager::OffEventHandlerType>> NapiAVSessionManager::distributedControllerEventHandlers_ = {
55 { DistributedSessionType::TYPE_SESSION_REMOTE, {
56 OnRemoteDistributedSessionChange, OffRemoteDistributedSessionChange } },
57 };
58
59 const std::string NapiAVSessionManager::DISTRIBUTED_SESSION_CHANGE_EVENT = "distributedSessionChange";
60
61 std::shared_ptr<NapiSessionListener> NapiAVSessionManager::listener_;
62 std::shared_ptr<NapiAsyncCallback> NapiAVSessionManager::asyncCallback_;
63 std::list<napi_ref> NapiAVSessionManager::serviceDiedCallbacks_;
64 std::mutex createControllerMutex_;
65 std::mutex listenersMutex_;
66
67 std::map<int32_t, int32_t> NapiAVSessionManager::errcode_ = {
68 {AVSESSION_ERROR, 6600101},
69 {ERR_NO_MEMORY, 6600101},
70 {ERR_SERVICE_NOT_EXIST, 6600101},
71 {ERR_SESSION_LISTENER_EXIST, 6600101},
72 {ERR_MARSHALLING, 6600101},
73 {ERR_UNMARSHALLING, 6600101},
74 {ERR_IPC_SEND_REQUEST, 6600101},
75 {ERR_CONTROLLER_IS_EXIST, 6600101},
76 {ERR_START_ABILITY_IS_RUNNING, 6600101},
77 {ERR_ABILITY_NOT_AVAILABLE, 6600101},
78 {ERR_START_ABILITY_TIMEOUT, 6600101},
79 {ERR_SESSION_NOT_EXIST, 6600102},
80 {ERR_CONTROLLER_NOT_EXIST, 6600103},
81 {ERR_RPC_SEND_REQUEST, 6600104},
82 {ERR_COMMAND_NOT_SUPPORT, 6600105},
83 {ERR_SESSION_DEACTIVE, 6600106},
84 {ERR_COMMAND_SEND_EXCEED_MAX, 6600107},
85 {ERR_DEVICE_CONNECTION_FAILED, 6600108},
86 {ERR_REMOTE_CONNECTION_NOT_EXIST, 6600109},
87 {ERR_SESSION_IS_EXIST, 6600101},
88 {ERR_PERMISSION_DENIED, 201},
89 {ERR_NO_PERMISSION, 202},
90 {ERR_INVALID_PARAM, 401},
91 {ERR_REPEAT_CAST, 6600101},
92 {ERR_WAIT_ALLCONNECT_TIMEOUT, 6600101},
93 {ERR_ALLCONNECT_CAST_REJECT, 6600101},
94 };
Init(napi_env env,napi_value exports)95 napi_value NapiAVSessionManager::Init(napi_env env, napi_value exports)
96 {
97 napi_property_descriptor descriptors[] = {
98 DECLARE_NAPI_STATIC_FUNCTION("createAVSession", CreateAVSession),
99 DECLARE_NAPI_STATIC_FUNCTION("createAVSessionWithExtra", CreateAVSessionWithExtra),
100 DECLARE_NAPI_STATIC_FUNCTION("getAllSessionDescriptors", GetAllSessionDescriptors),
101 DECLARE_NAPI_STATIC_FUNCTION("getHistoricalSessionDescriptors", GetHistoricalSessionDescriptors),
102 DECLARE_NAPI_STATIC_FUNCTION("getHistoricalAVQueueInfos", GetHistoricalAVQueueInfos),
103 DECLARE_NAPI_STATIC_FUNCTION("startAVPlayback", StartAVPlayback),
104 DECLARE_NAPI_STATIC_FUNCTION("createController", CreateController),
105 DECLARE_NAPI_STATIC_FUNCTION("getAVCastController", GetAVCastController),
106 DECLARE_NAPI_STATIC_FUNCTION("castAudio", CastAudio),
107 DECLARE_NAPI_STATIC_FUNCTION("on", OnEvent),
108 DECLARE_NAPI_STATIC_FUNCTION("off", OffEvent),
109 DECLARE_NAPI_STATIC_FUNCTION("sendSystemAVKeyEvent", SendSystemAVKeyEvent),
110 DECLARE_NAPI_STATIC_FUNCTION("sendSystemControlCommand", SendSystemControlCommand),
111 DECLARE_NAPI_STATIC_FUNCTION("startCastDeviceDiscovery", StartCastDiscovery),
112 DECLARE_NAPI_STATIC_FUNCTION("stopCastDeviceDiscovery", StopCastDiscovery),
113 DECLARE_NAPI_STATIC_FUNCTION("startDeviceLogging", StartDeviceLogging),
114 DECLARE_NAPI_STATIC_FUNCTION("stopDeviceLogging", StopDeviceLogging),
115 DECLARE_NAPI_STATIC_FUNCTION("setDiscoverable", SetDiscoverable),
116 DECLARE_NAPI_STATIC_FUNCTION("startCasting", StartCast),
117 DECLARE_NAPI_STATIC_FUNCTION("stopCasting", StopCast),
118 DECLARE_NAPI_STATIC_FUNCTION("getDistributedSessionController", GetDistributedSessionControllers),
119 };
120
121 napi_status status = napi_define_properties(env, exports, sizeof(descriptors) / sizeof(napi_property_descriptor),
122 descriptors);
123 if (status != napi_ok) {
124 SLOGE("define manager properties failed");
125 return NapiUtils::GetUndefinedValue(env);
126 }
127 return exports;
128 }
129
processMsg(std::shared_ptr<ContextBase> context,int32_t ret)130 void processMsg(std::shared_ptr<ContextBase> context, int32_t ret)
131 {
132 if (ret != AVSESSION_SUCCESS) {
133 if (ret == ERR_SESSION_IS_EXIST) {
134 context->errMessage = "CreateAVSession failed : session is existed";
135 } else {
136 context->errMessage = "CreateAVSession failed : native create session failed";
137 }
138 context->status = napi_generic_failure;
139 context->errCode = NapiAVSessionManager::errcode_[ret];
140 }
141 }
142
CreateAVSession(napi_env env,napi_callback_info info)143 napi_value NapiAVSessionManager::CreateAVSession(napi_env env, napi_callback_info info)
144 {
145 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::CreateAVSession");
146 struct ConcreteContext : public ContextBase {
147 std::string tag_;
148 int32_t type_{};
149 AppExecFwk::ElementName elementName_;
150 std::shared_ptr<AVSession> session_;
151 };
152 auto context = std::make_shared<ConcreteContext>();
153 context->taskId = NAPI_CREATE_AVSESSION_TASK_ID;
154
155 auto inputParser = [env, context](size_t argc, napi_value* argv) {
156 // require 3 arguments <context> <tag> <type>
157 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_THREE, "invalid arguments",
158 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
159 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->elementName_);
160 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "invalid context",
161 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
162 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->tag_);
163 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok && !context->tag_.empty(), "invalid tag",
164 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
165 std::string typeString;
166 context->status = NapiUtils::GetValue(env, argv[ARGV_THIRD], typeString);
167 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok && !typeString.empty(), "invalid type",
168 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
169 context->type_ = NapiUtils::ConvertSessionType(typeString);
170 CHECK_ARGS_RETURN_VOID(context, context->type_ >= 0, "wrong session type",
171 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
172 context->status = napi_ok;
173 };
174 context->GetCbInfo(env, info, inputParser);
175
176 auto res = AVSessionManager::GetInstance().RegisterServiceStartCallback(HandleServiceStart);
177 SLOGI("RegisterServiceStartCallback res=%{public}d", res);
178
179 auto executor = [context]() {
180 int32_t ret = AVSessionManager::GetInstance().CreateSession(context->tag_, context->type_,
181 context->elementName_, context->session_);
182 processMsg(context, ret);
183 };
184
185 auto complete = [context](napi_value& output) {
186 context->status = NapiAVSession::NewInstance(context->env, context->session_, output,
187 context->tag_, context->elementName_);
188 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
189 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
190 };
191
192 return NapiAsyncWork::Enqueue(env, context, "CreateAVSession", executor, complete);
193 }
194
CreateAVSessionWithExtra(napi_env env,napi_callback_info info)195 napi_value NapiAVSessionManager::CreateAVSessionWithExtra(napi_env env, napi_callback_info info)
196 {
197 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::CreateAVSession");
198 struct ConcreteContext : public ContextBase {
199 std::string tag_;
200 int32_t type_{};
201 AppExecFwk::ElementName elementName_;
202 std::shared_ptr<AVSession> session_;
203 std::string extraInfo_;
204 };
205 auto context = std::make_shared<ConcreteContext>();
206 context->taskId = NAPI_CREATE_AVSESSION_TASK_ID;
207
208 auto inputParser = [env, context](size_t argc, napi_value* argv) {
209 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_THREE, "invalid arguments",
210 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
211 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->elementName_);
212 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "invalid context",
213 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
214 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->tag_);
215 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok && !context->tag_.empty(), "invalid tag",
216 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
217 std::string typeString;
218 context->status = NapiUtils::GetValue(env, argv[ARGV_THIRD], typeString);
219 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok && !typeString.empty(), "invalid type",
220 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
221 context->type_ = NapiUtils::ConvertSessionType(typeString);
222 CHECK_ARGS_RETURN_VOID(context, context->type_ >= 0, "wrong session type",
223 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
224 std::string extraString;
225 context->status = NapiUtils::GetValue(env, argv[ARGV_FOURTH], extraString);
226 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok && !extraString.empty(), "invalid extra info",
227 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
228 context->extraInfo_ = extraString;
229 context->status = napi_ok;
230 };
231 context->GetCbInfo(env, info, inputParser);
232 AVSessionManager::GetInstance().RegisterServiceStartCallback(HandleServiceStart);
233 auto executor = [context]() {
234 int32_t ret = AVSessionManager::GetInstance().CreateSessionWithExtra(context->tag_, context->type_,
235 context->extraInfo_, context->elementName_,
236 context->session_);
237 processMsg(context, ret);
238 };
239
240 auto complete = [context](napi_value& output) {
241 context->status = NapiAVSession::NewInstance(context->env, context->session_, output,
242 context->tag_, context->elementName_);
243 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
244 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
245 };
246
247 return NapiAsyncWork::Enqueue(env, context, "CreateAVSessionWithExtra", executor, complete);
248 }
249
GetAllSessionDescriptors(napi_env env,napi_callback_info info)250 napi_value NapiAVSessionManager::GetAllSessionDescriptors(napi_env env, napi_callback_info info)
251 {
252 struct ConcreteContext : public ContextBase {
253 std::vector<AVSessionDescriptor> descriptors_;
254 };
255 auto context = std::make_shared<ConcreteContext>();
256 context->GetCbInfo(env, info);
257
258 auto executor = [context]() {
259 int32_t ret = AVSessionManager::GetInstance().GetAllSessionDescriptors(context->descriptors_);
260 if (ret != AVSESSION_SUCCESS) {
261 if (ret == ERR_NO_PERMISSION) {
262 context->errMessage = "GetAllSessionDescriptors failed : native no permission";
263 } else if (ret == ERR_PERMISSION_DENIED) {
264 context->errMessage = "GetAllSessionDescriptors failed : native permission denied";
265 } else {
266 context->errMessage = "GetAllSessionDescriptors failed : native server exception";
267 }
268 context->status = napi_generic_failure;
269 context->errCode = NapiAVSessionManager::errcode_[ret];
270 }
271 };
272
273 auto complete = [env, context](napi_value& output) {
274 context->status = NapiUtils::SetValue(env, context->descriptors_, output);
275 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
276 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
277 };
278
279 return NapiAsyncWork::Enqueue(env, context, "GetAllSessionDescriptors", executor, complete);
280 }
281
GetHistoricalSessionDescriptors(napi_env env,napi_callback_info info)282 napi_value NapiAVSessionManager::GetHistoricalSessionDescriptors(napi_env env, napi_callback_info info)
283 {
284 struct ConcreteContext : public ContextBase {
285 int32_t maxSize_ {};
286 std::vector<AVSessionDescriptor> descriptors_;
287 };
288 auto context = std::make_shared<ConcreteContext>();
289
290 auto input = [env, context](size_t argc, napi_value* argv) {
291 if (argc == ARGC_ONE && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_undefined)
292 && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_null)) {
293 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->maxSize_);
294 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "invalid arguments",
295 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
296 CHECK_ARGS_RETURN_VOID(context,
297 (context->maxSize_ >= static_cast<int32_t>(HISTORICAL_MIN_NUM)
298 && context->maxSize_ <= static_cast<int32_t>(HISTORICAL_MAX_NUM)),
299 "invalid arguments", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
300 } else {
301 context->maxSize_ = HISTORICAL_UNSET_NUM;
302 }
303 };
304
305 context->GetCbInfo(env, info, input);
306
307 auto executor = [context]() {
308 int32_t ret = AVSessionManager::GetInstance().GetHistoricalSessionDescriptors(context->maxSize_,
309 context->descriptors_);
310 if (ret != AVSESSION_SUCCESS) {
311 if (ret == ERR_NO_PERMISSION) {
312 context->errMessage = "GetHistoricalSessionDescriptors failed : native no permission";
313 } else if (ret == ERR_PERMISSION_DENIED) {
314 context->errMessage = "GetHistoricalSessionDescriptors failed : native permission denied";
315 } else {
316 context->errMessage = "GetHistoricalSessionDescriptors failed : native server exception";
317 }
318 context->status = napi_generic_failure;
319 context->errCode = NapiAVSessionManager::errcode_[ret];
320 }
321 };
322
323 auto complete = [env, context](napi_value& output) {
324 context->status = NapiUtils::SetValue(env, context->descriptors_, output);
325 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
326 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
327 };
328
329 return NapiAsyncWork::Enqueue(env, context, "GetHistoricalSessionDescriptors", executor, complete);
330 }
331
GetHistoricalAVQueueInfos(napi_env env,napi_callback_info info)332 napi_value NapiAVSessionManager::GetHistoricalAVQueueInfos(napi_env env, napi_callback_info info)
333 {
334 struct ConcreteContext : public ContextBase {
335 int32_t maxSize_ {};
336 int32_t maxAppSize_ {};
337 std::vector<AVQueueInfo> avQueueInfos_;
338 };
339 auto context = std::make_shared<ConcreteContext>();
340
341 auto input = [env, context](size_t argc, napi_value* argv) {
342 if (argc == ARGC_TWO && (!NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_undefined)
343 && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_null)
344 && !NapiUtils::TypeCheck(env, argv[ARGV_SECOND], napi_undefined)
345 && !NapiUtils::TypeCheck(env, argv[ARGV_SECOND], napi_null))) {
346 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->maxSize_);
347 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, " get avqueueinfo invalid maxSize",
348 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
349
350 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->maxAppSize_);
351 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, " get avqueueinfo invalid maxAppSize",
352 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
353 }
354 };
355
356 context->GetCbInfo(env, info, input);
357
358 auto executor = [context]() {
359 int32_t ret = AVSessionManager::GetInstance().GetHistoricalAVQueueInfos(context->maxSize_,
360 context->maxAppSize_, context->avQueueInfos_);
361 if (ret != AVSESSION_SUCCESS) {
362 if (ret == ERR_NO_PERMISSION) {
363 context->errMessage = "GetHistoricalAVQueueInfos failed : native no permission";
364 } else if (ret == ERR_PERMISSION_DENIED) {
365 context->errMessage = "GetHistoricalAVQueueInfos failed : native permission denied";
366 } else {
367 context->errMessage = "GetHistoricalAVQueueInfos failed : native server exception";
368 }
369 context->status = napi_generic_failure;
370 context->errCode = NapiAVSessionManager::errcode_[ret];
371 }
372 };
373
374 auto complete = [env, context](napi_value& output) {
375 context->status = NapiUtils::SetValue(env, context->avQueueInfos_, output);
376 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
377 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
378 };
379
380 return NapiAsyncWork::Enqueue(env, context, "GetHistoricalAVQueueInfos", executor, complete);
381 }
382
StartAVPlayback(napi_env env,napi_callback_info info)383 napi_value NapiAVSessionManager::StartAVPlayback(napi_env env, napi_callback_info info)
384 {
385 struct ConcreteContext : public ContextBase {
386 std::string bundleName_ {};
387 std::string assetId_ {};
388 };
389 auto context = std::make_shared<ConcreteContext>();
390
391 auto input = [env, context](size_t argc, napi_value* argv) {
392 if (argc == ARGC_TWO && (!NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_undefined)
393 && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_null)
394 && !NapiUtils::TypeCheck(env, argv[ARGV_SECOND], napi_undefined)
395 && !NapiUtils::TypeCheck(env, argv[ARGV_SECOND], napi_null))) {
396 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->bundleName_);
397 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok && !context->bundleName_.empty(),
398 " StartAVPlayback invalid bundlename", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
399
400 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->assetId_);
401 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, " StartAVPlayback invalid assetId",
402 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
403 }
404 };
405
406 context->GetCbInfo(env, info, input);
407
408 auto executor = [context]() {
409 int32_t ret = AVSessionManager::GetInstance().StartAVPlayback(context->bundleName_, context->assetId_);
410 if (ret != AVSESSION_SUCCESS) {
411 if (ret == ERR_NO_PERMISSION) {
412 context->errMessage = "StartAVPlayback failed : native no permission";
413 } else if (ret == ERR_PERMISSION_DENIED) {
414 context->errMessage = "StartAVPlayback failed : native permission denied";
415 } else {
416 context->errMessage = "StartAVPlayback failed : native server exception";
417 }
418 context->status = napi_generic_failure;
419 context->errCode = NapiAVSessionManager::errcode_[ret];
420 }
421 };
422
423 return NapiAsyncWork::Enqueue(env, context, "StartAVPlayback", executor);
424 }
425
GetDistributedSessionControllers(napi_env env,napi_callback_info info)426 napi_value NapiAVSessionManager::GetDistributedSessionControllers(napi_env env, napi_callback_info info)
427 {
428 SLOGI("GetDistributedSessionControllers");
429 struct ConcreteContext : public ContextBase {
430 DistributedSessionType sessionType_ {};
431 std::vector<std::shared_ptr<AVSessionController>> controllers_;
432 };
433 auto context = std::make_shared<ConcreteContext>();
434
435 auto input = [env, context](size_t argc, napi_value* argv) {
436 int32_t err = PermissionChecker::GetInstance().CheckPermission(
437 PermissionChecker::CHECK_SYSTEM_PERMISSION);
438 CHECK_ARGS_RETURN_VOID(context, err == ERR_NONE, "Check system permission error",
439 NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
440 if (argc == ARGC_ONE && (!NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_undefined)
441 && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_null))) {
442 int32_t sessionTypeValue = 0;
443 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], sessionTypeValue);
444 context->sessionType_ = DistributedSessionType(sessionTypeValue);
445 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok &&
446 context->sessionType_ >= DistributedSessionType::TYPE_SESSION_REMOTE &&
447 context->sessionType_ < DistributedSessionType::TYPE_SESSION_MAX,
448 "GetDistributedControllers invalid sessionType", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
449 }
450 };
451
452 context->GetCbInfo(env, info, input);
453
454 auto executor = [context]() {
455 int32_t ret = AVSessionManager::GetInstance().GetDistributedSessionControllers(
456 context->sessionType_, context->controllers_);
457 SLOGI("GetDistributedControllers ret:%{public}d|Size:%{public}d", ret, (int) context->controllers_.size());
458 if (ret != AVSESSION_SUCCESS) {
459 if (ret == ERR_NO_PERMISSION) {
460 context->errMessage = "GetDistributedSessionControllers failed : native no permission";
461 } else if (ret == ERR_PERMISSION_DENIED) {
462 context->errMessage = "GetDistributedSessionControllers failed : native permission denied";
463 } else if (ret == ERR_REMOTE_CONNECTION_NOT_EXIST) {
464 context->errMessage = "GetDistributedSessionControllers failed : connect not exist";
465 } else {
466 context->errMessage = "GetDistributedSessionControllers failed : native server exception";
467 }
468 context->status = napi_generic_failure;
469 context->errCode = NapiAVSessionManager::errcode_[ret];
470 }
471 };
472
473 auto complete = [env, context](napi_value& output) {
474 context->status = NapiUtils::SetValue(env, context->controllers_, output);
475 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
476 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
477 };
478 return NapiAsyncWork::Enqueue(env, context, "GetDistributedSessionControllers", executor, complete);
479 }
480
CreateController(napi_env env,napi_callback_info info)481 napi_value NapiAVSessionManager::CreateController(napi_env env, napi_callback_info info)
482 {
483 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::CreateController");
484 struct ConcreteContext : public ContextBase {
485 std::string sessionId_ {};
486 std::shared_ptr<AVSessionController> controller_;
487 };
488 auto context = std::make_shared<ConcreteContext>();
489 auto input = [env, context](size_t argc, napi_value* argv) {
490 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
491 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
492 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->sessionId_);
493 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (!context->sessionId_.empty()),
494 "invalid sessionId", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
495 };
496 context->GetCbInfo(env, info, input);
497 context->taskId = NAPI_CREATE_CONTROLLER_TASK_ID;
498 auto executor = [context]() {
499 int32_t ret = AVSessionManager::GetInstance().CreateController(context->sessionId_, context->controller_);
500 if (ret != AVSESSION_SUCCESS) {
501 if (ret == ERR_NO_PERMISSION) {
502 context->errMessage = "CreateController failed : native no permission";
503 } else if (ret == ERR_PERMISSION_DENIED) {
504 context->errMessage = "CreateController failed : native permission denied";
505 } else if (ret == ERR_INVALID_PARAM) {
506 context->errMessage = "CreateController failed : native invalid parameters";
507 } else if (ret == ERR_SESSION_NOT_EXIST) {
508 context->errMessage = "CreateController failed : native session not exist";
509 } else if (ret == ERR_CONTROLLER_IS_EXIST) {
510 SLOGE("create controlller with already has one");
511 context->errCode = ERR_CONTROLLER_IS_EXIST;
512 return;
513 } else {
514 context->errMessage = "CreateController failed : native server exception";
515 }
516 context->status = napi_generic_failure;
517 context->errCode = NapiAVSessionManager::errcode_[ret];
518 }
519 };
520 auto complete = [env, context](napi_value& output) {
521 SLOGE("check create controller with errCode %{public}d", static_cast<int>(context->errCode));
522 std::lock_guard lockGuard(createControllerMutex_);
523 if (context->errCode == ERR_CONTROLLER_IS_EXIST) {
524 SLOGE("check create controller meet repeat");
525 context->status = NapiAVSessionController::RepeatedInstance(env, context->sessionId_, output);
526 } else {
527 context->status = NapiAVSessionController::NewInstance(env, context->controller_, output);
528 }
529 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
530 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
531 };
532 return NapiAsyncWork::Enqueue(env, context, "CreateController", executor, complete);
533 }
534
GetAVCastController(napi_env env,napi_callback_info info)535 napi_value NapiAVSessionManager::GetAVCastController(napi_env env, napi_callback_info info)
536 {
537 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
538 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::GetAVCastController");
539 struct ConcreteContext : public ContextBase {
540 std::string sessionId_ {};
541 std::shared_ptr<AVCastController> castController_;
542 };
543 auto context = std::make_shared<ConcreteContext>();
544 auto input = [env, context](size_t argc, napi_value* argv) {
545 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
546 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
547 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->sessionId_);
548 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (!context->sessionId_.empty()),
549 "invalid sessionId", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
550 };
551 context->GetCbInfo(env, info, input);
552 context->taskId = NAPI_CREATE_CAST_CONTROLLER_TASK_ID;
553
554 auto executor = [context]() {
555 int32_t ret = AVSessionManager::GetInstance().GetAVCastController(context->sessionId_,
556 context->castController_);
557 if (ret != AVSESSION_SUCCESS) {
558 if (ret == ERR_NO_PERMISSION) {
559 context->errMessage = "GetAVCastController failed : native no permission";
560 } else if (ret == ERR_PERMISSION_DENIED) {
561 context->errMessage = "GetAVCastController failed : native permission denied";
562 } else if (ret == ERR_INVALID_PARAM) {
563 context->errMessage = "GetAVCastController failed : native invalid parameters";
564 } else if (ret == ERR_SESSION_NOT_EXIST) {
565 context->errMessage = "GetAVCastController failed : native session not exist";
566 } else {
567 context->errMessage = "GetAVCastController failed : native server exception";
568 }
569 context->status = napi_generic_failure;
570 context->errCode = NapiAVSessionManager::errcode_[ret];
571 }
572 };
573
574 auto complete = [env, context](napi_value& output) {
575 context->status = NapiAVCastController::NewInstance(env, context->castController_, output);
576 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
577 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
578 };
579
580 return NapiAsyncWork::Enqueue(env, context, "GetAVCastController", executor, complete);
581 #else
582 return nullptr;
583 #endif
584 }
585
CastAudio(napi_env env,napi_callback_info info)586 napi_value NapiAVSessionManager::CastAudio(napi_env env, napi_callback_info info)
587 {
588 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::CastAudio");
589 struct ConcreteContext : public ContextBase {
590 SessionToken sessionToken_ {};
591 bool isAll_ = false;
592 std::vector<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptors_;
593 };
594 auto context = std::make_shared<ConcreteContext>();
595 auto input = [env, context](size_t argc, napi_value* argv) {
596 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid arguments",
597 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
598 napi_valuetype type = napi_undefined;
599 context->status = napi_typeof(env, argv[ARGV_FIRST], &type);
600 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_string || type == napi_object),
601 "invalid type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
602 if (type == napi_string) {
603 std::string flag;
604 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], flag);
605 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (flag == "all"),
606 "invalid argument", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
607 context->isAll_ = true;
608 }
609 if (type == napi_object) {
610 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->sessionToken_);
611 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (!context->sessionToken_.sessionId.empty()),
612 "invalid session token", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
613 }
614 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->audioDeviceDescriptors_);
615 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (context->audioDeviceDescriptors_.size() > 0),
616 "invalid AudioDeviceDescriptor", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
617 };
618 context->GetCbInfo(env, info, input);
619 context->taskId = NAPI_CAST_AUDIO_TASK_ID;
620 auto executor = [context]() {
621 int32_t ret = AVSESSION_ERROR;
622 if (context->isAll_) {
623 ret = AVSessionManager::GetInstance().CastAudioForAll(context->audioDeviceDescriptors_);
624 } else {
625 ret = AVSessionManager::GetInstance().CastAudio(context->sessionToken_, context->audioDeviceDescriptors_);
626 }
627 if (ret != AVSESSION_SUCCESS) {
628 ErrCodeToMessage(ret, "CastAudio", context->errMessage);
629 context->status = napi_generic_failure;
630 context->errCode = NapiAVSessionManager::errcode_[ret];
631 }
632 };
633 auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
634 return NapiAsyncWork::Enqueue(env, context, "CastAudio", executor, complete);
635 }
636
ErrCodeToMessage(int32_t errCode,const std::string & tag,std::string & message)637 void NapiAVSessionManager::ErrCodeToMessage(int32_t errCode, const std::string& tag, std::string& message)
638 {
639 message = tag;
640 SLOGE("check error code for message:%{public}d", errCode);
641 switch (errCode) {
642 case ERR_SESSION_NOT_EXIST:
643 message.append(" failed : native session not exist");
644 break;
645 case ERR_INVALID_PARAM:
646 message.append(" failed : native invalid parameters");
647 break;
648 case ERR_NO_PERMISSION:
649 message.append(" failed : native no permission");
650 break;
651 case ERR_PERMISSION_DENIED:
652 message.append(" failed : native permission denied");
653 break;
654 default:
655 message.append(" failed : native server exception");
656 break;
657 }
658 }
659
RegisterNativeSessionListener(napi_env env)660 napi_status NapiAVSessionManager::RegisterNativeSessionListener(napi_env env)
661 {
662 std::lock_guard lockGuard(listenersMutex_);
663 if (listener_ != nullptr) {
664 return napi_ok;
665 }
666
667 listener_ = std::make_shared<NapiSessionListener>();
668 if (AVSessionManager::GetInstance().RegisterServiceDeathCallback(HandleServiceDied) != AVSESSION_SUCCESS) {
669 SLOGE("register service death callback fail!");
670 return napi_generic_failure;
671 }
672 if (listener_ == nullptr) {
673 SLOGE("OnEvent failed : no memory");
674 NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
675 return napi_generic_failure;
676 }
677 int32_t ret = AVSessionManager::GetInstance().RegisterSessionListener(listener_);
678 if (ret != AVSESSION_SUCCESS) {
679 SLOGE("native register session listener failed");
680 if (ret == ERR_INVALID_PARAM) {
681 NapiUtils::ThrowError(env, "OnEvent failed : native invalid parameters",
682 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
683 } else if (ret == ERR_NO_PERMISSION) {
684 NapiUtils::ThrowError(env, "OnEvent failed : native no permission",
685 NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
686 } else {
687 NapiUtils::ThrowError(env, "OnEvent failed : native server exception",
688 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
689 }
690 return napi_generic_failure;
691 }
692
693 return napi_ok;
694 }
695
OnEvent(napi_env env,napi_callback_info info)696 napi_value NapiAVSessionManager::OnEvent(napi_env env, napi_callback_info info)
697 {
698 auto context = std::make_shared<ContextBase>();
699 if (context == nullptr) {
700 SLOGE("OnEvent failed : no memory");
701 NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
702 return NapiUtils::GetUndefinedValue(env);
703 }
704
705 std::string eventName;
706 napi_value callback = nullptr;
707 auto input = [&eventName, &callback, env, &context](size_t argc, napi_value* argv) {
708 int32_t err = PermissionChecker::GetInstance().CheckPermission(
709 PermissionChecker::CHECK_SYSTEM_PERMISSION);
710 CHECK_ARGS_RETURN_VOID(context, err == ERR_NONE, "Check system permission error",
711 NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
712 /* require 2 arguments <event, callback> */
713 CHECK_ARGS_RETURN_VOID(context, argc >= ARGC_TWO, "invalid argument number",
714 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
715 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
716 CHECK_STATUS_RETURN_VOID(context, "get event name failed", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
717 CHECK_RETURN_VOID(eventName != DISTRIBUTED_SESSION_CHANGE_EVENT,
718 "no need process the distributed session changed event");
719 napi_valuetype type = napi_undefined;
720 context->status = napi_typeof(env, argv[ARGV_SECOND], &type);
721 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
722 "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
723 callback = argv[ARGV_SECOND];
724 };
725
726 context->GetCbInfo(env, info, input, true);
727 if (context->status != napi_ok) {
728 NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
729 return NapiUtils::GetUndefinedValue(env);
730 }
731
732 if (eventName == DISTRIBUTED_SESSION_CHANGE_EVENT) {
733 return OnDistributedSessionChangeEvent(env, info);
734 }
735
736 auto it = eventHandlers_.find(eventName);
737 if (it == eventHandlers_.end()) {
738 SLOGE("event name invalid");
739 NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
740 return NapiUtils::GetUndefinedValue(env);
741 }
742
743 if (RegisterNativeSessionListener(env) == napi_generic_failure) {
744 return NapiUtils::GetUndefinedValue(env);
745 }
746
747 if (it->second.first(env, callback) != napi_ok) {
748 NapiUtils::ThrowError(env, "add event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
749 }
750
751 return NapiUtils::GetUndefinedValue(env);
752 }
753
OffEvent(napi_env env,napi_callback_info info)754 napi_value NapiAVSessionManager::OffEvent(napi_env env, napi_callback_info info)
755 {
756 auto context = std::make_shared<ContextBase>();
757 if (context == nullptr) {
758 SLOGE("OffEvent failed : no memory");
759 NapiUtils::ThrowError(env, "OffEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
760 return NapiUtils::GetUndefinedValue(env);
761 }
762
763 std::string eventName;
764 napi_value callback = nullptr;
765 auto input = [&eventName, env, &context, &callback](size_t argc, napi_value* argv) {
766 int32_t err = PermissionChecker::GetInstance().CheckPermission(
767 PermissionChecker::CHECK_SYSTEM_PERMISSION);
768 CHECK_ARGS_RETURN_VOID(context, err == ERR_NONE, "Check system permission error",
769 NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
770 CHECK_ARGS_RETURN_VOID(context, argc >= ARGC_ONE || argc <= ARGC_THREE, "invalid argument number",
771 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
772 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
773 CHECK_STATUS_RETURN_VOID(context, "get event name failed",
774 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
775 if (argc == ARGC_TWO) {
776 callback = argv[ARGV_SECOND];
777 }
778 };
779
780 context->GetCbInfo(env, info, input, true);
781 if (context->status != napi_ok) {
782 NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
783 return NapiUtils::GetUndefinedValue(env);
784 }
785
786 if (eventName == DISTRIBUTED_SESSION_CHANGE_EVENT) {
787 return OffDistributedSessionChangeEvent(env, info);
788 }
789
790 auto it = eventHandlers_.find(eventName);
791 if (it == eventHandlers_.end()) {
792 SLOGE("event name invalid");
793 NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
794 return NapiUtils::GetUndefinedValue(env);
795 }
796
797 if (it->second.second(env, callback) != napi_ok) {
798 NapiUtils::ThrowError(env, "remove event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
799 }
800
801 return NapiUtils::GetUndefinedValue(env);
802 }
803
OnDistributedSessionChangeEvent(napi_env env,napi_callback_info info)804 napi_value NapiAVSessionManager::OnDistributedSessionChangeEvent(napi_env env, napi_callback_info info)
805 {
806 SLOGI("OnDistributedSessionChangeEvent");
807 struct ConcreteContext : public ContextBase {
808 DistributedSessionType sessionType_ {};
809 napi_value callback_ = nullptr;
810 };
811 auto context = std::make_shared<ConcreteContext>();
812 if (context == nullptr) {
813 NapiUtils::ThrowError(env, "OnSessionEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
814 return NapiUtils::GetUndefinedValue(env);
815 }
816
817 auto input = [env, &context](size_t argc, napi_value* argv) {
818 int32_t err = PermissionChecker::GetInstance().CheckPermission(
819 PermissionChecker::CHECK_SYSTEM_PERMISSION);
820 CHECK_ARGS_RETURN_VOID(context, err == ERR_NONE, "Check system permission error",
821 NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
822 /* require 3 arguments <event, callback> */
823 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_THREE, "invalid argument number",
824 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
825 int32_t sessionTypeValue = 0;
826 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], sessionTypeValue);
827 CHECK_STATUS_RETURN_VOID(context, "get session type failed", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
828 context->sessionType_ = DistributedSessionType(sessionTypeValue);
829 CHECK_ARGS_RETURN_VOID(context, context->sessionType_ >= DistributedSessionType::TYPE_SESSION_REMOTE &&
830 context->sessionType_ < DistributedSessionType::TYPE_SESSION_MAX,
831 "GetDistributedSessionControllers invalid sessionType",
832 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
833 napi_valuetype type = napi_undefined;
834 context->status = napi_typeof(env, argv[ARGV_THIRD], &type);
835 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
836 "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
837 context->callback_ = argv[ARGV_THIRD];
838 };
839
840 context->GetCbInfo(env, info, input, true);
841 if (context->status != napi_ok) {
842 NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
843 return NapiUtils::GetUndefinedValue(env);
844 }
845
846 auto it = distributedControllerEventHandlers_.find(context->sessionType_);
847 if (it == distributedControllerEventHandlers_.end()) {
848 NapiUtils::ThrowError(env, "session type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
849 return NapiUtils::GetUndefinedValue(env);
850 }
851
852 if (RegisterNativeSessionListener(env) == napi_generic_failure) {
853 return NapiUtils::GetUndefinedValue(env);
854 }
855
856 if (it->second.first(env, context->callback_) != napi_ok) {
857 NapiUtils::ThrowError(env, "add event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
858 }
859
860 return NapiUtils::GetUndefinedValue(env);
861 }
862
OffDistributedSessionChangeEvent(napi_env env,napi_callback_info info)863 napi_value NapiAVSessionManager::OffDistributedSessionChangeEvent(napi_env env, napi_callback_info info)
864 {
865 SLOGI("OffDistributedSessionChangeEvent");
866 struct ConcreteContext : public ContextBase {
867 DistributedSessionType sessionType_ {};
868 napi_value callback_ = nullptr;
869 };
870 auto context = std::make_shared<ConcreteContext>();
871 if (context == nullptr) {
872 NapiUtils::ThrowError(env, "OffSessionEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
873 return NapiUtils::GetUndefinedValue(env);
874 }
875
876 auto input = [env, &context](size_t argc, napi_value* argv) {
877 int32_t err = PermissionChecker::GetInstance().CheckPermission(
878 PermissionChecker::CHECK_SYSTEM_PERMISSION);
879 CHECK_ARGS_RETURN_VOID(context, err == ERR_NONE, "Check system permission error",
880 NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
881 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO || argc == ARGC_THREE, "invalid argument number",
882 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
883 int32_t sessionTypeValue = 0;
884 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], sessionTypeValue);
885 CHECK_STATUS_RETURN_VOID(context, "get session type failed", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
886 context->sessionType_ = DistributedSessionType(sessionTypeValue);
887 CHECK_ARGS_RETURN_VOID(context, context->sessionType_ >= DistributedSessionType::TYPE_SESSION_REMOTE &&
888 context->sessionType_ < DistributedSessionType::TYPE_SESSION_MAX,
889 "GetDistributedSessionControllers invalid sessionType",
890 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
891 if (argc == ARGC_THREE) {
892 napi_valuetype type = napi_undefined;
893 context->status = napi_typeof(env, argv[ARGV_THIRD], &type);
894 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
895 "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
896 context->callback_ = argv[ARGV_THIRD];
897 }
898 };
899
900 context->GetCbInfo(env, info, input, true);
901 if (context->status != napi_ok) {
902 NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
903 return NapiUtils::GetUndefinedValue(env);
904 }
905
906 auto it = distributedControllerEventHandlers_.find(context->sessionType_);
907 if (it == distributedControllerEventHandlers_.end()) {
908 NapiUtils::ThrowError(env, "session type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
909 return NapiUtils::GetUndefinedValue(env);
910 }
911
912 if (it->second.second(env, context->callback_) != napi_ok) {
913 NapiUtils::ThrowError(env, "remove event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
914 }
915
916 return NapiUtils::GetUndefinedValue(env);
917 }
918
SendSystemAVKeyEvent(napi_env env,napi_callback_info info)919 napi_value NapiAVSessionManager::SendSystemAVKeyEvent(napi_env env, napi_callback_info info)
920 {
921 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::SendSystemAVKeyEvent");
922 struct ConcreteContext : public ContextBase {
923 std::shared_ptr<MMI::KeyEvent> keyEvent_;
924 };
925 auto context = std::make_shared<ConcreteContext>();
926 auto input = [env, context](size_t argc, napi_value* argv) {
927 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
928 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
929 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->keyEvent_);
930 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (context->keyEvent_ != nullptr),
931 "invalid keyEvent", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
932 };
933 context->GetCbInfo(env, info, input);
934 context->taskId = NAPI_SEND_SYSTEM_AV_KEY_EVENT_TASK_ID;
935
936 auto executor = [context]() {
937 int32_t ret = AVSessionManager::GetInstance().SendSystemAVKeyEvent(*context->keyEvent_);
938 if (ret != AVSESSION_SUCCESS) {
939 if (ret == ERR_COMMAND_NOT_SUPPORT) {
940 context->errMessage = "SendSystemAVKeyEvent failed : native invalid keyEvent";
941 } else if (ret == ERR_NO_PERMISSION) {
942 context->errMessage = "SendSystemAVKeyEvent failed : native no permission";
943 } else if (ret == ERR_PERMISSION_DENIED) {
944 context->errMessage = "SendSystemAVKeyEvent failed : native permission denied";
945 } else {
946 context->errMessage = "SendSystemAVKeyEvent failed : native server exception";
947 }
948 context->status = napi_generic_failure;
949 context->errCode = NapiAVSessionManager::errcode_[ret];
950 }
951 };
952
953 return NapiAsyncWork::Enqueue(env, context, "SendSystemAVKeyEvent", executor);
954 }
955
SendSystemControlCommand(napi_env env,napi_callback_info info)956 napi_value NapiAVSessionManager::SendSystemControlCommand(napi_env env, napi_callback_info info)
957 {
958 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::SendSystemControlCommand");
959 struct ConcrentContext : public ContextBase {
960 AVControlCommand command;
961 };
962 auto context = std::make_shared<ConcrentContext>();
963 auto input = [env, context](size_t argc, napi_value* argv) {
964 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
965 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
966 context->status = NapiControlCommand::GetValue(env, argv[ARGV_FIRST], context->command);
967 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok), "invalid command",
968 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
969 };
970 context->GetCbInfo(env, info, input);
971 context->taskId = NAPI_SEND_SYSTEM_CONTROL_COMMAND_TASK_ID;
972
973 auto executor = [context]() {
974 int32_t ret = AVSessionManager::GetInstance().SendSystemControlCommand(context->command);
975 #ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
976 double speed = 0.0;
977 int64_t time = 0;
978 int32_t mode = AVPlaybackState::LOOP_MODE_SEQUENCE;
979 std::string assetId;
980 context->command.GetSpeed(speed);
981 context->command.GetSeekTime(time);
982 context->command.GetLoopMode(mode);
983 context->command.GetAssetId(assetId);
984 HISYSEVENT_FAULT("CONTROL_COMMAND_FAILED", "ERROR_TYPE", "SEND_CMD_FAILED",
985 "CMD", context->command.GetCommand(), "TIME", time, "SPEED", speed, "MODE", mode, "ASSETID", assetId,
986 "ERROR_CODE", ret, "ERROR_INFO", "native send control command failed");
987 #endif
988 if (ret != AVSESSION_SUCCESS) {
989 if (ret == ERR_COMMAND_NOT_SUPPORT) {
990 context->errMessage = "SendSystemControlCommand failed : native invalid command";
991 } else if (ret == ERR_NO_PERMISSION) {
992 context->errMessage = "SendSystemControlCommand failed : native send control command no permission";
993 HISYSEVENT_SECURITY("CONTROL_PERMISSION_DENIED", "ERROR_CODE", ret,
994 "ERROR_INFO", "SendSystemControlCommand failed : native no permission");
995 } else if (ret == ERR_PERMISSION_DENIED) {
996 context->errMessage = "SendSystemControlCommand failed : native send control command permission denied";
997 } else if (ret == ERR_COMMAND_SEND_EXCEED_MAX) {
998 context->errMessage = "SendSystemControlCommand failed : native send command overload, \
999 controls the frequency of sending self-query and control commands";
1000 } else {
1001 context->errMessage = "SendSystemControlCommand failed : native server exception, \
1002 you are advised to : 1.scheduled retry.\
1003 2.destroy the current session or session controller and re-create it.";
1004 }
1005 context->status = napi_generic_failure;
1006 context->errCode = NapiAVSessionManager::errcode_[ret];
1007 }
1008 };
1009
1010 return NapiAsyncWork::Enqueue(env, context, "SendSystemControlCommand", executor);
1011 }
1012
StartCastDiscovery(napi_env env,napi_callback_info info)1013 napi_value NapiAVSessionManager::StartCastDiscovery(napi_env env, napi_callback_info info)
1014 {
1015 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1016 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::StartCastDiscovery");
1017 struct ConcreteContext : public ContextBase {
1018 int32_t castDeviceCapability_;
1019 std::vector<std::string> drmSchemes_;
1020 };
1021 auto context = std::make_shared<ConcreteContext>();
1022 auto input = [env, context](size_t argc, napi_value* argv) {
1023 context->status = ProcessCastDiscoveryParams(env, argc, argv,
1024 context->castDeviceCapability_, context->drmSchemes_);
1025 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "invalid params",
1026 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1027 };
1028 context->GetCbInfo(env, info, input);
1029 context->taskId = NAPI_START_CAST_DISCOVERY_TASK_ID;
1030
1031 auto executor = [context]() {
1032 int32_t ret = AVSessionManager::GetInstance().StartCastDiscovery(context->castDeviceCapability_,
1033 context->drmSchemes_);
1034 if (ret != AVSESSION_SUCCESS) {
1035 if (ret == ERR_NO_PERMISSION) {
1036 context->errMessage = "StartCastDiscovery failed : native no permission";
1037 } else if (ret == ERR_PERMISSION_DENIED) {
1038 context->errMessage = "StartCastDiscovery failed : native permission denied";
1039 } else if (ret == ERR_INVALID_PARAM) {
1040 context->errMessage = "StartCastDiscovery failed : native invalid parameters";
1041 } else if (ret == ERR_SESSION_NOT_EXIST) {
1042 context->errMessage = "StartCastDiscovery failed : native session not exist";
1043 } else {
1044 context->errMessage = "StartCastDiscovery failed : native server exception, \
1045 you are advised to : 1.scheduled retry.\
1046 2.destroy the current session or session controller and re-create it.";
1047 }
1048 context->status = napi_generic_failure;
1049 context->errCode = NapiAVSessionManager::errcode_[ret];
1050 ReportStartCastDiscoveryFailInfo("NapiAVSessionManager::StartCastDiscovery", ret);
1051 }
1052 };
1053 return NapiAsyncWork::Enqueue(env, context, "StartCastDiscovery", executor);
1054 #else
1055 return nullptr;
1056 #endif
1057 }
1058
ProcessCastDiscoveryParams(napi_env env,size_t argc,napi_value * argv,int32_t & castDeviceCapability,std::vector<std::string> & drmSchemes)1059 napi_status NapiAVSessionManager::ProcessCastDiscoveryParams(
1060 napi_env env, size_t argc, napi_value* argv, int32_t& castDeviceCapability, std::vector<std::string>& drmSchemes)
1061 {
1062 napi_status status = napi_ok;
1063 if (argc == ARGC_ONE && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_undefined)
1064 && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_null)) {
1065 status = NapiUtils::GetValue(env, argv[ARGV_FIRST], castDeviceCapability);
1066 } else if (argc == ARGC_TWO) {
1067 SLOGD("get in argc two process");
1068 if (!NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_undefined) &&
1069 !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_null)) {
1070 status = NapiUtils::GetValue(env, argv[ARGV_FIRST], castDeviceCapability);
1071 if (status != napi_ok) {
1072 ReportStartCastDiscoveryFailInfo("NapiAVSessionManager::StartCastDiscovery", ERR_INVALID_PARAM);
1073 }
1074 } else {
1075 castDeviceCapability = ProtocolType::TYPE_CAST_PLUS_STREAM;
1076 }
1077 if (!NapiUtils::TypeCheck(env, argv[ARGV_SECOND], napi_undefined) &&
1078 !NapiUtils::TypeCheck(env, argv[ARGV_SECOND], napi_null)) {
1079 status = NapiUtils::GetValue(env, argv[ARGV_SECOND], drmSchemes);
1080 if (status != napi_ok) {
1081 ReportStartCastDiscoveryFailInfo("NapiAVSessionManager::StartCastDiscovery", ERR_INVALID_PARAM);
1082 }
1083 }
1084 } else {
1085 castDeviceCapability = ProtocolType::TYPE_CAST_PLUS_STREAM;
1086 }
1087 return status;
1088 }
1089
StopCastDiscovery(napi_env env,napi_callback_info info)1090 napi_value NapiAVSessionManager::StopCastDiscovery(napi_env env, napi_callback_info info)
1091 {
1092 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1093 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::StopCastDiscovery");
1094 auto context = std::make_shared<ContextBase>();
1095 if (context == nullptr) {
1096 SLOGE("Activate failed : no memory");
1097 ReportStopCastDiscoveryFailInfo("NapiAVSessionManager::StopCastDiscovery", ERR_NO_MEMORY);
1098 NapiUtils::ThrowError(env, "Activate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1099 return NapiUtils::GetUndefinedValue(env);
1100 }
1101
1102 context->GetCbInfo(env, info);
1103 context->taskId = NAPI_STOP_CAST_DISCOVERY_TASK_ID;
1104
1105 auto executor = [context]() {
1106 int32_t ret = AVSESSION_ERROR;
1107 ret = AVSessionManager::GetInstance().StopCastDiscovery();
1108 if (ret != AVSESSION_SUCCESS) {
1109 if (ret == ERR_NO_PERMISSION) {
1110 context->errMessage = "StopCastDiscovery failed : native no permission";
1111 } else if (ret == ERR_PERMISSION_DENIED) {
1112 context->errMessage = "StopCastDiscovery failed : native permission denied";
1113 } else if (ret == ERR_INVALID_PARAM) {
1114 context->errMessage = "StopCastDiscovery failed : native invalid parameters";
1115 } else if (ret == ERR_SESSION_NOT_EXIST) {
1116 context->errMessage = "StopCastDiscovery failed : native session not exist";
1117 } else {
1118 context->errMessage = "StopCastDiscovery failed : native server exception, \
1119 you are advised to : 1.scheduled retry.\
1120 2.destroy the current session or session controller and re-create it.";
1121 }
1122 context->status = napi_generic_failure;
1123 context->errCode = NapiAVSessionManager::errcode_[ret];
1124 ReportStopCastDiscoveryFailInfo("NapiAVSessionManager::StopCastDiscovery", ret);
1125 }
1126 };
1127 auto complete = [env](napi_value& output) {
1128 output = NapiUtils::GetUndefinedValue(env);
1129 };
1130 return NapiAsyncWork::Enqueue(env, context, "StopCastDiscovery", executor, complete);
1131 #else
1132 return nullptr;
1133 #endif
1134 }
1135
SetDiscoverable(napi_env env,napi_callback_info info)1136 napi_value NapiAVSessionManager::SetDiscoverable(napi_env env, napi_callback_info info)
1137 {
1138 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1139 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::SetDiscoverable");
1140 struct ConcreteContext : public ContextBase {
1141 bool enable_;
1142 };
1143 auto context = std::make_shared<ConcreteContext>();
1144 auto input = [env, context](size_t argc, napi_value* argv) {
1145 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
1146 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1147 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->enable_);
1148 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get streamIds_ failed",
1149 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1150 };
1151 context->GetCbInfo(env, info, input);
1152 context->taskId = NAPI_SET_DISCOVERABLE_TASK_ID;
1153
1154 auto executor = [context]() {
1155 int32_t ret = AVSessionManager::GetInstance().SetDiscoverable(context->enable_);
1156 if (ret != AVSESSION_SUCCESS) {
1157 if (ret == ERR_NO_PERMISSION) {
1158 context->errMessage = "SetDiscoverable failed : native no permission";
1159 } else if (ret == ERR_INVALID_PARAM) {
1160 context->errMessage = "SetDiscoverable failed : native invalid parameters";
1161 } else if (ret == ERR_SESSION_NOT_EXIST) {
1162 context->errMessage = "SetDiscoverable failed : native session not exist";
1163 } else {
1164 context->errMessage = "SetDiscoverable failed : native server exception, \
1165 you are advised to : 1.scheduled retry.\
1166 2.destroy the current session or session controller and re-create it.";
1167 }
1168 context->status = napi_generic_failure;
1169 context->errCode = NapiAVSessionManager::errcode_[ret];
1170 }
1171 };
1172 return NapiAsyncWork::Enqueue(env, context, "SetDiscoverable", executor);
1173 #else
1174 return nullptr;
1175 #endif
1176 }
1177
GetStartCastErrMsg(int32_t error)1178 std::string NapiAVSessionManager::GetStartCastErrMsg(int32_t error)
1179 {
1180 std::string err;
1181 const uint32_t systemId = 226;
1182 const uint32_t AvSessionModuleId = 18;
1183 const uint32_t CastEngineModuleId = 19;
1184 const uint32_t systemIdOffset = 21;
1185 const uint32_t moduleIdOffset = 16;
1186
1187 auto makeAvSessionErrorCode = [](int error) {
1188 return (systemId << systemIdOffset) | (AvSessionModuleId << moduleIdOffset) |
1189 static_cast<uint32_t>(std::abs(error));
1190 };
1191 auto makeCastEngineErrorCode = [](int error) {
1192 return (systemId << systemIdOffset) | (CastEngineModuleId << moduleIdOffset) |
1193 static_cast<uint32_t>(std::abs(error));
1194 };
1195 if (error == ERR_NO_PERMISSION) {
1196 err = "StartCast failed : native no permission";
1197 } else if (error == ERR_PERMISSION_DENIED) {
1198 err = "StartCast failed : native permission denied";
1199 } else if (error == ERR_INVALID_PARAM) {
1200 err = "StartCast failed : native invalid parameters";
1201 } else if (error == ERR_SESSION_NOT_EXIST) {
1202 err = "StartCast failed : native session not exist";
1203 } else if (error == ERR_WAIT_ALLCONNECT_TIMEOUT) {
1204 auto errorCode = makeAvSessionErrorCode(error);
1205 err = "StartCast failed : connect timeout, radarErrorCode:" + std::to_string(errorCode);
1206 } else if (error == ERR_ALLCONNECT_CAST_REJECT) {
1207 auto errorCode = makeAvSessionErrorCode(error);
1208 err = "StartCast failed : connect reject, radarErrorCode:" + std::to_string(errorCode);
1209 } else if (error == ERR_REPEAT_CAST) {
1210 auto errorCode = makeAvSessionErrorCode(error);
1211 err = "StartCast failed : repeat cast, radarErrorCode:" + std::to_string(errorCode);
1212 } else if (error == ERR_DEVICE_CONNECTION_FAILED) {
1213 auto errorCode = makeCastEngineErrorCode(error);
1214 err = "StartCast failed : device connect failed, radarErrorCode:" + std::to_string(errorCode);
1215 } else {
1216 err = "StartCast failed : native server exception, \
1217 you are advised to : 1.scheduled retry.\
1218 2.destroy the current session or session controller and re-create it.";
1219 }
1220 return err;
1221 }
1222
JudgeNumString(std::string str)1223 bool NapiAVSessionManager::JudgeNumString(std::string str)
1224 {
1225 SLOGI("enter JudgeNumString");
1226 if (str.empty()) {
1227 return false;
1228 }
1229
1230 int minNumChar = 48;
1231 int maxNumChar = 57;
1232 for (int i = 0; i < static_cast<int>(str.size()); i++) {
1233 if (str[i] < minNumChar || str[i] > maxNumChar) {
1234 return false;
1235 }
1236 }
1237 return true;
1238 }
1239
StartDeviceLogging(napi_env env,napi_callback_info info)1240 napi_value NapiAVSessionManager::StartDeviceLogging(napi_env env, napi_callback_info info)
1241 {
1242 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1243 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::StartDeviceLogging");
1244 struct ConcreteContext : public ContextBase {
1245 std::string fd_;
1246 uint32_t maxSize_;
1247 };
1248 auto context = std::make_shared<ConcreteContext>();
1249 if (context == nullptr) {
1250 SLOGE("Activate failed : no memory");
1251 NapiUtils::ThrowError(env, "Activate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1252 return NapiUtils::GetUndefinedValue(env);
1253 }
1254 auto input = [env, context](size_t argc, napi_value* argv) {
1255 int32_t napiInvalidParamErr = NapiAVSessionManager::errcode_[ERR_INVALID_PARAM];
1256 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid arguments", napiInvalidParamErr);
1257
1258 napi_valuetype type = napi_undefined;
1259 context->status = napi_typeof(env, argv[ARGV_FIRST], &type);
1260 bool condition = (context->status == napi_ok) && (type == napi_string);
1261 CHECK_ARGS_RETURN_VOID(context, condition, "invalid type invalid", napiInvalidParamErr);
1262 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->fd_);
1263 condition = (context->status == napi_ok);
1264 CHECK_ARGS_RETURN_VOID(context, condition, "fd getvalue fail", napiInvalidParamErr);
1265 CHECK_ARGS_RETURN_VOID(context, JudgeNumString(context->fd_),
1266 "fd is not a num string", napiInvalidParamErr);
1267
1268 context->status = napi_typeof(env, argv[ARGV_SECOND], &type);
1269 condition = (context->status == napi_ok) && (type == napi_number);
1270 CHECK_ARGS_RETURN_VOID(context, condition, "invalid type invalid", napiInvalidParamErr);
1271 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->maxSize_);
1272 condition = (context->status == napi_ok);
1273 CHECK_ARGS_RETURN_VOID(context, condition, "maxSize getvalue fail", napiInvalidParamErr);
1274 };
1275 context->GetCbInfo(env, info, input);
1276 context->taskId = NAPI_START_DEVICE_LOGGING_TASK_ID;
1277
1278 auto executor = [context]() {
1279 int32_t ret = AVSessionManager::GetInstance().StartDeviceLogging(
1280 std::stoi(context->fd_), context->maxSize_);
1281 if (ret != AVSESSION_SUCCESS) {
1282 context->status = napi_generic_failure;
1283 context->errCode = NapiAVSessionManager::errcode_[ret];
1284 SLOGE("StartDeviceLogging return error code = %{public}d", ret);
1285 }
1286 };
1287 return NapiAsyncWork::Enqueue(env, context, "StartDeviceLogging", executor);
1288 #else
1289 return nullptr;
1290 #endif
1291 }
1292
StopDeviceLogging(napi_env env,napi_callback_info info)1293 napi_value NapiAVSessionManager::StopDeviceLogging(napi_env env, napi_callback_info info)
1294 {
1295 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1296 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::StopCast");
1297 auto context = std::make_shared<ContextBase>();
1298 if (context == nullptr) {
1299 SLOGE("Activate failed : no memory");
1300 NapiUtils::ThrowError(env, "Activate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1301 return NapiUtils::GetUndefinedValue(env);
1302 }
1303 context->GetCbInfo(env, info);
1304 context->taskId = NAPI_STOP_DEVICE_LOGGING_TASK_ID;
1305
1306 auto executor = [context]() {
1307 int32_t ret = AVSESSION_ERROR;
1308 ret = AVSessionManager::GetInstance().StopDeviceLogging();
1309 if (ret != AVSESSION_SUCCESS) {
1310 context->status = napi_generic_failure;
1311 context->errCode = NapiAVSessionManager::errcode_[ret];
1312 SLOGE("StopDeviceLogging return error code = %{public}d", ret);
1313 }
1314 };
1315 auto complete = [env](napi_value& output) {
1316 output = NapiUtils::GetUndefinedValue(env);
1317 };
1318 return NapiAsyncWork::Enqueue(env, context, "StopDeviceLogging", executor, complete);
1319 #else
1320 return nullptr;
1321 #endif
1322 }
1323
StartCast(napi_env env,napi_callback_info info)1324 napi_value NapiAVSessionManager::StartCast(napi_env env, napi_callback_info info)
1325 {
1326 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1327 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::StartCast");
1328 struct ConcreteContext : public ContextBase {
1329 SessionToken sessionToken_ {};
1330 OutputDeviceInfo outputdeviceInfo_;
1331 };
1332 auto context = std::make_shared<ConcreteContext>();
1333 auto input = [env, context](size_t argc, napi_value* argv) {
1334 int32_t napiInvalidParamErr = NapiAVSessionManager::errcode_[ERR_INVALID_PARAM];
1335 CheckStartCastReportRadar(argc == ARGC_TWO, ERR_INVALID_PARAM);
1336 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid arguments", napiInvalidParamErr);
1337
1338 napi_valuetype type = napi_undefined;
1339 context->status = napi_typeof(env, argv[ARGV_FIRST], &type);
1340 bool condition = (context->status == napi_ok) && (type == napi_object);
1341 CheckStartCastReportRadar(condition, ERR_INVALID_PARAM);
1342 CHECK_ARGS_RETURN_VOID(context, condition, "invalid type invalid", napiInvalidParamErr);
1343
1344 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->sessionToken_);
1345 condition = (context->status == napi_ok) && (!context->sessionToken_.sessionId.empty());
1346 CheckStartCastReportRadar(condition, ERR_INVALID_PARAM);
1347 CHECK_ARGS_RETURN_VOID(context, condition, "invalid session token", napiInvalidParamErr);
1348
1349 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->outputdeviceInfo_);
1350 condition = (context->status == napi_ok) && (context->outputdeviceInfo_.deviceInfos_.size() > 0);
1351 CheckStartCastReportRadar(condition, ERR_INVALID_PARAM);
1352 CHECK_ARGS_RETURN_VOID(context, condition, "invalid outputdeviceInfo", napiInvalidParamErr);
1353 };
1354 context->GetCbInfo(env, info, input);
1355 context->taskId = NAPI_START_CAST_TASK_ID;
1356
1357 auto executor = [context]() {
1358 int32_t ret = AVSESSION_ERROR;
1359 ret = AVSessionManager::GetInstance().StartCast(context->sessionToken_, context->outputdeviceInfo_);
1360 if (ret != AVSESSION_SUCCESS) {
1361 context->errMessage = GetStartCastErrMsg(ret);
1362 context->status = napi_generic_failure;
1363 context->errCode = NapiAVSessionManager::errcode_[ret];
1364 ReportStartCastFailInfo(ret, context->outputdeviceInfo_);
1365 }
1366 };
1367
1368 auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
1369
1370 return NapiAsyncWork::Enqueue(env, context, "StartCast", executor, complete);
1371 #else
1372 return nullptr;
1373 #endif
1374 }
1375
StopCast(napi_env env,napi_callback_info info)1376 napi_value NapiAVSessionManager::StopCast(napi_env env, napi_callback_info info)
1377 {
1378 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
1379 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::StopCast");
1380 struct ConcreteContext : public ContextBase {
1381 SessionToken sessionToken_ {};
1382 };
1383 auto context = std::make_shared<ConcreteContext>();
1384 auto input = [env, context](size_t argc, napi_value* argv) {
1385 int32_t napiInvalidParamErr = NapiAVSessionManager::errcode_[ERR_INVALID_PARAM];
1386 CheckStopCastReportRadar(argc == ARGC_ONE, ERR_INVALID_PARAM);
1387 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments", napiInvalidParamErr);
1388
1389 napi_valuetype type = napi_undefined;
1390 context->status = napi_typeof(env, argv[ARGV_FIRST], &type);
1391 bool condition = (context->status == napi_ok) && (type == napi_object);
1392 CheckStopCastReportRadar(condition, ERR_INVALID_PARAM);
1393 CHECK_ARGS_RETURN_VOID(context, condition, "invalid type invalid", napiInvalidParamErr);
1394
1395 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->sessionToken_);
1396 condition = (context->status == napi_ok) && (!context->sessionToken_.sessionId.empty());
1397 CheckStopCastReportRadar(condition, ERR_INVALID_PARAM);
1398 CHECK_ARGS_RETURN_VOID(context, condition, "invalid session token", napiInvalidParamErr);
1399 };
1400 context->GetCbInfo(env, info, input);
1401 context->taskId = NAPI_STOP_CAST_TASK_ID;
1402
1403 auto executor = [context]() {
1404 int32_t ret = AVSESSION_ERROR;
1405 ret = AVSessionManager::GetInstance().StopCast(context->sessionToken_);
1406 if (ret != AVSESSION_SUCCESS) {
1407 if (ret == ERR_NO_PERMISSION) {
1408 context->errMessage = "StopCast failed : native no permission";
1409 } else if (ret == ERR_INVALID_PARAM) {
1410 context->errMessage = "StopCast failed : native invalid parameters";
1411 } else if (ret == ERR_SESSION_NOT_EXIST) {
1412 context->errMessage = "StopCast failed : native session not exist";
1413 } else {
1414 context->errMessage = "StopCast failed : native server exception, \
1415 you are advised to : 1.scheduled retry.\
1416 2.destroy the current session or session controller and re-create it.";
1417 }
1418 context->status = napi_generic_failure;
1419 context->errCode = NapiAVSessionManager::errcode_[ret];
1420 ReportStopCastFailInfo(ret);
1421 }
1422 };
1423
1424 auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
1425
1426 return NapiAsyncWork::Enqueue(env, context, "StopCast", executor, complete);
1427 #else
1428 return nullptr;
1429 #endif
1430 }
1431
OnSessionCreate(napi_env env,napi_value callback)1432 napi_status NapiAVSessionManager::OnSessionCreate(napi_env env, napi_value callback)
1433 {
1434 std::lock_guard lockGuard(listenersMutex_);
1435 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1436 return listener_->AddCallback(env, NapiSessionListener::EVENT_SESSION_CREATED, callback);
1437 }
1438
OnSessionDestroy(napi_env env,napi_value callback)1439 napi_status NapiAVSessionManager::OnSessionDestroy(napi_env env, napi_value callback)
1440 {
1441 std::lock_guard lockGuard(listenersMutex_);
1442 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1443 return listener_->AddCallback(env, NapiSessionListener::EVENT_SESSION_DESTROYED, callback);
1444 }
1445
OnTopSessionChange(napi_env env,napi_value callback)1446 napi_status NapiAVSessionManager::OnTopSessionChange(napi_env env, napi_value callback)
1447 {
1448 std::lock_guard lockGuard(listenersMutex_);
1449 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1450 return listener_->AddCallback(env, NapiSessionListener::EVENT_TOP_SESSION_CHANGED, callback);
1451 }
1452
OnAudioSessionChecked(napi_env env,napi_value callback)1453 napi_status NapiAVSessionManager::OnAudioSessionChecked(napi_env env, napi_value callback)
1454 {
1455 std::lock_guard lockGuard(listenersMutex_);
1456 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1457 return listener_->AddCallback(env, NapiSessionListener::EVENT_AUDIO_SESSION_CHECKED, callback);
1458 }
1459
OnDeviceAvailable(napi_env env,napi_value callback)1460 napi_status NapiAVSessionManager::OnDeviceAvailable(napi_env env, napi_value callback)
1461 {
1462 std::lock_guard lockGuard(listenersMutex_);
1463 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1464 return listener_->AddCallback(env, NapiSessionListener::EVENT_DEVICE_AVAILABLE, callback);
1465 }
1466
OnDeviceLogEvent(napi_env env,napi_value callback)1467 napi_status NapiAVSessionManager::OnDeviceLogEvent(napi_env env, napi_value callback)
1468 {
1469 return listener_->AddCallback(env, NapiSessionListener::EVENT_DEVICE_LOG_EVENT, callback);
1470 }
1471
OnDeviceOffline(napi_env env,napi_value callback)1472 napi_status NapiAVSessionManager::OnDeviceOffline(napi_env env, napi_value callback)
1473 {
1474 std::lock_guard lockGuard(listenersMutex_);
1475 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1476 return listener_->AddCallback(env, NapiSessionListener::EVENT_DEVICE_OFFLINE, callback);
1477 }
1478
OnServiceDie(napi_env env,napi_value callback)1479 napi_status NapiAVSessionManager::OnServiceDie(napi_env env, napi_value callback)
1480 {
1481 napi_ref ref = nullptr;
1482 CHECK_AND_RETURN_RET_LOG(napi_ok == NapiUtils::GetRefByCallback(env, serviceDiedCallbacks_, callback, ref),
1483 napi_generic_failure, "get callback reference failed");
1484 CHECK_AND_RETURN_RET_LOG(ref == nullptr, napi_ok, "callback has been registered");
1485 napi_status status = napi_create_reference(env, callback, ARGC_ONE, &ref);
1486 if (status != napi_ok) {
1487 SLOGE("napi_create_reference failed");
1488 return status;
1489 }
1490 if (asyncCallback_ == nullptr) {
1491 asyncCallback_ = std::make_shared<NapiAsyncCallback>(env);
1492 if (asyncCallback_ == nullptr) {
1493 SLOGE("no memory");
1494 return napi_generic_failure;
1495 }
1496 }
1497 serviceDiedCallbacks_.push_back(ref);
1498 SLOGI("do service die register when listener setup");
1499 return napi_ok;
1500 }
1501
OnRemoteDistributedSessionChange(napi_env env,napi_value callback)1502 napi_status NapiAVSessionManager::OnRemoteDistributedSessionChange(napi_env env, napi_value callback)
1503 {
1504 SLOGI("OnRemoteDistributedSessionChange AddCallback");
1505 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1506 return listener_->AddCallback(env, NapiSessionListener::EVENT_REMOTE_DISTRIBUTED_SESSION_CHANGED, callback);
1507 }
1508
OnDeviceStateChanged(napi_env env,napi_value callback)1509 napi_status NapiAVSessionManager::OnDeviceStateChanged(napi_env env, napi_value callback)
1510 {
1511 SLOGI("OnDeviceStateChanged AddCallback");
1512 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1513 return listener_->AddCallback(env, NapiSessionListener::EVENT_DEVICE_STATE_CHANGED, callback);
1514 }
1515
HandleServiceDied()1516 void NapiAVSessionManager::HandleServiceDied()
1517 {
1518 if (!serviceDiedCallbacks_.empty() && asyncCallback_ != nullptr) {
1519 for (auto callbackRef = serviceDiedCallbacks_.begin(); callbackRef != serviceDiedCallbacks_.end();
1520 ++callbackRef) {
1521 asyncCallback_->Call(*callbackRef);
1522 }
1523 }
1524 std::lock_guard lockGuard(listenersMutex_);
1525 if (listener_ != nullptr) {
1526 SLOGI("clear listener for service die");
1527 listener_ = nullptr;
1528 }
1529 }
1530
HandleServiceStart()1531 void NapiAVSessionManager::HandleServiceStart()
1532 {
1533 auto res = NapiAVSession::ReCreateInstance();
1534 SLOGI("HandleServiceStart ReCreateInstance ret=%{public}d", res);
1535 }
1536
OffSessionCreate(napi_env env,napi_value callback)1537 napi_status NapiAVSessionManager::OffSessionCreate(napi_env env, napi_value callback)
1538 {
1539 std::lock_guard lockGuard(listenersMutex_);
1540 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1541 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_SESSION_CREATED, callback);
1542 }
1543
OffSessionDestroy(napi_env env,napi_value callback)1544 napi_status NapiAVSessionManager::OffSessionDestroy(napi_env env, napi_value callback)
1545 {
1546 std::lock_guard lockGuard(listenersMutex_);
1547 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1548 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_SESSION_DESTROYED, callback);
1549 }
1550
OffTopSessionChange(napi_env env,napi_value callback)1551 napi_status NapiAVSessionManager::OffTopSessionChange(napi_env env, napi_value callback)
1552 {
1553 std::lock_guard lockGuard(listenersMutex_);
1554 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1555 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_TOP_SESSION_CHANGED, callback);
1556 }
1557
OffAudioSessionChecked(napi_env env,napi_value callback)1558 napi_status NapiAVSessionManager::OffAudioSessionChecked(napi_env env, napi_value callback)
1559 {
1560 std::lock_guard lockGuard(listenersMutex_);
1561 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1562 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_AUDIO_SESSION_CHECKED, callback);
1563 }
1564
OffDeviceAvailable(napi_env env,napi_value callback)1565 napi_status NapiAVSessionManager::OffDeviceAvailable(napi_env env, napi_value callback)
1566 {
1567 std::lock_guard lockGuard(listenersMutex_);
1568 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1569 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_DEVICE_AVAILABLE, callback);
1570 }
1571
OffDeviceLogEvent(napi_env env,napi_value callback)1572 napi_status NapiAVSessionManager::OffDeviceLogEvent(napi_env env, napi_value callback)
1573 {
1574 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1575 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_DEVICE_LOG_EVENT, callback);
1576 }
1577
OffDeviceOffline(napi_env env,napi_value callback)1578 napi_status NapiAVSessionManager::OffDeviceOffline(napi_env env, napi_value callback)
1579 {
1580 std::lock_guard lockGuard(listenersMutex_);
1581 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1582 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_DEVICE_OFFLINE, callback);
1583 }
1584
OffRemoteDistributedSessionChange(napi_env env,napi_value callback)1585 napi_status NapiAVSessionManager::OffRemoteDistributedSessionChange(napi_env env, napi_value callback)
1586 {
1587 SLOGI("OffRemoteDistributedSessionChange RemoveCallback");
1588 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1589 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_REMOTE_DISTRIBUTED_SESSION_CHANGED, callback);
1590 }
1591
OffDeviceStateChanged(napi_env env,napi_value callback)1592 napi_status NapiAVSessionManager::OffDeviceStateChanged(napi_env env, napi_value callback)
1593 {
1594 SLOGI("OffDeviceStateChanged RemoveCallback");
1595 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
1596 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_DEVICE_STATE_CHANGED, callback);
1597 }
1598
OffServiceDie(napi_env env,napi_value callback)1599 napi_status NapiAVSessionManager::OffServiceDie(napi_env env, napi_value callback)
1600 {
1601 SLOGI("OffServiceDie but no longer UnregisterServiceDeathCallback");
1602 if (callback == nullptr) {
1603 for (auto callbackRef = serviceDiedCallbacks_.begin(); callbackRef != serviceDiedCallbacks_.end();
1604 ++callbackRef) {
1605 napi_status ret = napi_delete_reference(env, *callbackRef);
1606 CHECK_AND_RETURN_RET_LOG(napi_ok == ret, ret, "delete callback reference failed");
1607 *callbackRef = nullptr;
1608 }
1609 serviceDiedCallbacks_.clear();
1610 return napi_ok;
1611 }
1612 napi_ref ref = nullptr;
1613 CHECK_AND_RETURN_RET_LOG(napi_ok == NapiUtils::GetRefByCallback(env, serviceDiedCallbacks_, callback, ref),
1614 napi_generic_failure, "get callback reference failed");
1615 CHECK_AND_RETURN_RET_LOG(ref != nullptr, napi_ok, "callback has been remove");
1616 serviceDiedCallbacks_.remove(ref);
1617 return napi_delete_reference(env, ref);
1618 }
1619
ReportStartCastDiscoveryFailInfo(std::string func,int32_t error)1620 void NapiAVSessionManager::ReportStartCastDiscoveryFailInfo(std::string func, int32_t error)
1621 {
1622 AVSessionRadarInfo info(func);
1623 info.errorCode_ = AVSessionRadar::GetRadarErrorCode(error);
1624 AVSessionRadar::GetInstance().FailToStartCastDiscovery(info);
1625 }
1626
ReportStopCastDiscoveryFailInfo(std::string func,int32_t error)1627 void NapiAVSessionManager::ReportStopCastDiscoveryFailInfo(std::string func, int32_t error)
1628 {
1629 AVSessionRadarInfo info(func);
1630 info.errorCode_ = AVSessionRadar::GetRadarErrorCode(error);
1631 AVSessionRadar::GetInstance().FailToStopCastDiscovery(info);
1632 }
1633
ReportStartCastFailInfo(int32_t error)1634 void NapiAVSessionManager::ReportStartCastFailInfo(int32_t error)
1635 {
1636 AVSessionRadarInfo info("NapiAVSessionManager::StartCast");
1637 info.errorCode_ = AVSessionRadar::GetRadarErrorCode(error);
1638 AVSessionRadar::GetInstance().FailToStartCast(info);
1639 }
1640
ReportStartCastFailInfo(int32_t error,const OutputDeviceInfo & outputDeviceInfo)1641 void NapiAVSessionManager::ReportStartCastFailInfo(int32_t error, const OutputDeviceInfo &outputDeviceInfo)
1642 {
1643 AVSessionRadarInfo info("NapiAVSessionManager::StartCast");
1644 info.errorCode_ = AVSessionRadar::GetRadarErrorCode(error);
1645 AVSessionRadar::GetInstance().FailToStartCast(outputDeviceInfo, info);
1646 }
1647
ReportStopCastFailInfo(int32_t error)1648 void NapiAVSessionManager::ReportStopCastFailInfo(int32_t error)
1649 {
1650 AVSessionRadarInfo info("NapiAVSessionManager::StopCast");
1651 info.errorCode_ = AVSessionRadar::GetRadarErrorCode(error);
1652 AVSessionRadar::GetInstance().FailToStopCast(info);
1653 }
1654
CheckStartCastReportRadar(bool condition,int32_t error)1655 void NapiAVSessionManager::CheckStartCastReportRadar(bool condition, int32_t error)
1656 {
1657 if (!condition) {
1658 ReportStartCastFailInfo(error);
1659 }
1660 }
1661
CheckStopCastReportRadar(bool condition,int32_t error)1662 void NapiAVSessionManager::CheckStopCastReportRadar(bool condition, int32_t error)
1663 {
1664 if (!condition) {
1665 ReportStopCastFailInfo(error);
1666 }
1667 }
1668 } // namespace OHOS::AVSession
1669