• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_avcontroller_callback.h"
17 #include "avsession_log.h"
18 #include "avsession_trace.h"
19 #include "napi_control_command.h"
20 #include "napi_meta_data.h"
21 #include "napi_playback_state.h"
22 #include "napi_media_description.h"
23 #include "napi_queue_item.h"
24 #include "napi_utils.h"
25 
26 namespace OHOS::AVSession {
NapiAVControllerCallback()27 NapiAVControllerCallback::NapiAVControllerCallback()
28 {
29     SLOGI("construct");
30 }
31 
~NapiAVControllerCallback()32 NapiAVControllerCallback::~NapiAVControllerCallback()
33 {
34     SLOGI("destroy");
35 }
36 
HandleEvent(int32_t event)37 void NapiAVControllerCallback::HandleEvent(int32_t event)
38 {
39     std::lock_guard<std::mutex> lockGuard(lock_);
40     if (callbacks_[event].empty()) {
41         SLOGE("not register callback event=%{public}d", event);
42         return;
43     }
44     for (auto ref = callbacks_[event].begin(); ref != callbacks_[event].end(); ++ref) {
45         asyncCallback_->Call(*ref);
46     }
47 }
48 
49 template<typename T>
HandleEvent(int32_t event,const T & param)50 void NapiAVControllerCallback::HandleEvent(int32_t event, const T& param)
51 {
52     std::lock_guard<std::mutex> lockGuard(lock_);
53     if (callbacks_[event].empty()) {
54         SLOGE("not register callback event=%{public}d", event);
55         return;
56     }
57     for (auto ref = callbacks_[event].begin(); ref != callbacks_[event].end(); ++ref) {
58         asyncCallback_->Call(*ref, [param](napi_env env, int& argc, napi_value *argv) {
59             argc = NapiUtils::ARGC_ONE;
60             auto status = NapiUtils::SetValue(env, param, *argv);
61             CHECK_RETURN_VOID(status == napi_ok, "ControllerCallback SetValue invalid");
62         });
63     }
64 }
65 
66 template<typename T>
HandleEvent(int32_t event,const std::string & firstParam,const T & secondParam)67 void NapiAVControllerCallback::HandleEvent(int32_t event, const std::string& firstParam, const T& secondParam)
68 {
69     std::lock_guard<std::mutex> lockGuard(lock_);
70     if (callbacks_[event].empty()) {
71         SLOGE("not register callback event=%{public}d", event);
72         return;
73     }
74     for (auto ref = callbacks_[event].begin(); ref != callbacks_[event].end(); ++ref) {
75         asyncCallback_->Call(*ref, [firstParam, secondParam](napi_env env, int& argc, napi_value *argv) {
76             argc = NapiUtils::ARGC_TWO;
77             auto status = NapiUtils::SetValue(env, firstParam, argv[0]);
78             CHECK_RETURN_VOID(status == napi_ok, "ControllerCallback SetValue invalid");
79             status = NapiUtils::SetValue(env, secondParam, argv[1]);
80             CHECK_RETURN_VOID(status == napi_ok, "ControllerCallback SetValue invalid");
81         });
82     }
83 }
84 
85 
86 template<typename T>
HandleEvent(int32_t event,const int32_t firstParam,const T & secondParam)87 void NapiAVControllerCallback::HandleEvent(int32_t event, const int32_t firstParam, const T& secondParam)
88 {
89     std::lock_guard<std::mutex> lockGuard(lock_);
90     if (callbacks_[event].empty()) {
91         SLOGE("not register callback event=%{public}d", event);
92         return;
93     }
94     for (auto ref = callbacks_[event].begin(); ref != callbacks_[event].end(); ++ref) {
95         asyncCallback_->Call(*ref, [firstParam, secondParam](napi_env env, int& argc, napi_value *argv) {
96             argc = NapiUtils::ARGC_TWO;
97             auto status = NapiUtils::SetValue(env, firstParam, argv[0]);
98             CHECK_RETURN_VOID(status == napi_ok, "ControllerCallback SetValue invalid");
99             status = NapiUtils::SetValue(env, secondParam, argv[1]);
100             CHECK_RETURN_VOID(status == napi_ok, "ControllerCallback SetValue invalid");
101         });
102     }
103 }
104 
OnSessionDestroy()105 void NapiAVControllerCallback::OnSessionDestroy()
106 {
107     HandleEvent(EVENT_SESSION_DESTROY);
108 }
109 
OnPlaybackStateChange(const AVPlaybackState & state)110 void NapiAVControllerCallback::OnPlaybackStateChange(const AVPlaybackState& state)
111 {
112     AVSESSION_TRACE_SYNC_START("NapiAVControllerCallback::OnPlaybackStateChange");
113     HandleEvent(EVENT_PLAYBACK_STATE_CHANGE, state);
114 }
115 
OnMetaDataChange(const AVMetaData & data)116 void NapiAVControllerCallback::OnMetaDataChange(const AVMetaData& data)
117 {
118     AVSESSION_TRACE_SYNC_START("NapiAVControllerCallback::OnMetaDataChange");
119     HandleEvent(EVENT_META_DATA_CHANGE, data);
120 }
121 
OnActiveStateChange(bool isActive)122 void NapiAVControllerCallback::OnActiveStateChange(bool isActive)
123 {
124     HandleEvent(EVENT_ACTIVE_STATE_CHANGE, isActive);
125 }
126 
OnValidCommandChange(const std::vector<int32_t> & cmds)127 void NapiAVControllerCallback::OnValidCommandChange(const std::vector<int32_t>& cmds)
128 {
129     std::vector<std::string> stringCmds = NapiControlCommand::ConvertCommands(cmds);
130     HandleEvent(EVENT_VALID_COMMAND_CHANGE, stringCmds);
131 }
132 
OnOutputDeviceChange(const int32_t connectionState,const OutputDeviceInfo & info)133 void NapiAVControllerCallback::OnOutputDeviceChange(const int32_t connectionState, const OutputDeviceInfo& info)
134 {
135     HandleEvent(EVENT_OUTPUT_DEVICE_CHANGE, connectionState, info);
136 }
137 
OnSessionEventChange(const std::string & event,const AAFwk::WantParams & args)138 void NapiAVControllerCallback::OnSessionEventChange(const std::string& event, const AAFwk::WantParams& args)
139 {
140     AVSESSION_TRACE_SYNC_START("NapiAVControllerCallback::OnSessionEventChange");
141     HandleEvent(EVENT_SESSION_EVENT_CHANGE, event, args);
142 }
143 
OnQueueItemsChange(const std::vector<AVQueueItem> & items)144 void NapiAVControllerCallback::OnQueueItemsChange(const std::vector<AVQueueItem>& items)
145 {
146     AVSESSION_TRACE_SYNC_START("NapiAVControllerCallback::OnQueueItemsChange");
147     HandleEvent(EVENT_QUEUE_ITEMS_CHANGE, items);
148 }
149 
OnQueueTitleChange(const std::string & title)150 void NapiAVControllerCallback::OnQueueTitleChange(const std::string& title)
151 {
152     AVSESSION_TRACE_SYNC_START("NapiAVControllerCallback::OnQueueTitleChange");
153     HandleEvent(EVENT_QUEUE_TITLE_CHANGE, title);
154 }
155 
OnExtrasChange(const AAFwk::WantParams & extras)156 void NapiAVControllerCallback::OnExtrasChange(const AAFwk::WantParams& extras)
157 {
158     AVSESSION_TRACE_SYNC_START("NapiAVControllerCallback::OnExtrasChange");
159     HandleEvent(EVENT_EXTRAS_CHANGE, extras);
160 }
161 
AddCallback(napi_env env,int32_t event,napi_value callback)162 napi_status NapiAVControllerCallback::AddCallback(napi_env env, int32_t event, napi_value callback)
163 {
164     std::lock_guard<std::mutex> lockGuard(lock_);
165     napi_ref ref = nullptr;
166 
167     CHECK_AND_RETURN_RET_LOG(napi_ok == NapiUtils::GetRefByCallback(env, callbacks_[event], callback, ref),
168                              napi_generic_failure, "get callback reference failed");
169     CHECK_AND_RETURN_RET_LOG(ref == nullptr, napi_ok, "callback has been registered");
170     napi_status status = napi_create_reference(env, callback, NapiUtils::ARGC_ONE, &ref);
171     if (status != napi_ok) {
172         SLOGE("napi_create_reference failed");
173         return status;
174     }
175     if (asyncCallback_ == nullptr) {
176         asyncCallback_ = std::make_shared<NapiAsyncCallback>(env);
177         if (asyncCallback_ == nullptr) {
178             SLOGE("no memory");
179             return napi_generic_failure;
180         }
181     }
182     callbacks_[event].push_back(ref);
183     return napi_ok;
184 }
185 
RemoveCallback(napi_env env,int32_t event,napi_value callback)186 napi_status NapiAVControllerCallback::RemoveCallback(napi_env env, int32_t event, napi_value callback)
187 {
188     std::lock_guard<std::mutex> lockGuard(lock_);
189     if (callback == nullptr) {
190         SLOGD("Remove callback, the callback is nullptr");
191         for (auto callbackRef = callbacks_[event].begin(); callbackRef != callbacks_[event].end(); ++callbackRef) {
192             napi_status ret = napi_delete_reference(env, *callbackRef);
193             CHECK_AND_RETURN_RET_LOG(ret == napi_ok, ret, "delete callback reference failed");
194             *callbackRef = nullptr;
195         }
196         callbacks_[event].clear();
197         return napi_ok;
198     }
199     napi_ref ref = nullptr;
200     CHECK_AND_RETURN_RET_LOG(napi_ok == NapiUtils::GetRefByCallback(env, callbacks_[event], callback, ref),
201                              napi_generic_failure, "get callback reference failed");
202     CHECK_AND_RETURN_RET_LOG(ref != nullptr, napi_ok, "callback has been remove");
203     callbacks_[event].remove(ref);
204     return napi_delete_reference(env, ref);
205 }
206 }
207