Merge changes from topic 'sensors_framework_hal' into oc-dev
* changes:
android.frameworks.sensorservice@1.0: make classes final
android.frameworks.sensorservice@1.0: ashmem direct channel check sizes.
android.frameworks.sensorservice@1.0: fix configureDirectChannel return positive integer.
Implement android.frameworks.sensorservice@1.0::IEventQueue.
Renamed HIDL SensorManager::mManager -> mInternalManager.
diff --git a/libs/sensor/include/sensor/SensorEventQueue.h b/libs/sensor/include/sensor/SensorEventQueue.h
index a03c7ee..baed2ee 100644
--- a/libs/sensor/include/sensor/SensorEventQueue.h
+++ b/libs/sensor/include/sensor/SensorEventQueue.h
@@ -83,7 +83,7 @@
status_t disableSensor(Sensor const* sensor) const;
status_t setEventRate(Sensor const* sensor, nsecs_t ns) const;
- // these are here only to support SensorManager.java
+ // these are here only to support SensorManager.java and HIDL Frameworks SensorManager.
status_t enableSensor(int32_t handle, int32_t samplingPeriodUs, int64_t maxBatchReportLatencyUs,
int reservedFlags) const;
status_t disableSensor(int32_t handle) const;
diff --git a/services/sensorservice/hidl/Android.bp b/services/sensorservice/hidl/Android.bp
index f00c297..748dafc 100644
--- a/services/sensorservice/hidl/Android.bp
+++ b/services/sensorservice/hidl/Android.bp
@@ -1,6 +1,7 @@
cc_library_shared {
name: "libsensorservicehidl",
srcs: [
+ "EventQueue.cpp",
"DirectReportChannel.cpp",
"SensorManager.cpp",
"utils.cpp",
@@ -19,6 +20,9 @@
"android.hardware.sensors@1.0",
"android.hidl.base@1.0",
],
+ static_libs: [
+ "android.hardware.sensors@1.0-convert",
+ ],
export_include_dirs: [
"include/"
],
diff --git a/services/sensorservice/hidl/DirectReportChannel.cpp b/services/sensorservice/hidl/DirectReportChannel.cpp
index 9caba47..773ce8c 100644
--- a/services/sensorservice/hidl/DirectReportChannel.cpp
+++ b/services/sensorservice/hidl/DirectReportChannel.cpp
@@ -32,8 +32,9 @@
// Methods from ::android::frameworks::sensorservice::V1_0::IDirectReportChannel follow.
Return<Result> DirectReportChannel::configure(int32_t sensorHandle, RateLevel rate) {
- return convertResult(mManager.configureDirectChannel(mId,
- static_cast<int>(sensorHandle), static_cast<int>(rate)));
+ int token = mManager.configureDirectChannel(mId,
+ static_cast<int>(sensorHandle), static_cast<int>(rate));
+ return token <= 0 ? convertResult(token) : Result::OK;
}
diff --git a/services/sensorservice/hidl/DirectReportChannel.h b/services/sensorservice/hidl/DirectReportChannel.h
index f4cd4e7..9134944 100644
--- a/services/sensorservice/hidl/DirectReportChannel.h
+++ b/services/sensorservice/hidl/DirectReportChannel.h
@@ -41,7 +41,7 @@
using ::android::hardware::Void;
using ::android::sp;
-struct DirectReportChannel : public IDirectReportChannel {
+struct DirectReportChannel final : public IDirectReportChannel {
DirectReportChannel(::android::SensorManager& manager, int channelId);
~DirectReportChannel();
diff --git a/services/sensorservice/hidl/EventQueue.cpp b/services/sensorservice/hidl/EventQueue.cpp
new file mode 100644
index 0000000..86d365c
--- /dev/null
+++ b/services/sensorservice/hidl/EventQueue.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 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 "EventQueue.h"
+#include "utils.h"
+
+#include <utils/Looper.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace V1_0 {
+namespace implementation {
+
+class EventQueueLooperCallback : public ::android::LooperCallback {
+public:
+ EventQueueLooperCallback(sp<EventQueue> queue, sp<IEventQueueCallback> callback)
+ : mQueue(queue), mCallback(callback) {
+ }
+
+ int handleEvent(__unused int fd, __unused int events, __unused void* data) {
+
+ ASensorEvent event;
+ ssize_t actual;
+ const sp<::android::SensorEventQueue>& internalQueue = mQueue->mInternalQueue;
+
+ while ((actual = internalQueue->read(&event, 1 /* count */)) > 0) {
+ internalQueue->sendAck(&event, actual);
+ mCallback->onEvent(convertEvent(event));
+ }
+
+ return 1; // continue to receive callbacks
+ }
+
+private:
+ sp<EventQueue> mQueue;
+ sp<IEventQueueCallback> mCallback;
+};
+
+EventQueue::EventQueue(
+ sp<IEventQueueCallback> callback,
+ sp<::android::Looper> looper,
+ sp<::android::SensorEventQueue> internalQueue)
+ : mLooper(looper),
+ mInternalQueue(internalQueue) {
+
+ mLooper->addFd(mInternalQueue->getFd(), ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT,
+ new EventQueueLooperCallback(this, callback), NULL /* data */);
+}
+
+EventQueue::~EventQueue() {
+ mLooper->removeFd(mInternalQueue->getFd());
+}
+
+// Methods from ::android::frameworks::sensorservice::V1_0::IEventQueue follow.
+Return<Result> EventQueue::enableSensor(int32_t sensorHandle, int32_t samplingPeriodUs,
+ int64_t maxBatchReportLatencyUs) {
+ // TODO implement
+ return convertResult(mInternalQueue->enableSensor(sensorHandle, samplingPeriodUs,
+ maxBatchReportLatencyUs, 0 /* reserved flags */));
+}
+
+Return<Result> EventQueue::disableSensor(int32_t sensorHandle) {
+ return convertResult(mInternalQueue->disableSensor(sensorHandle));
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/hidl/EventQueue.h b/services/sensorservice/hidl/EventQueue.h
new file mode 100644
index 0000000..87c614b
--- /dev/null
+++ b/services/sensorservice/hidl/EventQueue.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_EVENTQUEUE_H
+#define ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_EVENTQUEUE_H
+
+#include "SensorManager.h"
+
+#include <android/frameworks/sensorservice/1.0/IEventQueue.h>
+#include <android/frameworks/sensorservice/1.0/IEventQueueCallback.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <sensor/SensorManager.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::frameworks::sensorservice::V1_0::IEventQueue;
+using ::android::frameworks::sensorservice::V1_0::IEventQueueCallback;
+using ::android::frameworks::sensorservice::V1_0::Result;
+using ::android::hardware::Return;
+using ::android::sp;
+
+struct EventQueue final : public IEventQueue {
+ EventQueue(
+ sp<IEventQueueCallback> callback,
+ sp<::android::Looper> looper,
+ sp<::android::SensorEventQueue> internalQueue);
+ ~EventQueue();
+
+ // Methods from ::android::frameworks::sensorservice::V1_0::IEventQueue follow.
+ Return<Result> enableSensor(int32_t sensorHandle, int32_t samplingPeriodUs, int64_t maxBatchReportLatencyUs) override;
+ Return<Result> disableSensor(int32_t sensorHandle) override;
+
+private:
+ friend class EventQueueLooperCallback;
+ sp<::android::Looper> mLooper;
+ sp<::android::SensorEventQueue> mInternalQueue;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
+
+#endif // ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_EVENTQUEUE_H
diff --git a/services/sensorservice/hidl/SensorManager.cpp b/services/sensorservice/hidl/SensorManager.cpp
index 37e53dc..0743fc3 100644
--- a/services/sensorservice/hidl/SensorManager.cpp
+++ b/services/sensorservice/hidl/SensorManager.cpp
@@ -20,10 +20,14 @@
#endif
#include <android-base/logging.h>
-#include "DirectReportChannel.h"
#include "SensorManager.h"
+
+#include "EventQueue.h"
+#include "DirectReportChannel.h"
#include "utils.h"
+#include <thread>
+
namespace android {
namespace frameworks {
namespace sensorservice {
@@ -31,19 +35,28 @@
namespace implementation {
using ::android::hardware::sensors::V1_0::SensorInfo;
+using ::android::hardware::sensors::V1_0::SensorsEventFormatOffset;
using ::android::hardware::hidl_vec;
using ::android::hardware::Void;
using ::android::sp;
SensorManager::SensorManager()
- : mManager{::android::SensorManager::getInstanceForPackage(
+ : mInternalManager{::android::SensorManager::getInstanceForPackage(
String16(ISensorManager::descriptor))} {
}
+SensorManager::~SensorManager() {
+ // Stops pollAll inside the thread.
+ std::unique_lock<std::mutex> lock(mLooperMutex);
+ if (mLooper != nullptr) {
+ mLooper->wake();
+ }
+}
+
// Methods from ::android::frameworks::sensorservice::V1_0::ISensorManager follow.
Return<void> SensorManager::getSensorList(getSensorList_cb _hidl_cb) {
::android::Sensor const* const* list;
- ssize_t count = mManager.getSensorList(&list);
+ ssize_t count = mInternalManager.getSensorList(&list);
if (count < 0 || !list) {
LOG(ERROR) << "::android::SensorManager::getSensorList encounters " << count;
_hidl_cb({}, Result::UNKNOWN_ERROR);
@@ -59,7 +72,7 @@
}
Return<void> SensorManager::getDefaultSensor(SensorType type, getDefaultSensor_cb _hidl_cb) {
- ::android::Sensor const* sensor = mManager.getDefaultSensor(static_cast<int>(type));
+ ::android::Sensor const* sensor = mInternalManager.getDefaultSensor(static_cast<int>(type));
if (!sensor) {
_hidl_cb({}, Result::NOT_EXIST);
return Void();
@@ -90,12 +103,12 @@
Return<void> SensorManager::createAshmemDirectChannel(
const hidl_memory& mem, uint64_t size,
createAshmemDirectChannel_cb _hidl_cb) {
- if (size > mem.size()) {
+ if (size > mem.size() || size < (uint64_t)SensorsEventFormatOffset::TOTAL_LENGTH) {
_hidl_cb(nullptr, Result::BAD_VALUE);
return Void();
}
- createDirectChannel(mManager, size, SENSOR_DIRECT_MEM_TYPE_ASHMEM,
+ createDirectChannel(mInternalManager, size, SENSOR_DIRECT_MEM_TYPE_ASHMEM,
mem.handle(), _hidl_cb);
return Void();
@@ -105,16 +118,53 @@
const hidl_handle& buffer, uint64_t size,
createGrallocDirectChannel_cb _hidl_cb) {
- createDirectChannel(mManager, size, SENSOR_DIRECT_MEM_TYPE_GRALLOC,
+ createDirectChannel(mInternalManager, size, SENSOR_DIRECT_MEM_TYPE_GRALLOC,
buffer.getNativeHandle(), _hidl_cb);
return Void();
}
+/* One global looper for all event queues created from this SensorManager. */
+sp<::android::Looper> SensorManager::getLooper() {
+ std::unique_lock<std::mutex> lock(mLooperMutex);
+ if (mLooper == nullptr) {
+ std::condition_variable looperSet;
+
+ std::thread{[&mutex = mLooperMutex, &looper = mLooper, &looperSet] {
+ std::unique_lock<std::mutex> lock(mutex);
+ looper = Looper::prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS /* opts */);
+ lock.unlock();
+
+ looperSet.notify_one();
+ int pollResult = looper->pollAll(-1 /* timeout */);
+ if (pollResult != ALOOPER_POLL_WAKE) {
+ LOG(ERROR) << "Looper::pollAll returns unexpected " << pollResult;
+ }
+ LOG(INFO) << "Looper thread is terminated.";
+ }}.detach();
+ looperSet.wait(lock, [this]{ return this->mLooper != nullptr; });
+ }
+ return mLooper;
+}
+
Return<void> SensorManager::createEventQueue(
- __unused const sp<IEventQueueCallback> &callback, createEventQueue_cb _hidl_cb) {
- // TODO(b/35219747) Implement this
- _hidl_cb(nullptr, Result::UNKNOWN_ERROR);
+ const sp<IEventQueueCallback> &callback, createEventQueue_cb _hidl_cb) {
+ if (callback == nullptr) {
+ _hidl_cb(nullptr, Result::BAD_VALUE);
+ return Void();
+ }
+
+ sp<::android::Looper> looper = getLooper();
+ sp<::android::SensorEventQueue> internalQueue = mInternalManager.createEventQueue();
+ if (internalQueue == nullptr) {
+ LOG(WARNING) << "::android::SensorManager::createEventQueue returns nullptr.";
+ _hidl_cb(nullptr, Result::UNKNOWN_ERROR);
+ return Void();
+ }
+
+ sp<IEventQueue> queue = new EventQueue(callback, looper, internalQueue);
+ _hidl_cb(queue, Result::OK);
+
return Void();
}
diff --git a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
index 0b026c9..a2372df 100644
--- a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
+++ b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
@@ -17,11 +17,14 @@
#ifndef ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_SENSORMANAGER_H
#define ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_SENSORMANAGER_H
+#include <mutex>
+
#include <android/frameworks/sensorservice/1.0/ISensorManager.h>
#include <android/frameworks/sensorservice/1.0/types.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <sensor/SensorManager.h>
+#include <utils/Looper.h>
namespace android {
namespace frameworks {
@@ -34,9 +37,10 @@
using ::android::hardware::hidl_memory;
using ::android::hardware::Return;
-struct SensorManager : public ISensorManager {
+struct SensorManager final : public ISensorManager {
SensorManager();
+ ~SensorManager();
// Methods from ::android::frameworks::sensorservice::V1_0::ISensorManager follow.
Return<void> getSensorList(getSensorList_cb _hidl_cb) override;
@@ -44,9 +48,13 @@
Return<void> createAshmemDirectChannel(const hidl_memory& mem, uint64_t size, createAshmemDirectChannel_cb _hidl_cb) override;
Return<void> createGrallocDirectChannel(const hidl_handle& buffer, uint64_t size, createGrallocDirectChannel_cb _hidl_cb) override;
Return<void> createEventQueue(const sp<IEventQueueCallback> &callback, createEventQueue_cb _hidl_cb);
-private:
- ::android::SensorManager& mManager;
+private:
+ sp<::android::Looper> getLooper();
+
+ ::android::SensorManager& mInternalManager;
+ std::mutex mLooperMutex;
+ sp<::android::Looper> mLooper;
};
} // namespace implementation
diff --git a/services/sensorservice/hidl/utils.cpp b/services/sensorservice/hidl/utils.cpp
index 4e02741..b540525 100644
--- a/services/sensorservice/hidl/utils.cpp
+++ b/services/sensorservice/hidl/utils.cpp
@@ -16,6 +16,8 @@
#include "utils.h"
+#include <sensors/convert.h>
+
namespace android {
namespace frameworks {
namespace sensorservice {
@@ -26,7 +28,7 @@
using ::android::hardware::hidl_string;
using ::android::hardware::sensors::V1_0::SensorInfo;
-SensorInfo convertSensor(const Sensor &src) {
+SensorInfo convertSensor(const Sensor& src) {
SensorInfo dst;
const String8& name = src.getName();
const String8& vendor = src.getVendor();
@@ -36,7 +38,7 @@
dst.sensorHandle = src.getHandle();
dst.type = static_cast<::android::hardware::sensors::V1_0::SensorType>(
src.getType());
- // FIXME maxRange uses maxValue because ::android::Sensor wraps the
+ // maxRange uses maxValue because ::android::Sensor wraps the
// internal sensor_t in this way.
dst.maxRange = src.getMaxValue();
dst.resolution = src.getResolution();
@@ -70,6 +72,13 @@
}
}
+::android::hardware::sensors::V1_0::Event convertEvent(const ::ASensorEvent& src) {
+ ::android::hardware::sensors::V1_0::Event dst;
+ ::android::hardware::sensors::V1_0::implementation::convertFromSensorEvent(
+ reinterpret_cast<const sensors_event_t&>(src), &dst);
+ return dst;
+}
+
} // namespace implementation
} // namespace V1_0
} // namespace sensorservice
diff --git a/services/sensorservice/hidl/utils.h b/services/sensorservice/hidl/utils.h
index 0606e69..b350928 100644
--- a/services/sensorservice/hidl/utils.h
+++ b/services/sensorservice/hidl/utils.h
@@ -30,6 +30,8 @@
::android::hardware::sensors::V1_0::SensorInfo convertSensor(const ::android::Sensor &src);
Result convertResult(status_t status);
+::android::hardware::sensors::V1_0::Event convertEvent(const ::ASensorEvent &event);
+
} // namespace implementation
} // namespace V1_0
} // namespace sensorservice