From a689f8a65b544cbad7ced2464ed6234d2540b7fe Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Tue, 30 Jul 2019 11:35:48 -0400 Subject: [PATCH] Add skeleton for multihal 2.0 Creates a basic set of structures needed to implement multihal 2.0. Descriptions of each are as follows: HalProxy - Main point of contact from the sensors framework. Implements the ISensors interface and will implement several callbacks passed to sub-HALs in the future SubHal - Contains interface that sub-HALs are expected to implement in order to be loaded properly by the HalProxy. Also contains definitions for various callbacks and classes that will be fully implemented by the HalProxy. service.cpp - contains the main function that is reponsible for initializing the HalProxy and starting the thread pool that will handle communication between the HalProxy and sensors framework. Bug: 136511617 Test: compile for now. Stubbed out sub-HAL to be added in a followup CL to facilitate testing before a vendor implements the subHAL interface. Change-Id: If663159d444d721a0a65ebe49dd92e8924bbb3a3 --- sensors/2.0/multihal/Android.bp | 38 ++++ sensors/2.0/multihal/HalProxy.cpp | 182 ++++++++++++++++ sensors/2.0/multihal/HalProxy.h | 120 +++++++++++ sensors/2.0/multihal/OWNERS | 3 + sensors/2.0/multihal/SubHal.h | 202 ++++++++++++++++++ .../android.hardware.sensors@2.0-multihal.xml | 11 + ...d.hardware.sensors@2.0-service-multihal.rc | 6 + sensors/2.0/multihal/service.cpp | 41 ++++ 8 files changed, 603 insertions(+) create mode 100644 sensors/2.0/multihal/Android.bp create mode 100644 sensors/2.0/multihal/HalProxy.cpp create mode 100644 sensors/2.0/multihal/HalProxy.h create mode 100644 sensors/2.0/multihal/OWNERS create mode 100644 sensors/2.0/multihal/SubHal.h create mode 100644 sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml create mode 100644 sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc create mode 100644 sensors/2.0/multihal/service.cpp diff --git a/sensors/2.0/multihal/Android.bp b/sensors/2.0/multihal/Android.bp new file mode 100644 index 0000000000..4dec768abf --- /dev/null +++ b/sensors/2.0/multihal/Android.bp @@ -0,0 +1,38 @@ +// +// Copyright (C) 2019 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. + +cc_binary { + name: "android.hardware.sensors@2.0-service.multihal", + defaults: ["hidl_defaults"], + vendor: true, + relative_install_path: "hw", + srcs: [ + "service.cpp", + "HalProxy.cpp", + ], + init_rc: ["android.hardware.sensors@2.0-service-multihal.rc"], + shared_libs: [ + "android.hardware.sensors@1.0", + "android.hardware.sensors@2.0", + "libcutils", + "libfmq", + "libhidlbase", + "libhidltransport", + "liblog", + "libpower", + "libutils", + ], + vintf_fragments: ["android.hardware.sensors@2.0-multihal.xml"], +} diff --git a/sensors/2.0/multihal/HalProxy.cpp b/sensors/2.0/multihal/HalProxy.cpp new file mode 100644 index 0000000000..31f8a182b8 --- /dev/null +++ b/sensors/2.0/multihal/HalProxy.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2019 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 "HalProxy.h" + +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_0 { +namespace implementation { + +// TODO: Use this wake lock name as the prefix to all sensors HAL wake locks acquired. +// constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP"; + +// TODO: Use the following class as a starting point for implementing the full HalProxyCallback +// along with being inspiration for how to implement the ScopedWakelock class. +/** + * Callback class used to provide the HalProxy with the index of which subHal is invoking + */ +class SensorsCallbackProxy : public ISensorsCallback { + public: + SensorsCallbackProxy(wp& halProxy, int32_t subHalIndex) + : mHalProxy(halProxy), mSubHalIndex(subHalIndex) {} + + Return onDynamicSensorsConnected( + const hidl_vec& dynamicSensorsAdded) override { + sp halProxy(mHalProxy.promote()); + if (halProxy != nullptr) { + return halProxy->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex); + } + return Return(); + } + + Return onDynamicSensorsDisconnected( + const hidl_vec& dynamicSensorHandlesRemoved) override { + sp halProxy(mHalProxy.promote()); + if (halProxy != nullptr) { + return halProxy->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved, + mSubHalIndex); + } + return Return(); + } + + private: + wp& mHalProxy; + int32_t mSubHalIndex; +}; + +HalProxy::HalProxy() { + // TODO: Initialize all sub-HALs and discover sensors. +} + +HalProxy::~HalProxy() { + // TODO: Join any running threads and clean up FMQs and any other allocated + // state. +} + +Return HalProxy::getSensorsList(getSensorsList_cb /* _hidl_cb */) { + // TODO: Output sensors list created as part of HalProxy(). + return Void(); +} + +Return HalProxy::setOperationMode(OperationMode /* mode */) { + // TODO: Proxy API call to all sub-HALs and return appropriate result. + return Result::INVALID_OPERATION; +} + +Return HalProxy::activate(int32_t /* sensorHandle */, bool /* enabled */) { + // TODO: Proxy API call to appropriate sub-HAL. + return Result::INVALID_OPERATION; +} + +Return HalProxy::initialize( + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) { + Result result = Result::OK; + + // TODO: clean up sensor requests, if not already done elsewhere through a death recipient, and + // clean up any other resources that exist (FMQs, flags, threads, etc.) + + mDynamicSensorsCallback = sensorsCallback; + + // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions. + mEventQueue = + std::make_unique(eventQueueDescriptor, true /* resetPointers */); + + // Create the EventFlag that is used to signal to the framework that sensor events have been + // written to the Event FMQ + if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) { + result = Result::BAD_VALUE; + } + + // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP + // events have been successfully read and handled by the framework. + mWakeLockQueue = + std::make_unique(wakeLockDescriptor, true /* resetPointers */); + + if (!mDynamicSensorsCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) { + result = Result::BAD_VALUE; + } + + // TODO: start threads to read wake locks and process events from sub HALs. + + return result; +} + +Return HalProxy::batch(int32_t /* sensorHandle */, int64_t /* samplingPeriodNs */, + int64_t /* maxReportLatencyNs */) { + // TODO: Proxy API call to appropriate sub-HAL. + return Result::INVALID_OPERATION; +} + +Return HalProxy::flush(int32_t /* sensorHandle */) { + // TODO: Proxy API call to appropriate sub-HAL. + return Result::INVALID_OPERATION; +} + +Return HalProxy::injectSensorData(const Event& /* event */) { + // TODO: Proxy API call to appropriate sub-HAL. + return Result::INVALID_OPERATION; +} + +Return HalProxy::registerDirectChannel(const SharedMemInfo& /* mem */, + registerDirectChannel_cb _hidl_cb) { + // TODO: During init, discover the first sub-HAL in the config that has sensors with direct + // channel support, if any, and proxy the API call there. + _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */); + return Return(); +} + +Return HalProxy::unregisterDirectChannel(int32_t /* channelHandle */) { + // TODO: During init, discover the first sub-HAL in the config that has sensors with direct + // channel support, if any, and proxy the API call there. + return Result::INVALID_OPERATION; +} + +Return HalProxy::configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */, + RateLevel /* rate */, configDirectReport_cb _hidl_cb) { + // TODO: During init, discover the first sub-HAL in the config that has sensors with direct + // channel support, if any, and proxy the API call there. + _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */); + return Return(); +} + +Return HalProxy::debug(const hidl_handle& /* fd */, const hidl_vec& /* args */) { + // TODO: output debug information + return Return(); +} + +Return HalProxy::onDynamicSensorsConnected( + const hidl_vec& /* dynamicSensorsAdded */, int32_t /* subHalIndex */) { + // TODO: Map the SensorInfo to the global list and then invoke the framework's callback. + return Return(); +} + +Return HalProxy::onDynamicSensorsDisconnected( + const hidl_vec& /* dynamicSensorHandlesRemoved */, int32_t /* subHalIndex */) { + // TODO: Unmap the SensorInfo from the global list and then invoke the framework's callback. + return Return(); +} + +} // namespace implementation +} // namespace V2_0 +} // namespace sensors +} // namespace hardware +} // namespace android diff --git a/sensors/2.0/multihal/HalProxy.h b/sensors/2.0/multihal/HalProxy.h new file mode 100644 index 0000000000..b9855a6ac5 --- /dev/null +++ b/sensors/2.0/multihal/HalProxy.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2019 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 "SubHal.h" + +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_0 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::EventFlag; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::MessageQueue; +using ::android::hardware::MQDescriptor; +using ::android::hardware::Return; +using ::android::hardware::Void; + +struct HalProxy : public ISensors { + using Event = ::android::hardware::sensors::V1_0::Event; + using OperationMode = ::android::hardware::sensors::V1_0::OperationMode; + using RateLevel = ::android::hardware::sensors::V1_0::RateLevel; + using Result = ::android::hardware::sensors::V1_0::Result; + using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; + + HalProxy(); + ~HalProxy(); + + // Methods from ::android::hardware::sensors::V2_0::ISensors follow. + Return getSensorsList(getSensorsList_cb _hidl_cb) override; + + Return setOperationMode(OperationMode mode) override; + + Return activate(int32_t sensorHandle, bool enabled) override; + + Return initialize( + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) override; + + Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, + int64_t maxReportLatencyNs) override; + + Return flush(int32_t sensorHandle) override; + + Return injectSensorData(const Event& event) override; + + Return registerDirectChannel(const SharedMemInfo& mem, + registerDirectChannel_cb _hidl_cb) override; + + Return unregisterDirectChannel(int32_t channelHandle) override; + + Return configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, + configDirectReport_cb _hidl_cb) override; + + Return debug(const hidl_handle& fd, const hidl_vec& args) override; + + // Below methods from ::android::hardware::sensors::V2_0::ISensorsCaback with a minor change + // to pass in the sub-HAL index. While the above methods are invoked from the sensors framework + // via the binder, these methods are invoked from a callback provided to sub-HALs inside the + // same process as the HalProxy, but potentially running on different threads. + Return onDynamicSensorsConnected(const hidl_vec& dynamicSensorsAdded, + int32_t subHalIndex); + + Return onDynamicSensorsDisconnected(const hidl_vec& dynamicSensorHandlesRemoved, + int32_t subHalIndex); + + private: + using EventMessageQueue = MessageQueue; + using WakeLockMessageQueue = MessageQueue; + + /** + * The Event FMQ where sensor events are written + */ + std::unique_ptr mEventQueue; + + /** + * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events + */ + std::unique_ptr mWakeLockQueue; + + /** + * Event Flag to signal to the framework when sensor events are available to be read + */ + EventFlag* mEventQueueFlag; + + /** + * Callback to the sensors framework to inform it that new sensors have been added or removed. + */ + sp mDynamicSensorsCallback; +}; + +} // namespace implementation +} // namespace V2_0 +} // namespace sensors +} // namespace hardware +} // namespace android diff --git a/sensors/2.0/multihal/OWNERS b/sensors/2.0/multihal/OWNERS new file mode 100644 index 0000000000..e9556700d6 --- /dev/null +++ b/sensors/2.0/multihal/OWNERS @@ -0,0 +1,3 @@ +arthuri@google.com +bduddie@google.com +stange@google.com \ No newline at end of file diff --git a/sensors/2.0/multihal/SubHal.h b/sensors/2.0/multihal/SubHal.h new file mode 100644 index 0000000000..152f91d96c --- /dev/null +++ b/sensors/2.0/multihal/SubHal.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2019 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 +#include + +#include + +using ::android::hardware::sensors::V1_0::Event; +using ::android::hardware::sensors::V1_0::Result; +using ::android::hardware::sensors::V1_0::SensorInfo; + +// Indicates the current version of the multiHAL interface formatted as (HAL major version) << 24 | +// (HAL minor version) << 16 | (multiHAL version) +#define SUB_HAL_2_0_VERSION 0x02000000 + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_0 { +namespace implementation { + +/** + * Wrapper around wake lock acquisition functions (acquire/release_wake_lock) that provides a + * RAII-style mechanism for keeping a wake lock held for the duration of a scoped block. + * When a ScopedWakelock is created, it increments the reference count stored in the HalProxy + * for the sub-HALs specific wake lock, acquiring the wake lock if necessary. When the object goes + * out of scope, the ref count is decremented, potentially releasing the wake lock if no other + * references to the wake lock exist. + * + * This class is allocated through the createScopedWakelock callback inside the IHalProxyCallback + * provided to sub-HALs during initialization and should be used for all wake lock acquisition + * inside of the sub-HAL to ensure wake locks are not held indefinitely. + * + * The most prevalent use case for this class will be for posting events to the framework through + * the postEvents HalProxy callback. The expectation is that sub-HALs will create this + * ScopedWakelock through the createScopedWakelock upon receiving a sensor events. The lock boolean + * provided to createScopedWakelock will be set the according to whether the sensor events are + * from wakeup sensors. Then, the sub-HAL will perform any processing necessary before invoking the + * postEvents callback passing in the previously created ScopedWakelock. At this point, ownership + * of the object will be passed to the HalProxy that will then be responsible for ensuring any + * wake locks continue to be held, if necessary. + */ +class ScopedWakelock { + public: + ScopedWakelock(ScopedWakelock&&) = default; + ScopedWakelock& operator=(ScopedWakelock&&) = default; + virtual ~ScopedWakelock() { mLocked = false; }; + + bool isLocked() const { return mLocked; } + + protected: + bool mLocked; + + private: + // TODO: Mark HalProxy's subclass of ScopedWakelock as a friend so that it can be initialized. + ScopedWakelock(); + ScopedWakelock(const ScopedWakelock&) = delete; + ScopedWakelock& operator=(const ScopedWakelock&) = delete; +}; + +/** + * Interface that contains several callbacks into the HalProxy class to communicate dynamic sensor + * changes and sensor events to the framework and acquire wake locks. The HalProxy will ensure + * callbacks occurring at the same time from multiple sub-HALs are synchronized in a safe, efficient + * manner. + */ +class IHalProxyCallback : public ISensorsCallback { + public: + /** + * Thread-safe callback used to post events to the HalProxy. Sub-HALs should invoke this + * whenever new sensor events need to be delivered to the sensors framework. Once invoked, the + * HalProxy will attempt to send events to the sensors framework using a blocking write with a + * 5 second timeout. This write may be done asynchronously if the queue used to communicate + * with the framework is full to avoid blocking sub-HALs for the length of the timeout. If the + * write fails, the events will be dropped and any wake locks held will be released. + * + * The provided ScopedWakelock must be locked if the events are from wakeup sensors. If it's + * not locked accordingly, the HalProxy will crash as this indicates the sub-HAL isn't compliant + * with the sensors HAL 2.0 specification. Additionally, since ScopedWakelock isn't copyable, + * the HalProxy will take ownership of the wake lock given when this method is invoked. Once the + * method returns, the HalProxy will handle holding the wake lock, if necessary, until the + * framework has successfully processed any wakeup events. + * + * No return type is used for this callback to avoid sub-HALs trying to resend events when + * writes fail. Writes should only fail when the framework is under inordinate stress which will + * likely result in a framework restart so retrying will likely only result in overloading the + * HalProxy. Sub-HALs should always assume that the write was a success and perform any + * necessary cleanup. Additionally, the HalProxy will ensure it logs any errors (through ADB and + * bug reports) it encounters during delivery to ensure it's obvious that a failure occurred. + * + * @param events the events that should be sent to the sensors framework + * @param wakelock ScopedWakelock that should be locked to send events from wake sensors and + * unlocked otherwise. + */ + virtual void postEvents(const std::vector& events, ScopedWakelock wakelock) = 0; + + /** + * Initializes a ScopedWakelock on the stack that, when locked, will increment the reference + * count for the sub-HAL's wake lock managed inside the HalProxy. See the ScopedWakelock class + * definition for how it should be used. + * + * @param lock whether the ScopedWakelock should be locked before it's returned. + * @return the created ScopedWakelock + */ + virtual ScopedWakelock createScopedWakelock(bool lock) = 0; +}; + +/** + * ISensorsSubHal is an interface that sub-HALs must implement in order to be compliant with + * multihal 2.0 and in order for the HalProxy to successfully load and communicate with the sub-HAL. + * + * Any vendor wishing to implement this interface and support multihal 2.0 will need to create a + * dynamic library that exposes sensorsHalGetSubHal (defined below). This library will be loaded by + * the HalProxy when the sensors HAL is initialized and then the HalProxy will retrieve the vendor's + * implementation of sensorsHalGetSubHal. + * + * With the exception of the initialize method, ISensorsSubHal will implement the ISensors.hal spec. + * Any sensor handles given to the HalProxy, either through getSensorsList() or the + * onDynamicSensors(Dis)Connected callbacks, will be translated to avoid clashing with other sub-HAL + * handles. To achieve this, the HalProxy will use the upper byte to store the sub-HAL index and + * sub-HALs can continue to use the lower 3 bytes of the handle. + */ +class ISensorsSubHal : public ISensors { + // The ISensors version of initialize isn't used for multihal. Instead, sub-HALs must implement + // the version below to allow communciation logic to centralized in the HalProxy + Return initialize( + const ::android::hardware::MQDescriptorSync& /* eventQueueDescriptor */, + const ::android::hardware::MQDescriptorSync& /* wakeLockDescriptor */, + const sp& /* sensorsCallback */) final { + return Result::INVALID_OPERATION; + } + + /** + * Method defined in ::android::hidl::base::V1_0::IBase. + * + * This method should write debug information to hidl_handle that is useful for debugging + * issues. Suggestions include: + * - Sensor info including handle values and any other state available in the SensorInfo class + * - List of active sensors and their current sampling period and reporting latency + * - Information about pending flush requests + * - Current operating mode + * - Currently registered direct channel info + * - A history of any of the above + */ + virtual Return debug(const hidl_handle& fd, const hidl_vec& args) = 0; + + /** + * @return A human-readable name for use in wake locks and logging. + */ + virtual const std::string& getName() = 0; + + /** + * First method invoked on the sub-HAL after it's allocated through sensorsHalGetSubHal() by the + * HalProxy. Sub-HALs should use this to initialize any state and retain the callback given in + * order to communicate with the HalProxy. + * + * @param halProxyCallback callback used to inform the HalProxy when a dynamic sensor's state + * changes, new sensor events should be sent to the framework, and when a new ScopedWakelock + * should be created. + * @return result OK on success + */ + virtual Return initialize(const sp& halProxyCallback) = 0; +}; + +} // namespace implementation +} // namespace V2_0 +} // namespace sensors +} // namespace hardware +} // namespace android + +using ::android::hardware::sensors::V2_0::implementation::ISensorsSubHal; + +/** + * Function that must be exported so the HalProxy class can invoke it on the sub-HAL dynamic + * library. This function will only be invoked once at initialization time. + * + * NOTE: The supported sensors HAL version must match SUB_HAL_2_0_VERSION exactly or the HalProxy + * will fail to initialize. + * + * @param uint32_t when this function returns, this parameter must contain the HAL version that + * this sub-HAL supports. To support this version of multi-HAL, this must be set to + * SUB_HAL_2_0_VERSION. + * @return A statically allocated, valid ISensorsSubHal implementation. + */ +__attribute__((visibility("default"))) extern "C" ISensorsSubHal* sensorsHalGetSubHal( + uint32_t* version); diff --git a/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml b/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml new file mode 100644 index 0000000000..a771100ecc --- /dev/null +++ b/sensors/2.0/multihal/android.hardware.sensors@2.0-multihal.xml @@ -0,0 +1,11 @@ + + + android.hardware.sensors + hwbinder + 2.0 + + ISensors + multihal + + + diff --git a/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc b/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc new file mode 100644 index 0000000000..167168919a --- /dev/null +++ b/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc @@ -0,0 +1,6 @@ +service vendor.sensors-hal-2-0-multihal /vendor/bin/hw/android.hardware.sensors@2.0-service.multihal + class hal + user system + group system + capabilities BLOCK_SUSPEND + rlimit rtprio 10 10 diff --git a/sensors/2.0/multihal/service.cpp b/sensors/2.0/multihal/service.cpp new file mode 100644 index 0000000000..995cf3cbe0 --- /dev/null +++ b/sensors/2.0/multihal/service.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 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. + */ + +#define LOG_TAG "android.hardware.sensors@2.0-service" + +#include +#include +#include +#include +#include "HalProxy.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::hardware::sensors::V2_0::ISensors; +using android::hardware::sensors::V2_0::implementation::HalProxy; + +int main(int /* argc */, char** /* argv */) { + configureRpcThreadpool(1, true); + + android::sp halProxy = new HalProxy(); + if (halProxy->registerAsService() != ::android::OK) { + ALOGE("Failed to register Sensors HAL instance"); + return -1; + } + + joinRpcThreadpool(); + return 1; // joinRpcThreadpool shouldn't exit +}