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