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