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