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 #include "HidDefs.h"
17 #include "HidLog.h"
18 #include "HidTree.h"
19 #include <memory>
20 
21 namespace HidUtil {
22 
23 // HidTreeNode
HidTreeNode()24 HidTreeNode::HidTreeNode() : mNodeType(TYPE_UNINITIALIZED), mData(0), mFullUsage(0) {
25 }
26 
HidTreeNode(std::shared_ptr<HidTreeNode> parent,uint32_t data,uint32_t fullUsage,int nodeType)27 HidTreeNode::HidTreeNode(std::shared_ptr<HidTreeNode> parent,
28                          uint32_t data, uint32_t fullUsage, int nodeType)
29         : mNodeType(nodeType), mData(data),
30         mFullUsage(fullUsage), mParent(parent) {
31 }
32 
HidTreeNode(std::shared_ptr<HidTreeNode> parent,uint32_t data,uint32_t fullUsage)33 HidTreeNode::HidTreeNode(std::shared_ptr<HidTreeNode> parent,
34                          uint32_t data, uint32_t fullUsage)
35         : mNodeType(TYPE_NORMAL), mData(data),
36         mFullUsage(fullUsage), mParent(parent) {
37 }
38 
outputRecursive(std::ostream & os,int level) const39 void HidTreeNode::outputRecursive(std::ostream &os, int level) const {
40     insertIndentation(os, level);
41     os << "Node data: " << mData
42        << ", usage " << std::hex << mFullUsage << std::dec << LOG_ENDL;
43 
44     for (auto &child : mChildren) {
45         child->outputRecursive(os, level + 1);
46     }
47 }
48 
deepCopy(std::shared_ptr<HidTreeNode> parent) const49 std::shared_ptr<HidTreeNode> HidTreeNode::deepCopy(
50         std::shared_ptr<HidTreeNode> parent) const {
51     std::shared_ptr<HidTreeNode> copy(new HidTreeNode(parent, mData, mFullUsage, mNodeType));
52     for (auto &i : mChildren) {
53         copy->mChildren.push_back(i->deepCopy(copy));
54     }
55     return copy;
56 }
57 
insertIndentation(std::ostream & os,int level) const58 void HidTreeNode::insertIndentation(std::ostream &os, int level) const {
59     constexpr char indentCharacter = '\t';
60     std::fill_n(std::ostreambuf_iterator<char>(os), level, indentCharacter);
61 }
62 
addChild(std::shared_ptr<HidTreeNode> child)63 std::shared_ptr<HidTreeNode> HidTreeNode::addChild(std::shared_ptr<HidTreeNode> child) {
64     mChildren.push_back(child);
65     return child;
66 }
67 
getParent() const68 std::shared_ptr<HidTreeNode> HidTreeNode::getParent() const {
69     return mParent.lock();
70 }
71 
isReportCollection() const72 bool HidTreeNode::isReportCollection() const {
73     return mNodeType == TYPE_NORMAL && mChildren.size() == 1
74             && mChildren.front()->mNodeType == TYPE_REPORT;
75 }
76 
getFullUsage() const77 unsigned int HidTreeNode::getFullUsage() const {
78     return mFullUsage;
79 }
80 
getChildren()81 std::vector<std::shared_ptr<HidTreeNode>>& HidTreeNode::getChildren() {
82     return mChildren;
83 }
84 
getChildren() const85 const std::vector<std::shared_ptr<HidTreeNode>>& HidTreeNode::getChildren() const {
86     return mChildren;
87 }
88 
isUsageCollection() const89 bool HidTreeNode::isUsageCollection() const {
90     using namespace HidDef::CollectionType;
91     return mNodeType == TYPE_NORMAL && (mData == PHYSICAL || mData == APPLICATION);
92 }
93 
getNodeType() const94 int HidTreeNode::getNodeType() const {
95     return mNodeType;
96 }
97 
operator <<(std::ostream & os,const HidTreeNode & n)98 std::ostream& operator<<(std::ostream& os, const HidTreeNode& n) {
99     n.outputRecursive(os, 0);
100     return os;
101 }
102 
103 // HidReportNode
HidReportNode(std::shared_ptr<HidTreeNode> parent,const HidReport & report)104 HidReportNode::HidReportNode(std::shared_ptr<HidTreeNode> parent, const HidReport &report)
105     : HidTreeNode(parent, 0 /*data*/, 0 /*fullUsage*/, TYPE_REPORT), mReport(report) {
106 }
107 
outputRecursive(std::ostream & os,int level) const108 void HidReportNode::outputRecursive(std::ostream &os, int level) const {
109     insertIndentation(os, level);
110     os << mReport << LOG_ENDL;
111 }
112 
deepCopy(std::shared_ptr<HidTreeNode> parent) const113 std::shared_ptr<HidTreeNode> HidReportNode::deepCopy(
114         std::shared_ptr<HidTreeNode> parent) const {
115     std::shared_ptr<HidTreeNode> copy(new HidReportNode(parent, mReport));
116     return copy;
117 }
118 
getReport() const119 const HidReport& HidReportNode::getReport() const {
120     return mReport;
121 }
122 
collapse(unsigned int newUsage)123 void HidReportNode::collapse(unsigned int newUsage) {
124     mReport.setCollapsed(newUsage);
125 }
126 
127 } //namespace HidUtil
128