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