MH2 | Write processedEvents instead of original events.

Fix bug where the HalProxyCallback::postEvents method was passing the
unaltered events vector to HalProxy::postEventsToMessageQueue instead of
the processedEvents with altered sensorHandles. Add a unit test to test
that the proper sensorHandles are seen compared to the event posted from
subhal.

Additionally, fix problems with fake subhals and their dummy sensors
that allows VTS tests to pass all tests.

Bug: 136511617
Test: New unit tests pass and VTS tests under module
VtsHalSensorsV2_0Target passing.
Change-Id: If30da03a2399666700844523cd1104b07f6b65d2
This commit is contained in:
Stan Rokita 2019-10-22 12:08:47 -07:00
parent e7697c9a8b
commit 07b442e96c
6 changed files with 154 additions and 134 deletions

View file

@ -330,7 +330,7 @@ Return<void> HalProxy::onDynamicSensorsConnected(const hidl_vec<SensorInfo>& dyn
Return<void> HalProxy::onDynamicSensorsDisconnected(
const hidl_vec<int32_t>& dynamicSensorHandlesRemoved, int32_t subHalIndex) {
// TODO: Block this call until all pending events are flushed from queue
// TODO(b/143302327): Block this call until all pending events are flushed from queue
std::vector<int32_t> sensorHandles;
{
std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
@ -457,7 +457,8 @@ void HalProxy::startPendingWritesThread(HalProxy* halProxy) {
}
void HalProxy::handlePendingWrites() {
// TODO: Find a way to optimize locking strategy maybe using two mutexes instead of one.
// TODO(b/143302327): Find a way to optimize locking strategy maybe using two mutexes instead of
// one.
std::unique_lock<std::mutex> lock(mEventQueueWriteMutex);
while (mThreadsRun.load()) {
mEventQueueWriteCV.wait(
@ -485,8 +486,8 @@ void HalProxy::handlePendingWrites() {
}
lock.lock();
if (pendingWriteEvents.size() > eventQueueSize) {
// TODO: Check if this erase operation is too inefficient. It will copy all the
// events ahead of it down to fill gap off array at front after the erase.
// TODO(b/143302327): Check if this erase operation is too inefficient. It will copy
// all the events ahead of it down to fill gap off array at front after the erase.
pendingWriteEvents.erase(pendingWriteEvents.begin(),
pendingWriteEvents.begin() + eventQueueSize);
} else {
@ -554,8 +555,8 @@ void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events, size_t
numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
if (numToWrite > 0) {
if (mEventQueue->write(events.data(), numToWrite)) {
// TODO: While loop if mEventQueue->avaiableToWrite > 0 to possibly fit in more
// writes immediately
// TODO(b/143302327): While loop if mEventQueue->avaiableToWrite > 0 to possibly fit
// in more writes immediately
mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
} else {
numToWrite = 0;
@ -563,8 +564,8 @@ void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events, size_t
}
}
if (numToWrite < events.size()) {
// TODO: Bound the mPendingWriteEventsQueue so that we do not trigger OOMs if framework
// stalls
// TODO(b/143302327): Bound the mPendingWriteEventsQueue so that we do not trigger OOMs if
// framework stalls
std::vector<Event> eventsLeft(events.begin() + numToWrite, events.end());
mPendingWriteEventsQueue.push({eventsLeft, numWakeupEvents});
mEventQueueWriteCV.notify_one();
@ -655,7 +656,7 @@ void HalProxyCallback::postEvents(const std::vector<Event>& events, ScopedWakelo
" w/ index %zu.",
mSubHalIndex);
}
mHalProxy->postEventsToMessageQueue(events, numWakeupEvents, std::move(wakelock));
mHalProxy->postEventsToMessageQueue(processedEvents, numWakeupEvents, std::move(wakelock));
}
ScopedWakelock HalProxyCallback::createScopedWakelock(bool lock) {

View file

@ -27,6 +27,7 @@ cc_defaults {
"android.hardware.sensors@2.0",
"libcutils",
"libfmq",
"libhardware",
"libhidlbase",
"liblog",
"libpower",
@ -85,6 +86,7 @@ cc_test {
"libbase",
"libcutils",
"libfmq",
"libhardware",
"libhidlbase",
"liblog",
"libpower",

View file

@ -692,6 +692,38 @@ TEST(HalProxyTest, InvalidSensorHandleSubHalIndexProxyCalls) {
EXPECT_EQ(proxy.injectSensorData(event), Result::BAD_VALUE);
}
TEST(HalProxyTest, PostedEventSensorHandleSubHalIndexValid) {
constexpr size_t kQueueSize = 5;
constexpr int32_t subhal1Index = 0;
constexpr int32_t subhal2Index = 1;
AllSensorsSubHal subhal1;
AllSensorsSubHal subhal2;
std::vector<ISensorsSubHal*> subHals{&subhal1, &subhal2};
std::unique_ptr<EventMessageQueue> eventQueue = makeEventFMQ(kQueueSize);
std::unique_ptr<WakeupMessageQueue> wakeLockQueue = makeWakelockFMQ(kQueueSize);
::android::sp<ISensorsCallback> callback = new SensorsCallback();
HalProxy proxy(subHals);
proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback);
int32_t sensorHandleToPost = 0x00000001;
Event eventIn = makeAccelerometerEvent();
eventIn.sensorHandle = sensorHandleToPost;
std::vector<Event> eventsToPost{eventIn};
subhal1.postEvents(eventsToPost, false);
Event eventOut;
EXPECT_TRUE(eventQueue->read(&eventOut));
EXPECT_EQ(eventOut.sensorHandle, (subhal1Index << 24) | sensorHandleToPost);
subhal2.postEvents(eventsToPost, false);
EXPECT_TRUE(eventQueue->read(&eventOut));
EXPECT_EQ(eventOut.sensorHandle, (subhal2Index << 24) | sensorHandleToPost);
}
// Helper implementations follow
void testSensorsListFromProxyAndSubHal(const std::vector<SensorInfo>& proxySensorsList,
const std::vector<SensorInfo>& subHalSensorsList) {

View file

@ -16,6 +16,7 @@
#include "Sensor.h"
#include <hardware/sensors.h>
#include <utils/SystemClock.h>
#include <cmath>
@ -31,14 +32,21 @@ using ::android::hardware::sensors::V1_0::MetaDataEventType;
using ::android::hardware::sensors::V1_0::SensorFlagBits;
using ::android::hardware::sensors::V1_0::SensorStatus;
static constexpr float kDefaultMaxDelayUs = 10 * 1000 * 1000;
Sensor::Sensor(ISensorsEventCallback* callback)
Sensor::Sensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: mIsEnabled(false),
mSamplingPeriodNs(0),
mLastSampleTimeNs(0),
mCallback(callback),
mMode(OperationMode::NORMAL) {
mSensorInfo.sensorHandle = sensorHandle;
mSensorInfo.vendor = "Vendor String";
mSensorInfo.version = 1;
constexpr float kDefaultMaxDelayUs = 1000 * 1000;
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
mSensorInfo.flags = 0;
mRunThread = std::thread(startThread, this);
}
@ -171,8 +179,10 @@ Result Sensor::injectEvent(const Event& event) {
return result;
}
OnChangeSensor::OnChangeSensor(ISensorsEventCallback* callback)
: Sensor(callback), mPreviousEventSet(false) {}
OnChangeSensor::OnChangeSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: Sensor(sensorHandle, callback), mPreviousEventSet(false) {
mSensorInfo.flags |= SensorFlagBits::ON_CHANGE_MODE;
}
void OnChangeSensor::activate(bool enable) {
Sensor::activate(enable);
@ -196,175 +206,139 @@ std::vector<Event> OnChangeSensor::readEvents() {
return outputEvents;
}
AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
ContinuousSensor::ContinuousSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: Sensor(sensorHandle, callback) {
mSensorInfo.flags |= SensorFlagBits::CONTINUOUS_MODE;
}
AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: ContinuousSensor(sensorHandle, callback) {
mSensorInfo.name = "Accel Sensor";
mSensorInfo.vendor = "Vendor String";
mSensorInfo.version = 1;
mSensorInfo.type = SensorType::ACCELEROMETER;
mSensorInfo.typeAsString = "";
mSensorInfo.typeAsString = SENSOR_STRING_TYPE_ACCELEROMETER;
mSensorInfo.maxRange = 78.4f; // +/- 8g
mSensorInfo.resolution = 1.52e-5;
mSensorInfo.power = 0.001f; // mA
mSensorInfo.minDelay = 20 * 1000; // microseconds
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::DATA_INJECTION);
};
mSensorInfo.flags |= SensorFlagBits::DATA_INJECTION;
}
std::vector<Event> AccelSensor::readEvents() {
std::vector<Event> events;
Event event;
event.sensorHandle = mSensorInfo.sensorHandle;
event.sensorType = mSensorInfo.type;
event.timestamp = ::android::elapsedRealtimeNano();
event.u.vec3.x = 0;
event.u.vec3.y = 0;
event.u.vec3.z = -9.815;
event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
events.push_back(event);
return events;
}
PressureSensor::PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: Sensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
: ContinuousSensor(sensorHandle, callback) {
mSensorInfo.name = "Pressure Sensor";
mSensorInfo.vendor = "Vendor String";
mSensorInfo.version = 1;
mSensorInfo.type = SensorType::PRESSURE;
mSensorInfo.typeAsString = "";
mSensorInfo.typeAsString = SENSOR_STRING_TYPE_PRESSURE;
mSensorInfo.maxRange = 1100.0f; // hPa
mSensorInfo.resolution = 0.005f; // hPa
mSensorInfo.power = 0.001f; // mA
mSensorInfo.minDelay = 100 * 1000; // microseconds
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
mSensorInfo.flags = 0;
};
}
MagnetometerSensor::MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: Sensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
: ContinuousSensor(sensorHandle, callback) {
mSensorInfo.name = "Magnetic Field Sensor";
mSensorInfo.vendor = "Vendor String";
mSensorInfo.version = 1;
mSensorInfo.type = SensorType::MAGNETIC_FIELD;
mSensorInfo.typeAsString = "";
mSensorInfo.typeAsString = SENSOR_STRING_TYPE_MAGNETIC_FIELD;
mSensorInfo.maxRange = 1300.0f;
mSensorInfo.resolution = 0.01f;
mSensorInfo.power = 0.001f; // mA
mSensorInfo.minDelay = 20 * 1000; // microseconds
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
mSensorInfo.flags = 0;
};
}
LightSensor::LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: OnChangeSensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
: OnChangeSensor(sensorHandle, callback) {
mSensorInfo.name = "Light Sensor";
mSensorInfo.vendor = "Vendor String";
mSensorInfo.version = 1;
mSensorInfo.type = SensorType::LIGHT;
mSensorInfo.typeAsString = "";
mSensorInfo.typeAsString = SENSOR_STRING_TYPE_LIGHT;
mSensorInfo.maxRange = 43000.0f;
mSensorInfo.resolution = 10.0f;
mSensorInfo.power = 0.001f; // mA
mSensorInfo.minDelay = 200 * 1000; // microseconds
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
};
}
ProximitySensor::ProximitySensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: OnChangeSensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
: OnChangeSensor(sensorHandle, callback) {
mSensorInfo.name = "Proximity Sensor";
mSensorInfo.vendor = "Vendor String";
mSensorInfo.version = 1;
mSensorInfo.type = SensorType::PROXIMITY;
mSensorInfo.typeAsString = "";
mSensorInfo.typeAsString = SENSOR_STRING_TYPE_PROXIMITY;
mSensorInfo.maxRange = 5.0f;
mSensorInfo.resolution = 1.0f;
mSensorInfo.power = 0.012f; // mA
mSensorInfo.minDelay = 200 * 1000; // microseconds
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
mSensorInfo.flags =
static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE | SensorFlagBits::WAKE_UP);
};
mSensorInfo.flags |= SensorFlagBits::WAKE_UP;
}
GyroSensor::GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
GyroSensor::GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: ContinuousSensor(sensorHandle, callback) {
mSensorInfo.name = "Gyro Sensor";
mSensorInfo.vendor = "Vendor String";
mSensorInfo.version = 1;
mSensorInfo.type = SensorType::GYROSCOPE;
mSensorInfo.typeAsString = "";
mSensorInfo.typeAsString = SENSOR_STRING_TYPE_GYROSCOPE;
mSensorInfo.maxRange = 1000.0f * M_PI / 180.0f;
mSensorInfo.resolution = 1000.0f * M_PI / (180.0f * 32768.0f);
mSensorInfo.power = 0.001f;
mSensorInfo.minDelay = 2.5f * 1000; // microseconds
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
mSensorInfo.flags = 0;
};
}
std::vector<Event> GyroSensor::readEvents() {
std::vector<Event> events;
Event event;
event.sensorHandle = mSensorInfo.sensorHandle;
event.sensorType = mSensorInfo.type;
event.timestamp = ::android::elapsedRealtimeNano();
event.u.vec3.x = 0;
event.u.vec3.y = 0;
event.u.vec3.z = 0;
event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
events.push_back(event);
return events;
}
AmbientTempSensor::AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: OnChangeSensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
: OnChangeSensor(sensorHandle, callback) {
mSensorInfo.name = "Ambient Temp Sensor";
mSensorInfo.vendor = "Vendor String";
mSensorInfo.version = 1;
mSensorInfo.type = SensorType::AMBIENT_TEMPERATURE;
mSensorInfo.typeAsString = "";
mSensorInfo.typeAsString = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
mSensorInfo.maxRange = 80.0f;
mSensorInfo.resolution = 0.01f;
mSensorInfo.power = 0.001f;
mSensorInfo.minDelay = 40 * 1000; // microseconds
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
};
}
DeviceTempSensor::DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: OnChangeSensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
: ContinuousSensor(sensorHandle, callback) {
mSensorInfo.name = "Device Temp Sensor";
mSensorInfo.vendor = "Vendor String";
mSensorInfo.version = 1;
mSensorInfo.type = SensorType::TEMPERATURE;
mSensorInfo.typeAsString = "";
mSensorInfo.typeAsString = SENSOR_STRING_TYPE_TEMPERATURE;
mSensorInfo.maxRange = 80.0f;
mSensorInfo.resolution = 0.01f;
mSensorInfo.power = 0.001f;
mSensorInfo.minDelay = 40 * 1000; // microseconds
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
}
RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle,
ISensorsEventCallback* callback)
: OnChangeSensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
: OnChangeSensor(sensorHandle, callback) {
mSensorInfo.name = "Relative Humidity Sensor";
mSensorInfo.vendor = "Vendor String";
mSensorInfo.version = 1;
mSensorInfo.type = SensorType::RELATIVE_HUMIDITY;
mSensorInfo.typeAsString = "";
mSensorInfo.typeAsString = SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
mSensorInfo.maxRange = 100.0f;
mSensorInfo.resolution = 0.1f;
mSensorInfo.power = 0.001f;
mSensorInfo.minDelay = 40 * 1000; // microseconds
mSensorInfo.maxDelay = kDefaultMaxDelayUs;
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
}
} // namespace implementation

View file

@ -45,7 +45,7 @@ class ISensorsEventCallback {
class Sensor {
public:
Sensor(ISensorsEventCallback* callback);
Sensor(int32_t sensorHandle, ISensorsEventCallback* callback);
virtual ~Sensor();
const SensorInfo& getSensorInfo() const;
@ -81,7 +81,7 @@ class Sensor {
class OnChangeSensor : public Sensor {
public:
OnChangeSensor(ISensorsEventCallback* callback);
OnChangeSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
virtual void activate(bool enable) override;
@ -93,14 +93,40 @@ class OnChangeSensor : public Sensor {
bool mPreviousEventSet;
};
class AccelSensor : public Sensor {
class ContinuousSensor : public Sensor {
public:
AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
ContinuousSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
class GyroSensor : public Sensor {
class AccelSensor : public ContinuousSensor {
public:
AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
protected:
std::vector<Event> readEvents() override;
};
class GyroSensor : public ContinuousSensor {
public:
GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
protected:
std::vector<Event> readEvents() override;
};
class DeviceTempSensor : public ContinuousSensor {
public:
DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
class PressureSensor : public ContinuousSensor {
public:
PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
class MagnetometerSensor : public ContinuousSensor {
public:
MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
class AmbientTempSensor : public OnChangeSensor {
@ -108,21 +134,6 @@ class AmbientTempSensor : public OnChangeSensor {
AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
class DeviceTempSensor : public OnChangeSensor {
public:
DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
class PressureSensor : public Sensor {
public:
PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
class MagnetometerSensor : public Sensor {
public:
MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
class LightSensor : public OnChangeSensor {
public:
LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback);

View file

@ -172,11 +172,11 @@ ContinuousSensorsSubHal::ContinuousSensorsSubHal() {
AddSensor<GyroSensor>();
AddSensor<MagnetometerSensor>();
AddSensor<PressureSensor>();
AddSensor<DeviceTempSensor>();
}
OnChangeSensorsSubHal::OnChangeSensorsSubHal() {
AddSensor<AmbientTempSensor>();
AddSensor<DeviceTempSensor>();
AddSensor<LightSensor>();
AddSensor<ProximitySensor>();
AddSensor<RelativeHumiditySensor>();
@ -187,8 +187,8 @@ AllSensorsSubHal::AllSensorsSubHal() {
AddSensor<GyroSensor>();
AddSensor<MagnetometerSensor>();
AddSensor<PressureSensor>();
AddSensor<AmbientTempSensor>();
AddSensor<DeviceTempSensor>();
AddSensor<AmbientTempSensor>();
AddSensor<LightSensor>();
AddSensor<ProximitySensor>();
AddSensor<RelativeHumiditySensor>();