1 /*
2 * Copyright (c) 2024 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 "hot_area.h"
17 #include "devicestatus_define.h"
18
19 #undef LOG_TAG
20 #define LOG_TAG "HotArea"
21
22 namespace OHOS {
23 namespace Msdp {
24 namespace DeviceStatus {
25 namespace Cooperate {
26 namespace {
27 constexpr int32_t HOT_AREA_WIDTH { 100 };
28 constexpr int32_t HOT_AREA_MARGIN { 200 };
29 }; // namespace
30
AddListener(const RegisterHotareaListenerEvent & event)31 void HotArea::AddListener(const RegisterHotareaListenerEvent &event)
32 {
33 CALL_DEBUG_ENTER;
34 std::lock_guard guard(lock_);
35 HotAreaInfo info {
36 .pid = event.pid,
37 .msgId = MessageId::HOT_AREA_ADD_LISTENER,
38 };
39 auto [iter, isOk] = callbacks_.emplace(info);
40 if (!isOk) {
41 callbacks_.erase(iter);
42 callbacks_.emplace(info);
43 }
44 }
45
RemoveListener(const UnregisterHotareaListenerEvent & event)46 void HotArea::RemoveListener(const UnregisterHotareaListenerEvent &event)
47 {
48 CALL_DEBUG_ENTER;
49 std::lock_guard guard(lock_);
50 callbacks_.erase(HotAreaInfo { .pid = event.pid });
51 }
52
EnableCooperate(const EnableCooperateEvent & event)53 void HotArea::EnableCooperate(const EnableCooperateEvent &event)
54 {
55 CALL_DEBUG_ENTER;
56 std::lock_guard guard(lock_);
57 auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
58 CHKPV(display);
59 width_ = display->GetWidth();
60 height_ = display->GetHeight();
61 }
62
ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)63 int32_t HotArea::ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)
64 {
65 CALL_DEBUG_ENTER;
66 std::lock_guard guard(lock_);
67 CHKPR(pointerEvent, RET_ERR);
68 MMI::PointerEvent::PointerItem pointerItem;
69 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
70 FI_HILOGE("Corrupted pointer event");
71 return RET_ERR;
72 }
73 displayX_ = pointerItem.GetDisplayX();
74 displayY_ = pointerItem.GetDisplayY();
75 deltaX_ = pointerItem.GetRawDx();
76 deltaY_ = pointerItem.GetRawDy();
77 CheckInHotArea();
78 CheckPointerToEdge(type_);
79 NotifyMessage();
80 return RET_OK;
81 }
82
CheckInHotArea()83 void HotArea::CheckInHotArea()
84 {
85 CALL_DEBUG_ENTER;
86 if (displayX_ <= HOT_AREA_WIDTH && displayY_ >= HOT_AREA_MARGIN &&
87 displayY_ <= (height_ - HOT_AREA_MARGIN)) {
88 type_ = HotAreaType::AREA_LEFT;
89 } else if (displayX_ >= (width_ - HOT_AREA_WIDTH) && displayY_ >= HOT_AREA_MARGIN &&
90 displayY_ <= (height_ - HOT_AREA_MARGIN)) {
91 type_ = HotAreaType::AREA_RIGHT;
92 } else if (displayY_ <= HOT_AREA_WIDTH && displayX_ >= HOT_AREA_MARGIN &&
93 displayX_ <= (width_ - HOT_AREA_MARGIN)) {
94 type_ = HotAreaType::AREA_TOP;
95 } else if (displayY_ >= (height_ - HOT_AREA_WIDTH) && displayX_ >= HOT_AREA_MARGIN &&
96 displayX_ <= (width_ - HOT_AREA_MARGIN)) {
97 type_ = HotAreaType::AREA_BOTTOM;
98 } else {
99 type_ = HotAreaType::AREA_NONE;
100 }
101 }
102
CheckPointerToEdge(HotAreaType type)103 void HotArea::CheckPointerToEdge(HotAreaType type)
104 {
105 CALL_DEBUG_ENTER;
106 if (type == HotAreaType::AREA_LEFT) {
107 isEdge_ = displayX_ <= 0 && deltaX_ < 0;
108 } else if (type == HotAreaType::AREA_RIGHT) {
109 isEdge_ = displayX_ >= (width_ - 1) && deltaX_ > 0;
110 } else if (type == HotAreaType::AREA_TOP) {
111 isEdge_ = displayY_ <= 0 && deltaY_ < 0;
112 } else if (type == HotAreaType::AREA_BOTTOM) {
113 isEdge_ = displayY_ >= (height_ - 1) && deltaY_ > 0;
114 } else {
115 isEdge_ = false;
116 }
117 }
118
NotifyMessage()119 void HotArea::NotifyMessage()
120 {
121 CALL_DEBUG_ENTER;
122 OnHotAreaMessage(type_, isEdge_);
123 }
124
OnHotAreaMessage(HotAreaType msg,bool isEdge)125 void HotArea::OnHotAreaMessage(HotAreaType msg, bool isEdge)
126 {
127 CALL_DEBUG_ENTER;
128 for (const auto &callback : callbacks_) {
129 NotifyHotAreaMessage(callback.pid, callback.msgId, msg, isEdge);
130 }
131 }
132
OnClientDied(const ClientDiedEvent & event)133 void HotArea::OnClientDied(const ClientDiedEvent &event)
134 {
135 FI_HILOGI("Remove client died listener, pid: %{public}d", event.pid);
136 callbacks_.erase(HotAreaInfo { .pid = event.pid });
137 }
138
NotifyHotAreaMessage(int32_t pid,MessageId msgId,HotAreaType msg,bool isEdge)139 void HotArea::NotifyHotAreaMessage(int32_t pid, MessageId msgId, HotAreaType msg, bool isEdge)
140 {
141 CALL_DEBUG_ENTER;
142 CHKPV(env_);
143 auto session = env_->GetSocketSessionManager().FindSessionByPid(pid);
144 CHKPV(session);
145 NetPacket pkt(msgId);
146
147 pkt << displayX_ << displayY_ << static_cast<int32_t>(msg) << isEdge;
148 if (pkt.ChkRWError()) {
149 FI_HILOGE("Packet write data failed");
150 return;
151 }
152 if (!session->SendMsg(pkt)) {
153 FI_HILOGE("Sending failed");
154 return;
155 }
156 }
157 } // namespace Cooperate
158 } // namespace DeviceStatus
159 } // namespace Msdp
160 } // namespace OHOS