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