summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Lobdell <slobdell@google.com>2022-04-22 23:24:21 +0000
committerScott Lobdell <slobdell@google.com>2022-04-22 23:40:41 +0000
commit2e6182b4b608ca00559de04084e2f68cfc46c389 (patch)
tree77c11c7672223a23221dc29474309137a38e17ef
parentaecd66d2dea7a86bc32f2edb2cd04ad42455e1ee (diff)
parente22fdee1f283f965d9a85a0e6696ed4a39c3f41d (diff)
Merge TP1A.220414.003
Change-Id: Iecefb8eca9f62fc58105cc85d1e04c9f0623a4d0
-rw-r--r--modules/sensors/dynamic_sensor/DynamicSensorManager.cpp85
-rw-r--r--modules/sensors/dynamic_sensor/DynamicSensorManager.h35
-rw-r--r--modules/sensors/dynamic_sensor/HidRawSensor.cpp20
-rw-r--r--modules/sensors/dynamic_sensor/HidRawSensor.h2
-rw-r--r--modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp10
5 files changed, 125 insertions, 27 deletions
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
index be1a0044..efac5e95 100644
--- a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
@@ -87,7 +87,7 @@ int DynamicSensorManager::activate(int handle, bool enable) {
}
return operateSensor(handle,
- [&enable] (sp<BaseSensorObject> s)->int {
+ [=] (sp<BaseSensorObject> s)->int {
return s->enable(enable);
});
}
@@ -98,7 +98,7 @@ int DynamicSensorManager::batch(int handle, nsecs_t sample_period, nsecs_t batch
return 0;
}
return operateSensor(handle,
- [&sample_period, &batch_period] (sp<BaseSensorObject> s)->int {
+ [=] (sp<BaseSensorObject> s)->int {
return s->batch(sample_period, batch_period);
});
}
@@ -239,6 +239,87 @@ const sensor_t& DynamicSensorManager::getDynamicMetaSensor() const {
return mMetaSensor;
}
+int DynamicSensorManager::operateSensor(
+ int handle, OperateSensorFunc sensorFunc) {
+ std::shared_future<int> sensorOp;
+ {
+ std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
+
+ // Invoke the function asynchronously.
+ sensorOp = std::async(
+ [this, handle = handle, sensorFunc = sensorFunc,
+ sensorOpIndex = mNextSensorOpIndex] ()->int {
+ return operateSensor(handle, sensorFunc, sensorOpIndex);
+ }).share();
+
+ // Add sensor operation to the queue.
+ mSensorOpQueue.push({mNextSensorOpIndex, sensorOp});
+ mNextSensorOpIndex++;
+ }
+
+ // Wait for the sensor operation to complete.
+ if (sensorOp.wait_for(kSensorOpTimeout) != std::future_status::ready) {
+ ALOGE("sensor operation timed out");
+ return TIMED_OUT;
+ }
+
+ return sensorOp.get();
+}
+
+int DynamicSensorManager::operateSensor(
+ int handle, OperateSensorFunc sensorFunc, uint64_t sensorOpIndex) {
+ int rv = 0;
+
+ // Wait until this sensor operation is at the head of the queue.
+ while (1) {
+ std::shared_future<int> headSensorOp;
+
+ {
+ std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
+
+ if (mSensorOpQueue.front().first == sensorOpIndex) {
+ break;
+ }
+ headSensorOp = mSensorOpQueue.front().second;
+ }
+ headSensorOp.wait();
+ }
+
+ // Perform sensor operation.
+ sp<BaseSensorObject> sensor;
+ {
+ std::lock_guard<std::mutex> lk(mLock);
+ const auto i = mMap.find(handle);
+ if (i == mMap.end()) {
+ rv = BAD_VALUE;
+ }
+ if (rv == 0) {
+ sensor = i->second.promote();
+ if (sensor == nullptr) {
+ // sensor object is already gone
+ rv = BAD_VALUE;
+ }
+ }
+ }
+ if (rv == 0) {
+ rv = sensorFunc(sensor);
+ }
+
+ // Remove sensor operation from queue. When the operation's shared state is
+ // destroyed, execution of this function ceases. Thus, if the state is
+ // destroyed when the operation is removed from the queue, the lock will
+ // never be released. To prevent that, the state is shared locally, so it
+ // isn't destroyed until this function completes.
+ std::shared_future<int> sensorOp;
+ {
+ std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
+ sensorOp = mSensorOpQueue.front().second;
+ mSensorOpQueue.pop();
+ }
+
+ return rv;
+}
+
DynamicSensorManager::ConnectionReport::ConnectionReport(
int handle, sp<BaseSensorObject> sensor) :
mSensor(*(sensor->getSensor())),
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.h b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
index 264582ec..b8a73203 100644
--- a/modules/sensors/dynamic_sensor/DynamicSensorManager.h
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
@@ -22,7 +22,9 @@
#include <hardware/sensors.h>
#include <utils/RefBase.h>
+#include <future>
#include <mutex>
+#include <queue>
#include <string>
#include <unordered_map>
#include <vector>
@@ -92,24 +94,13 @@ private:
// returns next available handle to use upon a new sensor connection, or -1 if we run out.
int getNextAvailableHandle();
- // TF: int foo(sp<BaseSensorObject> obj);
- template <typename TF>
- int operateSensor(int handle, TF f) const {
- sp<BaseSensorObject> s;
- {
- std::lock_guard<std::mutex> lk(mLock);
- const auto i = mMap.find(handle);
- if (i == mMap.end()) {
- return BAD_VALUE;
- }
- s = i->second.promote();
- if (s == nullptr) {
- // sensor object is already gone
- return BAD_VALUE;
- }
- }
- return f(s);
- }
+ // Runs a sensor function with a timeout. On timeout, function could still
+ // be running, so any function parameter or closure lifetimes should match
+ // the function's lifetime.
+ using OperateSensorFunc = std::function<int(sp<BaseSensorObject>)>;
+ int operateSensor(int handle, OperateSensorFunc sensorFunc);
+ int operateSensor(int handle, OperateSensorFunc sensorFunc,
+ uint64_t sensorOpIndex);
// available sensor handle space
const std::pair<int, int> mHandleRange;
@@ -133,6 +124,14 @@ private:
// daemons
std::vector<sp<BaseDynamicSensorDaemon>> mDaemonVector;
+
+ // Sensor operation queue. Calls to the sensor HAL must complete within 1
+ // second.
+ static constexpr std::chrono::milliseconds
+ kSensorOpTimeout = std::chrono::milliseconds(900);
+ std::mutex mSensorOpQueueLock;
+ std::queue<std::pair<uint64_t, std::shared_future<int>>> mSensorOpQueue;
+ uint64_t mNextSensorOpIndex = 0;
};
} // namespace SensorHalExt
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.cpp b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
index 4520ddaa..3759e7e9 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensor.cpp
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.cpp
@@ -891,10 +891,18 @@ bool HidRawSensor::findSensorControlUsage(const std::vector<HidParser::ReportPac
mReportIntervalId = reportInterval->id;
mReportIntervalBitOffset = reportInterval->bitOffset;
mReportIntervalBitSize = reportInterval->bitSize;
-
- mFeatureInfo.minDelay = std::max(static_cast<int64_t>(1), reportInterval->minRaw) * 1000;
- mFeatureInfo.maxDelay = std::min(static_cast<int64_t>(1000000),
- reportInterval->maxRaw) * 1000; // maximum 1000 second
+ mReportIntervalScale = reportInterval->a;
+ mReportIntervalOffset = reportInterval->b;
+
+ mFeatureInfo.minDelay = 1000000.0
+ * (reportInterval->minRaw + reportInterval->b)
+ * reportInterval->a;
+ mFeatureInfo.minDelay = std::max(1000, mFeatureInfo.minDelay);
+ mFeatureInfo.maxDelay = 1000000.0
+ * (reportInterval->maxRaw + reportInterval->b)
+ * reportInterval->a;
+ mFeatureInfo.maxDelay = std::min(static_cast<int64_t>(1000000000),
+ mFeatureInfo.maxDelay);
}
return true;
return (mPowerStateId >= 0 || mReportingStateId >= 0) && mReportIntervalId >= 0;
@@ -981,7 +989,9 @@ int HidRawSensor::batch(int64_t samplingPeriod, int64_t batchingPeriod) {
if (device->getFeature(id, &buffer)
&& (8 * buffer.size()) >=
(mReportIntervalBitOffset + mReportIntervalBitSize)) {
- int64_t periodMs = samplingPeriod / 1000000; //ns -> ms
+ int64_t periodMs =
+ (((static_cast<double>(samplingPeriod)) / 1000000000.0)
+ / mReportIntervalScale) - mReportIntervalOffset;
int64_t maxPeriodMs =
(1LL << std::min(mReportIntervalBitSize, 63U)) - 1;
periodMs = std::min(periodMs, maxPeriodMs);
diff --git a/modules/sensors/dynamic_sensor/HidRawSensor.h b/modules/sensors/dynamic_sensor/HidRawSensor.h
index 66843fcd..074482a8 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensor.h
+++ b/modules/sensors/dynamic_sensor/HidRawSensor.h
@@ -195,6 +195,8 @@ private:
int mReportIntervalId;
unsigned int mReportIntervalBitOffset;
unsigned int mReportIntervalBitSize;
+ double mReportIntervalScale;
+ int64_t mReportIntervalOffset;
// Input report translate table
std::vector<ReportTranslateRecord> mTranslateTable;
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp
index 19aa4291..63210200 100644
--- a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp
@@ -240,8 +240,14 @@ std::vector<HidParser::ReportPacket> HidParser::convertGroupToPacket(
auto logical = r.getLogicalRange();
auto physical = r.getPhysicalRange();
- double scale = static_cast<double>((physical.second - physical.first))
- / (logical.second - logical.first);
+ double scale;
+ if ((physical.first != physical.second) &&
+ (logical.first != logical.second)) {
+ scale = static_cast<double>(physical.second - physical.first)
+ / (logical.second - logical.first);
+ } else {
+ scale = (physical.first != 0) ? physical.first : 1.0;
+ }
scale *= r.getExponentValue();
int64_t offset =
(physical.first * r.getExponentValue() / scale) -