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_control_command.h"
17 #include "avsession_log.h"
18 #include "avsession_errors.h"
19 #include "napi_utils.h"
20 #include "avmeta_data.h"
21
22 namespace OHOS::AVSession {
23 std::map<std::string, std::tuple<NapiControlCommand::GetterType, NapiControlCommand::SetterType, int32_t>>
24 NapiControlCommand::commandMap_ = {
25 { "play", { GetNoneParam, SetNoneParam, AVControlCommand::SESSION_CMD_PLAY } },
26 { "pause", { GetNoneParam, SetNoneParam, AVControlCommand::SESSION_CMD_PAUSE } },
27 { "stop", { GetNoneParam, SetNoneParam, AVControlCommand::SESSION_CMD_STOP } },
28 { "playNext", { GetNoneParam, SetNoneParam, AVControlCommand::SESSION_CMD_PLAY_NEXT } },
29 { "playPrevious", { GetNoneParam, SetNoneParam, AVControlCommand::SESSION_CMD_PLAY_PREVIOUS } },
30 { "fastForward", { GetForwardTime, SetForwardTime, AVControlCommand::SESSION_CMD_FAST_FORWARD } },
31 { "rewind", { GetRewindTime, SetRewindTime, AVControlCommand::SESSION_CMD_REWIND } },
32 { "seek", { GetSeekTime, SetSeekTime, AVControlCommand::SESSION_CMD_SEEK } },
33 { "setSpeed", { GetSpeed, SetSpeed, AVControlCommand::SESSION_CMD_SET_SPEED } },
34 { "setLoopMode", { GetLoopMode, SetLoopMode, AVControlCommand::SESSION_CMD_SET_LOOP_MODE } },
35 { "setTargetLoopMode",
36 { GetTargetLoopMode, SetTargetLoopMode, AVControlCommand::SESSION_CMD_SET_TARGET_LOOP_MODE } },
37 { "toggleFavorite", { GetAssetId, SetAssetId, AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE } },
38 { "playFromAssetId", { GetPlayFromAssetId, SetPlayFromAssetId, AVControlCommand::SESSION_CMD_PLAY_FROM_ASSETID } },
39 { "answer", { GetNoneParam, SetNoneParam, AVControlCommand::SESSION_CMD_AVCALL_ANSWER } },
40 { "hangUp", { GetNoneParam, SetNoneParam, AVControlCommand::SESSION_CMD_AVCALL_HANG_UP } },
41 { "toggleCallMute", { GetNoneParam, SetNoneParam, AVControlCommand::SESSION_CMD_AVCALL_TOGGLE_CALL_MUTE } },
42 };
43
ConvertCommand(const std::string & cmd)44 int32_t NapiControlCommand::ConvertCommand(const std::string& cmd)
45 {
46 for (const auto& [key, value] : commandMap_) {
47 if (key == cmd) {
48 return std::get<ENUM_INDEX>(value);
49 }
50 }
51 return AVControlCommand::SESSION_CMD_INVALID;
52 }
53
ConvertCommand(int32_t cmd)54 std::string NapiControlCommand::ConvertCommand(int32_t cmd)
55 {
56 for (const auto& [key, value] : commandMap_) {
57 if (std::get<ENUM_INDEX>(value) == cmd) {
58 return key;
59 }
60 }
61 return {};
62 }
63
ConvertCommands(const std::vector<int32_t> & cmds)64 std::vector<std::string> NapiControlCommand::ConvertCommands(const std::vector<int32_t>& cmds)
65 {
66 std::vector<std::string> result;
67 for (const auto& cmd : cmds) {
68 auto stringCmd = ConvertCommand(cmd);
69 if (!stringCmd.empty()) {
70 result.push_back(stringCmd);
71 }
72 }
73 return result;
74 }
75
GetValue(napi_env env,napi_value in,AVControlCommand & out)76 napi_status NapiControlCommand::GetValue(napi_env env, napi_value in, AVControlCommand& out)
77 {
78 std::string cmd;
79 auto status = NapiUtils::GetNamedProperty(env, in, "command", cmd);
80 if (status != napi_ok) {
81 SLOGE("get command property failed");
82 return status;
83 }
84
85 SLOGI("cmd=%{public}s", cmd.c_str());
86 auto it = commandMap_.find(cmd);
87 if (it == commandMap_.end()) {
88 SLOGE("cmd is invalid");
89 return napi_invalid_arg;
90 }
91 if (out.SetCommand(ConvertCommand(cmd)) != AVSESSION_SUCCESS) {
92 SLOGE("native set command failed");
93 return napi_invalid_arg;
94 }
95 auto getter = std::get<GETTER_INDEX>(it->second);
96 return getter(env, in, out);
97 }
98
SetValue(napi_env env,AVControlCommand & in,napi_value & out)99 napi_status NapiControlCommand::SetValue(napi_env env, AVControlCommand& in, napi_value& out)
100 {
101 napi_status status = napi_create_object(env, &out);
102 CHECK_RETURN((status == napi_ok) && (out != nullptr), "create object failed", status);
103
104 auto cmd = ConvertCommand(in.GetCommand());
105 napi_value property {};
106 status = NapiUtils::SetValue(env, cmd, property);
107 CHECK_RETURN(status == napi_ok, "create command property failed", status);
108 status = napi_set_named_property(env, out, "command", property);
109 CHECK_RETURN(status == napi_ok, "set command property failed", status);
110
111 auto it = commandMap_.find(cmd);
112 if (it == commandMap_.end()) {
113 SLOGE("cmd is invalid");
114 return napi_invalid_arg;
115 }
116
117 auto setter = std::get<SETTER_INDEX>(it->second);
118 return setter(env, in, out);
119 }
120
GetNoneParam(napi_env env,napi_value in,AVControlCommand & out)121 napi_status NapiControlCommand::GetNoneParam(napi_env env, napi_value in, AVControlCommand& out)
122 {
123 SLOGD("no param need to get");
124 (void)(env);
125 (void)(in);
126 (void)(out);
127 return napi_ok;
128 }
129
SetNoneParam(napi_env env,AVControlCommand & in,napi_value & out)130 napi_status NapiControlCommand::SetNoneParam(napi_env env, AVControlCommand& in, napi_value& out)
131 {
132 SLOGD("no param need to set");
133 (void)(env);
134 (void)(in);
135 (void)(out);
136 return napi_ok;
137 }
138
GetSpeed(napi_env env,napi_value in,AVControlCommand & out)139 napi_status NapiControlCommand::GetSpeed(napi_env env, napi_value in, AVControlCommand& out)
140 {
141 double speed {};
142 auto status = NapiUtils::GetNamedProperty(env, in, "parameter", speed);
143 if (status != napi_ok) {
144 SLOGE("get parameter failed");
145 return status;
146 }
147
148 CHECK_AND_RETURN_RET_LOG(out.SetSpeed(speed) == AVSESSION_SUCCESS, napi_invalid_arg, "set parameter failed");
149 return status;
150 }
151
SetSpeed(napi_env env,AVControlCommand & in,napi_value & out)152 napi_status NapiControlCommand::SetSpeed(napi_env env, AVControlCommand& in, napi_value& out)
153 {
154 double speed {};
155 CHECK_AND_RETURN_RET_LOG(in.GetSpeed(speed) == AVSESSION_SUCCESS, napi_invalid_arg, "get parameter failed");
156
157 napi_value property {};
158 auto status = NapiUtils::SetValue(env, speed, property);
159 if (status != napi_ok) {
160 SLOGE("create speed property failed");
161 return status;
162 }
163
164 status = napi_set_named_property(env, out, "parameter", property);
165 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "set parameter property failed");
166 return status;
167 }
168
GetForwardTime(napi_env env,napi_value in,AVControlCommand & out)169 napi_status NapiControlCommand::GetForwardTime(napi_env env, napi_value in, AVControlCommand& out)
170 {
171 int64_t time {};
172 auto status = NapiUtils::GetNamedProperty(env, in, "parameter", time);
173 if (status != napi_ok) {
174 SLOGI("get ForwardTime parameter failed but set default");
175 time = AVMetaData::SECONDS_15;
176 status = napi_ok;
177 }
178
179 SLOGD("GetForwardTime with time %{public}jd", static_cast<int64_t>(time));
180 CHECK_AND_RETURN_RET_LOG(out.SetForwardTime(time) == AVSESSION_SUCCESS, napi_invalid_arg, "set parameter failed");
181 return status;
182 }
183
SetForwardTime(napi_env env,AVControlCommand & in,napi_value & out)184 napi_status NapiControlCommand::SetForwardTime(napi_env env, AVControlCommand& in, napi_value& out)
185 {
186 int64_t time {};
187 CHECK_AND_RETURN_RET_LOG(in.GetForwardTime(time) == AVSESSION_SUCCESS, napi_invalid_arg, "get parameter failed");
188 SLOGD("SetForwardTime with time %{public}jd", static_cast<int64_t>(time));
189
190 napi_value property {};
191 auto status = NapiUtils::SetValue(env, time, property);
192 if (status != napi_ok) {
193 SLOGE("create ForwardTime property failed");
194 return status;
195 }
196
197 status = napi_set_named_property(env, out, "parameter", property);
198 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "set parameter property failed");
199 return status;
200 }
201
GetRewindTime(napi_env env,napi_value in,AVControlCommand & out)202 napi_status NapiControlCommand::GetRewindTime(napi_env env, napi_value in, AVControlCommand& out)
203 {
204 int64_t time {};
205 auto status = NapiUtils::GetNamedProperty(env, in, "parameter", time);
206 if (status != napi_ok) {
207 SLOGI("get RewindTime parameter failed but set default");
208 time = AVMetaData::SECONDS_15;
209 status = napi_ok;
210 }
211
212 SLOGD("GetRewindTime with time %{public}jd", static_cast<int64_t>(time));
213 CHECK_AND_RETURN_RET_LOG(out.SetRewindTime(time) == AVSESSION_SUCCESS, napi_invalid_arg, "set parameter failed");
214 return status;
215 }
216
SetRewindTime(napi_env env,AVControlCommand & in,napi_value & out)217 napi_status NapiControlCommand::SetRewindTime(napi_env env, AVControlCommand& in, napi_value& out)
218 {
219 int64_t time {};
220 CHECK_AND_RETURN_RET_LOG(in.GetRewindTime(time) == AVSESSION_SUCCESS, napi_invalid_arg, "get parameter failed");
221 SLOGD("SetRewindTime with time %{public}jd", static_cast<int64_t>(time));
222
223 napi_value property {};
224 auto status = NapiUtils::SetValue(env, time, property);
225 if (status != napi_ok) {
226 SLOGE("create RewindTime property failed");
227 return status;
228 }
229
230 status = napi_set_named_property(env, out, "parameter", property);
231 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "set parameter property failed");
232 return status;
233 }
234
GetSeekTime(napi_env env,napi_value in,AVControlCommand & out)235 napi_status NapiControlCommand::GetSeekTime(napi_env env, napi_value in, AVControlCommand& out)
236 {
237 int64_t time {};
238 auto status = NapiUtils::GetNamedProperty(env, in, "parameter", time);
239 if (status != napi_ok) {
240 SLOGE("get parameter failed");
241 return status;
242 }
243
244 CHECK_AND_RETURN_RET_LOG(out.SetSeekTime(time) == AVSESSION_SUCCESS, napi_invalid_arg, "set parameter failed");
245 return status;
246 }
247
SetSeekTime(napi_env env,AVControlCommand & in,napi_value & out)248 napi_status NapiControlCommand::SetSeekTime(napi_env env, AVControlCommand& in, napi_value& out)
249 {
250 int64_t time {};
251 CHECK_AND_RETURN_RET_LOG(in.GetSeekTime(time) == AVSESSION_SUCCESS, napi_invalid_arg, "get parameter failed");
252
253 napi_value property {};
254 auto status = NapiUtils::SetValue(env, time, property);
255 if (status != napi_ok) {
256 SLOGE("create speed property failed");
257 return status;
258 }
259
260 status = napi_set_named_property(env, out, "parameter", property);
261 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "set parameter property failed");
262 return status;
263 }
264
GetLoopMode(napi_env env,napi_value in,AVControlCommand & out)265 napi_status NapiControlCommand::GetLoopMode(napi_env env, napi_value in, AVControlCommand& out)
266 {
267 int32_t loopMode {};
268 auto status = NapiUtils::GetNamedProperty(env, in, "parameter", loopMode);
269 if (status != napi_ok) {
270 SLOGE("get parameter failed");
271 loopMode = AVPlaybackState::LOOP_MODE_UNDEFINED;
272 }
273
274 CHECK_AND_RETURN_RET_LOG(out.SetLoopMode(loopMode) == AVSESSION_SUCCESS, napi_invalid_arg, "set parameter failed");
275 return status;
276 }
277
SetLoopMode(napi_env env,AVControlCommand & in,napi_value & out)278 napi_status NapiControlCommand::SetLoopMode(napi_env env, AVControlCommand& in, napi_value& out)
279 {
280 int32_t loopMode {};
281 CHECK_AND_RETURN_RET_LOG(in.GetLoopMode(loopMode) == AVSESSION_SUCCESS, napi_invalid_arg, "get parameter failed");
282
283 napi_value property {};
284 auto status = NapiUtils::SetValue(env, loopMode, property);
285 if (status != napi_ok) {
286 SLOGE("create speed property failed");
287 return status;
288 }
289
290 status = napi_set_named_property(env, out, "parameter", property);
291 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "set parameter property failed");
292 return status;
293 }
294
GetTargetLoopMode(napi_env env,napi_value in,AVControlCommand & out)295 napi_status NapiControlCommand::GetTargetLoopMode(napi_env env, napi_value in, AVControlCommand& out)
296 {
297 int32_t targetLoopMode {};
298 auto status = NapiUtils::GetNamedProperty(env, in, "parameter", targetLoopMode);
299 if (status != napi_ok) {
300 SLOGE("get parameter failed");
301 targetLoopMode = AVPlaybackState::LOOP_MODE_UNDEFINED;
302 }
303
304 CHECK_AND_RETURN_RET_LOG(out.SetTargetLoopMode(targetLoopMode) == AVSESSION_SUCCESS,
305 napi_invalid_arg, "set parameter failed");
306 return status;
307 }
308
SetTargetLoopMode(napi_env env,AVControlCommand & in,napi_value & out)309 napi_status NapiControlCommand::SetTargetLoopMode(napi_env env, AVControlCommand& in, napi_value& out)
310 {
311 int32_t targetLoopMode {};
312 CHECK_AND_RETURN_RET_LOG(in.GetTargetLoopMode(targetLoopMode) == AVSESSION_SUCCESS,
313 napi_invalid_arg, "get parameter failed");
314
315 napi_value property {};
316 auto status = NapiUtils::SetValue(env, targetLoopMode, property);
317 if (status != napi_ok) {
318 SLOGE("create speed property failed");
319 return status;
320 }
321
322 status = napi_set_named_property(env, out, "parameter", property);
323 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "set parameter property failed");
324 return status;
325 }
326
GetAssetId(napi_env env,napi_value in,AVControlCommand & out)327 napi_status NapiControlCommand::GetAssetId(napi_env env, napi_value in, AVControlCommand& out)
328 {
329 std::string assetId;
330 auto status = NapiUtils::GetNamedProperty(env, in, "parameter", assetId);
331 if (status != napi_ok) {
332 SLOGE("get parameter failed");
333 return status;
334 }
335
336 CHECK_AND_RETURN_RET_LOG(out.SetAssetId(assetId) == AVSESSION_SUCCESS, napi_invalid_arg, "set parameter failed");
337 return status;
338 }
339
SetAssetId(napi_env env,AVControlCommand & in,napi_value & out)340 napi_status NapiControlCommand::SetAssetId(napi_env env, AVControlCommand& in, napi_value& out)
341 {
342 std::string assetId;
343 CHECK_AND_RETURN_RET_LOG(in.GetAssetId(assetId) == AVSESSION_SUCCESS, napi_invalid_arg, "get parameter failed");
344
345 napi_value property {};
346 auto status = NapiUtils::SetValue(env, assetId, property);
347 if (status != napi_ok) {
348 SLOGE("create speed property failed");
349 return status;
350 }
351
352 status = napi_set_named_property(env, out, "parameter", property);
353 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "set parameter property failed");
354 return status;
355 }
356
GetPlayFromAssetId(napi_env env,napi_value in,AVControlCommand & out)357 napi_status NapiControlCommand::GetPlayFromAssetId(napi_env env, napi_value in, AVControlCommand& out)
358 {
359 int64_t playFromAssetId {};
360 auto status = NapiUtils::GetNamedProperty(env, in, "parameter", playFromAssetId);
361 if (status != napi_ok) {
362 SLOGE("get parameter failed");
363 playFromAssetId = 0;
364 status = napi_ok;
365 }
366
367 CHECK_AND_RETURN_RET_LOG(out.SetPlayFromAssetId(playFromAssetId) == AVSESSION_SUCCESS,
368 napi_invalid_arg, "set parameter failed");
369 return status;
370 }
371
SetPlayFromAssetId(napi_env env,AVControlCommand & in,napi_value & out)372 napi_status NapiControlCommand::SetPlayFromAssetId(napi_env env, AVControlCommand& in, napi_value& out)
373 {
374 int64_t playFromAssetId {};
375 CHECK_AND_RETURN_RET_LOG(in.GetPlayFromAssetId(playFromAssetId) == AVSESSION_SUCCESS,
376 napi_invalid_arg, "get parameter failed");
377
378 napi_value property {};
379 auto status = NapiUtils::SetValue(env, playFromAssetId, property);
380 if (status != napi_ok) {
381 SLOGE("create playFromAssetId property failed");
382 return status;
383 }
384
385 status = napi_set_named_property(env, out, "parameter", property);
386 CHECK_AND_RETURN_RET_LOG(status == napi_ok, status, "set parameter property failed");
387 return status;
388 }
389 }
390