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:%{public}d, shadowInfoy:%{public}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:%{public}d, displayY:%{public}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)83 int32_t DragClient::AddDraglistener(ITunnelClient &tunnel, DragListenerPtr listener)
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         DefaultParam param {};
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)107 int32_t DragClient::RemoveDraglistener(ITunnelClient &tunnel, DragListenerPtr listener)
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         DefaultParam param {};
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)189 int32_t DragClient::UpdateDragStyle(ITunnelClient &tunnel, DragCursorStyle style)
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 };
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:%{public}d, shadowInfoy:%{public}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)332 int32_t DragClient::GetDragSummary(ITunnelClient &tunnel, std::map<std::string, int64_t> &summary)
333 {
334     DefaultParam param {};
335     GetDragSummaryReply reply {};
336 
337     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_DRAG_SUMMARY, param, reply);
338     if (ret != RET_OK) {
339         FI_HILOGE("ITunnelClient::GetParam fail");
340         return ret;
341     }
342     summary.swap(reply.summary_);
343     return RET_OK;
344 }
345 
GetDragState(ITunnelClient & tunnel,DragState & dragState)346 int32_t DragClient::GetDragState(ITunnelClient &tunnel, DragState &dragState)
347 {
348     DefaultParam param {};
349     GetDragStateReply reply {};
350 
351     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_DRAG_STATE, param, reply);
352     if (ret != RET_OK) {
353         FI_HILOGE("ITunnelClient::GetParam fail");
354         return ret;
355     }
356     dragState = reply.dragState_;
357     return RET_OK;
358 }
359 
EnterTextEditorArea(ITunnelClient & tunnel,bool enable)360 int32_t DragClient::EnterTextEditorArea(ITunnelClient &tunnel, bool enable)
361 {
362     EnterTextEditorAreaParam param { enable };
363     DefaultReply reply {};
364 
365     int32_t ret = tunnel.Control(Intention::DRAG, DragRequestID::ENTER_TEXT_EDITOR_AREA, param, reply);
366     if (ret != RET_OK) {
367         FI_HILOGE("ITunnelClient::Control fail");
368     }
369     return ret;
370 }
371 
GetDragAction(ITunnelClient & tunnel,DragAction & dragAction)372 int32_t DragClient::GetDragAction(ITunnelClient &tunnel, DragAction &dragAction)
373 {
374     DefaultParam param {};
375     GetDragActionReply reply {};
376 
377     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_DRAG_ACTION, param, reply);
378     if (ret != RET_OK) {
379         FI_HILOGE("ITunnelClient::GetParam fail");
380         return ret;
381     }
382     dragAction = reply.dragAction_;
383     return RET_OK;
384 }
385 
GetExtraInfo(ITunnelClient & tunnel,std::string & extraInfo)386 int32_t DragClient::GetExtraInfo(ITunnelClient &tunnel, std::string &extraInfo)
387 {
388     DefaultParam param {};
389     GetExtraInfoReply reply {};
390 
391     int32_t ret = tunnel.GetParam(Intention::DRAG, DragRequestID::GET_EXTRA_INFO, param, reply);
392     if (ret != RET_OK) {
393         FI_HILOGE("ITunnelClient::GetParam fail");
394         return ret;
395     }
396     extraInfo = std::move(reply.extraInfo_);
397     return RET_OK;
398 }
399 
AddPrivilege(ITunnelClient & tunnel)400 int32_t DragClient::AddPrivilege(ITunnelClient &tunnel)
401 {
402     DefaultParam param {};
403     DefaultReply reply {};
404 
405     int32_t ret = tunnel.Control(Intention::DRAG, DragRequestID::ADD_PRIVILEGE, param, reply);
406     if (ret != RET_OK) {
407         FI_HILOGE("ITunnelClient::Control fail");
408     }
409     return ret;
410 }
411 
EraseMouseIcon(ITunnelClient & tunnel)412 int32_t DragClient::EraseMouseIcon(ITunnelClient &tunnel)
413 {
414     DefaultParam param {};
415     DefaultReply reply {};
416 
417     int32_t ret = tunnel.Control(Intention::DRAG, DragRequestID::ERASE_MOUSE_ICON, param, reply);
418     if (ret != RET_OK) {
419         FI_HILOGE("ITunnelClient::Control fail");
420     }
421     return ret;
422 }
423 
AddSelectedPixelMap(ITunnelClient & tunnel,std::shared_ptr<OHOS::Media::PixelMap> pixelMap,std::function<void (bool)> callback)424 int32_t DragClient::AddSelectedPixelMap(ITunnelClient &tunnel, std::shared_ptr<OHOS::Media::PixelMap> pixelMap,
425     std::function<void(bool)> callback)
426 {
427     CALL_DEBUG_ENTER;
428     CHKPR(pixelMap, RET_ERR);
429     CHKPR(callback, RET_ERR);
430     std::lock_guard<std::mutex> guard(mtx_);
431     addSelectedPixelMapCallback_ = callback;
432     AddSelectedPixelMapParam param { pixelMap };
433     DefaultReply reply {};
434 
435     int32_t ret = tunnel.SetParam(Intention::DRAG, DragRequestID::ADD_SELECTED_PIXELMAP, param, reply);
436     if (ret != RET_OK) {
437         FI_HILOGE("ITunnelClient::SetParam fail");
438     }
439     return ret;
440 }
441 
OnAddSelectedPixelMapResult(const StreamClient & client,NetPacket & pkt)442 int32_t DragClient::OnAddSelectedPixelMapResult(const StreamClient &client, NetPacket &pkt)
443 {
444     CALL_DEBUG_ENTER;
445     bool result = false;
446 
447     pkt >> result;
448     if (pkt.ChkRWError()) {
449         FI_HILOGE("Packet read addSelectedPixelMap msg failed");
450         return RET_ERR;
451     }
452     std::lock_guard<std::mutex> guard(mtx_);
453     CHKPR(addSelectedPixelMapCallback_, RET_ERR);
454     addSelectedPixelMapCallback_(result);
455     return RET_OK;
456 }
457 
OnNotifyResult(const StreamClient & client,NetPacket & pkt)458 int32_t DragClient::OnNotifyResult(const StreamClient &client, NetPacket &pkt)
459 {
460     CALL_DEBUG_ENTER;
461     DragNotifyMsg notifyMsg;
462     int32_t result = 0;
463     int32_t dragBehavior = -1;
464     pkt >> notifyMsg.displayX >> notifyMsg.displayY >> result >> notifyMsg.targetPid >> dragBehavior;
465     if (pkt.ChkRWError()) {
466         FI_HILOGE("Packet read drag msg failed");
467         return RET_ERR;
468     }
469     if ((result < static_cast<int32_t>(DragResult::DRAG_SUCCESS)) ||
470         (result > static_cast<int32_t>(DragResult::DRAG_EXCEPTION))) {
471         FI_HILOGE("Invalid result:%{public}d", result);
472         return RET_ERR;
473     }
474     notifyMsg.result = static_cast<DragResult>(result);
475     if ((dragBehavior < static_cast<int32_t>(DragBehavior::UNKNOWN)) ||
476         (dragBehavior > static_cast<int32_t>(DragBehavior::MOVE))) {
477         FI_HILOGE("Invalid dragBehavior:%{public}d", dragBehavior);
478         return RET_ERR;
479     }
480     notifyMsg.dragBehavior = static_cast<DragBehavior>(dragBehavior);
481     std::lock_guard<std::mutex> guard(mtx_);
482     CHKPR(startDragListener_, RET_ERR);
483     startDragListener_->OnDragEndMessage(notifyMsg);
484     return RET_OK;
485 }
486 
OnNotifyHideIcon(const StreamClient & client,NetPacket & pkt)487 int32_t DragClient::OnNotifyHideIcon(const StreamClient& client, NetPacket& pkt)
488 {
489     CALL_DEBUG_ENTER;
490     std::lock_guard<std::mutex> guard(mtx_);
491     CHKPR(startDragListener_, RET_ERR);
492     startDragListener_->OnHideIconMessage();
493     return RET_OK;
494 }
495 
OnStateChangedMessage(const StreamClient & client,NetPacket & pkt)496 int32_t DragClient::OnStateChangedMessage(const StreamClient &client, NetPacket &pkt)
497 {
498     CALL_DEBUG_ENTER;
499     int32_t state = 0;
500     pkt >> state;
501     if (pkt.ChkRWError()) {
502         FI_HILOGE("Packet read drag msg failed");
503         return RET_ERR;
504     }
505     std::lock_guard<std::mutex> guard(mtx_);
506     for (const auto &listener : dragListeners_) {
507         listener->OnDragMessage(static_cast<DragState>(state));
508     }
509     return RET_OK;
510 }
511 
OnDragStyleChangedMessage(const StreamClient & client,NetPacket & pkt)512 int32_t DragClient::OnDragStyleChangedMessage(const StreamClient &client, NetPacket &pkt)
513 {
514     CALL_DEBUG_ENTER;
515     int32_t style = 0;
516     pkt >> style;
517     if (pkt.ChkRWError()) {
518         FI_HILOGE("Packet read drag msg failed");
519         return RET_ERR;
520     }
521     std::lock_guard<std::mutex> guard(mtx_);
522     for (const auto &listener : subscriptListeners_) {
523         listener->OnMessage(static_cast<DragCursorStyle>(style));
524     }
525     return RET_OK;
526 }
527 } // namespace DeviceStatus
528 } // namespace Msdp
529 } // namespace OHOS
530