• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_avcall_meta_data.h"
17 #include "napi_avcall_state.h"
18 #include "key_event.h"
19 #include "napi_async_work.h"
20 #include "napi_avcontroller_callback.h"
21 #include "napi_avsession_controller.h"
22 #include "napi_control_command.h"
23 #include "napi_meta_data.h"
24 #include "napi_playback_state.h"
25 #include "napi_utils.h"
26 #include "napi_media_description.h"
27 #include "napi_queue_item.h"
28 #include "want_agent.h"
29 #include "avsession_errors.h"
30 #include "avsession_trace.h"
31 #include "napi_avsession_manager.h"
32 #include "ipc_skeleton.h"
33 #include "tokenid_kit.h"
34 
35 namespace OHOS::AVSession {
36 static __thread napi_ref AVControllerConstructorRef = nullptr;
37 std::map<std::string, std::pair<NapiAVSessionController::OnEventHandlerType,
38     NapiAVSessionController::OffEventHandlerType>> NapiAVSessionController::EventHandlers_ = {
39     { "callMetadataChange", { OnAVCallMetaDataChange, OffAVCallMetaDataChange } },
40     { "callStateChange", { OnAVCallStateChange, OffAVCallStateChange } },
41     { "sessionDestroy", { OnSessionDestroy, OffSessionDestroy } },
42     { "metadataChange", { OnMetaDataChange, OffMetaDataChange } },
43     { "playbackStateChange", { OnPlaybackStateChange, OffPlaybackStateChange } },
44     { "activeStateChange", { OnActiveStateChange, OffActiveStateChange } },
45     { "validCommandChange", { OnValidCommandChange, OffValidCommandChange } },
46     { "outputDeviceChange", { OnOutputDeviceChange, OffOutputDeviceChange } },
47     { "sessionEvent", { OnSessionEventChange, OffSessionEventChange } },
48     { "queueItemsChange", { OnQueueItemsChange, OffQueueItemsChange } },
49     { "queueTitleChange", { OnQueueTitleChange, OffQueueTitleChange } },
50     { "extrasChange", { OnExtrasChange, OffExtrasChange } },
51     { "customDataChange", { OnCustomData, OffCustomData } },
52 };
53 std::map<std::string, NapiAVSessionController> NapiAVSessionController::ControllerList_ = {};
54 std::mutex NapiAVSessionController::uvMutex_;
55 std::mutex NapiAVSessionController::controllerListMutex_;
56 
NapiAVSessionController()57 NapiAVSessionController::NapiAVSessionController()
58 {
59     SLOGI("construct");
60 }
61 
~NapiAVSessionController()62 NapiAVSessionController::~NapiAVSessionController()
63 {
64     SLOGI("destroy");
65 }
66 
Init(napi_env env,napi_value exports)67 napi_value NapiAVSessionController::Init(napi_env env, napi_value exports)
68 {
69     napi_property_descriptor descriptors[] = {
70         DECLARE_NAPI_FUNCTION("on", OnEvent),
71         DECLARE_NAPI_FUNCTION("off", OffEvent),
72         DECLARE_NAPI_FUNCTION("getAVCallState", GetAVCallState),
73         DECLARE_NAPI_FUNCTION("getCallMetadata", GetAVCallMetaData),
74         DECLARE_NAPI_FUNCTION("getAVPlaybackState", GetAVPlaybackState),
75         DECLARE_NAPI_FUNCTION("getAVPlaybackStateSync", GetAVPlaybackStateSync),
76         DECLARE_NAPI_FUNCTION("getAVMetadata", GetAVMetaData),
77         DECLARE_NAPI_FUNCTION("getAVMetadataSync", GetAVMetaDataSync),
78         DECLARE_NAPI_FUNCTION("getOutputDevice", GetOutputDevice),
79         DECLARE_NAPI_FUNCTION("getOutputDeviceSync", GetOutputDeviceSync),
80         DECLARE_NAPI_FUNCTION("sendAVKeyEvent", SendAVKeyEvent),
81         DECLARE_NAPI_FUNCTION("getLaunchAbility", GetLaunchAbility),
82         DECLARE_NAPI_FUNCTION("getRealPlaybackPositionSync", GetRealPlaybackPositionSync),
83         DECLARE_NAPI_FUNCTION("isActive", IsSessionActive),
84         DECLARE_NAPI_FUNCTION("isActiveSync", IsSessionActiveSync),
85         DECLARE_NAPI_FUNCTION("destroy", Destroy),
86         DECLARE_NAPI_FUNCTION("getValidCommands", GetValidCommands),
87         DECLARE_NAPI_FUNCTION("getValidCommandsSync", GetValidCommandsSync),
88         DECLARE_NAPI_FUNCTION("sendControlCommand", SendControlCommand),
89         DECLARE_NAPI_FUNCTION("sendCommonCommand", SendCommonCommand),
90         DECLARE_NAPI_FUNCTION("sendCustomData", SendCustomData),
91         DECLARE_NAPI_FUNCTION("getAVQueueItems", GetAVQueueItems),
92         DECLARE_NAPI_FUNCTION("getAVQueueItemsSync", GetAVQueueItemsSync),
93         DECLARE_NAPI_FUNCTION("getAVQueueTitle", GetAVQueueTitle),
94         DECLARE_NAPI_FUNCTION("getAVQueueTitleSync", GetAVQueueTitleSync),
95         DECLARE_NAPI_FUNCTION("skipToQueueItem", SkipToQueueItem),
96         DECLARE_NAPI_FUNCTION("getExtras", GetExtras),
97         DECLARE_NAPI_FUNCTION("getExtrasWithEvent", GetExtrasWithEvent),
98     };
99 
100     auto property_count = sizeof(descriptors) / sizeof(napi_property_descriptor);
101     napi_value constructor {};
102     auto status = napi_define_class(env, "AVSessionController", NAPI_AUTO_LENGTH, ConstructorCallback, nullptr,
103         property_count, descriptors, &constructor);
104     if (status != napi_ok) {
105         SLOGE("define class failed");
106         return NapiUtils::GetUndefinedValue(env);
107     }
108     napi_create_reference(env, constructor, 1, &AVControllerConstructorRef);
109     return exports;
110 }
111 
ConstructorCallback(napi_env env,napi_callback_info info)112 napi_value NapiAVSessionController::ConstructorCallback(napi_env env, napi_callback_info info)
113 {
114     napi_value self;
115     NAPI_CALL_BASE(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr), nullptr);
116 
117     auto finalize = [](napi_env env, void* data, void* hint) {
118         auto* napiController = reinterpret_cast<NapiAVSessionController*>(data);
119         napi_delete_reference(env, napiController->wrapperRef_);
120         delete napiController;
121         napiController = nullptr;
122     };
123 
124     auto* napiController = new(std::nothrow) NapiAVSessionController();
125     if (napiController == nullptr) {
126         SLOGE("no memory");
127         return nullptr;
128     }
129     if (napi_wrap(env, self, static_cast<void*>(napiController), finalize, nullptr, nullptr) != napi_ok) {
130         SLOGE("wrap failed");
131         delete napiController;
132         napiController = nullptr;
133         return nullptr;
134     }
135     return self;
136 }
137 
NewInstance(napi_env env,const std::shared_ptr<AVSessionController> & nativeController,napi_value & out)138 napi_status NapiAVSessionController::NewInstance(
139     napi_env env, const std::shared_ptr<AVSessionController>& nativeController, napi_value& out)
140 {
141     napi_value constructor {};
142     NAPI_CALL_BASE(env, napi_get_reference_value(env, AVControllerConstructorRef, &constructor), napi_generic_failure);
143     napi_value instance{};
144     NAPI_CALL_BASE(env, napi_new_instance(env, constructor, 0, nullptr, &instance), napi_generic_failure);
145     CHECK_RETURN(nativeController != nullptr, "get native controller failed with null", napi_generic_failure);
146     NapiAVSessionController* napiController{};
147     NAPI_CALL_BASE(env, napi_unwrap(env, instance, reinterpret_cast<void**>(&napiController)), napi_generic_failure);
148     napiController->controller_ = std::move(nativeController);
149     napiController->sessionId_ = napiController->controller_->GetSessionId();
150 
151     CHECK_RETURN(DoRegisterCallback(env, napiController) == napi_ok, "add callback failed", napi_generic_failure);
152     SLOGD("add napiController instance prelock for sessionId: %{public}s***",
153         napiController->sessionId_.substr(0, ARGC_THREE).c_str());
154     std::lock_guard<std::mutex> lock(controllerListMutex_);
155     SLOGI("add napiController instance aftlock for sessionId: %{public}s***",
156         napiController->sessionId_.substr(0, ARGC_THREE).c_str());
157     ControllerList_[napiController->sessionId_] = *napiController;
158     napi_value property {};
159     auto status = NapiUtils::SetValue(env, napiController->sessionId_, property);
160     CHECK_RETURN(status == napi_ok, "create object failed", napi_generic_failure);
161     NAPI_CALL_BASE(env, napi_set_named_property(env, instance, "sessionId", property), napi_generic_failure);
162 
163     out = instance;
164     return napi_ok;
165 }
166 
RepeatedInstance(napi_env env,const std::string & controllerId,napi_value & out)167 napi_status NapiAVSessionController::RepeatedInstance(napi_env env, const std::string& controllerId, napi_value& out)
168 {
169     napi_value constructor {};
170     NAPI_CALL_BASE(env, napi_get_reference_value(env, AVControllerConstructorRef, &constructor), napi_generic_failure);
171     napi_value instance{};
172     NAPI_CALL_BASE(env, napi_new_instance(env, constructor, 0, nullptr, &instance), napi_generic_failure);
173     NapiAVSessionController* napiController{};
174     NAPI_CALL_BASE(env, napi_unwrap(env, instance, reinterpret_cast<void**>(&napiController)), napi_generic_failure);
175     SLOGD("check repeat controller prelock with sessionId %{public}s", controllerId.c_str());
176     std::lock_guard<std::mutex> lock(controllerListMutex_);
177     SLOGI("check repeat controller aftlock with sessionId %{public}s", controllerId.c_str());
178     if (ControllerList_.count(controllerId) <= 0) {
179         SLOGE("check repeat without cur session");
180         return napi_generic_failure;
181     }
182 
183     NapiAVSessionController* repeatedNapiController = &(ControllerList_[controllerId]);
184     napiController->controller_ = repeatedNapiController->controller_;
185     napiController->sessionId_ = repeatedNapiController->sessionId_;
186     napiController->callback_ = repeatedNapiController->callback_;
187     SLOGI("check repeat controller for copy res %{public}d", (napiController->controller_ == nullptr));
188 
189     napi_value property {};
190     auto status = NapiUtils::SetValue(env, napiController->sessionId_, property);
191     CHECK_RETURN(status == napi_ok, "create object failed", napi_generic_failure);
192     NAPI_CALL_BASE(env, napi_set_named_property(env, instance, "sessionId", property), napi_generic_failure);
193 
194     out = instance;
195     return napi_ok;
196 }
197 
GetAVPlaybackState(napi_env env,napi_callback_info info)198 napi_value NapiAVSessionController::GetAVPlaybackState(napi_env env, napi_callback_info info)
199 {
200     struct ConcreteContext : public ContextBase {
201         AVPlaybackState state;
202     };
203     auto context = std::make_shared<ConcreteContext>();
204     context->GetCbInfo(env, info);
205 
206     auto executor = [context]() {
207         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
208         if (napiController->controller_ == nullptr) {
209             SLOGE("GetAVPlaybackState failed : controller is nullptr");
210             context->status = napi_generic_failure;
211             context->errMessage = "GetAVPlaybackState failed : controller is nullptr";
212             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
213             return;
214         }
215         int32_t ret = napiController->controller_->GetAVPlaybackState(context->state);
216         if (ret != AVSESSION_SUCCESS) {
217             if (ret == ERR_SESSION_NOT_EXIST) {
218                 context->errMessage = "GetAVPlaybackState failed : native session not exist";
219             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
220                 context->errMessage = "GetAVPlaybackState failed : native controller not exist";
221             } else if (ret == ERR_NO_PERMISSION) {
222                 context->errMessage = "GetAVPlaybackState failed : native no permission";
223             } else {
224                 context->errMessage = "GetAVPlaybackState failed : native server exception";
225             }
226             SLOGE("controller GetAVPlaybackState failed:%{public}d", ret);
227             context->status = napi_generic_failure;
228             context->errCode = NapiAVSessionManager::errcode_[ret];
229         }
230     };
231 
232     auto complete = [env, context](napi_value& output) {
233         context->status = NapiPlaybackState::SetValue(env, context->state, output);
234         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
235             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
236     };
237     return NapiAsyncWork::Enqueue(env, context, "GetAVPlayback", executor, complete);
238 }
239 
GetAVPlaybackStateSync(napi_env env,napi_callback_info info)240 napi_value NapiAVSessionController::GetAVPlaybackStateSync(napi_env env, napi_callback_info info)
241 {
242     SLOGD("Start GetAVPlaybackStateSync");
243     auto context = std::make_shared<ContextBase>();
244     if (context == nullptr) {
245         SLOGE("OnEvent failed : no memory");
246         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
247         return NapiUtils::GetUndefinedValue(env);
248     }
249     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
250     auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
251     if (napiController->controller_ == nullptr) {
252         SLOGI("GetAVPlaybackStateSync failed : controller is nullptr");
253         NapiUtils::ThrowError(env, "GetAVPlaybackStateSync failed : controller is nullptr",
254             NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
255         return NapiUtils::GetUndefinedValue(env);
256     }
257 
258     AVPlaybackState state;
259     int32_t ret = napiController->controller_->GetAVPlaybackState(state);
260     SLOGD("Get playback state: %{public}d", state.GetState());
261     if (ret != AVSESSION_SUCCESS) {
262         std::string errMessage;
263         if (ret == ERR_SESSION_NOT_EXIST) {
264             errMessage = "GetAVPlaybackStateSync failed : native session not exist";
265         } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
266             errMessage = "GetAVPlaybackStateSync failed : native controller not exist";
267         } else if (ret == ERR_NO_PERMISSION) {
268             errMessage = "GetAVPlaybackStateSync failed : native no permission";
269         } else {
270             ret = AVSESSION_ERROR;
271             errMessage = "GetAVPlaybackStateSync failed : native server exception";
272         }
273         SLOGE("controller GetAVPlaybackStateSync failed:%{public}d", ret);
274         NapiUtils::ThrowError(env, errMessage.c_str(), NapiAVSessionManager::errcode_[ret]);
275         return NapiUtils::GetUndefinedValue(env);
276     }
277 
278     napi_value output {};
279     auto status = NapiUtils::SetValue(env, state, output);
280     if (status != napi_ok) {
281         SLOGE("convert native object to javascript object failed");
282         NapiUtils::ThrowError(env, "convert native object to javascript object failed",
283             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
284         return NapiUtils::GetUndefinedValue(env);
285     }
286     return output;
287 }
288 
GetAVCallMetaData(napi_env env,napi_callback_info info)289 napi_value NapiAVSessionController::GetAVCallMetaData(napi_env env, napi_callback_info info)
290 {
291     struct ConcreteContext : public ContextBase {
292         AVCallMetaData avCallMetaData;
293     };
294     auto context = std::make_shared<ConcreteContext>();
295     context->GetCbInfo(env, info);
296 
297     auto executor = [context]() {
298         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
299         if (napiController->controller_ == nullptr) {
300             SLOGE("GetAVCallMetaData failed : controller is nullptr");
301             context->status = napi_generic_failure;
302             context->errMessage = "GetAVCallMetaData failed : controller is nullptr";
303             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
304             return;
305         }
306         int32_t ret = napiController->controller_->GetAVCallMetaData(context->avCallMetaData);
307         if (ret != AVSESSION_SUCCESS) {
308             if (ret == ERR_SESSION_NOT_EXIST) {
309                 context->errMessage = "GetAVCallMetaData failed : native session not exist";
310             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
311                 context->errMessage = "GetAVCallMetaData failed : native controller not exist";
312             } else if (ret == ERR_NO_PERMISSION) {
313                 context->errMessage = "GetAVCallMetaData failed : native no permission";
314             } else {
315                 context->errMessage = "GetAVCallMetaData failed : native server exception";
316             }
317             SLOGE("controller GetAVCallMetaData failed:%{public}d", ret);
318             context->status = napi_generic_failure;
319             context->errCode = NapiAVSessionManager::errcode_[ret];
320         }
321     };
322 
323     auto complete = [env, context](napi_value& output) {
324         context->status = NapiAVCallMetaData::SetValue(env, context->avCallMetaData, output);
325         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
326             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
327     };
328 
329     return NapiAsyncWork::Enqueue(env, context, "GetAVCallMetaData", executor, complete);
330 }
331 
GetAVCallState(napi_env env,napi_callback_info info)332 napi_value NapiAVSessionController::GetAVCallState(napi_env env, napi_callback_info info)
333 {
334     struct ConcreteContext : public ContextBase {
335         AVCallState avCallState;
336     };
337     auto context = std::make_shared<ConcreteContext>();
338     context->GetCbInfo(env, info);
339 
340     auto executor = [context]() {
341         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
342         if (napiController->controller_ == nullptr) {
343             SLOGE("GetAVCallState failed : controller is nullptr");
344             context->status = napi_generic_failure;
345             context->errMessage = "GetAVCallState failed : controller is nullptr";
346             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
347             return;
348         }
349         int32_t ret = napiController->controller_->GetAVCallState(context->avCallState);
350         if (ret != AVSESSION_SUCCESS) {
351             if (ret == ERR_SESSION_NOT_EXIST) {
352                 context->errMessage = "GetAVCallState failed : native session not exist";
353             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
354                 context->errMessage = "GetAVCallState failed : native controller not exist";
355             } else if (ret == ERR_NO_PERMISSION) {
356                 context->errMessage = "GetAVCallState failed : native no permission";
357             } else {
358                 context->errMessage = "GetAVCallState failed : native server exception";
359             }
360             SLOGE("controller GetAVCallState failed:%{public}d", ret);
361             context->status = napi_generic_failure;
362             context->errCode = NapiAVSessionManager::errcode_[ret];
363         }
364     };
365 
366     auto complete = [env, context](napi_value& output) {
367         context->status = NapiAVCallState::SetValue(env, context->avCallState, output);
368         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
369             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
370     };
371     return NapiAsyncWork::Enqueue(env, context, "GetAVCallState", executor, complete);
372 }
373 
GetAVMetaData(napi_env env,napi_callback_info info)374 napi_value NapiAVSessionController::GetAVMetaData(napi_env env, napi_callback_info info)
375 {
376     struct ConcreteContext : public ContextBase {
377         AVMetaData data;
378     };
379     auto context = std::make_shared<ConcreteContext>();
380     context->GetCbInfo(env, info);
381 
382     auto executor = [context]() {
383         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
384         if (napiController->controller_ == nullptr) {
385             SLOGE("GetAVMetaData failed : controller is nullptr");
386             context->status = napi_generic_failure;
387             context->errMessage = "GetAVMetaData failed : controller is nullptr";
388             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
389             return;
390         }
391         int32_t ret = napiController->controller_->GetAVMetaData(context->data);
392         if (ret != AVSESSION_SUCCESS) {
393             if (ret == ERR_SESSION_NOT_EXIST) {
394                 context->errMessage = "GetAVMetaData failed : native session not exist";
395             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
396                 context->errMessage = "GetAVMetaData failed : native controller not exist";
397             } else if (ret == ERR_NO_PERMISSION) {
398                 context->errMessage = "GetAVMetaData failed : native no permission";
399             } else {
400                 context->errMessage = "GetAVMetaData failed : native server exception";
401             }
402             SLOGE("controller GetAVMetaData failed:%{public}d", ret);
403             context->status = napi_generic_failure;
404             context->errCode = NapiAVSessionManager::errcode_[ret];
405         }
406     };
407 
408     auto complete = [env, context](napi_value& output) {
409         context->status = NapiMetaData::SetValue(env, context->data, output);
410         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
411             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
412         SLOGI("metadata get done, clear cache");
413         context->data.Reset();
414     };
415 
416     return NapiAsyncWork::Enqueue(env, context, "GetAVMetaData", executor, complete);
417 }
418 
GetAVMetaDataSync(napi_env env,napi_callback_info info)419 napi_value NapiAVSessionController::GetAVMetaDataSync(napi_env env, napi_callback_info info)
420 {
421     SLOGD("Start GetAVMetaDataSync");
422     auto context = std::make_shared<ContextBase>();
423     if (context == nullptr) {
424         SLOGE("OnEvent failed : no memory");
425         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
426         return NapiUtils::GetUndefinedValue(env);
427     }
428 
429     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
430 
431     auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
432     if (napiController->controller_ == nullptr) {
433         SLOGE("GetAVMetaDataSync failed : controller is nullptr");
434         NapiUtils::ThrowError(env, "GetAVMetaDataSync failed : controller is nullptr",
435             NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
436         return NapiUtils::GetUndefinedValue(env);
437     }
438     AVMetaData data;
439     int32_t ret = napiController->controller_->GetAVMetaData(data);
440     if (ret != AVSESSION_SUCCESS) {
441         std::string errMessage;
442         if (ret == ERR_SESSION_NOT_EXIST) {
443             errMessage = "GetAVMetaDataSync failed : native session not exist";
444         } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
445             errMessage = "GetAVMetaDataSync failed : native controller not exist";
446         } else if (ret == ERR_NO_PERMISSION) {
447             errMessage = "GetAVMetaDataSync failed : native no permission";
448         } else {
449             ret = AVSESSION_ERROR;
450             errMessage = "GetAVMetaDataSync failed : native server exception";
451         }
452         SLOGE("controller GetAVMetaDataSync failed:%{public}d", ret);
453         NapiUtils::ThrowError(env, errMessage.c_str(), NapiAVSessionManager::errcode_[ret]);
454         return NapiUtils::GetUndefinedValue(env);
455     }
456 
457     napi_value output {};
458     auto status = NapiUtils::SetValue(env, data, output);
459     if (status != napi_ok) {
460         SLOGE("convert native object to javascript object failed");
461         NapiUtils::ThrowError(env, "convert native object to javascript object failed",
462             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
463         return NapiUtils::GetUndefinedValue(env);
464     }
465     return output;
466 }
467 
GetAVQueueItems(napi_env env,napi_callback_info info)468 napi_value NapiAVSessionController::GetAVQueueItems(napi_env env, napi_callback_info info)
469 {
470     struct ConcreteContext : public ContextBase {
471         std::vector<AVQueueItem> items_;
472     };
473     auto context = std::make_shared<ConcreteContext>();
474     context->GetCbInfo(env, info);
475 
476     auto executor = [context]() {
477         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
478         if (napiController->controller_ == nullptr) {
479             SLOGE("GetAVQueueItems failed : controller is nullptr");
480             context->status = napi_generic_failure;
481             context->errMessage = "GetAVQueueItems failed : controller is nullptr";
482             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
483             return;
484         }
485         int32_t ret = napiController->controller_->GetAVQueueItems(context->items_);
486         if (ret != AVSESSION_SUCCESS) {
487             if (ret == ERR_SESSION_NOT_EXIST) {
488                 context->errMessage = "GetAVQueueItems failed : native session not exist";
489             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
490                 context->errMessage = "GetAVQueueItems failed : native controller not exist";
491             } else if (ret == ERR_NO_PERMISSION) {
492                 context->errMessage = "GetAVQueueItems failed : native no permission";
493             } else {
494                 context->errMessage = "GetAVQueueItems failed : native server exception";
495             }
496             SLOGE("controller GetAVQueueItems failed:%{public}d", ret);
497             context->status = napi_generic_failure;
498             context->errCode = NapiAVSessionManager::errcode_[ret];
499         }
500     };
501 
502     auto complete = [env, context](napi_value& output) {
503         context->status = NapiUtils::SetValue(env, context->items_, output);
504         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
505             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
506     };
507 
508     return NapiAsyncWork::Enqueue(env, context, "GetAVQueueItems", executor, complete);
509 }
510 
GetAVQueueItemsSync(napi_env env,napi_callback_info info)511 napi_value NapiAVSessionController::GetAVQueueItemsSync(napi_env env, napi_callback_info info)
512 {
513     SLOGD("Start GetAVQueueItemsSync");
514     auto context = std::make_shared<ContextBase>();
515     if (context == nullptr) {
516         SLOGE("OnEvent failed : no memory");
517         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
518         return NapiUtils::GetUndefinedValue(env);
519     }
520 
521     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
522 
523     auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
524     if (napiController->controller_ == nullptr) {
525         SLOGE("GetAVQueueItemsSync failed : controller is nullptr");
526         NapiUtils::ThrowError(env, "GetAVQueueItemsSync failed : controller is nullptr",
527             NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
528         return NapiUtils::GetUndefinedValue(env);
529     }
530     std::vector<AVQueueItem> items;
531     int32_t ret = napiController->controller_->GetAVQueueItems(items);
532     SLOGD("Get queueItem size: %{public}zu", items.size());
533     if (ret != AVSESSION_SUCCESS) {
534         std::string errMessage;
535         if (ret == ERR_SESSION_NOT_EXIST) {
536             errMessage = "GetAVQueueItemsSync failed : native session not exist";
537         } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
538             errMessage = "GetAVQueueItemsSync failed : native controller not exist";
539         } else if (ret == ERR_NO_PERMISSION) {
540             errMessage = "GetAVQueueItemsSync failed : native no permission";
541         } else {
542             ret = AVSESSION_ERROR;
543             errMessage = "GetAVQueueItemsSync failed : native server exception";
544         }
545         SLOGE("controller GetAVQueueItemsSync failed:%{public}d", ret);
546         NapiUtils::ThrowError(env, errMessage.c_str(), NapiAVSessionManager::errcode_[ret]);
547         return NapiUtils::GetUndefinedValue(env);
548     }
549 
550     napi_value output {};
551     auto status = NapiUtils::SetValue(env, items, output);
552     if (status != napi_ok) {
553         SLOGE("convert native object to javascript object failed");
554         NapiUtils::ThrowError(env, "convert native object to javascript object failed",
555             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
556         return NapiUtils::GetUndefinedValue(env);
557     }
558     return output;
559 }
560 
GetAVQueueTitle(napi_env env,napi_callback_info info)561 napi_value NapiAVSessionController::GetAVQueueTitle(napi_env env, napi_callback_info info)
562 {
563     struct ConcreteContext : public ContextBase {
564         std::string title_;
565     };
566     auto context = std::make_shared<ConcreteContext>();
567     context->GetCbInfo(env, info);
568 
569     auto executor = [context]() {
570         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
571         if (napiController->controller_ == nullptr) {
572             SLOGE("GetAVQueueTitle failed : controller is nullptr");
573             context->status = napi_generic_failure;
574             context->errMessage = "GetAVQueueTitle failed : controller is nullptr";
575             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
576             return;
577         }
578         int32_t ret = napiController->controller_->GetAVQueueTitle(context->title_);
579         if (ret != AVSESSION_SUCCESS) {
580             if (ret == ERR_SESSION_NOT_EXIST) {
581                 context->errMessage = "GetAVQueueTitle failed : native session not exist";
582             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
583                 context->errMessage = "GetAVQueueTitle failed : native controller not exist";
584             } else if (ret == ERR_NO_PERMISSION) {
585                 context->errMessage = "GetAVQueueTitle failed : native no permission";
586             } else {
587                 context->errMessage = "GetAVQueueTitle failed : native server exception";
588             }
589             SLOGE("controller GetAVQueueTitle failed:%{public}d", ret);
590             context->status = napi_generic_failure;
591             context->errCode = NapiAVSessionManager::errcode_[ret];
592         }
593     };
594 
595     auto complete = [env, context](napi_value& output) {
596         context->status = NapiUtils::SetValue(env, context->title_, output);
597         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
598             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
599     };
600 
601     return NapiAsyncWork::Enqueue(env, context, "GetAVQueueTitle", executor, complete);
602 }
603 
GetAVQueueTitleSync(napi_env env,napi_callback_info info)604 napi_value NapiAVSessionController::GetAVQueueTitleSync(napi_env env, napi_callback_info info)
605 {
606     SLOGD("Start GetAVQueueTitleSync");
607     auto context = std::make_shared<ContextBase>();
608     if (context == nullptr) {
609         SLOGE("OnEvent failed : no memory");
610         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
611         return NapiUtils::GetUndefinedValue(env);
612     }
613 
614     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
615 
616     auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
617     if (napiController->controller_ == nullptr) {
618         SLOGE("GetAVQueueTitleSync failed : controller is nullptr");
619         NapiUtils::ThrowError(env, "GetAVQueueTitleSync failed : controller is nullptr",
620             NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
621         return NapiUtils::GetUndefinedValue(env);
622     }
623     std::string title;
624     int32_t ret = napiController->controller_->GetAVQueueTitle(title);
625     SLOGD("Get queue title: %{public}s", title.c_str());
626     if (ret != AVSESSION_SUCCESS) {
627         std::string errMessage;
628         if (ret == ERR_SESSION_NOT_EXIST) {
629             errMessage = "GetAVQueueTitleSync failed : native session not exist";
630         } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
631             errMessage = "GetAVQueueTitleSync failed : native controller not exist";
632         } else if (ret == ERR_NO_PERMISSION) {
633             errMessage = "GetAVQueueTitleSync failed : native no permission";
634         } else {
635             ret = AVSESSION_ERROR;
636             errMessage = "GetAVQueueTitleSync failed : native server exception";
637         }
638         SLOGE("controller GetAVQueueTitleSync failed:%{public}d", ret);
639         NapiUtils::ThrowError(env, errMessage.c_str(), NapiAVSessionManager::errcode_[ret]);
640         return NapiUtils::GetUndefinedValue(env);
641     }
642 
643     napi_value output {};
644     auto status = NapiUtils::SetValue(env, title, output);
645     if (status != napi_ok) {
646         SLOGE("convert native object to javascript object failed");
647         NapiUtils::ThrowError(env, "convert native object to javascript object failed",
648             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
649         return NapiUtils::GetUndefinedValue(env);
650     }
651     return output;
652 }
653 
SkipToQueueItem(napi_env env,napi_callback_info info)654 napi_value NapiAVSessionController::SkipToQueueItem(napi_env env, napi_callback_info info)
655 {
656     AVSESSION_TRACE_SYNC_START("NapiAVSessionController::SkipToQueueItem");
657     struct ConcreteContext : public ContextBase {
658         int32_t itemId_;
659     };
660     auto context = std::make_shared<ConcreteContext>();
661     if (context == nullptr) {
662         NapiUtils::ThrowError(env, "avsession SkipToQueueItem failed:no memory",
663             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
664         return NapiUtils::GetUndefinedValue(env);
665     }
666     auto inputParser = [env, context](size_t argc, napi_value* argv) {
667         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
668             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
669         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->itemId_);
670         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get itemId failed",
671             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
672     };
673     context->GetCbInfo(env, info, inputParser);
674     context->taskId = NAPI_SET_AV_META_DATA_TASK_ID;
675     auto executor = [context]() {
676         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
677         if (napiController->controller_ == nullptr) {
678             SLOGE("SkipToQueueItem failed : controller is nullptr");
679             context->status = napi_generic_failure;
680             context->errMessage = "SkipToQueueItem failed : controller is nullptr";
681             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
682             return;
683         }
684         int32_t ret = napiController->controller_->SkipToQueueItem(context->itemId_);
685         if (ret != AVSESSION_SUCCESS) {
686             if (ret == ERR_SESSION_NOT_EXIST) {
687                 context->errMessage = "SkipToQueueItem failed : native session not exist";
688             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
689                 context->errMessage = "SkipToQueueItem failed : native controller not exist";
690             } else if (ret == ERR_SESSION_DEACTIVE) {
691                 context->errMessage = "SkipToQueueItem failed : native session is not active";
692             } else if (ret == ERR_NO_PERMISSION) {
693                 context->errMessage = "SkipToQueueItem failed : native no permission";
694             } else {
695                 context->errMessage = "SkipToQueueItem failed : native server exception";
696             }
697             SLOGE("controller SkipToQueueItem failed:%{public}d", ret);
698             context->status = napi_generic_failure;
699             context->errCode = NapiAVSessionManager::errcode_[ret];
700         }
701     };
702     return NapiAsyncWork::Enqueue(env, context, "SkipToQueueItem", executor);
703 }
704 
GetExtras(napi_env env,napi_callback_info info)705 napi_value NapiAVSessionController::GetExtras(napi_env env, napi_callback_info info)
706 {
707     AVSESSION_TRACE_SYNC_START("NapiAVSessionController::GetExtras");
708     struct ConcreteContext : public ContextBase {
709         AAFwk::WantParams extras_;
710     };
711     auto context = std::make_shared<ConcreteContext>();
712     context->GetCbInfo(env, info);
713 
714     auto executor = [context]() {
715         SLOGD("NapiAVSessionController GetExtras process check lock");
716         std::lock_guard<std::mutex> lock(uvMutex_);
717         SLOGI("Start NapiAVSessionController GetExtras process");
718         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
719         if (napiController->controller_ == nullptr) {
720             SLOGE("GetExtras failed : controller is nullptr");
721             context->status = napi_generic_failure;
722             context->errMessage = "GetExtras failed : controller is nullptr";
723             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
724             return;
725         }
726         int32_t ret = napiController->controller_->GetExtras(context->extras_);
727         if (ret != AVSESSION_SUCCESS) {
728             if (ret == ERR_SESSION_NOT_EXIST) {
729                 context->errMessage = "GetExtras failed : native session not exist";
730             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
731                 context->errMessage = "GetExtras failed : native controller not exist";
732             } else if (ret == ERR_NO_PERMISSION) {
733                 context->errMessage = "GetExtras failed : native no permission";
734             } else {
735                 context->errMessage = "GetExtras failed : native server exception";
736             }
737             SLOGE("Controller getExtras failed:%{public}d", ret);
738             context->status = napi_generic_failure;
739             context->errCode = NapiAVSessionManager::errcode_[ret];
740         }
741     };
742 
743     auto complete = [env, context](napi_value& output) {
744         context->status = NapiUtils::SetValue(env, context->extras_, output);
745         CHECK_STATUS_RETURN_VOID(context, "Convert native object to javascript object failed",
746             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
747         SLOGI("check getextras done");
748     };
749 
750     return NapiAsyncWork::Enqueue(env, context, "GetExtras", executor, complete);
751 }
752 
GetExtrasWithEvent(napi_env env,napi_callback_info info)753 napi_value NapiAVSessionController::GetExtrasWithEvent(napi_env env, napi_callback_info info)
754 {
755     AVSESSION_TRACE_SYNC_START("NapiAVSessionController::GetExtrasWithEvent");
756     struct ConcreteContext : public ContextBase {
757         std::string extraEvent_;
758         AAFwk::WantParams extras_;
759     };
760     auto context = std::make_shared<ConcreteContext>();
761 
762     auto inputParser = [env, context](size_t argc, napi_value* argv) {
763         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "Invalid arguments",
764             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
765         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->extraEvent_);
766         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "Get extras event failed",
767             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
768     };
769     context->GetCbInfo(env, info, inputParser);
770 
771     auto executor = [context]() {
772         std::lock_guard<std::mutex> lock(uvMutex_);
773         SLOGI("Start NapiAVSessionController GetExtrasWithEvent process");
774         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
775         if (napiController->controller_ == nullptr) {
776             SLOGE("GetExtrasWithEvent failed : controller is nullptr");
777             context->status = napi_generic_failure;
778             context->errMessage = "GetExtrasWithEvent failed : controller is nullptr";
779             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
780             return;
781         }
782         int32_t ret = napiController->controller_->GetExtrasWithEvent(context->extraEvent_, context->extras_);
783         if (ret != AVSESSION_SUCCESS) {
784             if (ret == ERR_SESSION_NOT_EXIST) {
785                 context->errMessage = "GetExtrasWithEvent failed : native session not exist";
786             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
787                 context->errMessage = "GetExtrasWithEvent failed : native controller not exist";
788             } else if (ret == ERR_COMMAND_NOT_SUPPORT) {
789                 context->errMessage = "GetExtrasWithEvent failed : native invalid key event";
790             } else {
791                 context->errMessage = "GetExtrasWithEvent failed : native server exception";
792             }
793             SLOGE("Controller getExtras with event failed:%{public}d", ret);
794             context->status = napi_generic_failure;
795             context->errCode = NapiAVSessionManager::errcode_[ret];
796         }
797     };
798 
799     auto complete = [env, context](napi_value& output) {
800         context->status = NapiUtils::SetValue(env, context->extras_, output);
801         CHECK_STATUS_RETURN_VOID(context, "Convert native object to javascript object failed",
802             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
803         SLOGI("check getextraswithevent done");
804     };
805 
806     return NapiAsyncWork::Enqueue(env, context, "GetExtrasWithEvent", executor, complete);
807 }
808 
SendAVKeyEvent(napi_env env,napi_callback_info info)809 napi_value NapiAVSessionController::SendAVKeyEvent(napi_env env, napi_callback_info info)
810 {
811     AVSESSION_TRACE_SYNC_START("NapiAVSessionController::SendAVKeyEvent");
812     struct ConcreteContext : public ContextBase {
813         std::shared_ptr<MMI::KeyEvent> keyEvent_;
814     };
815     auto context = std::make_shared<ConcreteContext>();
816     auto input = [env, context](size_t argc, napi_value* argv) {
817         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
818             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
819         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->keyEvent_);
820         CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (context->keyEvent_ != nullptr),
821             "invalid keyEvent", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
822     };
823     context->GetCbInfo(env, info, input);
824     context->taskId = NAPI_SEND_AV_KEY_EVENT_TASK_ID;
825 
826     auto executor = [context]() {
827         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
828         if (napiController->controller_ == nullptr) {
829             SLOGE("SendAVKeyEvent failed : controller is nullptr");
830             context->status = napi_generic_failure;
831             context->errMessage = "SendAVKeyEvent failed : controller is nullptr";
832             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
833             return;
834         }
835         int32_t ret = napiController->controller_->SendAVKeyEvent(*context->keyEvent_);
836         if (ret != AVSESSION_SUCCESS) {
837             if (ret == ERR_SESSION_NOT_EXIST) {
838                 context->errMessage = "SendAVKeyEvent failed : native session not exist";
839             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
840                 context->errMessage = "SendAVKeyEvent failed : native controller not exist";
841             } else if (ret == ERR_SESSION_DEACTIVE) {
842                 context->errMessage = "SendAVKeyEvent failed : native session is not active";
843             } else if (ret == ERR_COMMAND_NOT_SUPPORT) {
844                 context->errMessage = "SendAVKeyEvent failed : native invalid KeyEvent";
845             } else if (ret == ERR_NO_PERMISSION) {
846                 context->errMessage = "SendAVKeyEvent failed : native no permission";
847             } else {
848                 context->errMessage = "SendAVKeyEvent failed : native server exception";
849             }
850             SLOGE("controller SendAVKeyEvent failed:%{public}d", ret);
851             context->status = napi_generic_failure;
852             context->errCode = NapiAVSessionManager::errcode_[ret];
853         }
854     };
855 
856     return NapiAsyncWork::Enqueue(env, context, "SendAVKeyEvent", executor);
857 }
858 
GetLaunchAbility(napi_env env,napi_callback_info info)859 napi_value NapiAVSessionController::GetLaunchAbility(napi_env env, napi_callback_info info)
860 {
861     struct ConcreteContext : public ContextBase {
862         AbilityRuntime::WantAgent::WantAgent* ability;
863     };
864     auto context = std::make_shared<ConcreteContext>();
865     context->GetCbInfo(env, info);
866 
867     auto executor = [context]() {
868         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
869         if (napiController == nullptr || napiController->controller_ == nullptr) {
870             SLOGE("GetLaunchAbility failed : controller is nullptr");
871             context->status = napi_generic_failure;
872             context->errMessage = "GetLaunchAbility failed : controller is nullptr";
873             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
874             return;
875         }
876         int32_t ret = napiController->controller_->GetLaunchAbilityInner(context->ability);
877         SLOGE("GetLaunchAbilityInner check:%{public}d", context->ability != nullptr);
878         if (ret != AVSESSION_SUCCESS) {
879             if (ret == ERR_SESSION_NOT_EXIST) {
880                 context->errMessage = "GetLaunchAbility failed : native session not exist";
881             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
882                 context->errMessage = "GetLaunchAbility failed : native controller not exist";
883             } else if (ret == ERR_NO_PERMISSION) {
884                 context->errMessage = "GetLaunchAbility failed : native no permission";
885             } else {
886                 context->errMessage = "GetLaunchAbility failed : native server exception";
887             }
888             SLOGE("controller GetLaunchAbility failed:%{public}d", ret);
889             context->status = napi_generic_failure;
890             context->errCode = NapiAVSessionManager::errcode_[ret];
891         }
892     };
893 
894     auto complete = [env, context](napi_value& output) {
895         context->status = NapiUtils::SetValue(env, context->ability, output);
896         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
897             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
898     };
899 
900     return NapiAsyncWork::Enqueue(env, context, "GetLaunchAbility", executor, complete);
901 }
902 
GetValidCommands(napi_env env,napi_callback_info info)903 napi_value NapiAVSessionController::GetValidCommands(napi_env env, napi_callback_info info)
904 {
905     struct ConcreteContext : public ContextBase {
906         std::vector<std::string> stringCmds;
907     };
908     auto context = std::make_shared<ConcreteContext>();
909     context->GetCbInfo(env, info);
910 
911     auto executor = [context]() {
912         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
913         if (napiController->controller_ == nullptr) {
914             SLOGE("GetValidCommands failed : controller is nullptr");
915             context->status = napi_generic_failure;
916             context->errMessage = "GetValidCommands failed : controller is nullptr";
917             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
918             return;
919         }
920         std::vector<int32_t> cmds;
921         int32_t ret = napiController->controller_->GetValidCommands(cmds);
922         if (ret != AVSESSION_SUCCESS) {
923             if (ret == ERR_SESSION_NOT_EXIST) {
924                 context->errMessage = "GetValidCommands failed : native session not exist";
925             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
926                 context->errMessage = "GetValidCommands failed : native controller not exist";
927             } else if (ret == ERR_NO_PERMISSION) {
928                 context->errMessage = "GetValidCommands failed : native no permission";
929             } else {
930                 context->errMessage = "GetValidCommands failed : native server exception";
931             }
932             SLOGE("controller GetValidCommands failed:%{public}d", ret);
933             context->status = napi_generic_failure;
934             context->errCode = NapiAVSessionManager::errcode_[ret];
935         }
936         context->stringCmds = NapiControlCommand::ConvertCommands(cmds);
937     };
938 
939     auto complete = [env, context](napi_value& output) {
940         SLOGI("GetValidCommands size:%{public}d", static_cast<int>(context->stringCmds.size()));
941         context->status = NapiUtils::SetValue(env, context->stringCmds, output);
942         CHECK_STATUS_RETURN_VOID(context, "GetValidCommands convert native object to javascript object failed",
943             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
944     };
945 
946     return NapiAsyncWork::Enqueue(env, context, "GetValidCommands", executor, complete);
947 }
948 
GetValidCommandsSync(napi_env env,napi_callback_info info)949 napi_value NapiAVSessionController::GetValidCommandsSync(napi_env env, napi_callback_info info)
950 {
951     SLOGD("Start GetValidCommandsSync");
952     auto context = std::make_shared<ContextBase>();
953     if (context == nullptr) {
954         SLOGE("OnEvent failed : no memory");
955         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
956         return NapiUtils::GetUndefinedValue(env);
957     }
958 
959     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
960 
961     auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
962     if (napiController->controller_ == nullptr) {
963         SLOGE("GetValidCommandsSync failed : controller is nullptr");
964         NapiUtils::ThrowError(env, "GetValidCommandsSync failed : controller is nullptr",
965             NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
966         return NapiUtils::GetUndefinedValue(env);
967     }
968     std::vector<int32_t> cmds;
969     int32_t ret = napiController->controller_->GetValidCommands(cmds);
970     SLOGD("Get valid commands size: %{public}zu", cmds.size());
971     if (ret != AVSESSION_SUCCESS) {
972         std::string errMessage;
973         if (ret == ERR_SESSION_NOT_EXIST) {
974             errMessage = "GetValidCommandsSync failed : native session not exist";
975         } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
976             errMessage = "GetValidCommandsSync failed : native controller not exist";
977         } else if (ret == ERR_NO_PERMISSION) {
978             errMessage = "GetValidCommandsSync failed : native no permission";
979         } else {
980             ret = AVSESSION_ERROR;
981             errMessage = "GetValidCommandsSync failed : native server exception";
982         }
983         SLOGE("controller GetValidCommandsSync failed:%{public}d", ret);
984         NapiUtils::ThrowError(env, errMessage.c_str(), NapiAVSessionManager::errcode_[ret]);
985         return NapiUtils::GetUndefinedValue(env);
986     }
987 
988     std::vector<std::string> stringCmds = NapiControlCommand::ConvertCommands(cmds);
989     napi_value output {};
990     auto status = NapiUtils::SetValue(env, stringCmds, output);
991     SLOGI("GetValidCommandsSync size:%{public}d", static_cast<int>(stringCmds.size()));
992     if (status != napi_ok) {
993         SLOGE("GetValidCommandsSync convert native object to javascript object failed");
994         NapiUtils::ThrowError(env, "GetValidCommandsSync convert native object to javascript object failed",
995             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
996         return NapiUtils::GetUndefinedValue(env);
997     }
998     return output;
999 }
1000 
IsSessionActive(napi_env env,napi_callback_info info)1001 napi_value NapiAVSessionController::IsSessionActive(napi_env env, napi_callback_info info)
1002 {
1003     struct ConcreteContext : public ContextBase {
1004         bool isActive {};
1005     };
1006     auto context = std::make_shared<ConcreteContext>();
1007     context->GetCbInfo(env, info);
1008 
1009     auto executor = [context]() {
1010         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1011         if (napiController->controller_ == nullptr) {
1012             SLOGE("IsSessionActive failed : controller is nullptr");
1013             context->status = napi_generic_failure;
1014             context->errMessage = "IsSessionActive failed : controller is nullptr";
1015             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
1016             return;
1017         }
1018         int32_t ret = napiController->controller_->IsSessionActive(context->isActive);
1019         if (ret != AVSESSION_SUCCESS) {
1020             if (ret == ERR_SESSION_NOT_EXIST) {
1021                 context->errMessage = "IsSessionActive failed : native session not exist";
1022             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
1023                 context->errMessage = "IsSessionActive failed : native controller not exist";
1024             } else if (ret == ERR_NO_PERMISSION) {
1025                 context->errMessage = "IsSessionActive failed : native no permission";
1026             } else {
1027                 context->errMessage = "IsSessionActive failed : native server exception";
1028             }
1029             SLOGE("controller IsSessionActive failed:%{public}d", ret);
1030             context->status = napi_generic_failure;
1031             context->errCode = NapiAVSessionManager::errcode_[ret];
1032         }
1033     };
1034 
1035     auto complete = [env, context](napi_value& output) {
1036         context->status = NapiUtils::SetValue(env, context->isActive, output);
1037         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
1038             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1039     };
1040 
1041     return NapiAsyncWork::Enqueue(env, context, "IsSessionActive", executor, complete);
1042 }
1043 
IsSessionActiveSync(napi_env env,napi_callback_info info)1044 napi_value NapiAVSessionController::IsSessionActiveSync(napi_env env, napi_callback_info info)
1045 {
1046     SLOGD("Start IsSessionActiveSync");
1047     auto context = std::make_shared<ContextBase>();
1048     if (context == nullptr) {
1049         SLOGE("OnEvent failed : no memory");
1050         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1051         return NapiUtils::GetUndefinedValue(env);
1052     }
1053 
1054     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
1055 
1056     auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1057     if (napiController->controller_ == nullptr) {
1058         SLOGE("IsSessionActiveSync failed : controller is nullptr");
1059         NapiUtils::ThrowError(env, "IsSessionActiveSync failed : controller is nullptr",
1060             NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
1061         return NapiUtils::GetUndefinedValue(env);
1062     }
1063     bool isActive {};
1064     int32_t ret = napiController->controller_->IsSessionActive(isActive);
1065     SLOGD("Get session active state: %{public}d", static_cast<int32_t>(isActive));
1066     if (ret != AVSESSION_SUCCESS) {
1067         std::string errMessage;
1068         if (ret == ERR_SESSION_NOT_EXIST) {
1069             errMessage = "IsSessionActiveSync failed : native session not exist";
1070         } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
1071             errMessage = "IsSessionActiveSync failed : native controller not exist";
1072         } else if (ret == ERR_NO_PERMISSION) {
1073             errMessage = "IsSessionActiveSync failed : native no permission";
1074         } else {
1075             ret = AVSESSION_ERROR;
1076             errMessage = "IsSessionActiveSync failed : native server exception";
1077         }
1078         SLOGE("controller IsSessionActiveSync failed:%{public}d", ret);
1079         NapiUtils::ThrowError(env, errMessage.c_str(), NapiAVSessionManager::errcode_[ret]);
1080         return NapiUtils::GetUndefinedValue(env);
1081     }
1082 
1083     napi_value output {};
1084     auto status = NapiUtils::SetValue(env, isActive, output);
1085     if (status != napi_ok) {
1086         SLOGE("convert native object to javascript object failed");
1087         NapiUtils::ThrowError(env, "convert native object to javascript object failed",
1088             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1089         return NapiUtils::GetUndefinedValue(env);
1090     }
1091     return output;
1092 }
1093 
SendControlCommand(napi_env env,napi_callback_info info)1094 napi_value NapiAVSessionController::SendControlCommand(napi_env env, napi_callback_info info)
1095 {
1096     AVSESSION_TRACE_SYNC_START("NapiAVSessionController::SendControlCommand");
1097     struct ConcrentContext : public ContextBase {
1098         AVControlCommand command;
1099     };
1100     auto context = std::make_shared<ConcrentContext>();
1101     auto input = [env, context](size_t argc, napi_value* argv) {
1102         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "invalid arguments",
1103             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1104         context->status = NapiControlCommand::GetValue(env, argv[ARGV_FIRST], context->command);
1105         CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok), "invalid command",
1106             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1107     };
1108     context->GetCbInfo(env, info, input);
1109     context->taskId = NAPI_SEND_CONTROL_COMMAND_TASK_ID;
1110 
1111     auto executor = [context]() {
1112         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1113         if (napiController->controller_ == nullptr) {
1114             SLOGE("SendControlCommand failed : controller is nullptr");
1115             context->status = napi_generic_failure;
1116             context->errMessage = "SendControlCommand failed : controller is nullptr";
1117             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
1118             return;
1119         }
1120         int32_t ret = napiController->controller_->SendControlCommand(context->command);
1121         if (ret != AVSESSION_SUCCESS) {
1122             if (ret == ERR_SESSION_NOT_EXIST) {
1123                 context->errMessage = "SendControlCommand failed : native session not exist";
1124             } else if (ret == ERR_CONTROLLER_NOT_EXIST) {
1125                 context->errMessage = "SendControlCommand failed : native controller not exist";
1126             } else if (ret == ERR_SESSION_DEACTIVE) {
1127                 context->errMessage = "SendControlCommand failed : native session is not active";
1128             } else if (ret == ERR_COMMAND_NOT_SUPPORT) {
1129                 context->errMessage = "SendControlCommand failed : native command not support";
1130             } else if (ret == ERR_COMMAND_SEND_EXCEED_MAX) {
1131                 context->errMessage = "SendControlCommand failed : native command send nums overload";
1132             } else if (ret == ERR_NO_PERMISSION) {
1133                 context->errMessage = "SendControlCommand failed : native no permission";
1134             } else {
1135                 context->errMessage = "SendControlCommand failed : native server exception";
1136             }
1137             SLOGE("controller SendControlCommand failed:%{public}d", ret);
1138             context->status = napi_generic_failure;
1139             context->errCode = NapiAVSessionManager::errcode_[ret];
1140         }
1141     };
1142 
1143     return NapiAsyncWork::Enqueue(env, context, "SendControlCommand", executor);
1144 }
1145 
SendCommonCommand(napi_env env,napi_callback_info info)1146 napi_value NapiAVSessionController::SendCommonCommand(napi_env env, napi_callback_info info)
1147 {
1148     AVSESSION_TRACE_SYNC_START("NapiAVSessionController::SendCommonCommand");
1149     struct ConcreteContext : public ContextBase {
1150         std::string commonCommand_;
1151         AAFwk::WantParams commandArgs_;
1152     };
1153     auto context = std::make_shared<ConcreteContext>();
1154     if (context == nullptr) {
1155         SLOGE("SendCommonCommand failed : no memory");
1156         NapiUtils::ThrowError(env, "SendCommonCommand failed : no memory",
1157             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1158         return NapiUtils::GetUndefinedValue(env);
1159     }
1160 
1161     auto inputParser = [env, context](size_t argc, napi_value* argv) {
1162         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "Invalid arguments",
1163             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1164         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->commonCommand_);
1165         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "Get common command failed",
1166             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1167         context->status = NapiUtils::GetValue(env, argv[ARGV_SECOND], context->commandArgs_);
1168         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "Get command args failed",
1169             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1170     };
1171     context->GetCbInfo(env, info, inputParser);
1172     context->taskId = NAPI_SEND_COMMON_COMMAND_TASK_ID;
1173 
1174     auto executor = [context]() {
1175         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1176         if (napiController->controller_ == nullptr) {
1177             SLOGE("SendCommonCommand failed : controller is nullptr");
1178             context->status = napi_generic_failure;
1179             context->errMessage = "SendCommonCommand failed : controller is nullptr";
1180             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
1181             return;
1182         }
1183         int32_t ret = napiController->controller_->
1184             SendCommonCommand(context->commonCommand_, context->commandArgs_);
1185         if (ret != AVSESSION_SUCCESS) {
1186             ErrCodeToMessage(ret, context->errMessage);
1187             SLOGE("Controller SendCommonCommand failed:%{public}d", ret);
1188             context->status = napi_generic_failure;
1189             context->errCode = NapiAVSessionManager::errcode_[ret];
1190         }
1191     };
1192 
1193     auto complete = [env](napi_value& output) {
1194         output = NapiUtils::GetUndefinedValue(env);
1195     };
1196     return NapiAsyncWork::Enqueue(env, context, "SendCommonCommand", executor, complete);
1197 }
1198 
SendCustomData(napi_env env,napi_callback_info info)1199 napi_value NapiAVSessionController::SendCustomData(napi_env env, napi_callback_info info)
1200 {
1201     AVSESSION_TRACE_SYNC_START("NapiAVSessionController::SendCustomData");
1202     struct ConcreteContext : public ContextBase {
1203         AAFwk::WantParams data_;
1204     };
1205     auto context = std::make_shared<ConcreteContext>();
1206     if (context == nullptr) {
1207         SLOGE("SendCustomData failed : no memory");
1208         NapiUtils::ThrowError(env, "SendCustomData failed : no memory",
1209             NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1210         return NapiUtils::GetUndefinedValue(env);
1211     }
1212 
1213     auto inputParser = [env, context](size_t argc, napi_value* argv) {
1214         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE, "Invalid arguments",
1215             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1216         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], context->data_);
1217         CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "Get data failed",
1218             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1219     };
1220     context->GetCbInfo(env, info, inputParser);
1221     context->taskId = NAPI_SEND_CUSTOM_DATA_TASK_ID;
1222 
1223     auto executor = [context]() {
1224         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1225         if (napiController->controller_ == nullptr) {
1226             SLOGE("SendCustomData failed : controller is nullptr");
1227             context->status = napi_generic_failure;
1228             context->errMessage = "SendCustomData failed : controller is nullptr";
1229             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
1230             return;
1231         }
1232         int32_t ret = napiController->controller_->SendCustomData(context->data_);
1233         if (ret != AVSESSION_SUCCESS) {
1234             ErrCodeToMessage(ret, context->errMessage);
1235             SLOGE("Controller SendCustomData failed:%{public}d", ret);
1236             context->status = napi_generic_failure;
1237             context->errCode = NapiAVSessionManager::errcode_[ret];
1238         }
1239     };
1240 
1241     return NapiAsyncWork::Enqueue(env, context, "SendCustomData", executor);
1242 }
1243 
ErrCodeToMessage(int32_t errCode,std::string & message)1244 void NapiAVSessionController::ErrCodeToMessage(int32_t errCode, std::string& message)
1245 {
1246     switch (errCode) {
1247         case ERR_SESSION_NOT_EXIST:
1248             message = "SetSessionEvent failed : native session not exist";
1249             break;
1250         case ERR_CONTROLLER_NOT_EXIST:
1251             message = "SendCommonCommand failed : native controller not exist";
1252             break;
1253         case ERR_SESSION_DEACTIVE:
1254             message = "SendCommonCommand failed : native session is not active";
1255             break;
1256         case ERR_NO_PERMISSION:
1257             message = "SetSessionEvent failed : native no permission";
1258             break;
1259         default:
1260             message = "SetSessionEvent failed : native server exception";
1261             break;
1262     }
1263 }
1264 
Destroy(napi_env env,napi_callback_info info)1265 napi_value NapiAVSessionController::Destroy(napi_env env, napi_callback_info info)
1266 {
1267     auto context = std::make_shared<ContextBase>();
1268     if (context == nullptr) {
1269         SLOGE("OnEvent failed : no memory");
1270         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1271         return NapiUtils::GetUndefinedValue(env);
1272     }
1273     context->GetCbInfo(env, info);
1274     auto executor = [context]() {
1275         SLOGD("Start NapiAVSessionController destroy process check lock");
1276         std::lock_guard<std::mutex> lock(uvMutex_);
1277         SLOGI("Start NapiAVSessionController destroy process");
1278         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1279         if (napiController->controller_ == nullptr) {
1280             SLOGE("Destroy controller failed : controller is nullptr");
1281             context->status = napi_generic_failure;
1282             context->errMessage = "Destroy controller failed : controller is nullptr";
1283             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
1284             return;
1285         }
1286         int32_t ret = napiController->controller_->Destroy();
1287         if (ret != AVSESSION_SUCCESS) {
1288             if (ret == ERR_CONTROLLER_NOT_EXIST) {
1289                 context->errMessage = "Destroy controller failed : native controller not exist";
1290             } else if (ret == ERR_NO_PERMISSION) {
1291                 context->errMessage = "Destroy controller failed : native no permission";
1292             } else {
1293                 context->errMessage = "Destroy controller failed : native server exception";
1294             }
1295             SLOGE("controller Destroy failed:%{public}d", ret);
1296             context->status = napi_generic_failure;
1297             context->errCode = NapiAVSessionManager::errcode_[ret];
1298             return;
1299         }
1300         SLOGI("NapiAVSessionController destroy process done");
1301     };
1302     auto complete = [env, context](napi_value& output) {
1303         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1304         napiController->callback_ = nullptr;
1305         napiController->controller_ = nullptr;
1306         std::lock_guard<std::mutex> lock(controllerListMutex_);
1307         SLOGI("repeat list check for controller destory");
1308         if (!ControllerList_.empty() && ControllerList_.find(napiController->sessionId_) != ControllerList_.end()) {
1309             SLOGI("repeat list erase for controller destory");
1310             ControllerList_.erase(napiController->sessionId_);
1311         }
1312         output = NapiUtils::GetUndefinedValue(env);
1313     };
1314     return NapiAsyncWork::Enqueue(env, context, "Destroy", executor, complete);
1315 }
1316 
GetRealPlaybackPositionSync(napi_env env,napi_callback_info info)1317 napi_value NapiAVSessionController::GetRealPlaybackPositionSync(napi_env env, napi_callback_info info)
1318 {
1319     auto context = std::make_shared<ContextBase>();
1320     if (context == nullptr) {
1321         SLOGE("OnEvent failed : no memory");
1322         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1323         return NapiUtils::GetUndefinedValue(env);
1324     }
1325 
1326     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
1327 
1328     auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1329     if (napiController->controller_ == nullptr) {
1330         SLOGI("GetRealPlaybackPositionSync failed : controller is nullptr");
1331         NapiUtils::ThrowError(env, "GetRealPlaybackPositionSync failed : controller is nullptr",
1332             NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
1333         return NapiUtils::GetUndefinedValue(env);
1334     }
1335 
1336     auto position = napiController->controller_->GetRealPlaybackPosition();
1337     napi_value output {};
1338     auto status = NapiUtils::SetValue(env, position, output);
1339     if (status != napi_ok) {
1340         SLOGE("convert native object to javascript object failed");
1341         NapiUtils::ThrowError(env, "convert native object to javascript object failed",
1342             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1343         return NapiUtils::GetUndefinedValue(env);
1344     }
1345     return output;
1346 }
1347 
GetOutputDevice(napi_env env,napi_callback_info info)1348 napi_value NapiAVSessionController::GetOutputDevice(napi_env env, napi_callback_info info)
1349 {
1350     struct ConcreteContext : public ContextBase {
1351         OutputDeviceInfo outputDeviceInfo_;
1352     };
1353     auto context = std::make_shared<ConcreteContext>();
1354     context->GetCbInfo(env, info);
1355 
1356     auto executor = [context]() {
1357         if (context == nullptr) {
1358             SLOGE("GetOutputDevice failed for context is nullptr");
1359             return;
1360         }
1361         auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1362         if (napiController->controller_ == nullptr) {
1363             SLOGE("GetOutputDevice failed : controller is nullptr");
1364             context->status = napi_generic_failure;
1365             context->errMessage = "GetOutputDevice failed : controller is nullptr";
1366             context->errCode = NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST];
1367             return;
1368         }
1369         AVSessionDescriptor descriptor;
1370         std::string sessionId = napiController->controller_->GetSessionId();
1371         AVSessionManager::GetInstance().GetSessionDescriptorsBySessionId(sessionId, descriptor);
1372         SLOGI("set outputdevice info for session:%{public}s***", sessionId.substr(0, ARGC_THREE).c_str());
1373         context->outputDeviceInfo_ = descriptor.outputDeviceInfo_;
1374     };
1375 
1376     auto complete = [env, context](napi_value& output) {
1377         context->status = NapiUtils::SetValue(env, context->outputDeviceInfo_, output);
1378         CHECK_STATUS_RETURN_VOID(context, "convert native object to javascript object failed",
1379             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1380     };
1381     return NapiAsyncWork::Enqueue(env, context, "GetOutputDevice", executor, complete);
1382 }
1383 
GetOutputDeviceSync(napi_env env,napi_callback_info info)1384 napi_value NapiAVSessionController::GetOutputDeviceSync(napi_env env, napi_callback_info info)
1385 {
1386     SLOGD("Start GetOutputDeviceSync");
1387     auto context = std::make_shared<ContextBase>();
1388     if (context == nullptr) {
1389         SLOGE("OnEvent failed : no memory");
1390         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1391         return NapiUtils::GetUndefinedValue(env);
1392     }
1393 
1394     context->GetCbInfo(env, info, NapiCbInfoParser(), true);
1395 
1396     auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1397     if (napiController->controller_ == nullptr) {
1398         SLOGE("GetOutputDeviceSync failed : controller is nullptr");
1399         NapiUtils::ThrowError(env, "GetOutputDeviceSync failed : controller is nullptr",
1400             NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
1401         return NapiUtils::GetUndefinedValue(env);
1402     }
1403 
1404     AVSessionDescriptor descriptor;
1405     AVSessionManager::GetInstance().GetSessionDescriptorsBySessionId(napiController->controller_->GetSessionId(),
1406         descriptor);
1407     napi_value output {};
1408     auto status = NapiUtils::SetValue(env, descriptor.outputDeviceInfo_, output);
1409     if (status != napi_ok) {
1410         SLOGE("convert native object to javascript object failed");
1411         NapiUtils::ThrowError(env, "convert native object to javascript object failed",
1412             NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1413         return NapiUtils::GetUndefinedValue(env);
1414     }
1415     return output;
1416 }
1417 
SetAVCallMetaFilter(napi_env env,NapiAVSessionController * napiController,napi_value filter)1418 napi_status NapiAVSessionController::SetAVCallMetaFilter(napi_env env, NapiAVSessionController* napiController,
1419     napi_value filter)
1420 {
1421     AVCallMetaData::AVCallMetaMaskType avCallMetaMask;
1422     auto status = NapiAVCallMetaData::ConvertFilter(env, filter, avCallMetaMask);
1423     CHECK_RETURN(status == napi_ok, "convert filter failed", status);
1424     auto ret = napiController->controller_->SetAVCallMetaFilter(avCallMetaMask);
1425     if (ret != AVSESSION_SUCCESS) {
1426         SLOGE("controller SetAVCallMetaFilter failed:%{public}d", ret);
1427         status = napi_generic_failure;
1428     }
1429     return status;
1430 }
1431 
SetAVCallStateFilter(napi_env env,NapiAVSessionController * napiController,napi_value filter)1432 napi_status NapiAVSessionController::SetAVCallStateFilter(napi_env env, NapiAVSessionController *napiController,
1433     napi_value filter)
1434 {
1435     AVCallState::AVCallStateMaskType avCallStateMask;
1436     auto status = NapiAVCallState::ConvertFilter(env, filter, avCallStateMask);
1437     CHECK_RETURN(status == napi_ok, "convert filter failed", status);
1438     auto ret = napiController->controller_->SetAVCallStateFilter(avCallStateMask);
1439     if (ret != AVSESSION_SUCCESS) {
1440         SLOGE("controller SetAVCallStateFilter failed:%{public}d", ret);
1441         status = napi_generic_failure;
1442     }
1443     return status;
1444 }
1445 
SetPlaybackStateFilter(napi_env env,NapiAVSessionController * napiController,napi_value filter)1446 napi_status NapiAVSessionController::SetPlaybackStateFilter(napi_env env, NapiAVSessionController *napiController,
1447                                                             napi_value filter)
1448 {
1449     AVPlaybackState::PlaybackStateMaskType playbackMask;
1450     auto status = NapiPlaybackState::ConvertFilter(env, filter, playbackMask);
1451     CHECK_RETURN(status == napi_ok, "convert filter failed", status);
1452     auto ret = napiController->controller_->SetPlaybackFilter(playbackMask);
1453     if (ret != AVSESSION_SUCCESS) {
1454         SLOGE("controller SetPlaybackFilter failed:%{public}d", ret);
1455         status = napi_generic_failure;
1456     }
1457     return status;
1458 }
1459 
SetMetaFilter(napi_env env,NapiAVSessionController * napiController,napi_value filter)1460 napi_status NapiAVSessionController::SetMetaFilter(napi_env env, NapiAVSessionController* napiController,
1461                                                    napi_value filter)
1462 {
1463     AVMetaData::MetaMaskType metaMask;
1464     auto status = NapiMetaData::ConvertFilter(env, filter, metaMask);
1465     CHECK_RETURN(status == napi_ok, "convert filter failed", status);
1466     auto ret = napiController->controller_->SetMetaFilter(metaMask);
1467     if (ret != AVSESSION_SUCCESS) {
1468         SLOGE("controller SetMetaFilter failed:%{public}d", ret);
1469         status = napi_generic_failure;
1470     }
1471     return status;
1472 }
1473 
DoRegisterCallback(napi_env env,NapiAVSessionController * napiController)1474 napi_status NapiAVSessionController::DoRegisterCallback(napi_env env, NapiAVSessionController* napiController)
1475 {
1476     SLOGI("do register callback with for sessionId: %{public}s***",
1477         napiController->sessionId_.substr(0, ARGC_THREE).c_str());
1478     if (napiController->callback_ == nullptr) {
1479         napiController->callback_ = std::make_shared<NapiAVControllerCallback>();
1480         if (napiController->callback_ == nullptr) {
1481             SLOGE("OnEvent failed : no memory");
1482             NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1483             return napi_generic_failure;
1484         }
1485         std::string registerControllerId = napiController->sessionId_;
1486         napiController->callback_->AddCallbackForSessionDestroy([registerControllerId]() {
1487             SLOGI("repeat list check for session destory: %{public}s", registerControllerId.c_str());
1488             std::lock_guard<std::mutex> lock(controllerListMutex_);
1489             if (!ControllerList_.empty() && ControllerList_.find(registerControllerId) != ControllerList_.end()) {
1490                 SLOGI("repeat list erase controller for session destory: %{public}s", registerControllerId.c_str());
1491                 ControllerList_.erase(registerControllerId);
1492             } else {
1493                 SLOGI("repeat list erase fail for session not in list: %{public}s", registerControllerId.c_str());
1494             }
1495         });
1496         auto ret = napiController->controller_->RegisterCallback(napiController->callback_);
1497         if (ret != AVSESSION_SUCCESS) {
1498             SLOGE("controller RegisterCallback failed:%{public}d", ret);
1499             if (ret == ERR_CONTROLLER_NOT_EXIST) {
1500                 NapiUtils::ThrowError(env, "OnEvent failed : native controller not exist",
1501                     NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
1502             } else if (ret == ERR_NO_MEMORY) {
1503                 NapiUtils::ThrowError(env, "OnEvent failed : native no memory",
1504                     NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1505             } else if (ret == ERR_NO_PERMISSION) {
1506                 NapiUtils::ThrowError(env, "OnEvent failed : native no permission",
1507                     NapiAVSessionManager::errcode_[ERR_NO_PERMISSION]);
1508             } else {
1509                 NapiUtils::ThrowError(env, "OnEvent failed : native server exception",
1510                     NapiAVSessionManager::errcode_[ret]);
1511             }
1512             napiController->callback_ = nullptr;
1513             return napi_generic_failure;
1514         }
1515     }
1516     return napi_ok;
1517 }
1518 
RegisterCallback(napi_env env,const std::shared_ptr<ContextBase> & context,const std::string & event,napi_value filter,napi_value callback)1519 napi_status NapiAVSessionController::RegisterCallback(napi_env env,
1520     const std::shared_ptr<ContextBase>& context,
1521     const std::string& event, napi_value filter, napi_value callback)
1522 {
1523     auto it = EventHandlers_.find(event);
1524     if (it == EventHandlers_.end()) {
1525         SLOGE("event name invalid");
1526         NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1527         return napi_generic_failure;
1528     }
1529     SLOGD("NapiAVSessionController RegisterCallback process check lock");
1530     std::lock_guard<std::mutex> lock(uvMutex_);
1531     SLOGD("NapiAVSessionController RegisterCallback process");
1532     auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1533     if (napiController->controller_ == nullptr) {
1534         SLOGE("OnEvent failed : controller is nullptr");
1535         NapiUtils::ThrowError(env, "OnEvent CTL null", NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
1536         return napi_generic_failure;
1537     }
1538     if (DoRegisterCallback(env, napiController) != napi_ok) {
1539         SLOGE("do register callback fail!");
1540         return napi_generic_failure;
1541     }
1542     if (it->second.first(env, napiController, filter, callback) != napi_ok) {
1543         SLOGE("add event callback failed");
1544         NapiUtils::ThrowError(env, "add event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1545         return napi_generic_failure;
1546     }
1547     return napi_ok;
1548 }
1549 
IsThreeParamForOnEvent(const std::string & event)1550 static bool IsThreeParamForOnEvent(const std::string& event)
1551 {
1552     return event == "metadataChange" || event == "playbackStateChange" ||
1553         event == "callMetadataChange" || event == "callStateChange";
1554 }
1555 
OnEvent(napi_env env,napi_callback_info info)1556 napi_value NapiAVSessionController::OnEvent(napi_env env, napi_callback_info info)
1557 {
1558     auto context = std::make_shared<ContextBase>();
1559     if (context == nullptr) {
1560         SLOGE("OnEvent failed : no memory");
1561         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1562         return NapiUtils::GetUndefinedValue(env);
1563     }
1564 
1565     std::string eventName;
1566     napi_value filter {};
1567     napi_value callback {};
1568     auto input = [&eventName, &callback, &filter, env, &context](size_t argc, napi_value* argv) {
1569         CHECK_ARGS_RETURN_VOID(context, argc >= ARGC_ONE, "invalid argument number",
1570             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1571         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
1572         CHECK_STATUS_RETURN_VOID(context, "get event name failed",
1573             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1574         napi_valuetype type = napi_undefined;
1575         if (!IsThreeParamForOnEvent(eventName)) {
1576             CHECK_ARGS_RETURN_VOID(context, argc == ARGC_TWO, "invalid argument number",
1577                 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1578             context->status = napi_typeof(env, argv[ARGV_SECOND], &type);
1579             CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
1580                                    "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1581             callback = argv[ARGV_SECOND];
1582         } else {
1583             CHECK_ARGS_RETURN_VOID(context, argc == ARGC_THREE, "invalid argument number",
1584                 NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1585             context->status = napi_typeof(env, argv[ARGV_SECOND], &type);
1586             CHECK_ARGS_RETURN_VOID(
1587                 context, (context->status == napi_ok) && (type == napi_object || type == napi_string),
1588                 "Second param type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1589             filter = argv[ARGV_SECOND];
1590             context->status = napi_typeof(env, argv[ARGV_THIRD], &type);
1591             CHECK_ARGS_RETURN_VOID(context, (context->status == napi_ok) && (type == napi_function),
1592                                    "callback type invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1593             callback = argv[ARGV_THIRD];
1594         }
1595     };
1596     context->GetCbInfo(env, info, input, true);
1597     if (context->status != napi_ok) {
1598         NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
1599         return NapiUtils::GetUndefinedValue(env);
1600     }
1601     RegisterCallback(env, context, eventName, filter, callback);
1602 
1603     return NapiUtils::GetUndefinedValue(env);
1604 }
1605 
OffEvent(napi_env env,napi_callback_info info)1606 napi_value NapiAVSessionController::OffEvent(napi_env env, napi_callback_info info)
1607 {
1608     auto context = std::make_shared<ContextBase>();
1609     if (context == nullptr) {
1610         SLOGE("OnEvent failed : no memory");
1611         NapiUtils::ThrowError(env, "OnEvent failed : no memory", NapiAVSessionManager::errcode_[ERR_NO_MEMORY]);
1612         return NapiUtils::GetUndefinedValue(env);
1613     }
1614 
1615     std::string eventName;
1616     napi_value callback = nullptr;
1617     auto input = [&eventName, env, &context, &callback](size_t argc, napi_value* argv) {
1618         CHECK_ARGS_RETURN_VOID(context, argc == ARGC_ONE || argc == ARGC_TWO, "invalid argument number",
1619             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1620         context->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], eventName);
1621         CHECK_STATUS_RETURN_VOID(context, "get event name failed",
1622             NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1623         if (argc == ARGC_TWO) {
1624             callback = argv[ARGV_SECOND];
1625         }
1626     };
1627     SLOGD("check offEvent eventName %{public}s", eventName.c_str());
1628     context->GetCbInfo(env, info, input, true);
1629     if (context->status != napi_ok) {
1630         SLOGE("check offEvent with status err");
1631         NapiUtils::ThrowError(env, context->errMessage.c_str(), context->errCode);
1632         return NapiUtils::GetUndefinedValue(env);
1633     }
1634 
1635     auto it = EventHandlers_.find(eventName);
1636     if (it == EventHandlers_.end()) {
1637         SLOGE("event name invalid:%{public}s", eventName.c_str());
1638         NapiUtils::ThrowError(env, "event name invalid", NapiAVSessionManager::errcode_[ERR_INVALID_PARAM]);
1639         return NapiUtils::GetUndefinedValue(env);
1640     }
1641 
1642     auto* napiController = reinterpret_cast<NapiAVSessionController*>(context->native);
1643     if (napiController->callback_ == nullptr) {
1644         SLOGI("function %{public}s not register yet", eventName.c_str());
1645         NapiUtils::ThrowError(env, "callback not register yet",
1646             NapiAVSessionManager::errcode_[ERR_CONTROLLER_NOT_EXIST]);
1647         return NapiUtils::GetUndefinedValue(env);
1648     }
1649 
1650     if (it->second.second(env, napiController, callback) != napi_ok) {
1651         NapiUtils::ThrowError(env, "remove event callback failed", NapiAVSessionManager::errcode_[AVSESSION_ERROR]);
1652     }
1653     SLOGD("check offEvent done");
1654     return NapiUtils::GetUndefinedValue(env);
1655 }
1656 
OnAVCallMetaDataChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1657 napi_status NapiAVSessionController::OnAVCallMetaDataChange(napi_env env, NapiAVSessionController* napiController,
1658     napi_value param, napi_value callback)
1659 {
1660     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1661     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1662         "callback has not been registered");
1663     napi_status status = SetAVCallMetaFilter(env, napiController, param);
1664     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "SetAVCallMetaFilter failed");
1665 
1666     return napiController->callback_->AddCallback(env,
1667         NapiAVControllerCallback::EVENT_AVCALL_META_DATA_CHANGE, callback);
1668 }
1669 
OnAVCallStateChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1670 napi_status NapiAVSessionController::OnAVCallStateChange(napi_env env, NapiAVSessionController* napiController,
1671     napi_value param, napi_value callback)
1672 {
1673     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1674     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1675         "callback has not been registered");
1676     napi_status status = SetAVCallStateFilter(env, napiController, param);
1677     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "SetAVCallStateFilter failed");
1678 
1679     return napiController->callback_->AddCallback(env,
1680         NapiAVControllerCallback::EVENT_AVCALL_STATE_CHANGE, callback);
1681 }
1682 
OnSessionDestroy(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1683 napi_status NapiAVSessionController::OnSessionDestroy(napi_env env, NapiAVSessionController* napiController,
1684                                                       napi_value param, napi_value callback)
1685 {
1686     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1687     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1688         "callback has not been registered");
1689     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_SESSION_DESTROY, callback);
1690 }
1691 
OnPlaybackStateChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1692 napi_status NapiAVSessionController::OnPlaybackStateChange(napi_env env, NapiAVSessionController* napiController,
1693                                                            napi_value param, napi_value callback)
1694 {
1695     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1696     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1697         "callback has not been registered");
1698     napi_status status = SetPlaybackStateFilter(env, napiController, param);
1699     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "SetPlaybackStateFilter failed");
1700     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_PLAYBACK_STATE_CHANGE,
1701                                                   callback);
1702 }
1703 
OnCustomData(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1704 napi_status NapiAVSessionController::OnCustomData(napi_env env, NapiAVSessionController* napiController,
1705                                                   napi_value param, napi_value callback)
1706 {
1707     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1708     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1709         "callback has not been registered");
1710     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_CUSTOM_DATA, callback);
1711 }
1712 
OnMetaDataChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1713 napi_status NapiAVSessionController::OnMetaDataChange(napi_env env, NapiAVSessionController* napiController,
1714                                                       napi_value param, napi_value callback)
1715 {
1716     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1717     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1718         "callback has not been registered");
1719     napi_status status = SetMetaFilter(env, napiController, param);
1720     CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "SetMetaFilter failed");
1721     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_META_DATA_CHANGE, callback);
1722 }
1723 
OnActiveStateChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1724 napi_status NapiAVSessionController::OnActiveStateChange(napi_env env, NapiAVSessionController* napiController,
1725                                                          napi_value param, napi_value callback)
1726 {
1727     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1728     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1729         "callback has not been registered");
1730     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_ACTIVE_STATE_CHANGE, callback);
1731 }
1732 
OnValidCommandChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1733 napi_status NapiAVSessionController::OnValidCommandChange(napi_env env, NapiAVSessionController* napiController,
1734                                                           napi_value param, napi_value callback)
1735 {
1736     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1737     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1738         "callback has not been registered");
1739     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_VALID_COMMAND_CHANGE,
1740                                                   callback);
1741 }
1742 
OnOutputDeviceChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1743 napi_status NapiAVSessionController::OnOutputDeviceChange(napi_env env, NapiAVSessionController* napiController,
1744                                                           napi_value param, napi_value callback)
1745 {
1746     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1747     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1748         "callback has not been registered");
1749     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_OUTPUT_DEVICE_CHANGE,
1750                                                   callback);
1751 }
1752 
OnSessionEventChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1753 napi_status NapiAVSessionController::OnSessionEventChange(napi_env env, NapiAVSessionController* napiController,
1754                                                           napi_value param, napi_value callback)
1755 {
1756     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1757     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1758         "callback has not been registered");
1759     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_SESSION_EVENT_CHANGE,
1760                                                   callback);
1761 }
1762 
OnQueueItemsChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1763 napi_status NapiAVSessionController::OnQueueItemsChange(napi_env env, NapiAVSessionController* napiController,
1764     napi_value param, napi_value callback)
1765 {
1766     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1767     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1768         "callback has not been registered");
1769     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_QUEUE_ITEMS_CHANGE,
1770         callback);
1771 }
1772 
OnQueueTitleChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1773 napi_status NapiAVSessionController::OnQueueTitleChange(napi_env env, NapiAVSessionController* napiController,
1774     napi_value param, napi_value callback)
1775 {
1776     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1777     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1778         "callback has not been registered");
1779     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_QUEUE_TITLE_CHANGE,
1780         callback);
1781 }
1782 
OnExtrasChange(napi_env env,NapiAVSessionController * napiController,napi_value param,napi_value callback)1783 napi_status NapiAVSessionController::OnExtrasChange(napi_env env, NapiAVSessionController* napiController,
1784     napi_value param, napi_value callback)
1785 {
1786     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1787     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1788         "callback has not been registered");
1789     return napiController->callback_->AddCallback(env, NapiAVControllerCallback::EVENT_EXTRAS_CHANGE,
1790         callback);
1791 }
1792 
OffAVCallMetaDataChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1793 napi_status NapiAVSessionController::OffAVCallMetaDataChange(napi_env env, NapiAVSessionController* napiController,
1794     napi_value callback)
1795 {
1796     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1797     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1798         "callback has not been registered");
1799     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_AVCALL_META_DATA_CHANGE,
1800         callback);
1801 }
1802 
OffAVCallStateChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1803 napi_status NapiAVSessionController::OffAVCallStateChange(napi_env env, NapiAVSessionController* napiController,
1804     napi_value callback)
1805 {
1806     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1807     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1808         "callback has not been registered");
1809     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_AVCALL_STATE_CHANGE,
1810         callback);
1811 }
1812 
OffSessionDestroy(napi_env env,NapiAVSessionController * napiController,napi_value callback)1813 napi_status NapiAVSessionController::OffSessionDestroy(napi_env env, NapiAVSessionController* napiController,
1814                                                        napi_value callback)
1815 {
1816     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1817     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1818         "callback has not been registered");
1819     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_SESSION_DESTROY, callback);
1820 }
1821 
OffPlaybackStateChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1822 napi_status NapiAVSessionController::OffPlaybackStateChange(napi_env env, NapiAVSessionController* napiController,
1823                                                             napi_value callback)
1824 {
1825     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1826     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1827         "callback has not been registered");
1828     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_PLAYBACK_STATE_CHANGE,
1829                                                      callback);
1830 }
1831 
OffCustomData(napi_env env,NapiAVSessionController * napiController,napi_value callback)1832 napi_status NapiAVSessionController::OffCustomData(napi_env env, NapiAVSessionController* napiController,
1833                                                    napi_value callback)
1834 {
1835     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1836     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1837         "callback has not been registered");
1838     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_CUSTOM_DATA, callback);
1839 }
1840 
OffMetaDataChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1841 napi_status NapiAVSessionController::OffMetaDataChange(napi_env env, NapiAVSessionController* napiController,
1842                                                        napi_value callback)
1843 {
1844     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1845     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1846         "callback has not been registered");
1847     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_META_DATA_CHANGE, callback);
1848 }
1849 
OffActiveStateChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1850 napi_status NapiAVSessionController::OffActiveStateChange(napi_env env, NapiAVSessionController* napiController,
1851                                                           napi_value callback)
1852 {
1853     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1854     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1855         "callback has not been registered");
1856     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_ACTIVE_STATE_CHANGE,
1857                                                      callback);
1858 }
1859 
OffValidCommandChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1860 napi_status NapiAVSessionController::OffValidCommandChange(napi_env env, NapiAVSessionController* napiController,
1861                                                            napi_value callback)
1862 {
1863     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1864     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1865         "callback has not been registered");
1866     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_VALID_COMMAND_CHANGE,
1867                                                      callback);
1868 }
1869 
OffOutputDeviceChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1870 napi_status NapiAVSessionController::OffOutputDeviceChange(napi_env env, NapiAVSessionController* napiController,
1871                                                            napi_value callback)
1872 {
1873     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1874     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1875         "callback has not been registered");
1876     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_OUTPUT_DEVICE_CHANGE,
1877                                                      callback);
1878 }
1879 
OffSessionEventChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1880 napi_status NapiAVSessionController::OffSessionEventChange(napi_env env, NapiAVSessionController* napiController,
1881                                                            napi_value callback)
1882 {
1883     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1884     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1885         "callback has not been registered");
1886     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_SESSION_EVENT_CHANGE,
1887                                                      callback);
1888 }
1889 
OffQueueItemsChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1890 napi_status NapiAVSessionController::OffQueueItemsChange(napi_env env, NapiAVSessionController* napiController,
1891     napi_value callback)
1892 {
1893     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1894     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1895         "callback has not been registered");
1896     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_QUEUE_ITEMS_CHANGE,
1897         callback);
1898 }
1899 
OffQueueTitleChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1900 napi_status NapiAVSessionController::OffQueueTitleChange(napi_env env, NapiAVSessionController* napiController,
1901     napi_value callback)
1902 {
1903     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1904     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1905         "callback has not been registered");
1906     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_QUEUE_TITLE_CHANGE,
1907         callback);
1908 }
1909 
OffExtrasChange(napi_env env,NapiAVSessionController * napiController,napi_value callback)1910 napi_status NapiAVSessionController::OffExtrasChange(napi_env env, NapiAVSessionController* napiController,
1911     napi_value callback)
1912 {
1913     CHECK_AND_RETURN_RET_LOG(napiController != nullptr, napi_generic_failure, "input param is nullptr");
1914     CHECK_AND_RETURN_RET_LOG(napiController->callback_ != nullptr, napi_generic_failure,
1915         "callback has not been registered");
1916     return napiController->callback_->RemoveCallback(env, NapiAVControllerCallback::EVENT_EXTRAS_CHANGE,
1917         callback);
1918 }
1919 }
1920