Merge changes Iad6b9ef2,I4f0d710a
* changes:
Read Sensor Events from Event FMQ
Initialize SensorDevice's FMQs
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index a6b9533..f87fcdc 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -46,6 +46,7 @@
"libhidlbase",
"libhidltransport",
"libhwbinder",
+ "libfmq",
"android.hardware.sensors@1.0",
"android.hardware.sensors@2.0",
],
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 7237bc8..25ed21c 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -13,7 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include "SensorDevice.h"
+
+#include "android/hardware/sensors/2.0/types.h"
#include "SensorService.h"
#include <android-base/logging.h>
@@ -29,6 +32,7 @@
using namespace android::hardware::sensors;
using namespace android::hardware::sensors::V1_0;
using namespace android::hardware::sensors::V1_0::implementation;
+using android::hardware::sensors::V2_0::EventQueueFlagBits;
using android::hardware::hidl_vec;
using android::SensorDeviceUtils::HidlServiceRegistrationWaiter;
@@ -87,22 +91,31 @@
(checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
}
-bool SensorDevice::connectHidlService() {
- bool connected = connectHidlServiceV2_0();
- if (!connected) {
- connected = connectHidlServiceV1_0();
+SensorDevice::~SensorDevice() {
+ if (mEventQueueFlag != nullptr) {
+ hardware::EventFlag::deleteEventFlag(&mEventQueueFlag);
+ mEventQueueFlag = nullptr;
}
- return connected;
}
-bool SensorDevice::connectHidlServiceV1_0() {
+bool SensorDevice::connectHidlService() {
+ HalConnectionStatus status = connectHidlServiceV2_0();
+ if (status == HalConnectionStatus::DOES_NOT_EXIST) {
+ status = connectHidlServiceV1_0();
+ }
+ return (status == HalConnectionStatus::CONNECTED);
+}
+
+SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV1_0() {
// SensorDevice will wait for HAL service to start if HAL is declared in device manifest.
size_t retry = 10;
+ HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN;
while (retry-- > 0) {
sp<V1_0::ISensors> sensors = V1_0::ISensors::getService();
if (sensors == nullptr) {
// no sensor hidl service found
+ connectionStatus = HalConnectionStatus::DOES_NOT_EXIST;
break;
}
@@ -113,25 +126,55 @@
// which will be done since the size is 0.
if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
// ok to continue
+ connectionStatus = HalConnectionStatus::CONNECTED;
break;
}
// hidl service is restarting, pointer is invalid.
mSensors = nullptr;
+ connectionStatus = HalConnectionStatus::FAILED_TO_CONNECT;
ALOGI("%s unsuccessful, remaining retry %zu.", __FUNCTION__, retry);
mRestartWaiter->wait();
}
- return (mSensors != nullptr);
+
+ return connectionStatus;
}
-bool SensorDevice::connectHidlServiceV2_0() {
+SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV2_0() {
+ HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN;
sp<V2_0::ISensors> sensors = V2_0::ISensors::getService();
- if (sensors != nullptr) {
+
+ if (sensors == nullptr) {
+ connectionStatus = HalConnectionStatus::DOES_NOT_EXIST;
+ } else {
mSensors = new SensorServiceUtil::SensorsWrapperV2_0(sensors);
- // TODO: initialize message queues
+ mEventQueue = std::make_unique<EventMessageQueue>(
+ SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
+ true /* configureEventFlagWord */);
+
+ mWakeLockQueue = std::make_unique<WakeLockQueue>(
+ SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
+ true /* configureEventFlagWord */);
+
+ hardware::EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag);
+
+ CHECK(mSensors != nullptr && mEventQueue != nullptr &&
+ mWakeLockQueue != nullptr && mEventQueueFlag != nullptr);
+
+ status_t status = StatusFromResult(checkReturn(mSensors->initializeMessageQueues(
+ *mEventQueue->getDesc(),
+ *mWakeLockQueue->getDesc())));
+
+ if (status != NO_ERROR) {
+ connectionStatus = HalConnectionStatus::FAILED_TO_CONNECT;
+ ALOGE("Failed to initialize message queues (%s)", strerror(-status));
+ } else {
+ connectionStatus = HalConnectionStatus::CONNECTED;
+ }
}
- return (mSensors != nullptr);
+
+ return connectionStatus;
}
void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
@@ -191,6 +234,19 @@
}
ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
+ ssize_t eventsRead = 0;
+ if (mSensors->supportsMessageQueues()) {
+ eventsRead = pollFmq(buffer, count);
+ } else if (mSensors->supportsPolling()) {
+ eventsRead = pollHal(buffer, count);
+ } else {
+ ALOGE("Must support polling or FMQ");
+ eventsRead = -1;
+ }
+ return eventsRead;
+}
+
+ssize_t SensorDevice::pollHal(sensors_event_t* buffer, size_t count) {
if (mSensors == nullptr) return NO_INIT;
ssize_t err;
@@ -236,6 +292,46 @@
return err;
}
+ssize_t SensorDevice::pollFmq(sensors_event_t* buffer, size_t maxNumEventsToRead) {
+ if (mSensors == nullptr) {
+ return NO_INIT;
+ }
+
+ ssize_t eventsRead = 0;
+ size_t availableEvents = mEventQueue->availableToRead();
+
+ if (availableEvents == 0) {
+ uint32_t eventFlagState = 0;
+
+ // Wait for events to become available. This is necessary so that the Event FMQ's read() is
+ // able to be called with the correct number of events to read. If the specified number of
+ // events is not available, then read() would return no events, possibly introducing
+ // additional latency in delivering events to applications.
+ mEventQueueFlag->wait(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS),
+ &eventFlagState);
+ availableEvents = mEventQueue->availableToRead();
+
+ if (availableEvents == 0) {
+ ALOGW("Event FMQ wake without any events");
+ }
+ }
+
+ size_t eventsToRead = std::min({availableEvents, maxNumEventsToRead, mEventBuffer.size()});
+ if (eventsToRead > 0) {
+ if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) {
+ for (size_t i = 0; i < eventsToRead; i++) {
+ convertToSensorEvent(mEventBuffer[i], &buffer[i]);
+ }
+ eventsRead = eventsToRead;
+ } else {
+ ALOGW("Failed to read %zu events, currently %zu events available",
+ eventsToRead, availableEvents);
+ }
+ }
+
+ return eventsRead;
+}
+
void SensorDevice::autoDisable(void *ident, int handle) {
Mutex::Autolock _l(mLock);
ssize_t activationIndex = mActivationCount.indexOfKey(handle);
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 595a627..2caebf9 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -21,12 +21,15 @@
#include "SensorServiceUtils.h"
#include "SensorsWrapper.h"
+#include <fmq/MessageQueue.h>
+#include <sensor/SensorEventQueue.h>
#include <sensor/Sensor.h>
#include <stdint.h>
#include <sys/types.h>
#include <utils/KeyedVector.h>
#include <utils/Singleton.h>
#include <utils/String8.h>
+#include <utils/Timers.h>
#include <string>
#include <unordered_map>
@@ -68,6 +71,8 @@
int mCount; // number of transport errors observed
};
+ ~SensorDevice();
+
ssize_t getSensorList(sensor_t const** list);
void handleDynamicSensorConnection(int handle, bool connected);
@@ -162,8 +167,18 @@
SortedVector<void *> mDisabledClients;
SensorDevice();
bool connectHidlService();
- bool connectHidlServiceV1_0();
- bool connectHidlServiceV2_0();
+
+ enum HalConnectionStatus {
+ CONNECTED, // Successfully connected to the HAL
+ DOES_NOT_EXIST, // Could not find the HAL
+ FAILED_TO_CONNECT, // Found the HAL but failed to connect/initialize
+ UNKNOWN,
+ };
+ HalConnectionStatus connectHidlServiceV1_0();
+ HalConnectionStatus connectHidlServiceV2_0();
+
+ ssize_t pollHal(sensors_event_t* buffer, size_t count);
+ ssize_t pollFmq(sensors_event_t* buffer, size_t count);
static void handleHidlDeath(const std::string &detail);
template<typename T>
@@ -190,6 +205,15 @@
sensors_event_t *dst);
bool mIsDirectReportSupported;
+
+ typedef hardware::MessageQueue<Event, hardware::kSynchronizedReadWrite> EventMessageQueue;
+ typedef hardware::MessageQueue<uint32_t, hardware::kSynchronizedReadWrite> WakeLockQueue;
+ std::unique_ptr<EventMessageQueue> mEventQueue;
+ std::unique_ptr<WakeLockQueue> mWakeLockQueue;
+
+ hardware::EventFlag* mEventQueueFlag;
+
+ std::array<Event, SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT> mEventBuffer;
};
// ---------------------------------------------------------------------------