1 /*
2 * Copyright (c) 2022 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_avsession_callback.h"
17 #include "avsession_log.h"
18 #include "napi_utils.h"
19 #include "avsession_trace.h"
20
21 namespace OHOS::AVSession {
NapiAVSessionCallback()22 NapiAVSessionCallback::NapiAVSessionCallback()
23 {
24 SLOGI("construct");
25 }
26
~NapiAVSessionCallback()27 NapiAVSessionCallback::~NapiAVSessionCallback()
28 {
29 SLOGI("destroy");
30 }
31
HandleEvent(int32_t event)32 void NapiAVSessionCallback::HandleEvent(int32_t event)
33 {
34 std::lock_guard<std::mutex> lockGuard(lock_);
35 if (callbacks_[event].empty()) {
36 SLOGE("not register callback event=%{public}d", event);
37 return;
38 }
39 for (auto ref = callbacks_[event].begin(); ref != callbacks_[event].end(); ++ref) {
40 asyncCallback_->Call(*ref);
41 }
42 }
43
44 template<typename T>
HandleEvent(int32_t event,const T & param)45 void NapiAVSessionCallback::HandleEvent(int32_t event, const T& param)
46 {
47 std::lock_guard<std::mutex> lockGuard(lock_);
48 if (callbacks_[event].empty()) {
49 SLOGE("not register callback event=%{public}d", event);
50 return;
51 }
52 for (auto ref = callbacks_[event].begin(); ref != callbacks_[event].end(); ++ref) {
53 asyncCallback_->Call(*ref, [param](napi_env env, int& argc, napi_value* argv) {
54 argc = NapiUtils::ARGC_ONE;
55 NapiUtils::SetValue(env, param, *argv);
56 });
57 }
58 }
59
OnPlay()60 void NapiAVSessionCallback::OnPlay()
61 {
62 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnPlay");
63 HandleEvent(EVENT_PLAY);
64 }
65
OnPause()66 void NapiAVSessionCallback::OnPause()
67 {
68 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnPause");
69 HandleEvent(EVENT_PAUSE);
70 }
71
OnStop()72 void NapiAVSessionCallback::OnStop()
73 {
74 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnStop");
75 HandleEvent(EVENT_STOP);
76 }
77
OnPlayNext()78 void NapiAVSessionCallback::OnPlayNext()
79 {
80 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnPlayNext");
81 HandleEvent(EVENT_PLAY_NEXT);
82 }
83
OnPlayPrevious()84 void NapiAVSessionCallback::OnPlayPrevious()
85 {
86 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnPlayPrevious");
87 HandleEvent(EVENT_PLAY_PREVIOUS);
88 }
89
OnFastForward()90 void NapiAVSessionCallback::OnFastForward()
91 {
92 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnFastForward");
93 HandleEvent(EVENT_FAST_FORWARD);
94 }
95
OnRewind()96 void NapiAVSessionCallback::OnRewind()
97 {
98 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnRewind");
99 HandleEvent(EVENT_REWIND);
100 }
101
OnSeek(int64_t time)102 void NapiAVSessionCallback::OnSeek(int64_t time)
103 {
104 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnSeek");
105 HandleEvent(EVENT_SEEK, time);
106 }
107
OnSetSpeed(double speed)108 void NapiAVSessionCallback::OnSetSpeed(double speed)
109 {
110 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnSetSpeed");
111 HandleEvent(EVENT_SET_SPEED, speed);
112 }
113
OnSetLoopMode(int32_t loopMode)114 void NapiAVSessionCallback::OnSetLoopMode(int32_t loopMode)
115 {
116 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnSetLoopMode");
117 HandleEvent(EVENT_SET_LOOP_MODE, loopMode);
118 }
119
OnToggleFavorite(const std::string & assertId)120 void NapiAVSessionCallback::OnToggleFavorite(const std::string& assertId)
121 {
122 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnToggleFavorite");
123 HandleEvent(EVENT_TOGGLE_FAVORITE, assertId);
124 }
125
OnMediaKeyEvent(const MMI::KeyEvent & keyEvent)126 void NapiAVSessionCallback::OnMediaKeyEvent(const MMI::KeyEvent& keyEvent)
127 {
128 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnMediaKeyEvent");
129 HandleEvent(EVENT_MEDIA_KEY_EVENT, std::make_shared<MMI::KeyEvent>(keyEvent));
130 }
131
OnOutputDeviceChange(const OutputDeviceInfo & outputDeviceInfo)132 void NapiAVSessionCallback::OnOutputDeviceChange(const OutputDeviceInfo& outputDeviceInfo)
133 {
134 AVSESSION_TRACE_SYNC_START("NapiAVSessionCallback::OnOutputDeviceChange");
135 HandleEvent(EVENT_OUTPUT_DEVICE_CHANGE, outputDeviceInfo);
136 }
137
AddCallback(napi_env env,int32_t event,napi_value callback)138 napi_status NapiAVSessionCallback::AddCallback(napi_env env, int32_t event, napi_value callback)
139 {
140 SLOGI("Add callback %{public}d", event);
141 std::lock_guard<std::mutex> lockGuard(lock_);
142 napi_ref ref = nullptr;
143 CHECK_AND_RETURN_RET_LOG(napi_ok == NapiUtils::GetRefByCallback(env, callbacks_[event], callback, ref),
144 napi_generic_failure, "get callback reference failed");
145 CHECK_AND_RETURN_RET_LOG(ref == nullptr, napi_ok, "callback has been registered");
146 napi_status status = napi_create_reference(env, callback, NapiUtils::ARGC_ONE, &ref);
147 if (status != napi_ok) {
148 SLOGE("napi_create_reference failed");
149 return status;
150 }
151 if (asyncCallback_ == nullptr) {
152 asyncCallback_ = std::make_shared<NapiAsyncCallback>(env);
153 if (asyncCallback_ == nullptr) {
154 SLOGE("no memory");
155 return napi_generic_failure;
156 }
157 }
158 callbacks_[event].push_back(ref);
159 return napi_ok;
160 }
161
RemoveCallback(napi_env env,int32_t event,napi_value callback)162 napi_status NapiAVSessionCallback::RemoveCallback(napi_env env, int32_t event, napi_value callback)
163 {
164 SLOGI("Remove callback %{public}d", event);
165 std::lock_guard<std::mutex> lockGuard(lock_);
166 if (callback == nullptr) {
167 for (auto callbackRef = callbacks_[event].begin(); callbackRef != callbacks_[event].end(); ++callbackRef) {
168 napi_status ret = napi_delete_reference(env, *callbackRef);
169 CHECK_AND_RETURN_RET_LOG(napi_ok == ret, ret, "delete callback reference failed");
170 }
171 callbacks_[event].clear();
172 return napi_ok;
173 }
174 napi_ref ref = nullptr;
175 CHECK_AND_RETURN_RET_LOG(napi_ok == NapiUtils::GetRefByCallback(env, callbacks_[event], callback, ref),
176 napi_generic_failure, "get callback reference failed");
177 CHECK_AND_RETURN_RET_LOG(ref != nullptr, napi_ok, "callback has been remove");
178 callbacks_[event].remove(ref);
179 return napi_delete_reference(env, ref);
180 }
181
IsCallbacksEmpty(int32_t event)182 bool NapiAVSessionCallback::IsCallbacksEmpty(int32_t event)
183 {
184 return callbacks_[event].empty();
185 }
186 }
187