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 "drag_client.h"
17 
18 #include "default_params.h"
19 #include "drag_params.h"
20 #include "devicestatus_define.h"
21 #include "proto.h"
22 
23 #undef LOG_TAG
24 #define LOG_TAG "DragClient"
25 
26 namespace OHOS {
27 namespace Msdp {
28 namespace DeviceStatus {
29 
StartDrag(ITunnelClient & tunnel,const DragData & dragData,std::shared_ptr<IStartDragListener> listener)30 int32_t DragClient::StartDrag(ITunnelClient &tunnel,
31     const DragData &dragData, std::shared_ptr<IStartDragListener> listener)
32 {
33     CALL_DEBUG_ENTER;
34     CHKPR(listener, RET_ERR);
35     if (dragData.shadowInfos.empty()) {
36         FI_HILOGE("shadowInfos is empty");
37         return ERR_INVALID_VALUE;
38     }
39     for (const auto& shadowInfo : dragData.shadowInfos) {
40         CHKPR(shadowInfo.pixelMap, RET_ERR);
41         if ((shadowInfo.x > 0) || (shadowInfo.y > 0) ||
42             (shadowInfo.x < -shadowInfo.pixelMap->GetWidth()) ||
43             (shadowInfo.y < -shadowInfo.pixelMap->GetHeight())) {
44             FI_HILOGE("Invalid parameter, shadowInfox:%{private}d, shadowInfoy:%{private}d",
45                 shadowInfo.x, shadowInfo.y);
46             return RET_ERR;
47         }
48     }
49     if ((dragData.dragNum <= 0) || (dragData.buffer.size() > MAX_BUFFER_SIZE) ||
50         (dragData.displayX < 0) || (dragData.displayY < 0)) {
51         FI_HILOGE("Start drag, invalid argument, dragNum:%{public}d, bufferSize:%{public}zu, "
52             "displayX:%{private}d, displayY:%{private}d",
53             dragData.dragNum, dragData.buffer.size(), dragData.displayX, dragData.displayY);
54         return RET_ERR;
55     }
56     {
57         std::lock_guard<std::mutex> guard(mtx_);
58         startDragListener_ = listener;
59     }
60     StartDragParam param { dragData };
61     DefaultReply reply {};
62 
63     int32_t ret = tunnel.Start(Intention::DRAG, param, reply);
64     if (ret != RET_OK) {
65         FI_HILOGE("ITunnelClient::Start fail");
66     }
67     return ret;
68 }
69 
StopDrag(ITunnelClient & tunnel,const DragDropResult & dropResult)70 int32_t DragClient::StopDrag(ITunnelClient &tunnel, const DragDropResult &dropResult)
71 {
72     CALL_DEBUG_ENTER;
73     StopDragParam param { dropResult };
74     DefaultReply reply;
75 
76     int32_t ret = tunnel.Stop(Intention::DRAG, param, reply);
77     if (ret != RET_OK) {
78         FI_HILOGE("ITunnelClient::Start fail");
79     }
80     return ret;
81 }
82 
AddDraglistener(ITunnelClient & tunnel,DragListenerPtr listener,bool isJsCaller)83 int32_t DragClient::AddDraglistener(ITunnelClient &tunnel, DragListenerPtr listener, bool isJsCaller)
84 {
85     CALL_DEBUG_ENTER;
86     CHKPR(listener, RET_ERR);
87     std::lock_guard<std::mutex> guard(mtx_);
88     if (dragListeners_.find(listener) != dragListeners_.end()) {
89         return RET_OK;
90     }
91     if (!hasRegistered_) {
92         AddDraglistenerParam param { isJsCaller };
93         DefaultReply reply {};
94         FI_HILOGI("Start drag listening");
95 
96         int32_t ret = tunnel.AddWatch(Intention::DRAG, DragRequestID::ADD_DRAG_LISTENER, param, reply);
97         if (ret != RET_OK) {
98             FI_HILOGE("ITunnelClient::AddWatch fail");
99             return ret;
100         }
101         hasRegistered_ = true;
102     }
103     dragListeners_.insert(listener);
104     return RET_OK;
105 }
106 
RemoveDraglistener(ITunnelClient & tunnel,DragListenerPtr listener,bool isJsCaller)107 int32_t DragClient::RemoveDraglistener(ITunnelClient &tunnel, DragListenerPtr listener, bool isJsCaller)
108 {
109     CALL_DEBUG_ENTER;
110     std::lock_guard<std::mutex> guard(mtx_);
111     if (listener == nullptr) {
112         dragListeners_.clear();
113     } else {
114         dragListeners_.erase(listener);
115     }
116     if (hasRegistered_ && dragListeners_.empty()) {
117         hasRegistered_ = false;
118         RemoveDraglistenerParam param { isJsCaller };
119         DefaultReply reply {};
120         FI_HILOGI("Stop drag listening");
121 
122         int32_t ret = tunnel.RemoveWatch(Intention::DRAG, DragRequestID::REMOVE_DRAG_LISTENER, param, reply);
123         if (ret != RET_OK) {
124             FI_HILOGE("ITunnelClient::RemoveWatch fail");
125             return ret;
126         }
127     }
128     return RET_OK;
129 }
130 
AddSubscriptListener(ITunnelClient & tunnel,SubscriptListenerPtr listener)131 int32_t DragClient::AddSubscriptListener(ITunnelClient &tunnel, SubscriptListenerPtr listener)
132 {
133     CHKPR(listener, RET_ERR);
134     std::lock_guard<std::mutex> guard(mtx_);
135     if (subscriptListeners_.find(listener) != subscriptListeners_.end()) {
136         return RET_OK;
137     }
138     if (!hasSubscriptRegistered_) {
139         DefaultParam param {};
140         DefaultReply reply {};
141         FI_HILOGI("Start subscript listening");
142 
143         int32_t ret = tunnel.AddWatch(Intention::DRAG, DragRequestID::ADD_SUBSCRIPT_LISTENER, param, reply);
144         if (ret != RET_OK) {
145             FI_HILOGE("ITunnelClient::AddWatch fail");
146             return ret;
147         }
148         hasSubscriptRegistered_ = true;
149     }
150     subscriptListeners_.insert(listener);
151     return RET_OK;
152 }
153 
RemoveSubscriptListener(ITunnelClient & tunnel,SubscriptListenerPtr listener)154 int32_t DragClient::RemoveSubscriptListener(ITunnelClient &tunnel, SubscriptListenerPtr listener)
155 {
156     std::lock_guard<std::mutex> guard(mtx_);
157     if (listener == nullptr) {
158         subscriptListeners_.clear();
159     } else {
160         subscriptListeners_.erase(listener);
161     }
162     if (hasSubscriptRegistered_ && subscriptListeners_.empty()) {
163         hasSubscriptRegistered_ = false;
164         DefaultParam param {};
165         DefaultReply reply {};
166         FI_HILOGI("Stop subscript listening");
167 
168         int32_t ret = tunnel.RemoveWatch(Intention::DRAG, DragRequestID::REMOVE_SUBSCRIPT_LISTENER, param, reply);
169         if (ret != RET_OK) {
170             FI_HILOGE("ITunnelClient::RemoveWatch fail");
171             return ret;
172         }
173     }
174     return RET_OK;
175 }
176 
SetDragWindowVisible(ITunnelClient & tunnel,bool visible,bool isForce)177 int32_t DragClient::SetDragWindowVisible(ITunnelClient &tunnel, bool visible, bool isForce)
178 {
179     SetDragWindowVisibleParam param { visible, isForce };
180     DefaultReply reply {};
181 
182     int32_t ret = tunnel.SetParam(Intention::DRAG, DragRequestID::SET_DRAG_WINDOW_VISIBLE, param, reply);
183     if (ret != RET_OK) {
184         FI_HILOGE("ITunnelClient::SetParam fail");
185     }
186     return ret;
187 }
188 
UpdateDragStyle(ITunnelClient & tunnel,DragCursorStyle style,int32_t eventId)189 int32_t DragClient::UpdateDragStyle(ITunnelClient &tunnel, DragCursorStyle style, int32_t eventId)
190 {
191     if ((style < DragCursorStyle::DEFAULT) || (style > DragCursorStyle::MOVE)) {
192         FI_HILOGE("Invalid style:%{public}d", static_cast<int32_t>(style));
193         return RET_ERR;
194     }
195     UpdateDragStyleParam param { style, eventId };
196     DefaultReply reply {};
197 
198     int32_t ret = tunnel.SetParam(Intention::DRAG, DragRequestID::UPDATE_DRAG_STYLE, param, reply);
199     if (ret != RET_OK) {
200         FI_HILOGE("ITunnelClient::SetParam fail");
201     }
202     return ret;
203 }
204 
UpdateShadowPic(ITunnelClient & tunnel,const ShadowInfo & shadowInfo)205 int32_t DragClient::UpdateShadowPic(ITunnelClient &tunnel, const ShadowInfo &shadowInfo)
206 {
207     CALL_DEBUG_ENTER;
208     CHKPR(shadowInfo.pixelMap, RET_ERR);
209     if ((shadowInfo.x > 0) || (shadowInfo.y > 0) ||
210         (shadowInfo.x < -shadowInfo.pixelMap->GetWidth()) ||
211         (shadowInfo.y < -shadowInfo.pixelMap->GetHeight())) {
212         FI_HILOGE("Invalid parameter, shadowInfox:%{private}d, shadowInfoy:%{private}d",
213             shadowInfo.x, shadowInfo.y);
214         return RET_ERR;
215     }
216     UpdateShadowPicParam param { shadowInfo };
217     DefaultReply reply {};
218 
219     int32_t ret = tunnel.SetParam(Intention::DRAG, DragRequestID::UPDATE_SHADOW_PIC, param, reply);
220     if (ret != RET_OK) {
221         FI_HILOGE("ITunnelClient::SetParam fail");
222     }
223     return ret;
224 }
225 
GetDragTargetPid(ITunnelClient & tunnel)226 int32_t DragClient::GetDragTargetPid(ITunnelClient &tunnel)
227 {
228     CALL_DEBUG_ENTER;
229     DefaultParam param {};
230     GetDragTargetPidReply reply {};
231 
232     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_DRAG_TARGET_PID, param, reply);
233     if (ret != RET_OK) {
234         FI_HILOGE("ITunnelClient::GetParam fail");
235         return -1;
236     }
237     return reply.targetPid_;
238 }
239 
GetUdKey(ITunnelClient & tunnel,std::string & udKey)240 int32_t DragClient::GetUdKey(ITunnelClient &tunnel, std::string &udKey)
241 {
242     DefaultParam param {};
243     GetUdKeyReply reply {};
244 
245     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_UDKEY, param, reply);
246     if (ret != RET_OK) {
247         FI_HILOGE("ITunnelClient::GetParam fail");
248         return ret;
249     }
250     udKey = reply.udKey_;
251     FI_HILOGI("UdKey:%{public}s", reply.udKey_.c_str());
252     return RET_OK;
253 }
254 
GetShadowOffset(ITunnelClient & tunnel,ShadowOffset & shadowOffset)255 int32_t DragClient::GetShadowOffset(ITunnelClient &tunnel, ShadowOffset &shadowOffset)
256 {
257     DefaultParam param {};
258     GetShadowOffsetReply reply {};
259 
260     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_SHADOW_OFFSET, param, reply);
261     if (ret != RET_OK) {
262         FI_HILOGE("ITunnelClient::GetParam fail");
263         return ret;
264     }
265     shadowOffset = reply.shadowOffset_;
266     return RET_OK;
267 }
268 
GetDragData(ITunnelClient & tunnel,DragData & dragData)269 int32_t DragClient::GetDragData(ITunnelClient &tunnel, DragData &dragData)
270 {
271     CALL_DEBUG_ENTER;
272     DefaultParam param {};
273     GetDragDataReply reply { dragData };
274 
275     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_DRAG_DATA, param, reply);
276     if (ret != RET_OK) {
277         FI_HILOGE("ITunnelClient::GetParam fail");
278     }
279     return ret;
280 }
281 
UpdatePreviewStyle(ITunnelClient & tunnel,const PreviewStyle & previewStyle)282 int32_t DragClient::UpdatePreviewStyle(ITunnelClient &tunnel, const PreviewStyle &previewStyle)
283 {
284     UpdatePreviewStyleParam param { previewStyle };
285     DefaultReply reply {};
286 
287     int32_t ret = tunnel.SetParam(Intention::DRAG, DragRequestID::UPDATE_PREVIEW_STYLE, param, reply);
288     if (ret != RET_OK) {
289         FI_HILOGE("ITunnelClient::SetParam fail");
290     }
291     return ret;
292 }
293 
UpdatePreviewStyleWithAnimation(ITunnelClient & tunnel,const PreviewStyle & previewStyle,const PreviewAnimation & animation)294 int32_t DragClient::UpdatePreviewStyleWithAnimation(ITunnelClient &tunnel,
295     const PreviewStyle &previewStyle, const PreviewAnimation &animation)
296 {
297     UpdatePreviewAnimationParam param { previewStyle, animation };
298     DefaultReply reply {};
299 
300     int32_t ret = tunnel.SetParam(Intention::DRAG, DragRequestID::UPDATE_PREVIEW_STYLE_WITH_ANIMATION, param, reply);
301     if (ret != RET_OK) {
302         FI_HILOGE("ITunnelClient::SetParam fail");
303     }
304     return ret;
305 }
306 
RotateDragWindowSync(ITunnelClient & tunnel,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)307 int32_t DragClient::RotateDragWindowSync(ITunnelClient &tunnel,
308     const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
309 {
310     RotateDragWindowSyncParam param { rsTransaction };
311     DefaultReply reply {};
312 
313     int32_t ret = tunnel.Control(Intention::DRAG, DragRequestID::ROTATE_DRAG_WINDOW_SYNC, param, reply);
314     if (ret != RET_OK) {
315         FI_HILOGE("ITunnelClient::Control fail");
316     }
317     return ret;
318 }
319 
SetDragWindowScreenId(ITunnelClient & tunnel,uint64_t displayId,uint64_t screenId)320 int32_t DragClient::SetDragWindowScreenId(ITunnelClient &tunnel, uint64_t displayId, uint64_t screenId)
321 {
322     SetDragWindowScreenIdParam param { displayId, screenId };
323     DefaultReply reply {};
324 
325     int32_t ret = tunnel.SetParam(Intention::DRAG, DragRequestID::SET_DRAG_WINDOW_SCREEN_ID, param, reply);
326     if (ret != RET_OK) {
327         FI_HILOGE("ITunnelClient::SetParam fail");
328     }
329     return ret;
330 }
331 
GetDragSummary(ITunnelClient & tunnel,std::map<std::string,int64_t> & summary,bool isJsCaller)332 int32_t DragClient::GetDragSummary(ITunnelClient &tunnel, std::map<std::string, int64_t> &summary,
333     bool isJsCaller)
334 {
335     GetDragSummaryParam param { isJsCaller };
336     GetDragSummaryReply reply {};
337 
338     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_DRAG_SUMMARY, param, reply);
339     if (ret != RET_OK) {
340         FI_HILOGE("ITunnelClient::GetParam fail");
341         return ret;
342     }
343     summary.swap(reply.summary_);
344     return RET_OK;
345 }
346 
GetDragState(ITunnelClient & tunnel,DragState & dragState)347 int32_t DragClient::GetDragState(ITunnelClient &tunnel, DragState &dragState)
348 {
349     DefaultParam param {};
350     GetDragStateReply reply {};
351 
352     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_DRAG_STATE, param, reply);
353     if (ret != RET_OK) {
354         FI_HILOGE("ITunnelClient::GetParam fail");
355         return ret;
356     }
357     dragState = reply.dragState_;
358     return RET_OK;
359 }
360 
EnableUpperCenterMode(ITunnelClient & tunnel,bool enable)361 int32_t DragClient::EnableUpperCenterMode(ITunnelClient &tunnel, bool enable)
362 {
363     EnterTextEditorAreaParam param { enable };
364     DefaultReply reply {};
365 
366     int32_t ret = tunnel.Control(Intention::DRAG, DragRequestID::ENTER_TEXT_EDITOR_AREA, param, reply);
367     if (ret != RET_OK) {
368         FI_HILOGE("ITunnelClient::Control fail");
369     }
370     return ret;
371 }
372 
GetDragAction(ITunnelClient & tunnel,DragAction & dragAction)373 int32_t DragClient::GetDragAction(ITunnelClient &tunnel, DragAction &dragAction)
374 {
375     DefaultParam param {};
376     GetDragActionReply reply {};
377 
378     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_DRAG_ACTION, param, reply);
379     if (ret != RET_OK) {
380         FI_HILOGE("ITunnelClient::GetParam fail");
381         return ret;
382     }
383     dragAction = reply.dragAction_;
384     return RET_OK;
385 }
386 
GetExtraInfo(ITunnelClient & tunnel,std::string & extraInfo)387 int32_t DragClient::GetExtraInfo(ITunnelClient &tunnel, std::string &extraInfo)
388 {
389     DefaultParam param {};
390     GetExtraInfoReply reply {};
391 
392     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_EXTRA_INFO, param, reply);
393     if (ret != RET_OK) {
394         FI_HILOGE("ITunnelClient::GetParam fail");
395         return ret;
396     }
397     extraInfo = std::move(reply.extraInfo_);
398     return RET_OK;
399 }
400 
AddPrivilege(ITunnelClient & tunnel)401 int32_t DragClient::AddPrivilege(ITunnelClient &tunnel)
402 {
403     DefaultParam param {};
404     DefaultReply reply {};
405 
406     int32_t ret = tunnel.Control(Intention::DRAG, DragRequestID::ADD_PRIVILEGE, param, reply);
407     if (ret != RET_OK) {
408         FI_HILOGE("ITunnelClient::Control fail");
409     }
410     return ret;
411 }
412 
EraseMouseIcon(ITunnelClient & tunnel)413 int32_t DragClient::EraseMouseIcon(ITunnelClient &tunnel)
414 {
415     DefaultParam param {};
416     DefaultReply reply {};
417 
418     int32_t ret = tunnel.Control(Intention::DRAG, DragRequestID::ERASE_MOUSE_ICON, param, reply);
419     if (ret != RET_OK) {
420         FI_HILOGE("ITunnelClient::Control fail");
421     }
422     return ret;
423 }
424 
SetMouseDragMonitorState(ITunnelClient & tunnel,bool state)425 int32_t DragClient::SetMouseDragMonitorState(ITunnelClient &tunnel, bool state)
426 {
427     SetMouseDragMonitorStateParam param { state };
428     DefaultReply reply {};
429 
430     int32_t ret = tunnel.Control(Intention::DRAG, DragRequestID::SET_MOUSE_DRAG_MONITOR_STATE, param, reply);
431     if (ret != RET_OK) {
432         FI_HILOGE("ITunnelClient::Control fail");
433     }
434     return ret;
435 }
436 
OnNotifyResult(const StreamClient & client,NetPacket & pkt)437 int32_t DragClient::OnNotifyResult(const StreamClient &client, NetPacket &pkt)
438 {
439     CALL_DEBUG_ENTER;
440     DragNotifyMsg notifyMsg;
441     int32_t result = 0;
442     int32_t dragBehavior = -1;
443     pkt >> notifyMsg.displayX >> notifyMsg.displayY >> result >> notifyMsg.targetPid >> dragBehavior;
444     if (pkt.ChkRWError()) {
445         FI_HILOGE("Packet read drag msg failed");
446         return RET_ERR;
447     }
448     if ((result < static_cast<int32_t>(DragResult::DRAG_SUCCESS)) ||
449         (result > static_cast<int32_t>(DragResult::DRAG_EXCEPTION))) {
450         FI_HILOGE("Invalid result:%{public}d", result);
451         return RET_ERR;
452     }
453     notifyMsg.result = static_cast<DragResult>(result);
454     if ((dragBehavior < static_cast<int32_t>(DragBehavior::UNKNOWN)) ||
455         (dragBehavior > static_cast<int32_t>(DragBehavior::MOVE))) {
456         FI_HILOGE("Invalid dragBehavior:%{public}d", dragBehavior);
457         return RET_ERR;
458     }
459     notifyMsg.dragBehavior = static_cast<DragBehavior>(dragBehavior);
460     std::lock_guard<std::mutex> guard(mtx_);
461     CHKPR(startDragListener_, RET_ERR);
462     startDragListener_->OnDragEndMessage(notifyMsg);
463     return RET_OK;
464 }
465 
OnNotifyHideIcon(const StreamClient & client,NetPacket & pkt)466 int32_t DragClient::OnNotifyHideIcon(const StreamClient& client, NetPacket& pkt)
467 {
468     CALL_DEBUG_ENTER;
469     std::lock_guard<std::mutex> guard(mtx_);
470     CHKPR(startDragListener_, RET_ERR);
471     startDragListener_->OnHideIconMessage();
472     return RET_OK;
473 }
474 
OnStateChangedMessage(const StreamClient & client,NetPacket & pkt)475 int32_t DragClient::OnStateChangedMessage(const StreamClient &client, NetPacket &pkt)
476 {
477     CALL_DEBUG_ENTER;
478     int32_t state = 0;
479     pkt >> state;
480     if (pkt.ChkRWError()) {
481         FI_HILOGE("Packet read drag msg failed");
482         return RET_ERR;
483     }
484     std::lock_guard<std::mutex> guard(mtx_);
485     for (const auto &listener : dragListeners_) {
486         listener->OnDragMessage(static_cast<DragState>(state));
487     }
488     return RET_OK;
489 }
490 
OnDragStyleChangedMessage(const StreamClient & client,NetPacket & pkt)491 int32_t DragClient::OnDragStyleChangedMessage(const StreamClient &client, NetPacket &pkt)
492 {
493     CALL_DEBUG_ENTER;
494     int32_t style = 0;
495     pkt >> style;
496     if (pkt.ChkRWError()) {
497         FI_HILOGE("Packet read drag msg failed");
498         return RET_ERR;
499     }
500     std::lock_guard<std::mutex> guard(mtx_);
501     for (const auto &listener : subscriptListeners_) {
502         listener->OnMessage(static_cast<DragCursorStyle>(style));
503     }
504     return RET_OK;
505 }
506 
OnConnected(ITunnelClient & tunnel)507 void DragClient::OnConnected(ITunnelClient &tunnel)
508 {
509     CALL_INFO_TRACE;
510     if (connectedDragListeners_.empty()) {
511         FI_HILOGE("The connect drag listener set is empty");
512         return;
513     }
514     for (const auto &listener : connectedDragListeners_) {
515         if (AddDraglistener(tunnel, listener) != RET_OK) {
516             FI_HILOGW("AddDraglistener failed");
517         }
518     }
519     connectedDragListeners_.clear();
520 }
521 
OnDisconnected(ITunnelClient & tunnel)522 void DragClient::OnDisconnected(ITunnelClient &tunnel)
523 {
524     CALL_INFO_TRACE;
525     std::lock_guard<std::mutex> guard(mtx_);
526     if (dragListeners_.empty()) {
527         FI_HILOGE("The drag listener set is empty");
528         return;
529     }
530     connectedDragListeners_ = dragListeners_;
531     dragListeners_.clear();
532     hasRegistered_ = false;
533 }
534 } // namespace DeviceStatus
535 } // namespace Msdp
536 } // namespace OHOS
537