1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef HIDUTIL_HIDTREE_H_
17 #define HIDUTIL_HIDTREE_H_
18 
19 #include "HidReport.h"
20 
21 #include <cstddef>
22 #include <vector>
23 #include <iostream>
24 
25 namespace HidUtil {
26 
27 // HID report parser output tree node
28 class HidTreeNode {
29     friend std::ostream& operator<<(std::ostream& os, const HidTreeNode& n);
30 public:
31     enum {
32         TYPE_UNINITIALIZED = 0,
33         TYPE_NORMAL = 1,
34         TYPE_REPORT = 2     // can be cast to HidReportNode
35     };
36     HidTreeNode();
37     HidTreeNode(std::shared_ptr<HidTreeNode> parent, uint32_t data, uint32_t fullUsage);
38 
39     virtual ~HidTreeNode() = default;
40 
41     // make a deep copy of tree at and below this node and attach it to specified parent node
42     virtual std::shared_ptr<HidTreeNode> deepCopy(
43           std::shared_ptr<HidTreeNode> parent = nullptr) const;
44 
45     // add child to this node
46     std::shared_ptr<HidTreeNode> addChild(std::shared_ptr<HidTreeNode> child);
47 
48     // get all children of a node
49     std::vector<std::shared_ptr<HidTreeNode>>& getChildren();
50     const std::vector<std::shared_ptr<HidTreeNode>>& getChildren() const;
51 
52     // get parent (nullptr if it is root node or if lock weak_ptr failed)
53     std::shared_ptr<HidTreeNode> getParent() const;
54 
55     // access usage of this node
56     unsigned int getFullUsage() const;
57 
58     bool isReportCollection() const;
59     bool isUsageCollection() const;
60     int getNodeType() const;
61 protected:
62     // for derived class to define different nodeType
63     HidTreeNode(std::shared_ptr<HidTreeNode> parent,
64               uint32_t data, uint32_t fullUsage, int nodeType);
65 
66     // helper for stream output
67     void insertIndentation(std::ostream &os, int level) const;
68 private:
69     // helper for stream output
70     virtual void outputRecursive(std::ostream& os, int level) const;
71 
72     int mNodeType;
73     uint32_t mData;
74     uint32_t mFullUsage;
75 
76     std::vector<std::shared_ptr<HidTreeNode>> mChildren;
77     std::weak_ptr<HidTreeNode> mParent;
78 };
79 
80 // Tree node that corresponds to an input, output or feature report
81 class HidReportNode : public HidTreeNode {
82 public:
83     HidReportNode(std::shared_ptr<HidTreeNode> parent, const HidReport &report);
84 
85     virtual std::shared_ptr<HidTreeNode> deepCopy(
86           std::shared_ptr<HidTreeNode> parent = nullptr) const override;
87 
88     // obtain HidReport attached to this node
89     const HidReport& getReport() const;
90 
91     // reset usage of node and set underlying report to collapsed
92     void collapse(unsigned int newUsage);
93 private:
94     virtual void outputRecursive(std::ostream &os, int level) const override;
95 
96     HidReport mReport;
97 };
98 
99 std::ostream& operator<<(std::ostream& os, const HidTreeNode& n);
100 
101 } // namespace HidUtil
102 
103 #endif // HIDUTIL_HIDTREE_H_
104