• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "folding_area_toast.h"
17 #include "common_event_manager.h"
18 #include "common_event_support.h"
19 #include "want.h"
20 #include "parameters.h"
21 #include "util.h"
22 #include "timer_manager.h"
23 #include "input_device_manager.h"
24 #include "input_windows_manager.h"
25 #include "product_type_parser.h"
26 #include "product_name_definition.h"
27 
28 #undef MMI_LOG_DOMAIN
29 #define MMI_LOG_DOMAIN MMI_LOG_SERVER
30 #undef MMI_LOG_TAG
31 #define MMI_LOG_TAG "FoldingAreaToast"
32 
33 namespace OHOS {
34 namespace MMI {
35 namespace {
36     const std::string OHOS_PERMISSION_FOLDING_AREA_TOUCH = "ohos.permission.NOTIFICATION_CONTROLLER";
37     const std::string FOLDAREA_TOUCH_STATUS = "usual.event.FOLDING_AREA_TOUCH";
38     const std::string FOLDAREA_TOUCH_STATE = "foldingAreaTouchState";
39     const int16_t FOLDAREA_DIM2_START = 1608;
40     const int16_t FOLDAREA_DIM2_END = 1688;
41     const int16_t FOLDAREA_MAX_PRESS_TIMES = 500;
42     const int16_t FOLDAREA_MAX_CLK_DB_TIME = 800;
43     const int16_t FOLDAREA_MAX_CLK_DB_END_TIME = 1500;
44     const int16_t FOLDAREA_MAX_CLK_NUM = 5;
45     const int16_t FOLDAREA_MAX_CLK_SAME_AREA = 100;
46     const std::string PRODUCT_TYPE = OHOS::system::GetParameter("const.build.product", "HYM");
47 } // namespace
48 
FoldingAreaToast()49 FoldingAreaToast::FoldingAreaToast()
50 {
51     // init touch device Id.
52     deviceId_ = -1;
53 }
54 
55 FoldingAreaToast::~FoldingAreaToast() = default;
56 
NotifyFoldingAreaTouchStatus(const int8_t state)57 void FoldingAreaToast::NotifyFoldingAreaTouchStatus(const int8_t state)
58 {
59     OHOS::AAFwk::Want want;
60     want.SetAction(FOLDAREA_TOUCH_STATUS);
61     want.SetParam(FOLDAREA_TOUCH_STATE, state);
62     MMI_HILOGD("TAC detect FoldingAreaTouchStatus state: %{public}d", state);
63     EventFwk::CommonEventData CommonEventData { want };
64     EventFwk::CommonEventPublishInfo publishInfo;
65     std::vector<std::string> permissionVec { OHOS_PERMISSION_FOLDING_AREA_TOUCH };
66     publishInfo.SetSubscriberPermissions(permissionVec);
67     EventFwk::CommonEventManager::PublishCommonEvent(CommonEventData, publishInfo);
68 }
69 
FoldingAreaClear(void)70 void FoldingAreaToast::FoldingAreaClear(void)
71 {
72     if (!touchId2FirstDownTimes_.empty()) {
73         touchId2FirstDownTimes_.clear();
74     }
75     if (!touchId2KeepDownTimes_.empty()) {
76         touchId2KeepDownTimes_.clear();
77     }
78     if (!touchId2KeepFrames_.empty()) {
79         touchId2KeepFrames_.clear();
80     }
81     if (!tacTouchs_.empty()) {
82         tacTouchs_.clear();
83     }
84     if (!touchId2clickTouchs_.empty()) {
85         touchId2clickTouchs_.clear();
86     }
87     if (!touchId2touchNum_.empty()) {
88         touchId2touchNum_.clear();
89     }
90     clickInFoldingAreaBeginTimeStamp_ = 0;
91     touchId_ = 0;
92     pointX_ = 0;
93     pointY_ = 0;
94 }
95 
FoldingAreaLongPressProcess(void)96 void FoldingAreaToast::FoldingAreaLongPressProcess(void)
97 {
98     if (pointY_ >= FOLDAREA_DIM2_START && pointY_ <= FOLDAREA_DIM2_END) {
99         touchId2KeepFrames_[touchId_]++;
100     } else {
101         touchId2KeepFrames_[touchId_] = 0;
102     }
103     if (touchId2KeepFrames_[touchId_] == 1) {
104         touchId2FirstDownTimes_[touchId_] = GetMillisTime();
105         touchId2KeepDownTimes_[touchId_] = 0;
106     }
107     if (touchId2KeepFrames_[touchId_] > 1) {
108         touchId2KeepDownTimes_[touchId_] = GetMillisTime() - touchId2FirstDownTimes_[touchId_];
109     }
110     if (touchId2KeepDownTimes_.count(touchId_) && touchId2KeepDownTimes_[touchId_] > FOLDAREA_MAX_PRESS_TIMES) {
111         MMI_HILOGD(
112             "TAC detect touch:%d, position = [%d,%d] long press frames %d cost times:%d, in folding area over 0.5s",
113             touchId_, pointX_, pointY_, touchId2KeepFrames_[touchId_], touchId2KeepDownTimes_[touchId_]);
114         NotifyFoldingAreaTouchStatus(1);
115         touchId2KeepFrames_[touchId_] = 0;
116         touchId2KeepDownTimes_[touchId_] = 0;
117     }
118 }
119 
FoldingAreaGetTouchid2TouchNum(void)120 void FoldingAreaToast::FoldingAreaGetTouchid2TouchNum(void)
121 {
122     for (auto clickTouch : touchId2clickTouchs_) {
123         uint16_t clickTouchDim1 = clickTouch.second.first;
124         uint16_t clickTouchDim2 = clickTouch.second.second;
125         for (auto tacTouch : tacTouchs_) {
126             uint16_t tacTouchDim1 = tacTouch.first;
127             uint16_t tacTouchDim2 = tacTouch.second;
128             MMI_HILOGD("TAC detect clickTouch position = [%d,%d], tacTouch position = [%d,%d]",
129                 clickTouchDim1, clickTouchDim2, tacTouchDim1,
130                 tacTouchDim2);
131             if ((tacTouchDim1 >= clickTouchDim1 && (tacTouchDim1 - clickTouchDim1) <= FOLDAREA_MAX_CLK_SAME_AREA) ||
132                 (tacTouchDim1 < clickTouchDim1 && (clickTouchDim1 - tacTouchDim1) <= FOLDAREA_MAX_CLK_SAME_AREA)) {
133                     touchId2touchNum_[clickTouch.first]++;
134             }
135         }
136     }
137 }
138 
FoldingAreaFastClickProcess(void)139 void FoldingAreaToast::FoldingAreaFastClickProcess(void)
140 {
141     if ((pointY_ < FOLDAREA_DIM2_START) || (pointY_ > FOLDAREA_DIM2_END)) {
142         return;
143     }
144     if (tacTouchs_.empty()) {
145         clickInFoldingAreaBeginTimeStamp_ = GetMillisTime();
146     }
147     if (GetMillisTime() < clickInFoldingAreaBeginTimeStamp_ + FOLDAREA_MAX_CLK_DB_TIME) {
148         tacTouchs_.push_back(std::make_pair(pointX_, pointY_));
149         touchId2clickTouchs_[touchId_].first = pointX_;
150         touchId2clickTouchs_[touchId_].second = pointY_;
151     }
152     if (!tacTouchs_.empty() && GetMillisTime() > clickInFoldingAreaBeginTimeStamp_ + FOLDAREA_MAX_CLK_DB_TIME &&
153         GetMillisTime() < clickInFoldingAreaBeginTimeStamp_ + FOLDAREA_MAX_CLK_DB_END_TIME) {
154         MMI_HILOGD("TAC detect tacTouchs_ over 1s, curTimeStamp:%ld", GetMillisTime());
155         FoldingAreaGetTouchid2TouchNum();
156         for (auto touchNum : touchId2touchNum_) {
157             if (touchNum.second >= FOLDAREA_MAX_CLK_NUM) {
158                 MMI_HILOGD(
159                     "TAC detect touch:%d fast click %d times position = [%d,%d] in 1s in folding area",
160                     touchNum.first, touchNum.second, touchId2clickTouchs_[touchNum.first].first,
161                     touchId2clickTouchs_[touchNum.first].second);
162                 NotifyFoldingAreaTouchStatus(1);
163             }
164         }
165         FoldingAreaClear();
166     }
167     if (!tacTouchs_.empty() && GetMillisTime() > clickInFoldingAreaBeginTimeStamp_ + FOLDAREA_MAX_CLK_DB_END_TIME) {
168         FoldingAreaClear();
169         MMI_HILOGD("TAC detect over 1500ms tacTouchs_ clear");
170     }
171 }
172 
FoldingAreaCheckDeviceId(struct libinput_event * event)173 void FoldingAreaToast::FoldingAreaCheckDeviceId(struct libinput_event *event)
174 {
175     if (deviceId_ == -1) {
176         libinput_device* device = libinput_event_get_device(event);
177         if (device != nullptr) {
178             deviceId_ = INPUT_DEV_MGR->FindInputDeviceId(device);
179         }
180     }
181 }
182 
FoldingAreaProcess(struct libinput_event * event)183 void FoldingAreaToast::FoldingAreaProcess(struct libinput_event *event)
184 {
185     if (PRODUCT_TYPE != DEVICE_TYPE_FOLD_PC) {
186         return;
187     }
188     FoldingAreaCheckDeviceId(event);
189     libinput_event_type eventType = libinput_event_get_type(event);
190     libinput_event_touch* touch = nullptr;
191     if (eventType == LIBINPUT_EVENT_TOUCH_DOWN || eventType == LIBINPUT_EVENT_TOUCH_UP ||
192         eventType == LIBINPUT_EVENT_TOUCH_MOTION || eventType == LIBINPUT_EVENT_TOUCH_CANCEL) {
193         touch = libinput_event_get_touch_event(event);
194         if (!touch) {
195             FoldingAreaClear();
196             return;
197         }
198         EventTouch touchInfo;
199         int32_t logicalDisplayId = -1;
200         if (!WIN_MGR->TouchPointToDisplayPoint(deviceId_, touch, touchInfo, logicalDisplayId)) {
201             FoldingAreaClear();
202             return;
203         } else {
204             pointX_ = static_cast<uint16_t>(touchInfo.point.x);
205             pointY_ = static_cast<uint16_t>(touchInfo.point.y);
206             auto displayInfo = WIN_MGR->GetPhysicalDisplay(logicalDisplayId);
207             if (!displayInfo || (displayInfo != nullptr && displayInfo->direction != Direction::DIRECTION0)) {
208                 FoldingAreaClear();
209                 return;
210             }
211         }
212         touchId_ = libinput_event_touch_get_slot(touch);
213         if (eventType == LIBINPUT_EVENT_TOUCH_UP || eventType == LIBINPUT_EVENT_TOUCH_CANCEL) {
214             touchId2KeepFrames_[touchId_] = 0;
215             touchId2KeepDownTimes_[touchId_] = 0;
216         }
217         if (eventType == LIBINPUT_EVENT_TOUCH_DOWN || eventType == LIBINPUT_EVENT_TOUCH_MOTION) {
218             FoldingAreaLongPressProcess();
219         }
220         if (eventType == LIBINPUT_EVENT_TOUCH_DOWN) {
221             FoldingAreaFastClickProcess();
222         }
223     }
224 }
225 } // namespace MMI
226 } // namespace OHOS