• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "coordination_hotarea.h"
17 
18 #include "coordination_sm.h"
19 #include "fi_log.h"
20 
21 namespace OHOS {
22 namespace Msdp {
23 namespace DeviceStatus {
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "CoordinationHotArea" };
26 std::shared_ptr<CoordinationHotArea> g_instance = nullptr;
27 constexpr int32_t HOT_AREA_WIDTH { 100 };
28 constexpr int32_t HOT_AREA_MARGIN { 200 };
29 }; // namespace
30 
GetInstance()31 std::shared_ptr<CoordinationHotArea> CoordinationHotArea::GetInstance()
32 {
33     static std::once_flag flag;
34     std::call_once(flag, [&]() {
35         g_instance.reset(new (std::nothrow) CoordinationHotArea());
36     });
37     return g_instance;
38 }
39 
AddHotAreaListener(sptr<HotAreaInfo> event)40 void CoordinationHotArea::AddHotAreaListener(sptr<HotAreaInfo> event)
41 {
42     CALL_DEBUG_ENTER;
43     CHKPV(event);
44     auto it = std::find_if(hotAreaCallbacks_.begin(), hotAreaCallbacks_.end(),
45         [event](auto info) {
46             return (*info).sess == event->sess;
47         });
48     if (it != hotAreaCallbacks_.end()) {
49         *it = event;
50         return;
51     }
52     hotAreaCallbacks_.emplace_back(event);
53 }
54 
RemoveHotAreaListener(sptr<HotAreaInfo> event)55 void CoordinationHotArea::RemoveHotAreaListener(sptr<HotAreaInfo> event)
56 {
57     CALL_DEBUG_ENTER;
58     if (hotAreaCallbacks_.empty() || event == nullptr) {
59         FI_HILOGE("Failed to remove hot area listener");
60         return;
61     }
62     for (auto it = hotAreaCallbacks_.begin(); it != hotAreaCallbacks_.end(); ++it) {
63         if ((*it)->sess == event->sess) {
64             hotAreaCallbacks_.erase(it);
65             return;
66         }
67     }
68 }
69 
OnHotAreaMessage(HotAreaType msg,bool isEdge)70 int32_t CoordinationHotArea::OnHotAreaMessage(HotAreaType msg, bool isEdge)
71 {
72     CALL_DEBUG_ENTER;
73     if (hotAreaCallbacks_.empty()) {
74         FI_HILOGW("Failed to invoke the listening interface, hotAreaCallbacks_ is empty");
75         return RET_ERR;
76     }
77     for (auto it = hotAreaCallbacks_.begin(); it != hotAreaCallbacks_.end(); ++it) {
78         sptr<HotAreaInfo> info = *it;
79         CHKPC(info);
80         NotifyHotAreaMessage(info->sess, info->msgId, msg, isEdge);
81     }
82     return RET_OK;
83 }
84 
ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)85 int32_t CoordinationHotArea::ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)
86 {
87     CALL_DEBUG_ENTER;
88     if (hotAreaCallbacks_.empty()) {
89         return RET_ERR;
90     }
91     CHKPR(pointerEvent, RET_ERR);
92     MMI::PointerEvent::PointerItem pointerItem;
93     pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem);
94     displayX_ = pointerItem.GetDisplayX();
95     displayY_ = pointerItem.GetDisplayY();
96     deltaX_ = pointerItem.GetRawDx();
97     deltaY_ = pointerItem.GetRawDy();
98     CheckInHotArea();
99     CheckPointerToEdge(type_);
100     NotifyMessage();
101     return RET_OK;
102 }
103 
CheckInHotArea()104 void CoordinationHotArea::CheckInHotArea()
105 {
106     CALL_DEBUG_ENTER;
107     if (displayX_ <= HOT_AREA_WIDTH && displayY_ >= HOT_AREA_MARGIN &&
108         displayY_ <= (height_ - HOT_AREA_MARGIN)) {
109         type_ = HotAreaType::AREA_LEFT;
110     } else if (displayX_ >= (width_ - HOT_AREA_WIDTH) && displayY_ >= HOT_AREA_MARGIN &&
111         displayY_ <= (height_ - HOT_AREA_MARGIN)) {
112         type_ = HotAreaType::AREA_RIGHT;
113     } else if (displayY_ <= HOT_AREA_WIDTH && displayX_ >= HOT_AREA_MARGIN &&
114         displayX_ <= (width_ - HOT_AREA_MARGIN)) {
115         type_ = HotAreaType::AREA_TOP;
116     } else if (displayY_ >= (height_ - HOT_AREA_WIDTH) && displayX_ >= HOT_AREA_MARGIN &&
117         displayX_ <= (width_ - HOT_AREA_MARGIN)) {
118         type_ = HotAreaType::AREA_BOTTOM;
119     } else {
120         type_ = HotAreaType::AREA_NONE;
121     }
122 }
123 
CheckPointerToEdge(HotAreaType type)124 void CoordinationHotArea::CheckPointerToEdge(HotAreaType type)
125 {
126     CALL_DEBUG_ENTER;
127     if (type == HotAreaType::AREA_LEFT) {
128         isEdge_ = displayX_ <= 0 && deltaX_ < 0;
129     } else if (type == HotAreaType::AREA_RIGHT) {
130         isEdge_ = displayX_ >= (width_ - 1) && deltaX_ > 0;
131     } else if (type == HotAreaType::AREA_TOP) {
132         isEdge_ = displayY_ <= 0 && deltaY_ < 0;
133     } else if (type == HotAreaType::AREA_BOTTOM) {
134         isEdge_ = displayY_ >= (height_ - 1) && deltaY_ > 0;
135     } else {
136         isEdge_ = false;
137     }
138 }
139 
NotifyHotAreaMessage(SessionPtr sess,MessageId msgId,HotAreaType msg,bool isEdge)140 void CoordinationHotArea::NotifyHotAreaMessage(SessionPtr sess, MessageId msgId, HotAreaType msg, bool isEdge)
141 {
142     CALL_DEBUG_ENTER;
143     CHKPV(sess);
144     NetPacket pkt(msgId);
145     pkt << displayX_ << displayY_ << static_cast<int32_t>(msg) << isEdge;
146     if (pkt.ChkRWError()) {
147         FI_HILOGE("Packet write data failed");
148         return;
149     }
150     if (!sess->SendMsg(pkt)) {
151         FI_HILOGE("Sending failed");
152         return;
153     }
154 }
155 
SetWidth(int32_t screenWidth)156 void CoordinationHotArea::SetWidth(int32_t screenWidth)
157 {
158     width_ = screenWidth;
159 }
160 
SetHeight(int32_t screenHight)161 void CoordinationHotArea::SetHeight(int32_t screenHight)
162 {
163     height_ = screenHight;
164 }
165 
NotifyMessage()166 void CoordinationHotArea::NotifyMessage()
167 {
168     CALL_DEBUG_ENTER;
169     OnHotAreaMessage(type_, isEdge_);
170 }
171 } // DeviceStatus
172 } // Msdp
173 } // OHOS