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 "HidGlobal.h"
18 #include "HidLog.h"
19 
20 namespace HidUtil {
21 using namespace HidDef::GlobalTag;
22 
append(const HidItem & i)23 bool HidGlobal::append(const HidItem &i) {
24     using namespace HidDef::TagType;
25     if (i.type != GLOBAL) {
26         LOG_E << "HidGlobal::append cannot process tag that is not global, " << i << LOG_ENDL;
27         return false;
28     }
29 
30     if (i.tag == PUSH || i.tag == POP) {
31         LOG_E << "PUSH and POP should be handled in HidGlobalStack, " << i << LOG_ENDL;
32         return false;
33     }
34 
35     int signedInteger;
36     unsigned unsignedInteger;
37     bool signedError = !i.dataAsSigned(&signedInteger);
38     bool unsignedError = !i.dataAsUnsigned(&unsignedInteger);
39 
40     bool valueError = false;
41     bool ret = true;
42     switch (i.tag) {
43         case USAGE_PAGE:
44             usagePage = unsignedInteger;
45             valueError = unsignedError;
46             break;
47         case LOGICAL_MINIMUM:
48             logicalMin = signedInteger;
49             valueError = signedError;
50             break;
51         case LOGICAL_MAXIMUM:
52             logicalMax = signedInteger;
53             valueError = signedError;
54             break;
55         case PHYSICAL_MINIMUM:
56             physicalMin = signedInteger;
57             valueError = signedError;
58             break;
59         case PHYSICAL_MAXIMUM:
60             physicalMax = signedInteger;
61             valueError = signedError;
62             break;
63         case UNIT_EXPONENT:
64             exponent = unsignedInteger;
65             valueError = unsignedError;
66             break;
67         case UNIT:
68             unit = unsignedInteger;
69             valueError = unsignedError;
70             break;
71         case REPORT_SIZE:
72             reportSize = unsignedInteger;
73             valueError = unsignedError;
74             break;
75         case REPORT_ID:
76             reportId = unsignedInteger;
77             valueError = unsignedError;
78             break;
79         case REPORT_COUNT:
80             reportCount = unsignedInteger;
81             valueError = unsignedError;
82             break;
83         default:
84             LOG_E << "unknown global tag, " << i << LOG_ENDL;
85             ret = false;
86     }
87 
88     if (valueError) {
89         LOG_E << "Cannot get signed / unsigned data at " << i << LOG_ENDL;
90         ret = false;
91     }
92     return ret;
93 }
94 
append(const HidItem & i)95 bool HidGlobalStack::append(const HidItem &i) {
96     using namespace HidDef::TagType;
97     if (i.type != GLOBAL) {
98         return false;
99     }
100 
101     bool ret = true;
102     if (i.tag == PUSH) {
103         mStack.push_back(top());
104     } else if (i.tag == POP) {
105         mStack.pop_back();
106         if (mStack.size() == 0) {
107             mStack.push_back(HidGlobal()); // fail-safe
108             ret = false;
109         }
110     } else {
111         ret = mStack.back().append(i);
112     }
113     return ret;
114 }
115 
HidGlobalStack()116 HidGlobalStack::HidGlobalStack() {
117     // default element
118     mStack.push_back(HidGlobal());
119 }
120 
top() const121 const HidGlobal& HidGlobalStack::top() const {
122     return mStack.back();
123 }
124 
125 } // namespace HidUtil
126