Add AIDL sensorservice implementation
Intended to be 1:1 functionality with the HIDL implementation.
Test: atest VtsHalSensorManagerTargetTest
Bug: 205764765
Change-Id: I7a30a7c119c6f48432cbefbaaebc7ad7dfc4a01e
diff --git a/services/sensorservice/aidl/Android.bp b/services/sensorservice/aidl/Android.bp
new file mode 100644
index 0000000..bbf49da
--- /dev/null
+++ b/services/sensorservice/aidl/Android.bp
@@ -0,0 +1,43 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_native_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_native_license"],
+}
+
+cc_library_shared {
+ name: "libsensorserviceaidl",
+ srcs: [
+ "EventQueue.cpp",
+ "DirectReportChannel.cpp",
+ "SensorManager.cpp",
+ "utils.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ header_libs: ["jni_headers"],
+ shared_libs: [
+ "libbase",
+ "libutils",
+ "libcutils",
+ "libbinder_ndk",
+ "libsensor",
+ "android.frameworks.sensorservice-V1-ndk",
+ "android.hardware.sensors-V1-ndk",
+ ],
+ export_include_dirs: [
+ "include/",
+ ],
+ static_libs: [
+ "android.hardware.sensors-V1-convert",
+ ],
+
+ export_header_lib_headers: ["jni_headers"],
+ local_include_dirs: [
+ "include/sensorserviceaidl/",
+ ],
+}
diff --git a/services/sensorservice/aidl/DirectReportChannel.cpp b/services/sensorservice/aidl/DirectReportChannel.cpp
new file mode 100644
index 0000000..cab53c1
--- /dev/null
+++ b/services/sensorservice/aidl/DirectReportChannel.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 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 "DirectReportChannel.h"
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+DirectReportChannel::DirectReportChannel(::android::SensorManager& manager, int channelId)
+ : mManager(manager), mId(channelId) {}
+
+DirectReportChannel::~DirectReportChannel() {
+ mManager.destroyDirectChannel(mId);
+}
+
+ndk::ScopedAStatus DirectReportChannel::configure(
+ int32_t sensorHandle, ::aidl::android::hardware::sensors::ISensors::RateLevel rate,
+ int32_t* _aidl_return) {
+ int token = mManager.configureDirectChannel(mId, sensorHandle, static_cast<int>(rate));
+ if (token <= 0) {
+ return ndk::ScopedAStatus::fromServiceSpecificError(token);
+ }
+ *_aidl_return = token;
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/DirectReportChannel.h b/services/sensorservice/aidl/DirectReportChannel.h
new file mode 100644
index 0000000..d9ea73d
--- /dev/null
+++ b/services/sensorservice/aidl/DirectReportChannel.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+#pragma once
+
+#include <aidl/android/frameworks/sensorservice/BnDirectReportChannel.h>
+#include <aidl/android/hardware/sensors/ISensors.h>
+#include <sensor/SensorManager.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+class DirectReportChannel final
+ : public ::aidl::android::frameworks::sensorservice::BnDirectReportChannel {
+public:
+ DirectReportChannel(::android::SensorManager& manager, int channelId);
+ ~DirectReportChannel();
+
+ ndk::ScopedAStatus configure(int32_t sensorHandle,
+ ::aidl::android::hardware::sensors::ISensors::RateLevel rate,
+ int32_t* _aidl_return) override;
+
+private:
+ ::android::SensorManager& mManager;
+ const int mId;
+};
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/EventQueue.cpp b/services/sensorservice/aidl/EventQueue.cpp
new file mode 100644
index 0000000..d4e8906
--- /dev/null
+++ b/services/sensorservice/aidl/EventQueue.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 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 <android-base/logging.h>
+#include <utils/Looper.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+using ::aidl::android::frameworks::sensorservice::IEventQueueCallback;
+using ::aidl::android::hardware::sensors::Event;
+
+class EventQueueLooperCallback : public ::android::LooperCallback {
+public:
+ EventQueueLooperCallback(sp<::android::SensorEventQueue> queue,
+ std::shared_ptr<IEventQueueCallback> callback)
+ : mQueue(queue), mCallback(callback) {}
+
+ int handleEvent(__unused int fd, __unused int events, __unused void* data) {
+ ASensorEvent event;
+ ssize_t actual;
+
+ auto internalQueue = mQueue.promote();
+ if (internalQueue == nullptr) {
+ return 1;
+ }
+
+ while ((actual = internalQueue->read(&event, 1)) > 0) {
+ internalQueue->sendAck(&event, actual);
+ ndk::ScopedAStatus ret = mCallback->onEvent(convertEvent(event));
+ if (!ret.isOk()) {
+ LOG(ERROR) << "Failed to envoke EventQueueCallback: " << ret;
+ }
+ }
+
+ return 1; // continue to receive callbacks
+ }
+
+private:
+ wp<::android::SensorEventQueue> mQueue;
+ std::shared_ptr<IEventQueueCallback> mCallback;
+};
+
+EventQueue::EventQueue(std::shared_ptr<IEventQueueCallback> callback, sp<::android::Looper> looper,
+ sp<::android::SensorEventQueue> internalQueue)
+ : mLooper(looper), mInternalQueue(internalQueue) {
+ mLooper->addFd(internalQueue->getFd(), ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT,
+ new EventQueueLooperCallback(internalQueue, callback), nullptr);
+}
+
+// FIXME why was this on onLastStrongRef instead of dtor?
+EventQueue::~EventQueue() {
+ mLooper->removeFd(mInternalQueue->getFd());
+}
+
+ndk::ScopedAStatus EventQueue::enableSensor(int32_t in_sensorHandle, int32_t in_samplingPeriodUs,
+ int64_t in_maxBatchReportLatencyUs) {
+ return convertResult(mInternalQueue->enableSensor(in_sensorHandle, in_samplingPeriodUs,
+ in_maxBatchReportLatencyUs, 0));
+}
+
+ndk::ScopedAStatus EventQueue::disableSensor(int32_t in_sensorHandle) {
+ return convertResult(mInternalQueue->disableSensor(in_sensorHandle));
+}
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/EventQueue.h b/services/sensorservice/aidl/EventQueue.h
new file mode 100644
index 0000000..0ae1eba
--- /dev/null
+++ b/services/sensorservice/aidl/EventQueue.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+#pragma once
+
+#include "SensorManagerAidl.h"
+
+#include <aidl/android/frameworks/sensorservice/BnEventQueue.h>
+#include <sensor/SensorManager.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+struct EventQueue final : public aidl::android::frameworks::sensorservice::BnEventQueue {
+ EventQueue(
+ std::shared_ptr<aidl::android::frameworks::sensorservice::IEventQueueCallback> callback,
+ sp<::android::Looper> looper, sp<::android::SensorEventQueue> internalQueue);
+ ~EventQueue();
+
+ ndk::ScopedAStatus enableSensor(int32_t in_sensorHandle, int32_t in_samplingPeriodUs,
+ int64_t in_maxBatchReportLatencyUs) override;
+ ndk::ScopedAStatus disableSensor(int32_t sensorHandle) override;
+
+private:
+ friend class EventQueueLooperCallback;
+ sp<::android::Looper> mLooper;
+ sp<::android::SensorEventQueue> mInternalQueue;
+};
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/SensorManager.cpp b/services/sensorservice/aidl/SensorManager.cpp
new file mode 100644
index 0000000..6d8d574
--- /dev/null
+++ b/services/sensorservice/aidl/SensorManager.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+// LOG_TAG defined via build flag.
+#ifndef LOG_TAG
+#define LOG_TAG "AidlSensorManager"
+#endif
+
+#include "DirectReportChannel.h"
+#include "EventQueue.h"
+#include "SensorManagerAidl.h"
+#include "utils.h"
+
+#include <aidl/android/hardware/sensors/ISensors.h>
+#include <android-base/logging.h>
+#include <android/binder_ibinder.h>
+#include <sched.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+using ::aidl::android::frameworks::sensorservice::IDirectReportChannel;
+using ::aidl::android::frameworks::sensorservice::IEventQueue;
+using ::aidl::android::frameworks::sensorservice::IEventQueueCallback;
+using ::aidl::android::frameworks::sensorservice::ISensorManager;
+using ::aidl::android::hardware::common::Ashmem;
+using ::aidl::android::hardware::sensors::ISensors;
+using ::aidl::android::hardware::sensors::SensorInfo;
+using ::aidl::android::hardware::sensors::SensorType;
+using ::android::frameworks::sensorservice::implementation::SensorManagerAidl;
+
+static const char* POLL_THREAD_NAME = "aidl_ssvc_poll";
+
+SensorManagerAidl::SensorManagerAidl(JavaVM* vm)
+ : mLooper(new Looper(false)), mStopThread(true), mJavaVm(vm) {}
+SensorManagerAidl::~SensorManagerAidl() {
+ // Stops pollAll inside the thread.
+ std::lock_guard<std::mutex> lock(mThreadMutex);
+
+ mStopThread = true;
+ if (mLooper != nullptr) {
+ mLooper->wake();
+ }
+ if (mPollThread.joinable()) {
+ mPollThread.join();
+ }
+}
+
+ndk::ScopedAStatus createDirectChannel(::android::SensorManager& manager, size_t size, int type,
+ const native_handle_t* handle,
+ std::shared_ptr<IDirectReportChannel>* chan) {
+ int channelId = manager.createDirectChannel(size, type, handle);
+ if (channelId < 0) {
+ return convertResult(channelId);
+ }
+ if (channelId == 0) {
+ return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_UNKNOWN_ERROR);
+ }
+ *chan = ndk::SharedRefBase::make<DirectReportChannel>(manager, channelId);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus SensorManagerAidl::createAshmemDirectChannel(
+ const Ashmem& in_mem, int64_t in_size,
+ std::shared_ptr<IDirectReportChannel>* _aidl_return) {
+ if (in_size > in_mem.size || in_size < ISensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH) {
+ return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_BAD_VALUE);
+ }
+ native_handle_t* handle = native_handle_create(1, 0);
+ handle->data[0] = dup(in_mem.fd.get());
+
+ auto status = createDirectChannel(getInternalManager(), in_size, SENSOR_DIRECT_MEM_TYPE_ASHMEM,
+ handle, _aidl_return);
+ int result = native_handle_close(handle);
+ CHECK(result == 0) << "Failed to close the native_handle_t: " << result;
+ result = native_handle_delete(handle);
+ CHECK(result == 0) << "Failed to delete the native_handle_t: " << result;
+
+ return status;
+}
+
+ndk::ScopedAStatus SensorManagerAidl::createGrallocDirectChannel(
+ const ndk::ScopedFileDescriptor& in_mem, int64_t in_size,
+ std::shared_ptr<IDirectReportChannel>* _aidl_return) {
+ native_handle_t* handle = native_handle_create(1, 0);
+ handle->data[0] = dup(in_mem.get());
+
+ auto status = createDirectChannel(getInternalManager(), in_size, SENSOR_DIRECT_MEM_TYPE_GRALLOC,
+ handle, _aidl_return);
+ int result = native_handle_close(handle);
+ CHECK(result == 0) << "Failed to close the native_handle_t: " << result;
+ result = native_handle_delete(handle);
+ CHECK(result == 0) << "Failed to delete the native_handle_t: " << result;
+
+ return status;
+}
+
+ndk::ScopedAStatus SensorManagerAidl::createEventQueue(
+ const std::shared_ptr<IEventQueueCallback>& in_callback,
+ std::shared_ptr<IEventQueue>* _aidl_return) {
+ if (in_callback == nullptr) {
+ return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_BAD_VALUE);
+ }
+
+ sp<::android::Looper> looper = getLooper();
+ if (looper == nullptr) {
+ LOG(ERROR) << "::android::SensorManagerAidl::createEventQueue cannot initialize looper";
+ return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_UNKNOWN_ERROR);
+ }
+
+ String8 package(String8::format("aidl_client_pid_%d", AIBinder_getCallingPid()));
+ sp<::android::SensorEventQueue> internalQueue = getInternalManager().createEventQueue(package);
+ if (internalQueue == nullptr) {
+ LOG(ERROR) << "::android::SensorManagerAidl::createEventQueue returns nullptr.";
+ return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_UNKNOWN_ERROR);
+ }
+
+ *_aidl_return = ndk::SharedRefBase::make<EventQueue>(in_callback, looper, internalQueue);
+
+ return ndk::ScopedAStatus::ok();
+}
+
+SensorInfo convertSensor(Sensor src) {
+ SensorInfo dst;
+ dst.sensorHandle = src.getHandle();
+ dst.name = src.getName();
+ dst.vendor = src.getVendor();
+ dst.version = src.getVersion();
+ dst.type = static_cast<SensorType>(src.getType());
+ dst.typeAsString = src.getStringType();
+ // maxRange uses maxValue because ::android::Sensor wraps the
+ // internal sensor_t in this way.
+ dst.maxRange = src.getMaxValue();
+ dst.resolution = src.getResolution();
+ dst.power = src.getPowerUsage();
+ dst.minDelayUs = src.getMinDelay();
+ dst.fifoReservedEventCount = src.getFifoReservedEventCount();
+ dst.fifoMaxEventCount = src.getFifoMaxEventCount();
+ dst.requiredPermission = src.getRequiredPermission();
+ dst.maxDelayUs = src.getMaxDelay();
+ dst.flags = src.getFlags();
+ return dst;
+}
+
+ndk::ScopedAStatus SensorManagerAidl::getDefaultSensor(SensorType in_type,
+ SensorInfo* _aidl_return) {
+ ::android::Sensor const* sensor =
+ getInternalManager().getDefaultSensor(static_cast<int>(in_type));
+ if (!sensor) {
+ return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_NOT_EXIST);
+ }
+ *_aidl_return = convertSensor(*sensor);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus SensorManagerAidl::getSensorList(std::vector<SensorInfo>* _aidl_return) {
+ Sensor const* const* list;
+ _aidl_return->clear();
+ ssize_t count = getInternalManager().getSensorList(&list);
+ if (count < 0 || list == nullptr) {
+ LOG(ERROR) << "SensorMAanger::getSensorList failed with count: " << count;
+ return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_UNKNOWN_ERROR);
+ }
+ _aidl_return->reserve(static_cast<size_t>(count));
+ for (ssize_t i = 0; i < count; ++i) {
+ _aidl_return->push_back(convertSensor(*list[i]));
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+::android::SensorManager& SensorManagerAidl::getInternalManager() {
+ std::lock_guard<std::mutex> lock(mInternalManagerMutex);
+ if (mInternalManager == nullptr) {
+ mInternalManager = &::android::SensorManager::getInstanceForPackage(
+ String16(ISensorManager::descriptor));
+ }
+ return *mInternalManager;
+}
+
+/* One global looper for all event queues created from this SensorManager. */
+sp<Looper> SensorManagerAidl::getLooper() {
+ std::lock_guard<std::mutex> lock(mThreadMutex);
+
+ if (!mPollThread.joinable()) {
+ // if thread not initialized, start thread
+ mStopThread = false;
+ std::thread pollThread{[&stopThread = mStopThread, looper = mLooper, javaVm = mJavaVm] {
+ struct sched_param p = {0};
+ p.sched_priority = 10;
+ if (sched_setscheduler(0 /* current thread*/, SCHED_FIFO, &p) != 0) {
+ LOG(ERROR) << "Could not use SCHED_FIFO for looper thread: " << strerror(errno);
+ }
+
+ // set looper
+ Looper::setForThread(looper);
+
+ // Attach the thread to JavaVM so that pollAll do not crash if the thread
+ // eventually calls into Java.
+ JavaVMAttachArgs args{.version = JNI_VERSION_1_2,
+ .name = POLL_THREAD_NAME,
+ .group = nullptr};
+ JNIEnv* env;
+ if (javaVm->AttachCurrentThread(&env, &args) != JNI_OK) {
+ LOG(FATAL) << "Cannot attach SensorManager looper thread to Java VM.";
+ }
+
+ LOG(INFO) << POLL_THREAD_NAME << " started.";
+ for (;;) {
+ int pollResult = looper->pollAll(-1 /* timeout */);
+ if (pollResult == Looper::POLL_WAKE) {
+ if (stopThread == true) {
+ LOG(INFO) << POLL_THREAD_NAME << ": requested to stop";
+ break;
+ } else {
+ LOG(INFO) << POLL_THREAD_NAME << ": spurious wake up, back to work";
+ }
+ } else {
+ LOG(ERROR) << POLL_THREAD_NAME << ": Looper::pollAll returns unexpected "
+ << pollResult;
+ break;
+ }
+ }
+
+ if (javaVm->DetachCurrentThread() != JNI_OK) {
+ LOG(ERROR) << "Cannot detach SensorManager looper thread from Java VM.";
+ }
+
+ LOG(INFO) << POLL_THREAD_NAME << " is terminated.";
+ }};
+ mPollThread = std::move(pollThread);
+ }
+ return mLooper;
+}
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/include/sensorserviceaidl/SensorManagerAidl.h b/services/sensorservice/aidl/include/sensorserviceaidl/SensorManagerAidl.h
new file mode 100644
index 0000000..c77ee88
--- /dev/null
+++ b/services/sensorservice/aidl/include/sensorserviceaidl/SensorManagerAidl.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include <aidl/android/frameworks/sensorservice/BnSensorManager.h>
+#include <jni.h>
+#include <sensor/SensorManager.h>
+#include <utils/Looper.h>
+#include <mutex>
+#include <thread>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+class SensorManagerAidl : public ::aidl::android::frameworks::sensorservice::BnSensorManager {
+public:
+ explicit SensorManagerAidl(JavaVM* vm);
+ ~SensorManagerAidl();
+
+ ::ndk::ScopedAStatus createAshmemDirectChannel(
+ const ::aidl::android::hardware::common::Ashmem& in_mem, int64_t in_size,
+ std::shared_ptr<::aidl::android::frameworks::sensorservice::IDirectReportChannel>*
+ _aidl_return) override;
+ ::ndk::ScopedAStatus createEventQueue(
+ const std::shared_ptr<::aidl::android::frameworks::sensorservice::IEventQueueCallback>&
+ in_callback,
+ std::shared_ptr<::aidl::android::frameworks::sensorservice::IEventQueue>* _aidl_return)
+ override;
+ ::ndk::ScopedAStatus createGrallocDirectChannel(
+ const ::ndk::ScopedFileDescriptor& in_buffer, int64_t in_size,
+ std::shared_ptr<::aidl::android::frameworks::sensorservice::IDirectReportChannel>*
+ _aidl_return) override;
+ ::ndk::ScopedAStatus getDefaultSensor(
+ ::aidl::android::hardware::sensors::SensorType in_type,
+ ::aidl::android::hardware::sensors::SensorInfo* _aidl_return) override;
+ ::ndk::ScopedAStatus getSensorList(
+ std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) override;
+
+private:
+ // Block until ::android::SensorManager is initialized.
+ ::android::SensorManager& getInternalManager();
+ sp<Looper> getLooper();
+
+ std::mutex mInternalManagerMutex;
+ ::android::SensorManager* mInternalManager = nullptr; // does not own
+ sp<Looper> mLooper;
+
+ volatile bool mStopThread;
+ std::mutex mThreadMutex; // protects mPollThread
+ std::thread mPollThread;
+
+ JavaVM* mJavaVm;
+};
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/utils.cpp b/services/sensorservice/aidl/utils.cpp
new file mode 100644
index 0000000..26bcdc5
--- /dev/null
+++ b/services/sensorservice/aidl/utils.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 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 "utils.h"
+
+#include <aidl/android/frameworks/sensorservice/ISensorManager.h>
+#include <aidl/sensors/convert.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+ndk::ScopedAStatus convertResult(status_t src) {
+ using ::aidl::android::frameworks::sensorservice::ISensorManager;
+
+ int err = 0;
+ switch (src) {
+ case OK:
+ return ndk::ScopedAStatus::ok();
+ case NAME_NOT_FOUND:
+ err = ISensorManager::RESULT_NOT_EXIST;
+ break;
+ case NO_MEMORY:
+ err = ISensorManager::RESULT_NO_MEMORY;
+ break;
+ case NO_INIT:
+ err = ISensorManager::RESULT_NO_INIT;
+ break;
+ case PERMISSION_DENIED:
+ err = ISensorManager::RESULT_PERMISSION_DENIED;
+ break;
+ case BAD_VALUE:
+ err = ISensorManager::RESULT_BAD_VALUE;
+ break;
+ case INVALID_OPERATION:
+ err = ISensorManager::RESULT_INVALID_OPERATION;
+ break;
+ default:
+ err = ISensorManager::RESULT_UNKNOWN_ERROR;
+ }
+ return ndk::ScopedAStatus::fromServiceSpecificError(err);
+}
+
+::aidl::android::hardware::sensors::Event convertEvent(const ::ASensorEvent& src) {
+ ::aidl::android::hardware::sensors::Event dst;
+ ::android::hardware::sensors::implementation::
+ convertFromSensorEvent(reinterpret_cast<const sensors_event_t&>(src), &dst);
+ return dst;
+}
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/utils.h b/services/sensorservice/aidl/utils.h
new file mode 100644
index 0000000..06ba59e
--- /dev/null
+++ b/services/sensorservice/aidl/utils.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/sensors/Event.h>
+#include <sensor/Sensor.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+::ndk::ScopedAStatus convertResult(status_t status);
+::aidl::android::hardware::sensors::Event convertEvent(const ::ASensorEvent& event);
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android