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 "avcast_controller_proxy.h"
17 #include "avcast_controller_callback_client.h"
18 #include "avsession_errors.h"
19 #include "avsession_log.h"
20 #include "avsession_trace.h"
21 #include "media_info_holder.h"
22 #include "surface_utils.h"
23
24 namespace OHOS::AVSession {
AVCastControllerProxy(const sptr<IRemoteObject>& impl)25 AVCastControllerProxy::AVCastControllerProxy(const sptr<IRemoteObject>& impl)
26 : IRemoteProxy<IAVCastController>(impl)
27 {
28 SLOGD("AVCastControllerProxy construct");
29 }
30
~AVCastControllerProxy()31 AVCastControllerProxy::~AVCastControllerProxy()
32 {
33 SLOGI("AVCastControllerProxy destroy");
34 Destroy();
35 }
36
SendControlCommand(const AVCastControlCommand& cmd)37 int32_t AVCastControllerProxy::SendControlCommand(const AVCastControlCommand& cmd)
38 {
39 AVSESSION_TRACE_SYNC_START("AVCastControllerProxy::SendControlCommand");
40 CHECK_AND_RETURN_RET_LOG(!isDestroy_, ERR_CONTROLLER_NOT_EXIST, "controller is destroy");
41 CHECK_AND_RETURN_RET_LOG(cmd.IsValid(), ERR_COMMAND_NOT_SUPPORT, "command not valid");
42 MessageParcel parcel;
43 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()), ERR_MARSHALLING,
44 "write interface token failed");
45 CHECK_AND_RETURN_RET_LOG(parcel.WriteParcelable(&cmd), ERR_MARSHALLING, "write cmd failed");
46
47 auto remote = Remote();
48 CHECK_AND_RETURN_RET_LOG(remote != nullptr, ERR_SERVICE_NOT_EXIST, "get remote service failed");
49 MessageParcel reply;
50 MessageOption option;
51 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_SEND_CONTROL_COMMAND, parcel, reply, option) == 0,
52 ERR_IPC_SEND_REQUEST, "send request failed");
53
54 int32_t ret = AVSESSION_ERROR;
55 return reply.ReadInt32(ret) ? ret : AVSESSION_ERROR;
56 }
57
Start(const AVQueueItem& avQueueItem)58 int32_t AVCastControllerProxy::Start(const AVQueueItem& avQueueItem)
59 {
60 CHECK_AND_RETURN_RET_LOG(!isDestroy_, ERR_CONTROLLER_NOT_EXIST, "controller is destroy");
61 MessageParcel parcel;
62 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()), ERR_MARSHALLING,
63 "write interface token failed");
64 CHECK_AND_RETURN_RET_LOG(parcel.WriteParcelable(&avQueueItem), ERR_UNMARSHALLING, "Write avQueueItem failed");
65 CHECK_AND_RETURN_RET_LOG(parcel.WriteFileDescriptor(avQueueItem.GetDescription()->GetFdSrc().fd_),
66 ERR_UNMARSHALLING, "Write avQueueItem failed");
67 SLOGI("Start received fd %{public}d", avQueueItem.GetDescription()->GetFdSrc().fd_);
68
69 auto remote = Remote();
70 CHECK_AND_RETURN_RET_LOG(remote != nullptr, ERR_SERVICE_NOT_EXIST, "get remote service failed");
71 MessageParcel reply;
72 MessageOption option;
73 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_START, parcel, reply, option) == 0,
74 ERR_IPC_SEND_REQUEST, "send request failed");
75 int32_t ret = AVSESSION_ERROR;
76 return reply.ReadInt32(ret) ? ret : AVSESSION_ERROR;
77 }
78
Prepare(const AVQueueItem& avQueueItem)79 int32_t AVCastControllerProxy::Prepare(const AVQueueItem& avQueueItem)
80 {
81 CHECK_AND_RETURN_RET_LOG(!isDestroy_, ERR_CONTROLLER_NOT_EXIST, "controller is destroy");
82 MessageParcel parcel;
83 parcel.SetMaxCapacity(defaultIpcCapacity);
84 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()), ERR_MARSHALLING,
85 "write interface token failed");
86 CHECK_AND_RETURN_RET_LOG(parcel.WriteParcelable(&avQueueItem), ERR_UNMARSHALLING, "Write avQueueItem failed");
87 if (avQueueItem.GetDescription()->GetFdSrc().fd_ == 0) {
88 parcel.WriteBool(false);
89 } else {
90 parcel.WriteBool(true);
91 CHECK_AND_RETURN_RET_LOG(parcel.WriteFileDescriptor(avQueueItem.GetDescription()->GetFdSrc().fd_),
92 ERR_UNMARSHALLING, "Write avQueueItem failed");
93 }
94 SLOGI("Prepare received fd %{public}d", avQueueItem.GetDescription()->GetFdSrc().fd_);
95
96 auto remote = Remote();
97 CHECK_AND_RETURN_RET_LOG(remote != nullptr, ERR_SERVICE_NOT_EXIST, "get remote service failed");
98 MessageParcel reply;
99 MessageOption option;
100 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_PREPARE, parcel, reply, option) == 0,
101 ERR_IPC_SEND_REQUEST, "send request failed");
102 int32_t ret = AVSESSION_ERROR;
103 return reply.ReadInt32(ret) ? ret : AVSESSION_ERROR;
104 }
105
GetDuration(int32_t& duration)106 int32_t AVCastControllerProxy::GetDuration(int32_t& duration)
107 {
108 MessageParcel parcel;
109 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()), ERR_MARSHALLING,
110 "write interface token failed");
111
112 auto remote = Remote();
113 CHECK_AND_RETURN_RET_LOG(remote != nullptr, ERR_SERVICE_NOT_EXIST, "get remote service failed");
114 MessageParcel reply;
115 MessageOption option;
116 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_GET_DURATION, parcel, reply, option) == 0,
117 ERR_IPC_SEND_REQUEST, "send request failed");
118
119 int32_t ret = AVSESSION_ERROR;
120 CHECK_AND_RETURN_RET_LOG(reply.ReadInt32(ret), ERR_UNMARSHALLING, "read int32 failed");
121 if (ret == AVSESSION_SUCCESS) {
122 int32_t tempDuration;
123 CHECK_AND_RETURN_RET_LOG(reply.ReadInt32(tempDuration), ERR_UNMARSHALLING, "read string failed");
124 duration = tempDuration;
125 }
126 return ret;
127 }
128
GetCastAVPlaybackState(AVPlaybackState& state)129 int32_t AVCastControllerProxy::GetCastAVPlaybackState(AVPlaybackState& state)
130 {
131 MessageParcel parcel;
132 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()),
133 AVSESSION_ERROR, "write interface token failed");
134
135 auto remote = Remote();
136 CHECK_AND_RETURN_RET_LOG(remote != nullptr, AVSESSION_ERROR, "get remote service failed");
137 MessageParcel reply;
138 MessageOption option;
139 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_GET_CAST_AV_PLAYBACK_STATE, parcel,
140 reply, option) == 0, AVSESSION_ERROR, "send request failed");
141
142 int32_t ret = AVSESSION_ERROR;
143 CHECK_AND_RETURN_RET_LOG(reply.ReadInt32(ret), ERR_UNMARSHALLING, "read int32 failed");
144 if (ret == AVSESSION_SUCCESS) {
145 sptr<AVPlaybackState> state_ = reply.ReadParcelable<AVPlaybackState>();
146 CHECK_AND_RETURN_RET_LOG(state_ != nullptr, ERR_UNMARSHALLING, "read AVPlaybackState failed");
147 state = *state_;
148 }
149 return ret;
150 }
151
GetCurrentItem(AVQueueItem& currentItem)152 int32_t AVCastControllerProxy::GetCurrentItem(AVQueueItem& currentItem)
153 {
154 MessageParcel parcel;
155 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()),
156 AVSESSION_ERROR, "write interface token failed");
157
158 auto remote = Remote();
159 CHECK_AND_RETURN_RET_LOG(remote != nullptr, AVSESSION_ERROR, "get remote service failed");
160 MessageParcel reply;
161 reply.SetMaxCapacity(defaultIpcCapacity);
162 MessageOption option;
163 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_GET_CURRENT_ITEM, parcel,
164 reply, option) == 0, AVSESSION_ERROR, "send request failed");
165
166 int32_t ret = AVSESSION_ERROR;
167 CHECK_AND_RETURN_RET_LOG(reply.ReadInt32(ret), ERR_UNMARSHALLING, "read int32 failed");
168 if (ret == AVSESSION_SUCCESS) {
169 sptr<AVQueueItem> currentItem_ = reply.ReadParcelable<AVQueueItem>();
170 CHECK_AND_RETURN_RET_LOG(currentItem_ != nullptr, ERR_UNMARSHALLING, "read AVQueueItem failed");
171 currentItem = *currentItem_;
172 }
173 return ret;
174 }
175
GetValidCommands(std::vector<int32_t>& cmds)176 int32_t AVCastControllerProxy::GetValidCommands(std::vector<int32_t>& cmds)
177 {
178 CHECK_AND_RETURN_RET_LOG(!isDestroy_, ERR_CONTROLLER_NOT_EXIST, "controller is destroy");
179 MessageParcel parcel;
180 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()),
181 ERR_MARSHALLING, "write interface token failed");
182
183 auto remote = Remote();
184 CHECK_AND_RETURN_RET_LOG(remote != nullptr, AVSESSION_ERROR, "get remote service failed");
185 MessageParcel reply;
186 MessageOption option;
187 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_GET_VALID_COMMANDS, parcel,
188 reply, option) == 0, AVSESSION_ERROR, "send request failed");
189
190 int32_t ret = AVSESSION_ERROR;
191 CHECK_AND_RETURN_RET_LOG(reply.ReadInt32(ret), ERR_UNMARSHALLING, "read int32 failed");
192 if (ret == AVSESSION_SUCCESS) {
193 CHECK_AND_RETURN_RET_LOG(reply.ReadInt32Vector(&cmds), ERR_UNMARSHALLING, "read int32 vector failed");
194 }
195 return ret;
196 }
197
SetDisplaySurface(std::string& surfaceId)198 int32_t AVCastControllerProxy::SetDisplaySurface(std::string& surfaceId)
199 {
200 AVSESSION_TRACE_SYNC_START("AVCastControllerProxy::SetDisplaySurface");
201 errno = 0;
202 uint64_t surfaceUniqueId = static_cast<uint64_t>(std::strtoll(surfaceId.c_str(), nullptr, 10));
203 if (errno == ERANGE) {
204 return ERR_INVALID_PARAM;
205 }
206
207 sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(surfaceUniqueId);
208 if (!surface) {
209 SLOGE("surface is null, surface uniqueId %{public}lu", surfaceUniqueId);
210 return AVSESSION_ERROR;
211 }
212 sptr<IBufferProducer> producer = surface->GetProducer();
213 if (!producer) {
214 SLOGE("producer is null");
215 return AVSESSION_ERROR;
216 }
217
218 MessageParcel parcel;
219 MessageParcel reply;
220 MessageOption option;
221
222 if (!parcel.WriteInterfaceToken(GetDescriptor())) {
223 SLOGE("Failed to write the interface token");
224 return AVSESSION_ERROR;
225 }
226 if (!parcel.WriteRemoteObject(producer->AsObject())) {
227 SLOGE("Failed to write surface producer");
228 return AVSESSION_ERROR;
229 }
230 auto remote = Remote();
231 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_SET_DISPLAY_SURFACE, parcel, reply, option) == 0,
232 ERR_IPC_SEND_REQUEST, "send request failed");
233
234 int32_t ret = AVSESSION_ERROR;
235 return reply.ReadInt32(ret) ? ret : AVSESSION_ERROR;
236 }
237
ProcessMediaKeyResponse(const std::string& assetId, const std::vector<uint8_t>& response)238 int32_t AVCastControllerProxy::ProcessMediaKeyResponse(const std::string& assetId, const std::vector<uint8_t>& response)
239 {
240 AVSESSION_TRACE_SYNC_START("AVCastControllerProxy::ProcessMediaKeyResponse");
241 MessageParcel parcel;
242 MessageParcel reply;
243 MessageOption option;
244 auto len = response.size();
245 if (len > parcel.GetDataCapacity()) {
246 SLOGD("ProcessMediaKeyResponse SetDataCapacity totalSize: %lu", len);
247 parcel.SetMaxCapacity(len + len);
248 parcel.SetDataCapacity(len);
249 }
250
251 if (!parcel.WriteInterfaceToken(GetDescriptor())) {
252 SLOGE("Failed to write the interface token");
253 return AVSESSION_ERROR;
254 }
255 if (!parcel.WriteString(assetId)) {
256 SLOGE("Failed to write assetId");
257 return AVSESSION_ERROR;
258 }
259
260 if (!parcel.WriteInt32(response.size())) {
261 SLOGE("Failed to write response size");
262 return AVSESSION_ERROR;
263 }
264 if (len != 0) {
265 if (!parcel.WriteBuffer(response.data(), len)) {
266 SLOGE("AVCastControllerProxy ProcessMediaKeyResponse write response failed");
267 return IPC_PROXY_ERR;
268 }
269 }
270
271 auto remote = Remote();
272 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_PROVIDE_KEY_RESPONSE, parcel, reply, option) == 0,
273 ERR_IPC_SEND_REQUEST, "send request failed");
274
275 int32_t ret = AVSESSION_ERROR;
276 return reply.ReadInt32(ret) ? ret : AVSESSION_ERROR;
277 }
278
SetCastPlaybackFilter(const AVPlaybackState::PlaybackStateMaskType& filter)279 int32_t AVCastControllerProxy::SetCastPlaybackFilter(const AVPlaybackState::PlaybackStateMaskType& filter)
280 {
281 CHECK_AND_RETURN_RET_LOG(!isDestroy_, ERR_CONTROLLER_NOT_EXIST, "controller is destroy");
282 MessageParcel parcel;
283 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()), ERR_MARSHALLING,
284 "write interface token failed");
285 CHECK_AND_RETURN_RET_LOG(parcel.WriteString(filter.to_string()), ERR_MARSHALLING, "write filter failed");
286
287 auto remote = Remote();
288 CHECK_AND_RETURN_RET_LOG(remote != nullptr, ERR_SERVICE_NOT_EXIST, "get remote service failed");
289 MessageParcel reply;
290 MessageOption option;
291 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_SET_CAST_PLAYBACK_FILTER, parcel, reply,
292 option) == 0, ERR_IPC_SEND_REQUEST, "send request failed");
293
294 int32_t ret = AVSESSION_ERROR;
295 return reply.ReadInt32(ret) ? ret : AVSESSION_ERROR;
296 }
297
AddAvailableCommand(const int32_t cmd)298 int32_t AVCastControllerProxy::AddAvailableCommand(const int32_t cmd)
299 {
300 SLOGI("add available command in");
301 CHECK_AND_RETURN_RET_LOG(!isDestroy_, ERR_CONTROLLER_NOT_EXIST, "controller is destroy");
302 CHECK_AND_RETURN_RET_LOG(cmd > AVCastControlCommand::CAST_CONTROL_CMD_INVALID, AVSESSION_ERROR, "invalid cmd");
303 CHECK_AND_RETURN_RET_LOG(cmd < AVCastControlCommand::CAST_CONTROL_CMD_MAX, AVSESSION_ERROR, "invalid cmd");
304 MessageParcel parcel;
305 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()), ERR_MARSHALLING,
306 "write interface token failed");
307 CHECK_AND_RETURN_RET_LOG(parcel.WriteInt32(cmd),
308 ERR_MARSHALLING, "write valid command failed");
309
310 auto remote = Remote();
311 CHECK_AND_RETURN_RET_LOG(remote != nullptr, AVSESSION_ERROR, "get remote service failed");
312 MessageParcel reply;
313 MessageOption option;
314 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_ADD_AVAILABLE_COMMAND, parcel,
315 reply, option) == 0, AVSESSION_ERROR, "send request failed");
316
317 int32_t ret = AVSESSION_ERROR;
318 return reply.ReadInt32(ret) ? ret : AVSESSION_ERROR;
319 }
320
RemoveAvailableCommand(const int32_t cmd)321 int32_t AVCastControllerProxy::RemoveAvailableCommand(const int32_t cmd)
322 {
323 SLOGI("remove available command in");
324 CHECK_AND_RETURN_RET_LOG(!isDestroy_, ERR_CONTROLLER_NOT_EXIST, "controller is destroy");
325 CHECK_AND_RETURN_RET_LOG(cmd > AVCastControlCommand::CAST_CONTROL_CMD_INVALID, AVSESSION_ERROR, "invalid cmd");
326 CHECK_AND_RETURN_RET_LOG(cmd < AVCastControlCommand::CAST_CONTROL_CMD_MAX, AVSESSION_ERROR, "invalid cmd");
327 MessageParcel parcel;
328 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()), ERR_MARSHALLING,
329 "write interface token failed");
330 CHECK_AND_RETURN_RET_LOG(parcel.WriteInt32(cmd),
331 ERR_MARSHALLING, "write valid command failed");
332
333 auto remote = Remote();
334 CHECK_AND_RETURN_RET_LOG(remote != nullptr, AVSESSION_ERROR, "get remote service failed");
335 MessageParcel reply;
336 MessageOption option;
337 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_REMOVE_AVAILABLE_COMMAND, parcel,
338 reply, option) == 0, AVSESSION_ERROR, "send request failed");
339
340 int32_t ret = AVSESSION_ERROR;
341 return reply.ReadInt32(ret) ? ret : AVSESSION_ERROR;
342 }
343
RegisterCallback(const std::shared_ptr<AVCastControllerCallback>& callback)344 int32_t AVCastControllerProxy::RegisterCallback(const std::shared_ptr<AVCastControllerCallback>& callback)
345 {
346 CHECK_AND_RETURN_RET_LOG(!isDestroy_, ERR_CONTROLLER_NOT_EXIST, "controller is destroy");
347
348 sptr<AVCastControllerCallbackClient> callback_;
349 callback_ = new(std::nothrow) AVCastControllerCallbackClient(callback);
350 CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, ERR_NO_MEMORY, "new AVCastControllerCallbackClient failed");
351
352 return RegisterCallbackInner(callback_);
353 }
354
RegisterCallbackInner(const sptr<IRemoteObject>& callback)355 int32_t AVCastControllerProxy::RegisterCallbackInner(const sptr<IRemoteObject>& callback)
356 {
357 MessageParcel parcel;
358 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()), ERR_MARSHALLING,
359 "write interface token failed");
360 CHECK_AND_RETURN_RET_LOG(parcel.WriteRemoteObject(callback), ERR_MARSHALLING,
361 "write remote object failed");
362
363 auto remote = Remote();
364 CHECK_AND_RETURN_RET_LOG(remote != nullptr, ERR_SERVICE_NOT_EXIST, "get remote service failed");
365 MessageParcel reply;
366 MessageOption option;
367 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_REGISTER_CALLBACK, parcel, reply, option) == 0,
368 ERR_IPC_SEND_REQUEST, "send request failed");
369
370 int32_t ret = AVSESSION_ERROR;
371 return reply.ReadInt32(ret) ? ret : AVSESSION_ERROR;
372 }
373
Destroy()374 int32_t AVCastControllerProxy::Destroy()
375 {
376 CHECK_AND_RETURN_RET_LOG(!isDestroy_, ERR_CONTROLLER_NOT_EXIST, "controller is destroy");
377 MessageParcel parcel;
378 CHECK_AND_RETURN_RET_LOG(parcel.WriteInterfaceToken(GetDescriptor()), ERR_MARSHALLING,
379 "write interface token failed");
380
381 auto remote = Remote();
382 CHECK_AND_RETURN_RET_LOG(remote != nullptr, ERR_SERVICE_NOT_EXIST, "get remote service failed");
383 MessageParcel reply;
384 MessageOption option;
385 CHECK_AND_RETURN_RET_LOG(remote->SendRequest(CAST_CONTROLLER_CMD_DESTROY, parcel, reply, option) == 0,
386 ERR_IPC_SEND_REQUEST, "send request failed");
387 isDestroy_ = true;
388
389 int32_t ret = AVSESSION_ERROR;
390 return reply.ReadInt32(ret) ? ret : AVSESSION_ERROR;
391 }
392 }
393