1 /*
2  * Copyright (C) 2016 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 
17 #include "SensorList.h"
18 
19 #include <hardware/sensors.h>
20 #include <utils/String8.h>
21 
22 #include <cinttypes>
23 
24 namespace android {
25 namespace SensorServiceUtil {
26 
27 const Sensor SensorList::mNonSensor = Sensor("unknown");
28 
add(int handle,SensorInterface * si,bool isForDebug,bool isVirtual)29 bool SensorList::add(
30         int handle, SensorInterface* si, bool isForDebug, bool isVirtual) {
31     std::lock_guard<std::mutex> lk(mLock);
32     if (handle == si->getSensor().getHandle() &&
33         mUsedHandle.insert(handle).second) {
34         // will succeed as the mUsedHandle does not have this handle
35         mHandleMap.emplace(handle, Entry(si, isForDebug, isVirtual));
36         return true;
37     }
38     // handle exist already or handle mismatch
39     return false;
40 }
41 
remove(int handle)42 bool SensorList::remove(int handle) {
43     std::lock_guard<std::mutex> lk(mLock);
44     auto entry = mHandleMap.find(handle);
45     if (entry != mHandleMap.end()) {
46         mHandleMap.erase(entry);
47         return true;
48     }
49     return false;
50 }
51 
getName(int handle) const52 String8 SensorList::getName(int handle) const {
53     return getOne<String8>(
54             handle, [] (const Entry& e) -> String8 {return e.si->getSensor().getName();},
55             mNonSensor.getName());
56 }
57 
getInterface(int handle) const58 sp<SensorInterface> SensorList::getInterface(int handle) const {
59     return getOne<sp<SensorInterface>>(
60             handle, [] (const Entry& e) -> sp<SensorInterface> {return e.si;}, nullptr);
61 }
62 
63 
isNewHandle(int handle) const64 bool SensorList::isNewHandle(int handle) const {
65     std::lock_guard<std::mutex> lk(mLock);
66     return mUsedHandle.find(handle) == mUsedHandle.end();
67 }
68 
getUserSensors() const69 const Vector<Sensor> SensorList::getUserSensors() const {
70     // lock in forEachEntry
71     Vector<Sensor> sensors;
72     forEachEntry(
73             [&sensors] (const Entry& e) -> bool {
74                 if (!e.isForDebug && !e.si->getSensor().isDynamicSensor()) {
75                     sensors.add(e.si->getSensor());
76                 }
77                 return true;
78             });
79     return sensors;
80 }
81 
getUserDebugSensors() const82 const Vector<Sensor> SensorList::getUserDebugSensors() const {
83     // lock in forEachEntry
84     Vector<Sensor> sensors;
85     forEachEntry(
86             [&sensors] (const Entry& e) -> bool {
87                 if (!e.si->getSensor().isDynamicSensor()) {
88                     sensors.add(e.si->getSensor());
89                 }
90                 return true;
91             });
92     return sensors;
93 }
94 
getDynamicSensors() const95 const Vector<Sensor> SensorList::getDynamicSensors() const {
96     // lock in forEachEntry
97     Vector<Sensor> sensors;
98     forEachEntry(
99             [&sensors] (const Entry& e) -> bool {
100                 if (!e.isForDebug && e.si->getSensor().isDynamicSensor()) {
101                     sensors.add(e.si->getSensor());
102                 }
103                 return true;
104             });
105     return sensors;
106 }
107 
getVirtualSensors() const108 const Vector<Sensor> SensorList::getVirtualSensors() const {
109     // lock in forEachEntry
110     Vector<Sensor> sensors;
111     forEachEntry(
112             [&sensors] (const Entry& e) -> bool {
113                 if (e.isVirtual) {
114                     sensors.add(e.si->getSensor());
115                 }
116                 return true;
117             });
118     return sensors;
119 }
120 
dump() const121 std::string SensorList::dump() const {
122     String8 result;
123 
124     forEachSensor([&result] (const Sensor& s) -> bool {
125             result.appendFormat(
126                     "%#010x) %-25s | %-15s | ver: %" PRId32 " | type: %20s(%" PRId32
127                         ") | perm: %s | flags: 0x%08x\n",
128                     s.getHandle(),
129                     s.getName().string(),
130                     s.getVendor().string(),
131                     s.getVersion(),
132                     s.getStringType().string(),
133                     s.getType(),
134                     s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a",
135                     static_cast<int>(s.getFlags()));
136 
137             result.append("\t");
138             const int reportingMode = s.getReportingMode();
139             if (reportingMode == AREPORTING_MODE_CONTINUOUS) {
140                 result.append("continuous | ");
141             } else if (reportingMode == AREPORTING_MODE_ON_CHANGE) {
142                 result.append("on-change | ");
143             } else if (reportingMode == AREPORTING_MODE_ONE_SHOT) {
144                 result.append("one-shot | ");
145             } else if (reportingMode == AREPORTING_MODE_SPECIAL_TRIGGER) {
146                 result.append("special-trigger | ");
147             } else {
148                 result.append("unknown-mode | ");
149             }
150 
151             if (s.getMaxDelay() > 0) {
152                 result.appendFormat("minRate=%.2fHz | ", 1e6f / s.getMaxDelay());
153             } else {
154                 result.appendFormat("maxDelay=%" PRId32 "us | ", s.getMaxDelay());
155             }
156 
157             if (s.getMinDelay() > 0) {
158                 result.appendFormat("maxRate=%.2fHz | ", 1e6f / s.getMinDelay());
159             } else {
160                 result.appendFormat("minDelay=%" PRId32 "us | ", s.getMinDelay());
161             }
162 
163             if (s.getFifoMaxEventCount() > 0) {
164                 result.appendFormat("FIFO (max,reserved) = (%" PRIu32 ", %" PRIu32 ") events | ",
165                         s.getFifoMaxEventCount(),
166                         s.getFifoReservedEventCount());
167             } else {
168                 result.append("no batching | ");
169             }
170 
171             if (s.isWakeUpSensor()) {
172                 result.appendFormat("wakeUp | ");
173             } else {
174                 result.appendFormat("non-wakeUp | ");
175             }
176 
177             if (s.isDataInjectionSupported()) {
178                 result.appendFormat("data-injection, ");
179             }
180 
181             if (s.isDynamicSensor()) {
182                 result.appendFormat("dynamic, ");
183             }
184 
185             if (s.hasAdditionalInfo()) {
186                 result.appendFormat("has-additional-info, ");
187             }
188             result.append("\n");
189 
190             if (s.getHighestDirectReportRateLevel() > SENSOR_DIRECT_RATE_STOP) {
191                 result.appendFormat("\thighest rate level = %d, support shared mem: ",
192                         s.getHighestDirectReportRateLevel());
193                 if (s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_ASHMEM)) {
194                     result.append("ashmem, ");
195                 }
196                 if (s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_GRALLOC)) {
197                     result.append("gralloc, ");
198                 }
199                 result.append("\n");
200             }
201             return true;
202         });
203     return std::string(result.string());
204 }
205 
~SensorList()206 SensorList::~SensorList() {
207 }
208 
209 } // namespace SensorServiceUtil
210 } // namespace android
211 
212