Merge "Camera: Fix a crash in removeCamera()"
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index e117a98..fd996fb 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -145,7 +145,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.drm</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>ICryptoFactory</name>
<regex-instance>.*</regex-instance>
@@ -157,7 +157,7 @@
</hal>
<hal format="hidl" optional="false">
<name>android.hardware.drm</name>
- <version>1.1</version>
+ <version>1.2</version>
<interface>
<name>ICryptoFactory</name>
<regex-instance>.*</regex-instance>
diff --git a/sensors/2.0/default/Android.bp b/sensors/2.0/default/Android.bp
index 11612d3..db0b148 100644
--- a/sensors/2.0/default/Android.bp
+++ b/sensors/2.0/default/Android.bp
@@ -32,6 +32,7 @@
"libhidlbase",
"libhidltransport",
"liblog",
+ "libpower",
"libutils",
],
}
diff --git a/sensors/2.0/default/Sensor.cpp b/sensors/2.0/default/Sensor.cpp
index d3e3f7e..168b402 100644
--- a/sensors/2.0/default/Sensor.cpp
+++ b/sensors/2.0/default/Sensor.cpp
@@ -29,14 +29,20 @@
using ::android::hardware::sensors::V1_0::SensorStatus;
Sensor::Sensor(ISensorsEventCallback* callback)
- : mIsEnabled(false), mSamplingPeriodNs(0), mLastSampleTimeNs(0), mCallback(callback) {
+ : mIsEnabled(false),
+ mSamplingPeriodNs(0),
+ mLastSampleTimeNs(0),
+ mCallback(callback),
+ mMode(OperationMode::NORMAL) {
mRunThread = std::thread(startThread, this);
}
Sensor::~Sensor() {
+ std::unique_lock<std::mutex> lock(mRunMutex);
mStopThread = true;
mIsEnabled = false;
mWaitCV.notify_all();
+ lock.release();
mRunThread.join();
}
@@ -60,6 +66,7 @@
void Sensor::activate(bool enable) {
if (mIsEnabled != enable) {
+ std::unique_lock<std::mutex> lock(mRunMutex);
mIsEnabled = enable;
mWaitCV.notify_all();
}
@@ -79,7 +86,7 @@
ev.sensorType = SensorType::ADDITIONAL_INFO;
ev.u.meta.what = MetaDataEventType::META_DATA_FLUSH_COMPLETE;
std::vector<Event> evs{ev};
- mCallback->postEvents(evs);
+ mCallback->postEvents(evs, isWakeUpSensor());
return Result::OK;
}
@@ -89,13 +96,14 @@
}
void Sensor::run() {
- std::mutex runMutex;
- std::unique_lock<std::mutex> runLock(runMutex);
+ std::unique_lock<std::mutex> runLock(mRunMutex);
constexpr int64_t kNanosecondsInSeconds = 1000 * 1000 * 1000;
while (!mStopThread) {
- if (!mIsEnabled) {
- mWaitCV.wait(runLock, [&] { return mIsEnabled || mStopThread; });
+ if (!mIsEnabled || mMode == OperationMode::DATA_INJECTION) {
+ mWaitCV.wait(runLock, [&] {
+ return ((mIsEnabled && mMode == OperationMode::NORMAL) || mStopThread);
+ });
} else {
timespec curTime;
clock_gettime(CLOCK_REALTIME, &curTime);
@@ -105,7 +113,7 @@
if (now >= nextSampleTime) {
mLastSampleTimeNs = now;
nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
- mCallback->postEvents(readEvents());
+ mCallback->postEvents(readEvents(), isWakeUpSensor());
}
mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now));
@@ -113,6 +121,10 @@
}
}
+bool Sensor::isWakeUpSensor() {
+ return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::WAKE_UP);
+}
+
std::vector<Event> Sensor::readEvents() {
std::vector<Event> events;
Event event;
@@ -127,6 +139,33 @@
return events;
}
+void Sensor::setOperationMode(OperationMode mode) {
+ if (mMode != mode) {
+ std::unique_lock<std::mutex> lock(mRunMutex);
+ mMode = mode;
+ mWaitCV.notify_all();
+ }
+}
+
+bool Sensor::supportsDataInjection() const {
+ return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::DATA_INJECTION);
+}
+
+Result Sensor::injectEvent(const Event& event) {
+ Result result = Result::OK;
+ if (event.sensorType == SensorType::ADDITIONAL_INFO) {
+ // When in OperationMode::NORMAL, SensorType::ADDITIONAL_INFO is used to push operation
+ // environment data into the device.
+ } else if (!supportsDataInjection()) {
+ result = Result::INVALID_OPERATION;
+ } else if (mMode == OperationMode::DATA_INJECTION) {
+ mCallback->postEvents(std::vector<Event>{event}, isWakeUpSensor());
+ } else {
+ result = Result::BAD_VALUE;
+ }
+ return result;
+}
+
AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
mSensorInfo.sensorHandle = sensorHandle;
mSensorInfo.name = "Accel Sensor";
@@ -142,7 +181,8 @@
mSensorInfo.fifoReservedEventCount = 0;
mSensorInfo.fifoMaxEventCount = 0;
mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::WAKE_UP);
+ mSensorInfo.flags =
+ static_cast<uint32_t>(SensorFlagBits::WAKE_UP | SensorFlagBits::DATA_INJECTION);
};
} // namespace implementation
diff --git a/sensors/2.0/default/Sensor.h b/sensors/2.0/default/Sensor.h
index 75d9aab..3ab2299 100644
--- a/sensors/2.0/default/Sensor.h
+++ b/sensors/2.0/default/Sensor.h
@@ -21,10 +21,12 @@
#include <condition_variable>
#include <memory>
+#include <mutex>
#include <thread>
#include <vector>
using ::android::hardware::sensors::V1_0::Event;
+using ::android::hardware::sensors::V1_0::OperationMode;
using ::android::hardware::sensors::V1_0::Result;
using ::android::hardware::sensors::V1_0::SensorInfo;
using ::android::hardware::sensors::V1_0::SensorType;
@@ -38,7 +40,7 @@
class ISensorsEventCallback {
public:
virtual ~ISensorsEventCallback(){};
- virtual void postEvents(const std::vector<Event>& events) = 0;
+ virtual void postEvents(const std::vector<Event>& events, bool wakeup) = 0;
};
class Sensor {
@@ -51,11 +53,17 @@
void activate(bool enable);
Result flush();
+ void setOperationMode(OperationMode mode);
+ bool supportsDataInjection() const;
+ Result injectEvent(const Event& event);
+
protected:
void run();
virtual std::vector<Event> readEvents();
static void startThread(Sensor* sensor);
+ bool isWakeUpSensor();
+
bool mIsEnabled;
int64_t mSamplingPeriodNs;
int64_t mLastSampleTimeNs;
@@ -63,9 +71,12 @@
std::atomic_bool mStopThread;
std::condition_variable mWaitCV;
+ std::mutex mRunMutex;
std::thread mRunThread;
ISensorsEventCallback* mCallback;
+
+ OperationMode mMode;
};
class AccelSensor : public Sensor {
diff --git a/sensors/2.0/default/Sensors.cpp b/sensors/2.0/default/Sensors.cpp
index cceb7d5..18240da 100644
--- a/sensors/2.0/default/Sensors.cpp
+++ b/sensors/2.0/default/Sensors.cpp
@@ -30,8 +30,16 @@
using ::android::hardware::sensors::V1_0::RateLevel;
using ::android::hardware::sensors::V1_0::Result;
using ::android::hardware::sensors::V1_0::SharedMemInfo;
+using ::android::hardware::sensors::V2_0::SensorTimeout;
-Sensors::Sensors() : mEventQueueFlag(nullptr) {
+constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP";
+
+Sensors::Sensors()
+ : mEventQueueFlag(nullptr),
+ mOutstandingWakeUpEvents(0),
+ mReadWakeLockQueueRun(false),
+ mAutoReleaseWakeLockTime(0),
+ mHasWakeLock(false) {
std::shared_ptr<AccelSensor> accel =
std::make_shared<AccelSensor>(1 /* sensorHandle */, this /* callback */);
mSensors[accel->getSensorInfo().sensorHandle] = accel;
@@ -39,6 +47,8 @@
Sensors::~Sensors() {
deleteEventFlag();
+ mReadWakeLockQueueRun = false;
+ mWakeLockThread.join();
}
// Methods from ::android::hardware::sensors::V2_0::ISensors follow.
@@ -54,9 +64,11 @@
return Void();
}
-Return<Result> Sensors::setOperationMode(OperationMode /* mode */) {
- // TODO implement
- return Result{};
+Return<Result> Sensors::setOperationMode(OperationMode mode) {
+ for (auto sensor : mSensors) {
+ sensor.second->setOperationMode(mode);
+ }
+ return Result::OK;
}
Return<Result> Sensors::activate(int32_t sensorHandle, bool enabled) {
@@ -99,6 +111,10 @@
result = Result::BAD_VALUE;
}
+ // Start the thread to read events from the Wake Lock FMQ
+ mReadWakeLockQueueRun = true;
+ mWakeLockThread = std::thread(startReadWakeLockThread, this);
+
return result;
}
@@ -120,9 +136,13 @@
return Result::BAD_VALUE;
}
-Return<Result> Sensors::injectSensorData(const Event& /* event */) {
- // TODO implement
- return Result{};
+Return<Result> Sensors::injectSensorData(const Event& event) {
+ auto sensor = mSensors.find(event.sensorHandle);
+ if (sensor != mSensors.end()) {
+ return sensor->second->injectEvent(event);
+ }
+
+ return Result::BAD_VALUE;
}
Return<void> Sensors::registerDirectChannel(const SharedMemInfo& /* mem */,
@@ -141,15 +161,67 @@
return Return<void>();
}
-void Sensors::postEvents(const std::vector<Event>& events) {
- std::lock_guard<std::mutex> l(mLock);
+void Sensors::postEvents(const std::vector<Event>& events, bool wakeup) {
+ std::lock_guard<std::mutex> lock(mWriteLock);
+ if (mEventQueue->write(events.data(), events.size())) {
+ mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
- // TODO: read events from the Wake Lock FMQ in the right place
- std::vector<uint32_t> tmp(mWakeLockQueue->availableToRead());
- mWakeLockQueue->read(tmp.data(), mWakeLockQueue->availableToRead());
+ if (wakeup) {
+ // Keep track of the number of outstanding WAKE_UP events in order to properly hold
+ // a wake lock until the framework has secured a wake lock
+ updateWakeLock(events.size(), 0 /* eventsHandled */);
+ }
+ }
+}
- mEventQueue->write(events.data(), events.size());
- mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
+void Sensors::updateWakeLock(int32_t eventsWritten, int32_t eventsHandled) {
+ std::lock_guard<std::mutex> lock(mWakeLockLock);
+ int32_t newVal = mOutstandingWakeUpEvents + eventsWritten - eventsHandled;
+ if (newVal < 0) {
+ mOutstandingWakeUpEvents = 0;
+ } else {
+ mOutstandingWakeUpEvents = newVal;
+ }
+
+ if (eventsWritten > 0) {
+ // Update the time at which the last WAKE_UP event was sent
+ mAutoReleaseWakeLockTime = ::android::uptimeMillis() +
+ static_cast<uint32_t>(SensorTimeout::WAKE_LOCK_SECONDS) * 1000;
+ }
+
+ if (!mHasWakeLock && mOutstandingWakeUpEvents > 0 &&
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName) == 0) {
+ mHasWakeLock = true;
+ } else if (mHasWakeLock) {
+ // Check if the wake lock should be released automatically if
+ // SensorTimeout::WAKE_LOCK_SECONDS has elapsed since the last WAKE_UP event was written to
+ // the Wake Lock FMQ.
+ if (::android::uptimeMillis() > mAutoReleaseWakeLockTime) {
+ ALOGD("No events read from wake lock FMQ for %d seconds, auto releasing wake lock",
+ SensorTimeout::WAKE_LOCK_SECONDS);
+ mOutstandingWakeUpEvents = 0;
+ }
+
+ if (mOutstandingWakeUpEvents == 0 && release_wake_lock(kWakeLockName) == 0) {
+ mHasWakeLock = false;
+ }
+ }
+}
+
+void Sensors::readWakeLockFMQ() {
+ while (mReadWakeLockQueueRun.load()) {
+ constexpr int64_t kReadTimeoutNs = 500 * 1000 * 1000; // 500 ms
+ uint32_t eventsHandled = 0;
+
+ // Read events from the Wake Lock FMQ. Timeout after a reasonable amount of time to ensure
+ // that any held wake lock is able to be released if it is held for too long.
+ mWakeLockQueue->readBlocking(&eventsHandled, 1 /* count */, kReadTimeoutNs);
+ updateWakeLock(0 /* eventsWritten */, eventsHandled);
+ }
+}
+
+void Sensors::startReadWakeLockThread(Sensors* sensors) {
+ sensors->readWakeLockFMQ();
}
void Sensors::deleteEventFlag() {
diff --git a/sensors/2.0/default/Sensors.h b/sensors/2.0/default/Sensors.h
index f543935..eba3f97 100644
--- a/sensors/2.0/default/Sensors.h
+++ b/sensors/2.0/default/Sensors.h
@@ -21,10 +21,13 @@
#include <android/hardware/sensors/2.0/ISensors.h>
#include <fmq/MessageQueue.h>
+#include <hardware_legacy/power.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
+#include <atomic>
#include <memory>
+#include <thread>
namespace android {
namespace hardware {
@@ -80,7 +83,7 @@
Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
configDirectReport_cb _hidl_cb) override;
- void postEvents(const std::vector<Event>& events) override;
+ void postEvents(const std::vector<Event>& events, bool wakeup) override;
private:
/**
@@ -88,6 +91,18 @@
*/
void deleteEventFlag();
+ /**
+ * Function to read the Wake Lock FMQ and release the wake lock when appropriate
+ */
+ void readWakeLockFMQ();
+
+ static void startReadWakeLockThread(Sensors* sensors);
+
+ /**
+ * Responsible for acquiring and releasing a wake lock when there are unhandled WAKE_UP events
+ */
+ void updateWakeLock(int32_t eventsWritten, int32_t eventsHandled);
+
using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;
@@ -117,9 +132,39 @@
std::map<int32_t, std::shared_ptr<Sensor>> mSensors;
/**
- * Lock to protect writes and reads to the FMQs
+ * Lock to protect writes to the FMQs
*/
- std::mutex mLock;
+ std::mutex mWriteLock;
+
+ /**
+ * Lock to protect acquiring and releasing the wake lock
+ */
+ std::mutex mWakeLockLock;
+
+ /**
+ * Track the number of WAKE_UP events that have not been handled by the framework
+ */
+ uint32_t mOutstandingWakeUpEvents;
+
+ /**
+ * A thread to read the Wake Lock FMQ
+ */
+ std::thread mWakeLockThread;
+
+ /**
+ * Flag to indicate that the Wake Lock Thread should continue to run
+ */
+ std::atomic_bool mReadWakeLockQueueRun;
+
+ /**
+ * Track the time when the wake lock should automatically be released
+ */
+ int64_t mAutoReleaseWakeLockTime;
+
+ /**
+ * Flag to indicate if a wake lock has been acquired
+ */
+ bool mHasWakeLock;
};
} // namespace implementation
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index 3e5837b..cc78af3 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -164,6 +164,7 @@
void activateAllSensors(bool enable);
std::vector<SensorInfo> getNonOneShotSensors();
std::vector<SensorInfo> getOneShotSensors();
+ std::vector<SensorInfo> getInjectEventSensors();
int32_t getInvalidSensorHandle();
};
@@ -243,6 +244,16 @@
return sensors;
}
+std::vector<SensorInfo> SensorsHidlTest::getInjectEventSensors() {
+ std::vector<SensorInfo> sensors;
+ for (const SensorInfo& info : getSensorsList()) {
+ if (info.flags & static_cast<uint32_t>(SensorFlagBits::DATA_INJECTION)) {
+ sensors.push_back(info);
+ }
+ }
+ return sensors;
+}
+
int32_t SensorsHidlTest::getInvalidSensorHandle() {
// Find a sensor handle that does not exist in the sensor list
int32_t maxHandle = 0;
@@ -297,63 +308,71 @@
});
}
-// Test if sensor list returned is valid
+// Test that SetOperationMode returns the expected value
TEST_F(SensorsHidlTest, SetOperationMode) {
- std::vector<SensorInfo> sensorList = getSensorsList();
-
- bool needOperationModeSupport =
- std::any_of(sensorList.begin(), sensorList.end(),
- [](const auto& s) { return (s.flags & SensorFlagBits::DATA_INJECTION) != 0; });
- if (!needOperationModeSupport) {
- return;
+ std::vector<SensorInfo> sensors = getInjectEventSensors();
+ if (getInjectEventSensors().size() > 0) {
+ ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
+ ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::DATA_INJECTION));
+ ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
+ } else {
+ ASSERT_EQ(Result::BAD_VALUE, getSensors()->setOperationMode(OperationMode::DATA_INJECTION));
}
-
- ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
- ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::DATA_INJECTION));
- ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
}
-// Test if sensor list returned is valid
+// Test that an injected event is written back to the Event FMQ
TEST_F(SensorsHidlTest, InjectSensorEventData) {
- std::vector<SensorInfo> sensorList = getSensorsList();
- std::vector<SensorInfo> sensorSupportInjection;
-
- bool needOperationModeSupport =
- std::any_of(sensorList.begin(), sensorList.end(), [&sensorSupportInjection](const auto& s) {
- bool ret = (s.flags & SensorFlagBits::DATA_INJECTION) != 0;
- if (ret) {
- sensorSupportInjection.push_back(s);
- }
- return ret;
- });
- if (!needOperationModeSupport) {
+ std::vector<SensorInfo> sensors = getInjectEventSensors();
+ if (sensors.size() == 0) {
return;
}
- ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::DATA_INJECTION));
- for (const auto& s : sensorSupportInjection) {
- switch (s.type) {
- case SensorType::ACCELEROMETER:
- case SensorType::GYROSCOPE:
- case SensorType::MAGNETIC_FIELD: {
- usleep(100000); // sleep 100ms
+ EventCallback callback;
+ getEnvironment()->registerCallback(&callback);
- Event dummy;
- dummy.timestamp = android::elapsedRealtimeNano();
- dummy.sensorType = s.type;
- dummy.sensorHandle = s.sensorHandle;
- Vec3 v = {1, 2, 3, SensorStatus::ACCURACY_HIGH};
- dummy.u.vec3 = v;
+ // AdditionalInfo event should not be sent to Event FMQ
+ Event additionalInfoEvent;
+ additionalInfoEvent.sensorType = SensorType::ADDITIONAL_INFO;
+ additionalInfoEvent.timestamp = android::elapsedRealtimeNano();
- EXPECT_EQ(Result::OK, getSensors()->injectSensorData(dummy));
- break;
- }
- default:
- break;
- }
+ Event injectedEvent;
+ injectedEvent.timestamp = android::elapsedRealtimeNano();
+ Vec3 data = {1, 2, 3, SensorStatus::ACCURACY_HIGH};
+ injectedEvent.u.vec3 = data;
+
+ for (const auto& s : sensors) {
+ additionalInfoEvent.sensorHandle = s.sensorHandle;
+ EXPECT_EQ(Result::OK, getSensors()->injectSensorData(additionalInfoEvent));
+
+ injectedEvent.sensorType = s.type;
+ injectedEvent.sensorHandle = s.sensorHandle;
+ EXPECT_EQ(Result::OK, getSensors()->injectSensorData(injectedEvent));
}
+
+ // Wait for events to be written back to the Event FMQ
+ callback.waitForEvents(sensors, 1000 /* timeoutMs */);
+
+ for (const auto& s : sensors) {
+ auto events = callback.getEvents(s.sensorHandle);
+ auto lastEvent = events.back();
+
+ // Verify that only a single event has been received
+ ASSERT_EQ(events.size(), 1);
+
+ // Verify that the event received matches the event injected and is not the additional
+ // info event
+ ASSERT_EQ(lastEvent.sensorType, s.type);
+ ASSERT_EQ(lastEvent.sensorType, s.type);
+ ASSERT_EQ(lastEvent.timestamp, injectedEvent.timestamp);
+ ASSERT_EQ(lastEvent.u.vec3.x, injectedEvent.u.vec3.x);
+ ASSERT_EQ(lastEvent.u.vec3.y, injectedEvent.u.vec3.y);
+ ASSERT_EQ(lastEvent.u.vec3.z, injectedEvent.u.vec3.z);
+ ASSERT_EQ(lastEvent.u.vec3.status, injectedEvent.u.vec3.status);
+ }
+
+ getEnvironment()->unregisterCallback();
ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
}