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 26namespace OHOS { 27namespace Msdp { 28namespace DeviceStatus { 29 30int32_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 70int32_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 83int32_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 107int32_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 131int32_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 154int32_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 177int32_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 189int32_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 205int32_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 226int32_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 240int32_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 255int32_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 269int32_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 282int32_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 294int32_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 307int32_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 320int32_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 332int32_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 347int32_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 361int32_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 373int32_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 387int32_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 401int32_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 413int32_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 425int32_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 437int32_t DragClient::AddSelectedPixelMap(ITunnelClient &tunnel, std::shared_ptr<OHOS::Media::PixelMap> pixelMap, 438 std::function<void(bool)> callback) 439{ 440 CALL_DEBUG_ENTER; 441 CHKPR(pixelMap, RET_ERR); 442 CHKPR(callback, RET_ERR); 443 std::lock_guard<std::mutex> guard(mtx_); 444 addSelectedPixelMapCallback_ = callback; 445 AddSelectedPixelMapParam param { pixelMap }; 446 DefaultReply reply {}; 447 448 int32_t ret = tunnel.SetParam(Intention::DRAG, DragRequestID::ADD_SELECTED_PIXELMAP, param, reply); 449 if (ret != RET_OK) { 450 FI_HILOGE("ITunnelClient::SetParam fail"); 451 } 452 return ret; 453} 454 455int32_t DragClient::OnAddSelectedPixelMapResult(const StreamClient &client, NetPacket &pkt) 456{ 457 CALL_DEBUG_ENTER; 458 bool result = false; 459 460 pkt >> result; 461 if (pkt.ChkRWError()) { 462 FI_HILOGE("Packet read addSelectedPixelMap msg failed"); 463 return RET_ERR; 464 } 465 std::lock_guard<std::mutex> guard(mtx_); 466 CHKPR(addSelectedPixelMapCallback_, RET_ERR); 467 addSelectedPixelMapCallback_(result); 468 return RET_OK; 469} 470 471int32_t DragClient::OnNotifyResult(const StreamClient &client, NetPacket &pkt) 472{ 473 CALL_DEBUG_ENTER; 474 DragNotifyMsg notifyMsg; 475 int32_t result = 0; 476 int32_t dragBehavior = -1; 477 pkt >> notifyMsg.displayX >> notifyMsg.displayY >> result >> notifyMsg.targetPid >> dragBehavior; 478 if (pkt.ChkRWError()) { 479 FI_HILOGE("Packet read drag msg failed"); 480 return RET_ERR; 481 } 482 if ((result < static_cast<int32_t>(DragResult::DRAG_SUCCESS)) || 483 (result > static_cast<int32_t>(DragResult::DRAG_EXCEPTION))) { 484 FI_HILOGE("Invalid result:%{public}d", result); 485 return RET_ERR; 486 } 487 notifyMsg.result = static_cast<DragResult>(result); 488 if ((dragBehavior < static_cast<int32_t>(DragBehavior::UNKNOWN)) || 489 (dragBehavior > static_cast<int32_t>(DragBehavior::MOVE))) { 490 FI_HILOGE("Invalid dragBehavior:%{public}d", dragBehavior); 491 return RET_ERR; 492 } 493 notifyMsg.dragBehavior = static_cast<DragBehavior>(dragBehavior); 494 std::lock_guard<std::mutex> guard(mtx_); 495 CHKPR(startDragListener_, RET_ERR); 496 startDragListener_->OnDragEndMessage(notifyMsg); 497 return RET_OK; 498} 499 500int32_t DragClient::OnNotifyHideIcon(const StreamClient& client, NetPacket& pkt) 501{ 502 CALL_DEBUG_ENTER; 503 std::lock_guard<std::mutex> guard(mtx_); 504 CHKPR(startDragListener_, RET_ERR); 505 startDragListener_->OnHideIconMessage(); 506 return RET_OK; 507} 508 509int32_t DragClient::OnStateChangedMessage(const StreamClient &client, NetPacket &pkt) 510{ 511 CALL_DEBUG_ENTER; 512 int32_t state = 0; 513 pkt >> state; 514 if (pkt.ChkRWError()) { 515 FI_HILOGE("Packet read drag msg failed"); 516 return RET_ERR; 517 } 518 std::lock_guard<std::mutex> guard(mtx_); 519 for (const auto &listener : dragListeners_) { 520 listener->OnDragMessage(static_cast<DragState>(state)); 521 } 522 return RET_OK; 523} 524 525int32_t DragClient::OnDragStyleChangedMessage(const StreamClient &client, NetPacket &pkt) 526{ 527 CALL_DEBUG_ENTER; 528 int32_t style = 0; 529 pkt >> style; 530 if (pkt.ChkRWError()) { 531 FI_HILOGE("Packet read drag msg failed"); 532 return RET_ERR; 533 } 534 std::lock_guard<std::mutex> guard(mtx_); 535 for (const auto &listener : subscriptListeners_) { 536 listener->OnMessage(static_cast<DragCursorStyle>(style)); 537 } 538 return RET_OK; 539} 540 541void DragClient::OnConnected(ITunnelClient &tunnel) 542{ 543 CALL_INFO_TRACE; 544 if (connectedDragListeners_.empty()) { 545 FI_HILOGE("The connect drag listener set is empty"); 546 return; 547 } 548 for (const auto &listener : connectedDragListeners_) { 549 if (AddDraglistener(tunnel, listener) != RET_OK) { 550 FI_HILOGW("AddDraglistener failed"); 551 } 552 } 553 connectedDragListeners_.clear(); 554} 555 556void DragClient::OnDisconnected(ITunnelClient &tunnel) 557{ 558 CALL_INFO_TRACE; 559 std::lock_guard<std::mutex> guard(mtx_); 560 if (dragListeners_.empty()) { 561 FI_HILOGE("The drag listener set is empty"); 562 return; 563 } 564 connectedDragListeners_ = dragListeners_; 565 dragListeners_.clear(); 566 hasRegistered_ = false; 567} 568} // namespace DeviceStatus 569} // namespace Msdp 570} // namespace OHOS 571