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