/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SensorList.h"
#include <hardware/sensors.h>
#include <utils/String8.h>
#include <cinttypes>
namespace android {
namespace SensorServiceUtil {
const Sensor SensorList::mNonSensor = Sensor("unknown");
bool SensorList::add(
int handle, SensorInterface* si, bool isForDebug, bool isVirtual) {
std::lock_guard<std::mutex> lk(mLock);
if (handle == si->getSensor().getHandle() &&
mUsedHandle.insert(handle).second) {
// will succeed as the mUsedHandle does not have this handle
mHandleMap.emplace(handle, Entry(si, isForDebug, isVirtual));
return true;
}
// handle exist already or handle mismatch
return false;
}
bool SensorList::remove(int handle) {
std::lock_guard<std::mutex> lk(mLock);
auto entry = mHandleMap.find(handle);
if (entry != mHandleMap.end()) {
mHandleMap.erase(entry);
return true;
}
return false;
}
String8 SensorList::getName(int handle) const {
return getOne<String8>(
handle, [] (const Entry& e) -> String8 {return e.si->getSensor().getName();},
mNonSensor.getName());
}
sp<SensorInterface> SensorList::getInterface(int handle) const {
return getOne<sp<SensorInterface>>(
handle, [] (const Entry& e) -> sp<SensorInterface> {return e.si;}, nullptr);
}
bool SensorList::isNewHandle(int handle) const {
std::lock_guard<std::mutex> lk(mLock);
return mUsedHandle.find(handle) == mUsedHandle.end();
}
const Vector<Sensor> SensorList::getUserSensors() const {
// lock in forEachEntry
Vector<Sensor> sensors;
forEachEntry(
[&sensors] (const Entry& e) -> bool {
if (!e.isForDebug && !e.si->getSensor().isDynamicSensor()) {
sensors.add(e.si->getSensor());
}
return true;
});
return sensors;
}
const Vector<Sensor> SensorList::getUserDebugSensors() const {
// lock in forEachEntry
Vector<Sensor> sensors;
forEachEntry(
[&sensors] (const Entry& e) -> bool {
if (!e.si->getSensor().isDynamicSensor()) {
sensors.add(e.si->getSensor());
}
return true;
});
return sensors;
}
const Vector<Sensor> SensorList::getDynamicSensors() const {
// lock in forEachEntry
Vector<Sensor> sensors;
forEachEntry(
[&sensors] (const Entry& e) -> bool {
if (!e.isForDebug && e.si->getSensor().isDynamicSensor()) {
sensors.add(e.si->getSensor());
}
return true;
});
return sensors;
}
const Vector<Sensor> SensorList::getVirtualSensors() const {
// lock in forEachEntry
Vector<Sensor> sensors;
forEachEntry(
[&sensors] (const Entry& e) -> bool {
if (e.isVirtual) {
sensors.add(e.si->getSensor());
}
return true;
});
return sensors;
}
std::string SensorList::dump() const {
String8 result;
forEachSensor([&result] (const Sensor& s) -> bool {
result.appendFormat(
"%#010x) %-25s | %-15s | ver: %" PRId32 " | type: %20s(%" PRId32
") | perm: %s\n\t",
s.getHandle(),
s.getName().string(),
s.getVendor().string(),
s.getVersion(),
s.getStringType().string(),
s.getType(),
s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a");
const int reportingMode = s.getReportingMode();
if (reportingMode == AREPORTING_MODE_CONTINUOUS) {
result.append(" continuous | ");
} else if (reportingMode == AREPORTING_MODE_ON_CHANGE) {
result.append(" on-change | ");
} else if (reportingMode == AREPORTING_MODE_ONE_SHOT) {
result.append(" one-shot | ");
} else if (reportingMode == AREPORTING_MODE_SPECIAL_TRIGGER) {
result.append(" special-trigger | ");
} else {
result.append(" unknown-mode | ");
}
if (s.getMaxDelay() > 0) {
result.appendFormat("minRate=%.2fHz | ", 1e6f / s.getMaxDelay());
} else {
result.appendFormat("maxDelay=%" PRId32 "us | ", s.getMaxDelay());
}
if (s.getMinDelay() > 0) {
result.appendFormat("maxRate=%.2fHz | ", 1e6f / s.getMinDelay());
} else {
result.appendFormat("minDelay=%" PRId32 "us | ", s.getMinDelay());
}
if (s.getFifoMaxEventCount() > 0) {
result.appendFormat("FIFO (max,reserved) = (%" PRIu32 ", %" PRIu32 ") events | ",
s.getFifoMaxEventCount(),
s.getFifoReservedEventCount());
} else {
result.append("no batching | ");
}
if (s.isWakeUpSensor()) {
result.appendFormat("wakeUp | ");
} else {
result.appendFormat("non-wakeUp | ");
}
if (s.isDynamicSensor()) {
result.appendFormat("dynamic, ");
}
if (s.hasAdditionalInfo()) {
result.appendFormat("has-additional-info, ");
}
result.append("\n");
return true;
});
return std::string(result.string());
}
SensorList::~SensorList() {
}
} // namespace SensorServiceUtil
} // namespace android