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