• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <android/util/ProtoOutputStream.h>
20 #include <frameworks/base/core/proto/android/service/sensor_service.proto.h>
21 #include <hardware/sensors.h>
22 #include <utils/String8.h>
23 
24 #include <cinttypes>
25 
26 namespace android {
27 namespace SensorServiceUtil {
28 
29 const Sensor SensorList::mNonSensor = Sensor("unknown");
30 
add(int handle,SensorInterface * si,bool isForDebug,bool isVirtual)31 bool SensorList::add(
32         int handle, SensorInterface* si, bool isForDebug, bool isVirtual) {
33     std::lock_guard<std::mutex> lk(mLock);
34     if (handle == si->getSensor().getHandle() &&
35         mUsedHandle.insert(handle).second) {
36         // will succeed as the mUsedHandle does not have this handle
37         mHandleMap.emplace(handle, Entry(si, isForDebug, isVirtual));
38         return true;
39     }
40     // handle exist already or handle mismatch
41     return false;
42 }
43 
remove(int handle)44 bool SensorList::remove(int handle) {
45     std::lock_guard<std::mutex> lk(mLock);
46     auto entry = mHandleMap.find(handle);
47     if (entry != mHandleMap.end()) {
48         mHandleMap.erase(entry);
49         return true;
50     }
51     return false;
52 }
53 
getName(int handle) const54 String8 SensorList::getName(int handle) const {
55     return getOne<String8>(
56             handle, [] (const Entry& e) -> String8 {return e.si->getSensor().getName();},
57             mNonSensor.getName());
58 }
59 
getStringType(int handle) const60 String8 SensorList::getStringType(int handle) const {
61     return getOne<String8>(
62             handle, [] (const Entry& e) -> String8 {return e.si->getSensor().getStringType();},
63             mNonSensor.getStringType());
64 }
65 
getInterface(int handle) const66 sp<SensorInterface> SensorList::getInterface(int handle) const {
67     return getOne<sp<SensorInterface>>(
68             handle, [] (const Entry& e) -> sp<SensorInterface> {return e.si;}, nullptr);
69 }
70 
71 
isNewHandle(int handle) const72 bool SensorList::isNewHandle(int handle) const {
73     std::lock_guard<std::mutex> lk(mLock);
74     return mUsedHandle.find(handle) == mUsedHandle.end();
75 }
76 
getUserSensors() const77 const Vector<Sensor> SensorList::getUserSensors() const {
78     // lock in forEachEntry
79     Vector<Sensor> sensors;
80     forEachEntry(
81             [&sensors] (const Entry& e) -> bool {
82                 if (!e.isForDebug && !e.si->getSensor().isDynamicSensor()) {
83                     sensors.add(e.si->getSensor());
84                 }
85                 return true;
86             });
87     return sensors;
88 }
89 
getUserDebugSensors() const90 const Vector<Sensor> SensorList::getUserDebugSensors() const {
91     // lock in forEachEntry
92     Vector<Sensor> sensors;
93     forEachEntry(
94             [&sensors] (const Entry& e) -> bool {
95                 if (!e.si->getSensor().isDynamicSensor()) {
96                     sensors.add(e.si->getSensor());
97                 }
98                 return true;
99             });
100     return sensors;
101 }
102 
getDynamicSensors() const103 const Vector<Sensor> SensorList::getDynamicSensors() const {
104     // lock in forEachEntry
105     Vector<Sensor> sensors;
106     forEachEntry(
107             [&sensors] (const Entry& e) -> bool {
108                 if (!e.isForDebug && e.si->getSensor().isDynamicSensor()) {
109                     sensors.add(e.si->getSensor());
110                 }
111                 return true;
112             });
113     return sensors;
114 }
115 
getVirtualSensors() const116 const Vector<Sensor> SensorList::getVirtualSensors() const {
117     // lock in forEachEntry
118     Vector<Sensor> sensors;
119     forEachEntry(
120             [&sensors] (const Entry& e) -> bool {
121                 if (e.isVirtual) {
122                     sensors.add(e.si->getSensor());
123                 }
124                 return true;
125             });
126     return sensors;
127 }
128 
dump() const129 std::string SensorList::dump() const {
130     String8 result;
131 
132     forEachSensor([&result] (const Sensor& s) -> bool {
133             result.appendFormat(
134                     "%#010x) %-25s | %-15s | ver: %" PRId32 " | type: %20s(%" PRId32
135                         ") | perm: %s | flags: 0x%08x\n",
136                     s.getHandle(),
137                     s.getName().string(),
138                     s.getVendor().string(),
139                     s.getVersion(),
140                     s.getStringType().string(),
141                     s.getType(),
142                     s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a",
143                     static_cast<int>(s.getFlags()));
144 
145             result.append("\t");
146             const int reportingMode = s.getReportingMode();
147             if (reportingMode == AREPORTING_MODE_CONTINUOUS) {
148                 result.append("continuous | ");
149             } else if (reportingMode == AREPORTING_MODE_ON_CHANGE) {
150                 result.append("on-change | ");
151             } else if (reportingMode == AREPORTING_MODE_ONE_SHOT) {
152                 result.append("one-shot | ");
153             } else if (reportingMode == AREPORTING_MODE_SPECIAL_TRIGGER) {
154                 result.append("special-trigger | ");
155             } else {
156                 result.append("unknown-mode | ");
157             }
158 
159             if (s.getMaxDelay() > 0) {
160                 result.appendFormat("minRate=%.2fHz | ", 1e6f / s.getMaxDelay());
161             } else {
162                 result.appendFormat("maxDelay=%" PRId32 "us | ", s.getMaxDelay());
163             }
164 
165             if (s.getMinDelay() > 0) {
166                 result.appendFormat("maxRate=%.2fHz | ", 1e6f / s.getMinDelay());
167             } else {
168                 result.appendFormat("minDelay=%" PRId32 "us | ", s.getMinDelay());
169             }
170 
171             if (s.getFifoMaxEventCount() > 0) {
172                 result.appendFormat("FIFO (max,reserved) = (%" PRIu32 ", %" PRIu32 ") events | ",
173                         s.getFifoMaxEventCount(),
174                         s.getFifoReservedEventCount());
175             } else {
176                 result.append("no batching | ");
177             }
178 
179             if (s.isWakeUpSensor()) {
180                 result.appendFormat("wakeUp | ");
181             } else {
182                 result.appendFormat("non-wakeUp | ");
183             }
184 
185             if (s.isDataInjectionSupported()) {
186                 result.appendFormat("data-injection, ");
187             }
188 
189             if (s.isDynamicSensor()) {
190                 result.appendFormat("dynamic, ");
191             }
192 
193             if (s.hasAdditionalInfo()) {
194                 result.appendFormat("has-additional-info, ");
195             }
196             result.append("\n");
197 
198             if (s.getHighestDirectReportRateLevel() > SENSOR_DIRECT_RATE_STOP) {
199                 result.appendFormat("\thighest rate level = %d, support shared mem: ",
200                         s.getHighestDirectReportRateLevel());
201                 if (s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_ASHMEM)) {
202                     result.append("ashmem, ");
203                 }
204                 if (s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_GRALLOC)) {
205                     result.append("gralloc, ");
206                 }
207                 result.append("\n");
208             }
209             return true;
210         });
211     return std::string(result.string());
212 }
213 
214 /**
215  * Dump debugging information as android.service.SensorListProto protobuf message using
216  * ProtoOutputStream.
217  *
218  * See proto definition and some notes about ProtoOutputStream in
219  * frameworks/base/core/proto/android/service/sensor_service.proto
220  */
dump(util::ProtoOutputStream * proto) const221 void SensorList::dump(util::ProtoOutputStream* proto) const {
222     using namespace service::SensorListProto;
223     using namespace service::SensorListProto::SensorProto;
224 
225     forEachSensor([&proto] (const Sensor& s) -> bool {
226         const uint64_t token = proto->start(SENSORS);
227         proto->write(HANDLE, s.getHandle());
228         proto->write(NAME, std::string(s.getName().string()));
229         proto->write(VENDOR, std::string(s.getVendor().string()));
230         proto->write(VERSION, s.getVersion());
231         proto->write(STRING_TYPE, std::string(s.getStringType().string()));
232         proto->write(TYPE, s.getType());
233         proto->write(REQUIRED_PERMISSION, std::string(s.getRequiredPermission().size() ?
234                 s.getRequiredPermission().string() : ""));
235         proto->write(FLAGS, int(s.getFlags()));
236         switch (s.getReportingMode()) {
237             case AREPORTING_MODE_CONTINUOUS:
238                 proto->write(REPORTING_MODE, RM_CONTINUOUS);
239                 break;
240             case AREPORTING_MODE_ON_CHANGE:
241                 proto->write(REPORTING_MODE, RM_ON_CHANGE);
242                 break;
243             case AREPORTING_MODE_ONE_SHOT:
244                 proto->write(REPORTING_MODE, RM_ONE_SHOT);
245                 break;
246             case AREPORTING_MODE_SPECIAL_TRIGGER:
247                 proto->write(REPORTING_MODE, RM_SPECIAL_TRIGGER);
248                 break;
249             default:
250                 proto->write(REPORTING_MODE, RM_UNKNOWN);
251         }
252         proto->write(MAX_DELAY_US, s.getMaxDelay());
253         proto->write(MIN_DELAY_US, s.getMinDelay());
254         proto->write(FIFO_MAX_EVENT_COUNT, int(s.getFifoMaxEventCount()));
255         proto->write(FIFO_RESERVED_EVENT_COUNT, int(s.getFifoReservedEventCount()));
256         proto->write(IS_WAKEUP, s.isWakeUpSensor());
257         proto->write(DATA_INJECTION_SUPPORTED, s.isDataInjectionSupported());
258         proto->write(IS_DYNAMIC, s.isDynamicSensor());
259         proto->write(HAS_ADDITIONAL_INFO, s.hasAdditionalInfo());
260         proto->write(HIGHEST_RATE_LEVEL, s.getHighestDirectReportRateLevel());
261         proto->write(ASHMEM, s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_ASHMEM));
262         proto->write(GRALLOC, s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_GRALLOC));
263         proto->write(MIN_VALUE, s.getMinValue());
264         proto->write(MAX_VALUE, s.getMaxValue());
265         proto->write(RESOLUTION, s.getResolution());
266         proto->write(POWER_USAGE, s.getPowerUsage());
267         proto->end(token);
268         return true;
269     });
270 }
271 
~SensorList()272 SensorList::~SensorList() {
273 }
274 
275 } // namespace SensorServiceUtil
276 } // namespace android
277 
278