1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4#
5# Copyright (c) 2024 Huawei Device Co., Ltd.
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#     http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19from src.beans.base_bean import BaseBean
20from src.beans.event_procedures import EventProcedures
21from src.beans.frame_node import FrameNode
22from src.beans.touch_point import TouchPoint
23from src.utils.log_wrapper import log_info, log_error
24from src.utils.value_parser import pack_string_until_next_keyword
25
26
27# includes touch points and frame nodes(hittest) and event procedures
28class EventTree(BaseBean):
29    tree_id = -1  # the index in dump
30    touch_points = []
31    frame_nodes = []
32    event_procedures = None
33
34    def __init__(self, input_str):
35        super().__init__()
36        self.tree_id = -1
37        self.touch_points = []
38        self.frame_nodes = []
39        self.event_procedures = None
40        self.parse_event_tree(input_str)
41        self.check_parse_result()
42
43    def parse_event_tree(self, input_str):
44        spliced_lines = input_str.split('\n')
45        self.parse_tree_index(spliced_lines)
46        current_index = self.parse_touch_points(spliced_lines, 0)
47        current_index = self.parse_hit_tests(spliced_lines, current_index)
48        current_index = self.parse_event_procedures(spliced_lines, current_index)
49        return current_index
50
51    def parse_tree_index(self, lines):
52        if lines is None or len(lines) == 0:
53            return
54        tree_index_str = lines[0]
55        spliced_tree_lines = tree_index_str.split(': ')
56        if len(spliced_tree_lines) != 2:
57            log_error('parse tree index failed, input str: ' + tree_index_str)
58            return
59        self.tree_id = int(spliced_tree_lines[0])
60
61    def parse_touch_points(self, texts, start_index):
62        start_keyword = 'touch points:'
63        end_keywords = ['hittest:']
64        packed_result = pack_string_until_next_keyword(texts, start_index, start_keyword, end_keywords)
65        packed_str = packed_result[0]
66        if packed_str is None or len(packed_str) == 0:
67            return packed_result[1]
68        spliced_touch_points = packed_str.split('\n')
69        for touch_point_str in spliced_touch_points:
70            if touch_point_str.find('id: ') == -1:
71                continue
72            touch_point = TouchPoint(touch_point_str)
73            if touch_point is not None and touch_point.is_succeed():
74                self.touch_points.append(touch_point)
75        return packed_result[1]
76
77    def parse_hit_tests(self, texts, start_index):
78        start_keyword = 'hittest:'
79        end_keywords = ['event procedures:']
80        packed_result = pack_string_until_next_keyword(texts, start_index, start_keyword, end_keywords)
81        packed_str = packed_result[0]
82        if packed_str is None or len(packed_str) == 0:
83            return packed_result[1]
84        spliced_frame_nodes = packed_str.split('\n')
85        for frame_node_str in spliced_frame_nodes:
86            if frame_node_str.find('nodeId: ') == -1:
87                continue
88            frame_node = FrameNode(frame_node_str)
89            if frame_node is not None and frame_node.is_succeed():
90                self.frame_nodes.append(frame_node)
91        return packed_result[1]
92
93    def parse_event_procedures(self, texts, start_index):
94        start_keyword = 'event procedures:'
95        end_keywords = ['event tree =>']
96        packed_result = pack_string_until_next_keyword(texts, start_index, start_keyword, end_keywords)
97        packed_str = packed_result[0]
98        if packed_str is None or len(packed_str) == 0:
99            return packed_result[1]
100        self.event_procedures = EventProcedures(packed_str)
101        return packed_result[1]
102
103    def is_parse_failed(self):
104        if self.tree_id == -1 or self.touch_points is None or len(self.touch_points) == 0:
105            return True
106        if self.frame_nodes is None or len(self.frame_nodes) == 0 or self.event_procedures is None:
107            return True
108        return False
109
110    # check the parse result
111    def check_parse_result(self):
112        if self.is_parse_failed():
113            self.parse_failed()
114        else:
115            self.parse_succeed()
116
117    def to_string(self):
118        result_str = 'touch points: '
119        for touch_point in self.touch_points:
120            result_str += '\n' + touch_point.to_string()
121        result_str += '\n' + 'hittest: '
122        for frame_node in self.frame_nodes:
123            result_str += '\n' + frame_node.to_string()
124        result_str += '\n' + self.event_procedures.to_string()
125        return result_str
126
127    def dump(self):
128        log_info(self.to_string())
129
130    def update_event_nodes(self):
131        if self.event_procedures is None or self.frame_nodes is None or len(self.frame_nodes) == 0:
132            return
133        self.event_procedures.update_event_nodes_with_frame_nodes(self.frame_nodes)
134