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 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 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 52 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 58 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 64 bool SensorList::isNewHandle(int handle) const { 65 std::lock_guard<std::mutex> lk(mLock); 66 return mUsedHandle.find(handle) == mUsedHandle.end(); 67 } 68 69 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 82 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 95 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 108 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 121 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 206 SensorList::~SensorList() { 207 } 208 209 } // namespace SensorServiceUtil 210 } // namespace android 211 212