1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "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
33 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
34 #include "napi_avcast_controller.h"
35 #endif
36
37 namespace OHOS::AVSession {
38 using namespace Security::AccessToken;
39 std::map<std::string, std::pair<NapiAVSessionManager::OnEventHandlerType, NapiAVSessionManager::OffEventHandlerType>>
40 NapiAVSessionManager::eventHandlers_ = {
41 { "sessionCreate", { OnSessionCreate, OffSessionCreate } },
42 { "sessionDestroy", { OnSessionDestroy, OffSessionDestroy } },
43 { "topSessionChange", { OnTopSessionChange, OffTopSessionChange } },
44 { "sessionServiceDie", { OnServiceDie, OffServiceDie } },
45 { "deviceAvailable", { OnDeviceAvailable, OffDeviceAvailable } },
46 { "deviceOffline", { OnDeviceOffline, OffDeviceOffline } },
47 };
48
49 std::shared_ptr<NapiSessionListener> NapiAVSessionManager::listener_;
50 std::shared_ptr<NapiAsyncCallback> NapiAVSessionManager::asyncCallback_;
51 std::list<napi_ref> NapiAVSessionManager::serviceDiedCallbacks_;
52
53 std::map<int32_t, int32_t> NapiAVSessionManager::errcode_ = {
54 {AVSESSION_ERROR, 6600101},
55 {ERR_NO_MEMORY, 6600101},
56 {ERR_SERVICE_NOT_EXIST, 6600101},
57 {ERR_SESSION_LISTENER_EXIST, 6600101},
58 {ERR_MARSHALLING, 6600101},
59 {ERR_UNMARSHALLING, 6600101},
60 {ERR_IPC_SEND_REQUEST, 6600101},
61 {ERR_CONTROLLER_IS_EXIST, 6600101},
62 {ERR_START_ABILITY_IS_RUNNING, 6600101},
63 {ERR_ABILITY_NOT_AVAILABLE, 6600101},
64 {ERR_START_ABILITY_TIMEOUT, 6600101},
65 {ERR_SESSION_NOT_EXIST, 6600102},
66 {ERR_CONTROLLER_NOT_EXIST, 6600103},
67 {ERR_RPC_SEND_REQUEST, 6600104},
68 {ERR_COMMAND_NOT_SUPPORT, 6600105},
69 {ERR_SESSION_DEACTIVE, 6600106},
70 {ERR_COMMAND_SEND_EXCEED_MAX, 6600107},
71 {ERR_DEVICE_CONNECTION_FAILED, 6600108},
72 {ERR_REMOTE_CONNECTION_NOT_EXIST, 6600109},
73 {ERR_NO_PERMISSION, 202},
74 {ERR_INVALID_PARAM, 401},
75 };
Init(napi_env env,napi_value exports)76 napi_value NapiAVSessionManager::Init(napi_env env, napi_value exports)
77 {
78 napi_property_descriptor descriptors[] = {
79 DECLARE_NAPI_STATIC_FUNCTION("createAVSession", CreateAVSession),
80 DECLARE_NAPI_STATIC_FUNCTION("getAllSessionDescriptors", GetAllSessionDescriptors),
81 DECLARE_NAPI_STATIC_FUNCTION("getHistoricalSessionDescriptors", GetHistoricalSessionDescriptors),
82 DECLARE_NAPI_STATIC_FUNCTION("createController", CreateController),
83 DECLARE_NAPI_STATIC_FUNCTION("getAVCastController", GetAVCastController),
84 DECLARE_NAPI_STATIC_FUNCTION("castAudio", CastAudio),
85 DECLARE_NAPI_STATIC_FUNCTION("on", OnEvent),
86 DECLARE_NAPI_STATIC_FUNCTION("off", OffEvent),
87 DECLARE_NAPI_STATIC_FUNCTION("sendSystemAVKeyEvent", SendSystemAVKeyEvent),
88 DECLARE_NAPI_STATIC_FUNCTION("sendSystemControlCommand", SendSystemControlCommand),
89 DECLARE_NAPI_STATIC_FUNCTION("startCastDeviceDiscovery", StartCastDiscovery),
90 DECLARE_NAPI_STATIC_FUNCTION("stopCastDeviceDiscovery", StopCastDiscovery),
91 DECLARE_NAPI_STATIC_FUNCTION("setDiscoverable", SetDiscoverable),
92 DECLARE_NAPI_STATIC_FUNCTION("startCasting", StartCast),
93 DECLARE_NAPI_STATIC_FUNCTION("stopCasting", StopCast),
94 };
95
96 napi_status status = napi_define_properties(env, exports, sizeof(descriptors) / sizeof(napi_property_descriptor),
97 descriptors);
98 if (status != napi_ok) {
99 SLOGE("define manager properties failed");
100 return NapiUtils::GetUndefinedValue(env);
101 }
102 return exports;
103 }
104
CreateAVSession(napi_env env,napi_callback_info info)105 napi_value NapiAVSessionManager::CreateAVSession(napi_env env, napi_callback_info info)
106 {
107 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::CreateAVSession");
108 struct ConcreteContext : public ContextBase {
109 std::string tag_;
110 int32_t type_{};
111 AppExecFwk::ElementName elementName_;
112 std::shared_ptr<AVSession> session_;
113 };
114 auto context = std::make_shared<ConcreteContext>();
115 context->taskId = NAPI_CREATE_AVSESSION_TASK_ID;
116
117 auto inputParser = [env, context](size_t argc, napi_value* argv) {
118 // require 3 arguments <context> <tag> <type>
119 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_THREE, "invalid arguments",
120 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
121 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->elementName_);
122 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "invalid context",
123 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
124 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->tag_);
125 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok && !context->tag_.empty(), "invalid tag",
126 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
127 std::string typeString;
128 context->status = NapiUtils::GetValue(env, argv[ARGV_THIRD], typeString);
129 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok && !typeString.empty(), "invalid type",
130 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
131 context->type_ = NapiUtils::ConvertSessionType(typeString);
132 CHECK_ARGS_RETURN_VOID(context, context->type_ >= 0, "wrong session type",
133 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
134 context->status = napi_ok;
135 };
136 context->GetCbInfo(env, info, inputParser);
137
138 auto executor = [context]() {
139 context->session_ = AVSessionManager::GetInstance().CreateSession(context->tag_, context->type_,
140 context->elementName_);
141 if (context->session_ == nullptr) {
142 context->status = napi_generic_failure;
143 context->errMessage = "CreateAVSession failed : native create session failed";
144 context->errCode = NapiAVSessionManager::errcode_[AVSESSION_ERROR];
145 }
146 };
147
148 auto complete = [context](napi_value& output) {
149 context->status = NapiAVSession::NewInstance(context->env, context->session_, output);
150 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
151 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
152 };
153
154 return NapiAsyncWork::Enqueue(env, context, "CreateAVSession", executor, complete);
155 }
156
GetAllSessionDescriptors(napi_env env,napi_callback_info info)157 napi_value NapiAVSessionManager::GetAllSessionDescriptors(napi_env env, napi_callback_info info)
158 {
159 struct ConcreteContext : public ContextBase {
160 std::vector<AVSessionDescriptor> descriptors_;
161 };
162 auto context = std::make_shared<ConcreteContext>();
163 context->GetCbInfo(env, info);
164
165 auto executor = [context]() {
166 int32_t ret = AVSessionManager::GetInstance().GetAllSessionDescriptors(context->descriptors_);
167 if (ret != AVSESSION_SUCCESS) {
168 if (ret == ERR_NO_PERMISSION) {
169 context->errMessage = "GetAllSessionDescriptors failed : native no permission";
170 } else {
171 context->errMessage = "GetAllSessionDescriptors failed : native server exception";
172 }
173 context->status = napi_generic_failure;
174 context->errCode = NapiAVSessionManager::errcode_[ret];
175 }
176 };
177
178 auto complete = [env, context](napi_value& output) {
179 context->status = NapiUtils::SetValue(env, context->descriptors_, output);
180 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
181 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
182 };
183
184 return NapiAsyncWork::Enqueue(env, context, "GetAllSessionDescriptors", executor, complete);
185 }
186
GetHistoricalSessionDescriptors(napi_env env,napi_callback_info info)187 napi_value NapiAVSessionManager::GetHistoricalSessionDescriptors(napi_env env, napi_callback_info info)
188 {
189 struct ConcreteContext : public ContextBase {
190 int32_t maxSize_ {};
191 std::vector<AVSessionDescriptor> descriptors_;
192 };
193 auto context = std::make_shared<ConcreteContext>();
194
195 auto input = [env, context](size_t argc, napi_value* argv) {
196 if (argc == ARGC_ONE && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_undefined)
197 && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_null)) {
198 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->maxSize_);
199 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "invalid arguments",
200 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
201 CHECK_ARGS_RETURN_VOID(context,
202 (context->maxSize_ >= (int32_t)HISTORICAL_MIN_NUM && context->maxSize_ <= (int32_t)HISTORICAL_MAX_NUM),
203 "invalid arguments", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
204 } else {
205 context->maxSize_ = HISTORICAL_UNSET_NUM;
206 }
207 };
208
209 context->GetCbInfo(env, info, input);
210
211 auto executor = [context]() {
212 int32_t ret = AVSessionManager::GetInstance().GetHistoricalSessionDescriptors(context->maxSize_,
213 context->descriptors_);
214 if (ret != AVSESSION_SUCCESS) {
215 if (ret == ERR_NO_PERMISSION) {
216 context->errMessage = "GetHistoricalSessionDescriptors failed : native no permission";
217 } else {
218 context->errMessage = "GetHistoricalSessionDescriptors failed : native server exception";
219 }
220 context->status = napi_generic_failure;
221 context->errCode = NapiAVSessionManager::errcode_[ret];
222 }
223 };
224
225 auto complete = [env, context](napi_value& output) {
226 context->status = NapiUtils::SetValue(env, context->descriptors_, output);
227 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
228 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
229 };
230
231 return NapiAsyncWork::Enqueue(env, context, "GetHistoricalSessionDescriptors", executor, complete);
232 }
233
CreateController(napi_env env,napi_callback_info info)234 napi_value NapiAVSessionManager::CreateController(napi_env env, napi_callback_info info)
235 {
236 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::CreateController");
237 struct ConcreteContext : public ContextBase {
238 std::string sessionId_ {};
239 std::shared_ptr<AVSessionController> controller_;
240 };
241 auto context = std::make_shared<ConcreteContext>();
242 auto input = [env, context](size_t argc, napi_value* argv) {
243 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
244 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
245 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->sessionId_);
246 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (!context->sessionId_.empty()),
247 "invalid sessionId", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
248 };
249 context->GetCbInfo(env, info, input);
250 context->taskId = NAPI_CREATE_CONTROLLER_TASK_ID;
251
252 auto executor = [context]() {
253 int32_t ret = AVSessionManager::GetInstance().CreateController(context->sessionId_, context->controller_);
254 if (ret != AVSESSION_SUCCESS) {
255 if (ret == ERR_NO_PERMISSION) {
256 context->errMessage = "CreateController failed : native no permission";
257 } else if (ret == ERR_INVALID_PARAM) {
258 context->errMessage = "CreateController failed : native invalid parameters";
259 } else if (ret == ERR_SESSION_NOT_EXIST) {
260 context->errMessage = "CreateController failed : native session not exist";
261 } else {
262 context->errMessage = "CreateController 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 = NapiAVSessionController::NewInstance(env, context->controller_, 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, "CreateController", executor, complete);
276 }
277
GetAVCastController(napi_env env,napi_callback_info info)278 napi_value NapiAVSessionManager::GetAVCastController(napi_env env, napi_callback_info info)
279 {
280 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
281 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::GetAVCastController");
282 struct ConcreteContext : public ContextBase {
283 std::string sessionId_ {};
284 std::shared_ptr<AVCastController> castController_;
285 };
286 auto context = std::make_shared<ConcreteContext>();
287 auto input = [env, context](size_t argc, napi_value* argv) {
288 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
289 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
290 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->sessionId_);
291 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (!context->sessionId_.empty()),
292 "invalid sessionId", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
293 };
294 context->GetCbInfo(env, info, input);
295 context->taskId = NAPI_CREATE_CAST_CONTROLLER_TASK_ID;
296
297 auto executor = [context]() {
298 int32_t ret = AVSessionManager::GetInstance().GetAVCastController(context->sessionId_,
299 context->castController_);
300 if (ret != AVSESSION_SUCCESS) {
301 if (ret == ERR_NO_PERMISSION) {
302 context->errMessage = "GetAVCastController failed : native no permission";
303 } else if (ret == ERR_INVALID_PARAM) {
304 context->errMessage = "GetAVCastController failed : native invalid parameters";
305 } else if (ret == ERR_SESSION_NOT_EXIST) {
306 context->errMessage = "GetAVCastController failed : native session not exist";
307 } else {
308 context->errMessage = "GetAVCastController failed : native server exception";
309 }
310 context->status = napi_generic_failure;
311 context->errCode = NapiAVSessionManager::errcode_[ret];
312 }
313 };
314
315 auto complete = [env, context](napi_value& output) {
316 context->status = NapiAVCastController::NewInstance(env, context->castController_, output);
317 CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
318 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
319 };
320
321 return NapiAsyncWork::Enqueue(env, context, "GetAVCastController", executor, complete);
322 #else
323 return nullptr;
324 #endif
325 }
326
CastAudio(napi_env env,napi_callback_info info)327 napi_value NapiAVSessionManager::CastAudio(napi_env env, napi_callback_info info)
328 {
329 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::CastAudio");
330 struct ConcreteContext : public ContextBase {
331 SessionToken sessionToken_ {};
332 bool isAll_ = false;
333 std::vector<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptors_;
334 };
335 auto context = std::make_shared<ConcreteContext>();
336 auto input = [env, context](size_t argc, napi_value* argv) {
337 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid arguments",
338 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
339 napi_valuetype type = napi_undefined;
340 context->status = napi_typeof(env, argv[ARGV_FIRST], &type);
341 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_string || type == napi_object),
342 "invalid type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
343 if (type == napi_string) {
344 std::string flag;
345 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], flag);
346 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (flag == "all"),
347 "invalid argument", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
348 context->isAll_ = true;
349 }
350 if (type == napi_object) {
351 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->sessionToken_);
352 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (!context->sessionToken_.sessionId.empty()),
353 "invalid session token", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
354 }
355 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->audioDeviceDescriptors_);
356 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (context->audioDeviceDescriptors_.size() > 0),
357 "invalid AudioDeviceDescriptor", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
358 };
359 context->GetCbInfo(env, info, input);
360 context->taskId = NAPI_CAST_AUDIO_TASK_ID;
361 auto executor = [context]() {
362 int32_t ret = AVSESSION_ERROR;
363 if (context->isAll_) {
364 ret = AVSessionManager::GetInstance().CastAudioForAll(context->audioDeviceDescriptors_);
365 } else {
366 ret = AVSessionManager::GetInstance().CastAudio(context->sessionToken_, context->audioDeviceDescriptors_);
367 }
368 if (ret != AVSESSION_SUCCESS) {
369 ErrCodeToMessage(ret, "CastAudio", context->errMessage);
370 context->status = napi_generic_failure;
371 context->errCode = NapiAVSessionManager::errcode_[ret];
372 }
373 };
374 auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
375 return NapiAsyncWork::Enqueue(env, context, "CastAudio", executor, complete);
376 }
377
ErrCodeToMessage(int32_t errCode,const std::string & tag,std::string & message)378 void NapiAVSessionManager::ErrCodeToMessage(int32_t errCode, const std::string& tag, std::string& message)
379 {
380 message = tag;
381 SLOGE("check error code for message:%{public}d", errCode);
382 switch (errCode) {
383 case ERR_SESSION_NOT_EXIST:
384 message.append(" failed : native session not exist");
385 break;
386 case ERR_INVALID_PARAM:
387 message.append(" failed : native invalid parameters");
388 break;
389 case ERR_NO_PERMISSION:
390 message.append(" failed : native no permission");
391 break;
392 default:
393 message.append(" failed : native server exception");
394 break;
395 }
396 }
397
RegisterNativeSessionListener(napi_env env)398 napi_status NapiAVSessionManager::RegisterNativeSessionListener(napi_env env)
399 {
400 if (listener_ != nullptr) {
401 return napi_ok;
402 }
403
404 listener_ = std::make_shared<NapiSessionListener>();
405 if (listener_ == nullptr) {
406 SLOGE("OnEvent failed : no memory");
407 NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
408 return napi_generic_failure;
409 }
410 int32_t ret = AVSessionManager::GetInstance().RegisterSessionListener(listener_);
411 if (ret != AVSESSION_SUCCESS) {
412 SLOGE("native register session listener failed");
413 if (ret == ERR_INVALID_PARAM) {
414 NapiUtils::ThrowError(env, "OnEvent failed : native invalid parameters",
415 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
416 } else if (ret == ERR_NO_PERMISSION) {
417 NapiUtils::ThrowError(env, "OnEvent failed : native no permission",
418 NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
419 } else {
420 NapiUtils::ThrowError(env, "OnEvent failed : native server exception",
421 NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
422 }
423 return napi_generic_failure;
424 }
425
426 return napi_ok;
427 }
428
OnEvent(napi_env env,napi_callback_info info)429 napi_value NapiAVSessionManager::OnEvent(napi_env env, napi_callback_info info)
430 {
431 auto context = std::make_shared<ContextBase>();
432 if (context == nullptr) {
433 SLOGE("OnEvent failed : no memory");
434 NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
435 return NapiUtils::GetUndefinedValue(env);
436 }
437
438 std::string eventName;
439 napi_value callback = nullptr;
440 auto input = [&eventName, &callback, env, &context](size_t argc, napi_value* argv) {
441 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
442 bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
443 CHECK_ARGS_RETURN_VOID(context, isSystemApp, "Check system permission error",
444 NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
445
446 /* require 2 arguments <event, callback> */
447 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid argument number",
448 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
449 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
450 CHECK_STATUS_RETURN_VOID(context, "get event name failed", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
451 napi_valuetype type = napi_undefined;
452 context->status = napi_typeof(env, argv[ARGV_SECOND], &type);
453 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
454 "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
455 callback = argv[ARGV_SECOND];
456 };
457
458 context->GetCbInfo(env, info, input, true);
459 if (context->status != napi_ok) {
460 NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
461 return NapiUtils::GetUndefinedValue(env);
462 }
463
464 auto it = eventHandlers_.find(eventName);
465 if (it == eventHandlers_.end()) {
466 SLOGE("event name invalid");
467 NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
468 return NapiUtils::GetUndefinedValue(env);
469 }
470
471 if (RegisterNativeSessionListener(env) == napi_generic_failure) {
472 return NapiUtils::GetUndefinedValue(env);
473 }
474
475 if (it->second.first(env, callback) != napi_ok) {
476 NapiUtils::ThrowError(env, "add event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
477 }
478
479 return NapiUtils::GetUndefinedValue(env);
480 }
481
OffEvent(napi_env env,napi_callback_info info)482 napi_value NapiAVSessionManager::OffEvent(napi_env env, napi_callback_info info)
483 {
484 auto context = std::make_shared<ContextBase>();
485 if (context == nullptr) {
486 SLOGE("OnEvent failed : no memory");
487 NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
488 return NapiUtils::GetUndefinedValue(env);
489 }
490
491 std::string eventName;
492 napi_value callback = nullptr;
493 auto input = [&eventName, env, &context, &callback](size_t argc, napi_value* argv) {
494 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
495 bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
496 CHECK_ARGS_RETURN_VOID(context, isSystemApp, "Check system permission error",
497 NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
498
499 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE || argc == ARGC_TWO, "invalid argument number",
500 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
501 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
502 CHECK_STATUS_RETURN_VOID(context, "get event name failed",
503 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
504 if (argc == ARGC_TWO) {
505 callback = argv[ARGV_SECOND];
506 }
507 };
508
509 context->GetCbInfo(env, info, input, true);
510 if (context->status != napi_ok) {
511 NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
512 return NapiUtils::GetUndefinedValue(env);
513 }
514
515 auto it = eventHandlers_.find(eventName);
516 if (it == eventHandlers_.end()) {
517 SLOGE("event name invalid");
518 NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
519 return NapiUtils::GetUndefinedValue(env);
520 }
521
522 if (it->second.second(env, callback) != napi_ok) {
523 NapiUtils::ThrowError(env, "remove event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
524 }
525
526 return NapiUtils::GetUndefinedValue(env);
527 }
528
SendSystemAVKeyEvent(napi_env env,napi_callback_info info)529 napi_value NapiAVSessionManager::SendSystemAVKeyEvent(napi_env env, napi_callback_info info)
530 {
531 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::SendSystemAVKeyEvent");
532 struct ConcreteContext : public ContextBase {
533 std::shared_ptr<MMI::KeyEvent> keyEvent_;
534 };
535 auto context = std::make_shared<ConcreteContext>();
536 auto input = [env, context](size_t argc, napi_value* argv) {
537 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
538 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
539 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->keyEvent_);
540 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (context->keyEvent_ != nullptr),
541 "invalid keyEvent", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
542 };
543 context->GetCbInfo(env, info, input);
544 context->taskId = NAPI_SEND_SYSTEM_AV_KEY_EVENT_TASK_ID;
545
546 auto executor = [context]() {
547 int32_t ret = AVSessionManager::GetInstance().SendSystemAVKeyEvent(*context->keyEvent_);
548 if (ret != AVSESSION_SUCCESS) {
549 if (ret == ERR_COMMAND_NOT_SUPPORT) {
550 context->errMessage = "SendSystemAVKeyEvent failed : native invalid keyEvent";
551 } else if (ret == ERR_NO_PERMISSION) {
552 context->errMessage = "SendSystemAVKeyEvent failed : native no permission";
553 } else {
554 context->errMessage = "SendSystemAVKeyEvent failed : native server exception";
555 }
556 context->status = napi_generic_failure;
557 context->errCode = NapiAVSessionManager::errcode_[ret];
558 }
559 };
560
561 return NapiAsyncWork::Enqueue(env, context, "SendSystemAVKeyEvent", executor);
562 }
563
SendSystemControlCommand(napi_env env,napi_callback_info info)564 napi_value NapiAVSessionManager::SendSystemControlCommand(napi_env env, napi_callback_info info)
565 {
566 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::SendSystemControlCommand");
567 struct ConcrentContext : public ContextBase {
568 AVControlCommand command;
569 };
570 auto context = std::make_shared<ConcrentContext>();
571 auto input = [env, context](size_t argc, napi_value* argv) {
572 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
573 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
574 context->status = NapiControlCommand::GetValue(env, argv[ARGV_FIRST], context->command);
575 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok), "invalid command",
576 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
577 };
578 context->GetCbInfo(env, info, input);
579 context->taskId = NAPI_SEND_SYSTEM_CONTROL_COMMAND_TASK_ID;
580
581 auto executor = [context]() {
582 int32_t ret = AVSessionManager::GetInstance().SendSystemControlCommand(context->command);
583 #ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
584 double speed;
585 int64_t time;
586 int32_t mode;
587 std::string assetId;
588 context->command.GetSpeed(speed);
589 context->command.GetSeekTime(time);
590 context->command.GetLoopMode(mode);
591 context->command.GetAssetId(assetId);
592 HISYSEVENT_FAULT("CONTROL_COMMAND_FAILED", "ERROR_TYPE", "SEND_CMD_FAILED",
593 "CMD", context->command.GetCommand(), "TIME", time, "SPEED", speed, "MODE", mode, "ASSETID", assetId,
594 "ERROR_CODE", ret, "ERROR_INFO", "native send control command failed");
595 #endif
596 if (ret != AVSESSION_SUCCESS) {
597 if (ret == ERR_COMMAND_NOT_SUPPORT) {
598 context->errMessage = "SendSystemControlCommand failed : native invalid command";
599 } else if (ret == ERR_NO_PERMISSION) {
600 context->errMessage = "SendSystemControlCommand failed : native send control command no permission";
601 HISYSEVENT_SECURITY("CONTROL_PERMISSION_DENIED", "ERROR_CODE", ret,
602 "ERROR_INFO", "SendSystemControlCommand failed : native no permission");
603 } else if (ret == ERR_COMMAND_SEND_EXCEED_MAX) {
604 context->errMessage = "SendSystemControlCommand failed : native send command overload";
605 } else {
606 context->errMessage = "SendSystemControlCommand failed : native server exception";
607 }
608 context->status = napi_generic_failure;
609 context->errCode = NapiAVSessionManager::errcode_[ret];
610 }
611 };
612
613 return NapiAsyncWork::Enqueue(env, context, "SendSystemControlCommand", executor);
614 }
615
StartCastDiscovery(napi_env env,napi_callback_info info)616 napi_value NapiAVSessionManager::StartCastDiscovery(napi_env env, napi_callback_info info)
617 {
618 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
619 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::StartCastDiscovery");
620 struct ConcreteContext : public ContextBase {
621 int32_t castDeviceCapability_;
622 };
623 auto context = std::make_shared<ConcreteContext>();
624 auto input = [env, context](size_t argc, napi_value* argv) {
625 if (argc == ARGC_ONE && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_undefined)
626 && !NapiUtils::TypeCheck(env, argv[ARGV_FIRST], napi_null)) {
627 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->castDeviceCapability_);
628 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "invalid castDeviceCapability",
629 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
630 } else {
631 context->castDeviceCapability_ = ProtocolType::TYPE_CAST_PLUS_STREAM;
632 }
633 };
634 context->GetCbInfo(env, info, input);
635 context->taskId = NAPI_START_CAST_DISCOVERY_TASK_ID;
636
637 auto executor = [context]() {
638 int32_t ret = AVSessionManager::GetInstance().StartCastDiscovery(context->castDeviceCapability_);
639 if (ret != AVSESSION_SUCCESS) {
640 if (ret == ERR_NO_PERMISSION) {
641 context->errMessage = "StartCastDiscovery failed : native no permission";
642 } else if (ret == ERR_INVALID_PARAM) {
643 context->errMessage = "StartCastDiscovery failed : native invalid parameters";
644 } else if (ret == ERR_SESSION_NOT_EXIST) {
645 context->errMessage = "StartCastDiscovery failed : native session not exist";
646 } else {
647 context->errMessage = "StartCastDiscovery failed : native server exception";
648 }
649 context->status = napi_generic_failure;
650 context->errCode = NapiAVSessionManager::errcode_[ret];
651 }
652 };
653 return NapiAsyncWork::Enqueue(env, context, "StartCastDiscovery", executor);
654 #else
655 return nullptr;
656 #endif
657 }
658
StopCastDiscovery(napi_env env,napi_callback_info info)659 napi_value NapiAVSessionManager::StopCastDiscovery(napi_env env, napi_callback_info info)
660 {
661 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
662 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::StopCastDiscovery");
663 auto context = std::make_shared<ContextBase>();
664 if (context == nullptr) {
665 SLOGE("Activate failed : no memory");
666 NapiUtils::ThrowError(env, "Activate failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
667 return NapiUtils::GetUndefinedValue(env);
668 }
669
670 context->GetCbInfo(env, info);
671 context->taskId = NAPI_STOP_CAST_DISCOVERY_TASK_ID;
672
673 auto executor = [context]() {
674 int32_t ret = AVSESSION_ERROR;
675 ret = AVSessionManager::GetInstance().StopCastDiscovery();
676 if (ret != AVSESSION_SUCCESS) {
677 if (ret == ERR_NO_PERMISSION) {
678 context->errMessage = "StopCastDiscovery failed : native no permission";
679 } else if (ret == ERR_INVALID_PARAM) {
680 context->errMessage = "StopCastDiscovery failed : native invalid parameters";
681 } else if (ret == ERR_SESSION_NOT_EXIST) {
682 context->errMessage = "StopCastDiscovery failed : native session not exist";
683 } else {
684 context->errMessage = "StopCastDiscovery failed : native server exception";
685 }
686 context->status = napi_generic_failure;
687 context->errCode = NapiAVSessionManager::errcode_[ret];
688 }
689 };
690 auto complete = [env](napi_value& output) {
691 output = NapiUtils::GetUndefinedValue(env);
692 };
693 return NapiAsyncWork::Enqueue(env, context, "StopCastDiscovery", executor, complete);
694 #else
695 return nullptr;
696 #endif
697 }
698
SetDiscoverable(napi_env env,napi_callback_info info)699 napi_value NapiAVSessionManager::SetDiscoverable(napi_env env, napi_callback_info info)
700 {
701 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
702 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::SetDiscoverable");
703 struct ConcreteContext : public ContextBase {
704 bool enable_;
705 };
706 auto context = std::make_shared<ConcreteContext>();
707 auto input = [env, context](size_t argc, napi_value* argv) {
708 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
709 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
710 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->enable_);
711 CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get streamIds_ failed",
712 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
713 };
714 context->GetCbInfo(env, info, input);
715 context->taskId = NAPI_SET_DISCOVERABLE_TASK_ID;
716
717 auto executor = [context]() {
718 int32_t ret = AVSessionManager::GetInstance().SetDiscoverable(context->enable_);
719 if (ret != AVSESSION_SUCCESS) {
720 if (ret == ERR_NO_PERMISSION) {
721 context->errMessage = "SetDiscoverable failed : native no permission";
722 } else if (ret == ERR_INVALID_PARAM) {
723 context->errMessage = "SetDiscoverable failed : native invalid parameters";
724 } else if (ret == ERR_SESSION_NOT_EXIST) {
725 context->errMessage = "SetDiscoverable failed : native session not exist";
726 } else {
727 context->errMessage = "SetDiscoverable failed : native server exception";
728 }
729 context->status = napi_generic_failure;
730 context->errCode = NapiAVSessionManager::errcode_[ret];
731 }
732 };
733 return NapiAsyncWork::Enqueue(env, context, "SetDiscoverable", executor);
734 #else
735 return nullptr;
736 #endif
737 }
738
StartCast(napi_env env,napi_callback_info info)739 napi_value NapiAVSessionManager::StartCast(napi_env env, napi_callback_info info)
740 {
741 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
742 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::StartCast");
743 struct ConcreteContext : public ContextBase {
744 SessionToken sessionToken_ {};
745 OutputDeviceInfo outputdeviceInfo_;
746 };
747 auto context = std::make_shared<ConcreteContext>();
748 auto input = [env, context](size_t argc, napi_value* argv) {
749 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid arguments",
750 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
751
752 napi_valuetype type = napi_undefined;
753 context->status = napi_typeof(env, argv[ARGV_FIRST], &type);
754 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_object),
755 "invalid type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
756 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->sessionToken_);
757 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok)
758 && (!context->sessionToken_.sessionId.empty()),
759 "invalid session token", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
760 context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->outputdeviceInfo_);
761 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok)
762 && (context->outputdeviceInfo_.deviceInfos_.size() > 0),
763 "invalid outputdeviceInfo", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
764 };
765 context->GetCbInfo(env, info, input);
766 context->taskId = NAPI_START_CAST_TASK_ID;
767
768 auto executor = [context]() {
769 int32_t ret = AVSESSION_ERROR;
770 ret = AVSessionManager::GetInstance().StartCast(context->sessionToken_, context->outputdeviceInfo_);
771 if (ret != AVSESSION_SUCCESS) {
772 if (ret == ERR_NO_PERMISSION) {
773 context->errMessage = "StartCast failed : native no permission";
774 } else if (ret == ERR_INVALID_PARAM) {
775 context->errMessage = "StartCast failed : native invalid parameters";
776 } else if (ret == ERR_SESSION_NOT_EXIST) {
777 context->errMessage = "StartCast failed : native session not exist";
778 } else {
779 context->errMessage = "StartCast failed : native server exception";
780 }
781 context->status = napi_generic_failure;
782 context->errCode = NapiAVSessionManager::errcode_[ret];
783 }
784 };
785
786 auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
787
788 return NapiAsyncWork::Enqueue(env, context, "StartCast", executor, complete);
789 #else
790 return nullptr;
791 #endif
792 }
793
StopCast(napi_env env,napi_callback_info info)794 napi_value NapiAVSessionManager::StopCast(napi_env env, napi_callback_info info)
795 {
796 #ifdef CASTPLUS_CAST_ENGINE_ENABLE
797 AVSESSION_TRACE_SYNC_START("NapiAVSessionManager::StopCast");
798 struct ConcreteContext : public ContextBase {
799 SessionToken sessionToken_ {};
800 };
801 auto context = std::make_shared<ConcreteContext>();
802 auto input = [env, context](size_t argc, napi_value* argv) {
803 CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
804 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
805
806 napi_valuetype type = napi_undefined;
807 context->status = napi_typeof(env, argv[ARGV_FIRST], &type);
808 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_object),
809 "invalid type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
810 context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->sessionToken_);
811 CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (!context->sessionToken_.sessionId.empty()),
812 "invalid session token", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
813 };
814 context->GetCbInfo(env, info, input);
815 context->taskId = NAPI_STOP_CAST_TASK_ID;
816
817 auto executor = [context]() {
818 int32_t ret = AVSESSION_ERROR;
819 ret = AVSessionManager::GetInstance().StopCast(context->sessionToken_);
820 if (ret != AVSESSION_SUCCESS) {
821 if (ret == ERR_NO_PERMISSION) {
822 context->errMessage = "StopCast failed : native no permission";
823 } else if (ret == ERR_INVALID_PARAM) {
824 context->errMessage = "StopCast failed : native invalid parameters";
825 } else if (ret == ERR_SESSION_NOT_EXIST) {
826 context->errMessage = "StopCast failed : native session not exist";
827 } else {
828 context->errMessage = "StopCast failed : native server exception";
829 }
830 context->status = napi_generic_failure;
831 context->errCode = NapiAVSessionManager::errcode_[ret];
832 }
833 };
834
835 auto complete = [env](napi_value& output) { output = NapiUtils::GetUndefinedValue(env); };
836
837 return NapiAsyncWork::Enqueue(env, context, "StopCast", executor, complete);
838 #else
839 return nullptr;
840 #endif
841 }
842
OnSessionCreate(napi_env env,napi_value callback)843 napi_status NapiAVSessionManager::OnSessionCreate(napi_env env, napi_value callback)
844 {
845 return listener_->AddCallback(env, NapiSessionListener::EVENT_SESSION_CREATED, callback);
846 }
847
OnSessionDestroy(napi_env env,napi_value callback)848 napi_status NapiAVSessionManager::OnSessionDestroy(napi_env env, napi_value callback)
849 {
850 return listener_->AddCallback(env, NapiSessionListener::EVENT_SESSION_DESTROYED, callback);
851 }
852
OnTopSessionChange(napi_env env,napi_value callback)853 napi_status NapiAVSessionManager::OnTopSessionChange(napi_env env, napi_value callback)
854 {
855 return listener_->AddCallback(env, NapiSessionListener::EVENT_TOP_SESSION_CHANGED, callback);
856 }
857
OnAudioSessionChecked(napi_env env,napi_value callback)858 napi_status NapiAVSessionManager::OnAudioSessionChecked(napi_env env, napi_value callback)
859 {
860 return listener_->AddCallback(env, NapiSessionListener::EVENT_AUDIO_SESSION_CHECKED, callback);
861 }
862
OnDeviceAvailable(napi_env env,napi_value callback)863 napi_status NapiAVSessionManager::OnDeviceAvailable(napi_env env, napi_value callback)
864 {
865 return listener_->AddCallback(env, NapiSessionListener::EVENT_DEVICE_AVAILABLE, callback);
866 }
867
OnDeviceOffline(napi_env env,napi_value callback)868 napi_status NapiAVSessionManager::OnDeviceOffline(napi_env env, napi_value callback)
869 {
870 return listener_->AddCallback(env, NapiSessionListener::EVENT_DEVICE_OFFLINE, callback);
871 }
872
OnServiceDie(napi_env env,napi_value callback)873 napi_status NapiAVSessionManager::OnServiceDie(napi_env env, napi_value callback)
874 {
875 napi_ref ref = nullptr;
876 CHECK_AND_RETURN_RET_LOG(napi_ok == NapiUtils::GetRefByCallback(env, serviceDiedCallbacks_, callback, ref),
877 napi_generic_failure, "get callback reference failed");
878 CHECK_AND_RETURN_RET_LOG(ref == nullptr, napi_ok, "callback has been registered");
879 napi_status status = napi_create_reference(env, callback, ARGC_ONE, &ref);
880 if (status != napi_ok) {
881 SLOGE("napi_create_reference failed");
882 return status;
883 }
884 if (asyncCallback_ == nullptr) {
885 asyncCallback_ = std::make_shared<NapiAsyncCallback>(env);
886 if (asyncCallback_ == nullptr) {
887 SLOGE("no memory");
888 return napi_generic_failure;
889 }
890 }
891 serviceDiedCallbacks_.push_back(ref);
892 if (AVSessionManager::GetInstance().RegisterServiceDeathCallback(HandleServiceDied) != AVSESSION_SUCCESS) {
893 return napi_generic_failure;
894 }
895 return napi_ok;
896 }
897
HandleServiceDied()898 void NapiAVSessionManager::HandleServiceDied()
899 {
900 if (!serviceDiedCallbacks_.empty() && asyncCallback_ != nullptr) {
901 for (auto callbackRef = serviceDiedCallbacks_.begin(); callbackRef != serviceDiedCallbacks_.end();
902 ++callbackRef) {
903 asyncCallback_->Call(*callbackRef);
904 }
905 }
906 }
907
OffSessionCreate(napi_env env,napi_value callback)908 napi_status NapiAVSessionManager::OffSessionCreate(napi_env env, napi_value callback)
909 {
910 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
911 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_SESSION_CREATED, callback);
912 }
913
OffSessionDestroy(napi_env env,napi_value callback)914 napi_status NapiAVSessionManager::OffSessionDestroy(napi_env env, napi_value callback)
915 {
916 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
917 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_SESSION_DESTROYED, callback);
918 }
919
OffTopSessionChange(napi_env env,napi_value callback)920 napi_status NapiAVSessionManager::OffTopSessionChange(napi_env env, napi_value callback)
921 {
922 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
923 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_TOP_SESSION_CHANGED, callback);
924 }
925
OffAudioSessionChecked(napi_env env,napi_value callback)926 napi_status NapiAVSessionManager::OffAudioSessionChecked(napi_env env, napi_value callback)
927 {
928 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
929 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_AUDIO_SESSION_CHECKED, callback);
930 }
931
OffDeviceAvailable(napi_env env,napi_value callback)932 napi_status NapiAVSessionManager::OffDeviceAvailable(napi_env env, napi_value callback)
933 {
934 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
935 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_DEVICE_AVAILABLE, callback);
936 }
937
OffDeviceOffline(napi_env env,napi_value callback)938 napi_status NapiAVSessionManager::OffDeviceOffline(napi_env env, napi_value callback)
939 {
940 CHECK_AND_RETURN_RET_LOG(listener_ != nullptr, napi_generic_failure, "callback has not been registered");
941 return listener_->RemoveCallback(env, NapiSessionListener::EVENT_DEVICE_OFFLINE, callback);
942 }
943
OffServiceDie(napi_env env,napi_value callback)944 napi_status NapiAVSessionManager::OffServiceDie(napi_env env, napi_value callback)
945 {
946 AVSessionManager::GetInstance().UnregisterServiceDeathCallback();
947 if (callback == nullptr) {
948 for (auto callbackRef = serviceDiedCallbacks_.begin(); callbackRef != serviceDiedCallbacks_.end();
949 ++callbackRef) {
950 napi_status ret = napi_delete_reference(env, *callbackRef);
951 CHECK_AND_RETURN_RET_LOG(napi_ok == ret, ret, "delete callback reference failed");
952 *callbackRef = nullptr;
953 }
954 serviceDiedCallbacks_.clear();
955 return napi_ok;
956 }
957 napi_ref ref = nullptr;
958 CHECK_AND_RETURN_RET_LOG(napi_ok == NapiUtils::GetRefByCallback(env, serviceDiedCallbacks_, callback, ref),
959 napi_generic_failure, "get callback reference failed");
960 CHECK_AND_RETURN_RET_LOG(ref != nullptr, napi_ok, "callback has been remove");
961 serviceDiedCallbacks_.remove(ref);
962 return napi_delete_reference(env, ref);
963 }
964 }
965