• 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 "core/common/event_dump.h"
17 
18 namespace OHOS::Ace::NG {
19 namespace {
20 constexpr size_t MAX_EVENT_TREE_RECORD_CNT = 5;
21 constexpr size_t MAX_FRAME_NODE_CNT = 256;
22 constexpr int32_t MAX_EVENT_TREE_TOUCH_DOWN_CNT = 10;
23 constexpr int32_t MAX_EVENT_TREE_TOUCH_POINT_CNT = 20;
24 constexpr int32_t MAX_EVENT_TREE_GESTURE_CNT = 100;
25 } // end of namespace
26 
Dump(std::list<std::pair<int32_t,std::string>> & dumpList,int32_t depth) const27 void FrameNodeSnapshot::Dump(std::list<std::pair<int32_t, std::string>>& dumpList, int32_t depth) const
28 {
29     std::stringstream oss;
30     oss << "nodeId: " << nodeId << ", "
31         << "parentId: " << parentNodeId << ", "
32         << "tag: " << tag << ", ";
33     if (!comId.empty()) {
34         oss << "comId: " << comId << ", ";
35     }
36     oss << "monopolizeEvents: " << monopolizeEvents << ", "
37         << "isHit: " << isHit << ", "
38         << "hitTestMode: " << hitTestMode << ", ";
39 #ifndef IS_RELEASE_VERSION
40     oss << "responseRegion: ";
41     for (const auto& rect : responseRegionList) {
42         oss << rect.ToString().c_str();
43     }
44 #endif
45     dumpList.emplace_back(std::make_pair(depth, oss.str()));
46 }
47 
TouchPointSnapshot(const TouchEvent & event)48 TouchPointSnapshot::TouchPointSnapshot(const TouchEvent& event)
49 {
50     id = event.id;
51     point = OffsetF(event.x, event.y);
52     screenPoint = OffsetF(event.screenX, event.screenY);
53     type = event.type;
54     timestamp = GetCurrentTimestamp();
55     isInjected = event.isInjected;
56 }
57 
Dump(std::list<std::pair<int32_t,std::string>> & dumpList,int32_t depth) const58 void TouchPointSnapshot::Dump(std::list<std::pair<int32_t, std::string>>& dumpList, int32_t depth) const
59 {
60     std::stringstream oss;
61 #ifdef IS_RELEASE_VERSION
62     oss << "id: " << id << ", "
63         << "type: " << GestureSnapshot::TransTouchType(type) << ", "
64         << "timestamp: " << ConvertTimestampToStr(timestamp) << ", "
65         << "isInjected: " << isInjected;
66 #else
67     oss << "id: " << id << ", "
68         << "point: " << point.ToString() << ", "
69         << "screenPoint: " << screenPoint.ToString() << ", "
70         << "type: " << GestureSnapshot::TransTouchType(type) << ", "
71         << "timestamp: " << ConvertTimestampToStr(timestamp) << ", "
72         << "isInjected: " << isInjected;
73 #endif
74     dumpList.emplace_back(std::make_pair(depth, oss.str()));
75 }
76 
AddTouchPoint(const TouchEvent & event)77 void EventTreeRecord::AddTouchPoint(const TouchEvent& event)
78 {
79     if (!eventTreeList.empty()) {
80         if (eventTreeList.back().touchPoints.size() > MAX_EVENT_TREE_TOUCH_POINT_CNT) {
81             eventTreeList.pop_back();
82             TAG_LOGW(AceLogTag::ACE_INPUTTRACKING,
83                 "EventTreeList last record touchPoint size is over limit! Last record is cleaned.");
84         }
85         if (!eventTreeList.empty() && event.type == Ace::TouchType::DOWN &&
86             eventTreeList.back().downFingerIds_.count(event.id) > 0) {
87             eventTreeList.pop_back();
88             TAG_LOGW(AceLogTag::ACE_INPUTTRACKING,
89                 "EventTreeList last record receive DOWN event twice. Last record is cleaned.");
90         }
91     }
92     TouchType type = event.type;
93     if (type == Ace::TouchType::DOWN) {
94         // multi fingers touch down will be in one tree
95         if (eventTreeList.empty() || eventTreeList.back().touchDownCount <= 0 ||
96             eventTreeList.back().touchDownCount >= MAX_EVENT_TREE_TOUCH_DOWN_CNT) {
97             eventTreeList.emplace_back(EventTree());
98             if (eventTreeList.size() > MAX_EVENT_TREE_RECORD_CNT) {
99                 eventTreeList.erase(eventTreeList.begin());
100             }
101         }
102         eventTreeList.back().touchDownCount++;
103         eventTreeList.back().downFingerIds_.insert(event.id);
104     }
105 
106     if (eventTreeList.empty()) {
107         return;
108     }
109 
110     if (type == TouchType::UP || type == TouchType::CANCEL || type == TouchType::PULL_UP ||
111         type == TouchType::PULL_OUT_WINDOW) {
112         eventTreeList.back().touchDownCount--;
113         eventTreeList.back().downFingerIds_.erase(event.id);
114     }
115     eventTreeList.back().touchPoints.emplace_back(TouchPointSnapshot(event));
116 }
117 
AddFrameNodeSnapshot(FrameNodeSnapshot && node)118 void EventTreeRecord::AddFrameNodeSnapshot(FrameNodeSnapshot&& node)
119 {
120     if (eventTreeList.empty()) {
121         return;
122     }
123     if (eventTreeList.back().hitTestTree.size() < MAX_FRAME_NODE_CNT) {
124         bool isInList = false;
125         for (auto& iter : eventTreeList.back().hitTestTree) {
126             if (iter.nodeId == node.nodeId) {
127                 isInList = true;
128                 break;
129             }
130         }
131         if (isInList) {
132             return;
133         }
134         eventTreeList.back().hitTestTree.emplace_back(node);
135     }
136 }
137 
AddGestureSnapshot(int32_t finger,RefPtr<GestureSnapshot> && gesture)138 void EventTreeRecord::AddGestureSnapshot(int32_t finger, RefPtr<GestureSnapshot>&& gesture)
139 {
140     if (eventTreeList.empty()) {
141         return;
142     }
143     if (eventTreeList.size() > MAX_EVENT_TREE_RECORD_CNT) {
144         eventTreeList.clear();
145         TAG_LOGW(AceLogTag::ACE_INPUTTRACKING, "EventTreeList size is over MAX, clean event tree.");
146         return;
147     }
148     auto& gestureTree = eventTreeList.back().gestureTree;
149     auto& gestureMap = eventTreeList.back().gestureMap;
150     if (gestureMap.size() > MAX_EVENT_TREE_GESTURE_CNT) {
151         eventTreeList.clear();
152         TAG_LOGW(AceLogTag::ACE_INPUTTRACKING, "GestureMap size is over MAX, clean event tree.");
153         return;
154     }
155     gestureMap[gesture->id] = gesture;
156     gestureTree[finger].emplace_back(gesture);
157 }
158 
AddGestureProcedure(uint64_t id,const std::string & procedure,const std::string & state,const std::string & disposal,int64_t timestamp)159 void EventTreeRecord::AddGestureProcedure(uint64_t id,
160     const std::string& procedure, const std::string& state, const std::string& disposal, int64_t timestamp)
161 {
162     if (eventTreeList.empty()) {
163         return;
164     }
165     auto& gestureMap = eventTreeList.back().gestureMap;
166     auto iter = gestureMap.find(id);
167     if (iter == gestureMap.end()) {
168         return;
169     }
170     // TouchEventActuator don't record move
171     if (iter->second->type == "TouchEventActuator" && procedure == "HandleTouchMove") {
172         return;
173     }
174     iter->second->AddProcedure(procedure, state, disposal, timestamp);
175 }
176 
AddGestureProcedure(uint64_t id,const TouchEvent & point,const std::string & state,const std::string & disposal,int64_t timestamp)177 void EventTreeRecord::AddGestureProcedure(uint64_t id,
178     const TouchEvent& point, const std::string& state, const std::string& disposal, int64_t timestamp)
179 {
180     if (eventTreeList.empty()) {
181         return;
182     }
183     auto& gestureMap = eventTreeList.back().gestureMap;
184     auto iter = gestureMap.find(id);
185     if (iter == gestureMap.end()) {
186         return;
187     }
188 
189     if ((point.type == TouchType::MOVE || point.type == TouchType::PULL_MOVE) &&
190         !iter->second->CheckNeedAddMove(state, disposal)) {
191         return;
192     }
193     std::string procedure = std::string("Handle").append(GestureSnapshot::TransTouchType(point.type));
194     iter->second->AddProcedure(procedure, state, disposal, timestamp);
195 }
196 
Dump(std::list<std::pair<int32_t,std::string>> & dumpList,int32_t depth,int32_t startNumber) const197 void EventTreeRecord::Dump(std::list<std::pair<int32_t, std::string>>& dumpList,
198     int32_t depth, int32_t startNumber) const
199 {
200     int32_t index = 0;
201     int32_t listDepth = depth + 1;
202     int32_t detailDepth = listDepth + 1;
203     for (auto& tree : eventTreeList) {
204         if (index < startNumber) {
205             index++;
206             continue;
207         }
208         std::string header = std::to_string(index).append(": event tree =>");
209 
210         // dump needful touch points:
211         dumpList.emplace_back(std::make_pair(depth, header));
212         dumpList.emplace_back(std::make_pair(listDepth, "touch points:"));
213         for (auto& item : tree.touchPoints) {
214             item.Dump(dumpList, detailDepth);
215         }
216 
217         // dump hit test frame nodes:
218         dumpList.emplace_back(std::make_pair(listDepth, "hittest:"));
219         for (auto& item : tree.hitTestTree) {
220             item.Dump(dumpList, detailDepth);
221         }
222 
223         // dump gesture event and procedure:
224         dumpList.emplace_back(std::make_pair(listDepth, "event procedures:"));
225         for (auto iter = tree.gestureTree.begin(); iter != tree.gestureTree.end(); ++iter) {
226             dumpList.emplace_back(std::make_pair(detailDepth,
227                 std::string("finger:").append(std::to_string(iter->first))));
228             for (const auto& item : iter->second) {
229                 item->Dump(dumpList, detailDepth + 1);
230             }
231         }
232         ++index;
233     }
234 }
235 } // end of namespace
236