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