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