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