Merge "Wifi: Move LOCAL_VINTF_FRAGMENTS to executables"
diff --git a/sensors/2.0/multihal/Android.bp b/sensors/2.0/multihal/Android.bp
index 697bf9e..216cc20 100644
--- a/sensors/2.0/multihal/Android.bp
+++ b/sensors/2.0/multihal/Android.bp
@@ -42,6 +42,7 @@
srcs: [
"service.cpp",
"HalProxy.cpp",
+ "ScopedWakelock.cpp",
],
init_rc: ["android.hardware.sensors@2.0-service-multihal.rc"],
vintf_fragments: ["android.hardware.sensors@2.0-multihal.xml"],
@@ -61,6 +62,7 @@
vendor_available: true,
srcs: [
"HalProxy.cpp",
+ "ScopedWakelock.cpp",
],
export_header_lib_headers: [
"android.hardware.sensors@2.0-multihal.header",
diff --git a/sensors/2.0/multihal/HalProxy.cpp b/sensors/2.0/multihal/HalProxy.cpp
index b4d2466..81d1b64 100644
--- a/sensors/2.0/multihal/HalProxy.cpp
+++ b/sensors/2.0/multihal/HalProxy.cpp
@@ -16,12 +16,17 @@
#include "HalProxy.h"
+#include "SubHal.h"
+
#include <android/hardware/sensors/2.0/types.h>
+#include "hardware_legacy/power.h"
+
#include <dlfcn.h>
#include <fstream>
#include <functional>
+#include <thread>
namespace android {
namespace hardware {
@@ -29,53 +34,18 @@
namespace V2_0 {
namespace implementation {
+using ::android::hardware::sensors::V2_0::EventQueueFlagBits;
+
typedef ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*);
-// 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>& halProxy, int32_t subHalIndex)
- : mHalProxy(halProxy), mSubHalIndex(subHalIndex) {}
-
- Return<void> onDynamicSensorsConnected(
- const hidl_vec<SensorInfo>& dynamicSensorsAdded) override {
- sp<HalProxy> halProxy(mHalProxy.promote());
- if (halProxy != nullptr) {
- return halProxy->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex);
- }
- return Return<void>();
- }
-
- Return<void> onDynamicSensorsDisconnected(
- const hidl_vec<int32_t>& dynamicSensorHandlesRemoved) override {
- sp<HalProxy> halProxy(mHalProxy.promote());
- if (halProxy != nullptr) {
- return halProxy->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved,
- mSubHalIndex);
- }
- return Return<void>();
- }
-
- private:
- wp<HalProxy>& mHalProxy;
- int32_t mSubHalIndex;
-};
-
HalProxy::HalProxy() {
const char* kMultiHalConfigFile = "/vendor/etc/sensors/hals.conf";
initializeSubHalListFromConfigFile(kMultiHalConfigFile);
- initializeSensorList();
+ initializeSubHalCallbacksAndSensorList();
}
HalProxy::HalProxy(std::vector<ISensorsSubHal*>& subHalList) : mSubHalList(subHalList) {
- initializeSensorList();
+ initializeSubHalCallbacksAndSensorList();
}
HalProxy::~HalProxy() {
@@ -84,7 +54,11 @@
}
Return<void> HalProxy::getSensorsList(getSensorsList_cb _hidl_cb) {
- _hidl_cb(mSensorList);
+ std::vector<SensorInfo> sensors;
+ for (const auto& iter : mSensors) {
+ sensors.push_back(iter.second);
+ }
+ _hidl_cb(sensors);
return Void();
}
@@ -148,6 +122,17 @@
// TODO: start threads to read wake locks and process events from sub HALs.
+ for (size_t i = 0; i < mSubHalList.size(); i++) {
+ auto subHal = mSubHalList[i];
+ const auto& subHalCallback = mSubHalCallbacks[i];
+ Result currRes = subHal->initialize(subHalCallback);
+ if (currRes != Result::OK) {
+ result = currRes;
+ ALOGE("Subhal '%s' failed to initialize.", subHal->getName().c_str());
+ break;
+ }
+ }
+
return result;
}
@@ -239,6 +224,13 @@
}
}
+void HalProxy::initializeSubHalCallbacks() {
+ for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
+ sp<IHalProxyCallback> callback = new HalProxyCallback(this, subHalIndex);
+ mSubHalCallbacks.push_back(callback);
+ }
+}
+
void HalProxy::initializeSensorList() {
for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
ISensorsSubHal* subHal = mSubHalList[subHalIndex];
@@ -250,7 +242,7 @@
ALOGV("Loaded sensor: %s", sensor.name.c_str());
sensor.sensorHandle |= (subHalIndex << 24);
setDirectChannelFlags(&sensor, subHal);
- mSensorList.push_back(sensor);
+ mSensors[sensor.sensorHandle] = sensor;
}
}
});
@@ -260,6 +252,48 @@
}
}
+void HalProxy::initializeSubHalCallbacksAndSensorList() {
+ initializeSubHalCallbacks();
+ initializeSensorList();
+}
+
+void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events) {
+ std::lock_guard<std::mutex> lock(mEventQueueMutex);
+ size_t numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
+ if (numToWrite > 0) {
+ if (mEventQueue->write(events.data(), numToWrite)) {
+ // TODO: While loop if mEventQueue->avaiableToWrite > 0 to possibly fit in more writes
+ // immediately
+ mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
+ } else {
+ numToWrite = 0;
+ }
+ }
+ if (numToWrite < events.size()) {
+ // TODO: Post from events[numToWrite -> end] to background events queue
+ // Signal background thread
+ }
+}
+
+// TODO: Implement the wakelock timeout in these next two methods. Also pass in the subhal
+// index for better tracking.
+
+void HalProxy::incrementRefCountAndMaybeAcquireWakelock() {
+ std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
+ if (mWakelockRefCount == 0) {
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName);
+ }
+ mWakelockRefCount++;
+}
+
+void HalProxy::decrementRefCountAndMaybeReleaseWakelock() {
+ std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
+ mWakelockRefCount--;
+ if (mWakelockRefCount == 0) {
+ release_wake_lock(kWakeLockName);
+ }
+}
+
void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal) {
bool sensorSupportsDirectChannel =
(sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
@@ -282,6 +316,49 @@
return sensorHandle & (~kSensorHandleSubHalIndexMask);
}
+void HalProxyCallback::postEvents(const std::vector<Event>& events, ScopedWakelock wakelock) {
+ (void)wakelock;
+ size_t numWakeupEvents;
+ std::vector<Event> processedEvents = processEvents(events, &numWakeupEvents);
+ if (numWakeupEvents > 0) {
+ ALOG_ASSERT(wakelock.isLocked(),
+ "Wakeup events posted while wakelock unlocked for subhal"
+ " w/ index %zu.",
+ mSubHalIndex);
+ } else {
+ ALOG_ASSERT(!wakelock.isLocked(),
+ "No Wakeup events posted but wakelock locked for subhal"
+ " w/ index %zu.",
+ mSubHalIndex);
+ }
+
+ mHalProxy->postEventsToMessageQueue(processedEvents);
+}
+
+ScopedWakelock HalProxyCallback::createScopedWakelock(bool lock) {
+ ScopedWakelock wakelock(mHalProxy, lock);
+ return wakelock;
+}
+
+std::vector<Event> HalProxyCallback::processEvents(const std::vector<Event>& events,
+ size_t* numWakeupEvents) const {
+ std::vector<Event> eventsOut;
+ *numWakeupEvents = 0;
+ for (Event event : events) {
+ event.sensorHandle = setSubHalIndex(event.sensorHandle);
+ eventsOut.push_back(event);
+ if ((mHalProxy->getSensorInfo(event.sensorHandle).flags & V1_0::SensorFlagBits::WAKE_UP) !=
+ 0) {
+ (*numWakeupEvents)++;
+ }
+ }
+ return eventsOut;
+}
+
+uint32_t HalProxyCallback::setSubHalIndex(uint32_t sensorHandle) const {
+ return sensorHandle | mSubHalIndex << 24;
+}
+
} // namespace implementation
} // namespace V2_0
} // namespace sensors
diff --git a/sensors/2.0/multihal/ScopedWakelock.cpp b/sensors/2.0/multihal/ScopedWakelock.cpp
new file mode 100644
index 0000000..0430fa3
--- /dev/null
+++ b/sensors/2.0/multihal/ScopedWakelock.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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 "ScopedWakelock.h"
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V2_0 {
+namespace implementation {
+
+ScopedWakelock::ScopedWakelock(IScopedWakelockRefCounter* refCounter, bool locked)
+ : mRefCounter(refCounter), mLocked(locked) {
+ // TODO: Move this implementation into HalProxy object instead
+ if (mLocked) {
+ mRefCounter->incrementRefCountAndMaybeAcquireWakelock();
+ }
+}
+
+ScopedWakelock::~ScopedWakelock() {
+ // TODO: Move this implementation into HalProxy object instead
+ if (mLocked) {
+ mRefCounter->decrementRefCountAndMaybeReleaseWakelock();
+ }
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace sensors
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/sensors/2.0/multihal/include/HalProxy.h b/sensors/2.0/multihal/include/HalProxy.h
index 4ecb58b..bdcc1ff 100644
--- a/sensors/2.0/multihal/include/HalProxy.h
+++ b/sensors/2.0/multihal/include/HalProxy.h
@@ -24,6 +24,8 @@
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
+#include <map>
+
namespace android {
namespace hardware {
namespace sensors {
@@ -39,13 +41,15 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
-class HalProxy : public ISensors {
+class HalProxy : public ISensors, public IScopedWakelockRefCounter {
public:
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 SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo;
+ using ISensorsSubHal = ::android::hardware::sensors::V2_0::implementation::ISensorsSubHal;
explicit HalProxy();
// Test only constructor.
@@ -91,10 +95,45 @@
Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& dynamicSensorHandlesRemoved,
int32_t subHalIndex);
+ // Below methods follow IScopedWakelockRefCounter
+
+ /**
+ * Increment ref count and maybe acquire wakelock.
+ */
+ void incrementRefCountAndMaybeAcquireWakelock() override;
+
+ /**
+ * Decrement ref count and maybe release wakelock.
+ */
+ void decrementRefCountAndMaybeReleaseWakelock() override;
+
+ // Below methods are for HalProxyCallback
+
+ /**
+ * Post events to the event message queue if there is room to write them. Otherwise post the
+ * remaining events to a background thread for a blocking write with a 5 second timeout.
+ *
+ * @param events The list of events to post to the message queue.
+ */
+ void postEventsToMessageQueue(const std::vector<Event>& events);
+
+ /**
+ * Get the SensorInfo object associated with the sensorHandle.
+ *
+ * @param sensorHandle The sensorHandle for the sensor.
+ *
+ * @return The sensor info for the sensor.
+ */
+ const SensorInfo& getSensorInfo(uint32_t sensorHandle) const {
+ return mSensors.at(sensorHandle);
+ }
+
private:
using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;
+ const char* kWakeLockName = "SensorsHAL_WAKEUP";
+
/**
* The Event FMQ where sensor events are written
*/
@@ -120,14 +159,16 @@
*/
std::vector<ISensorsSubHal*> mSubHalList;
+ std::vector<const sp<IHalProxyCallback>> mSubHalCallbacks;
+
/**
- * List of SensorInfo objects that contains the sensor info from subhals as
+ * Map of sensor handles to SensorInfo objects that contains the sensor info from subhals as
* well as the modified sensor handle for the framework.
*
- * The subhal index is encoded in the first byte of the sensor handle and
- * the remaining bytes are generated by the subhal to identify the sensor.
+ * The subhal index is encoded in the first byte of the sensor handle and the remaining
+ * bytes are generated by the subhal to identify the sensor.
*/
- std::vector<SensorInfo> mSensorList;
+ std::map<uint32_t, SensorInfo> mSensors;
//! The current operation mode for all subhals.
OperationMode mCurrentOperationMode = OperationMode::NORMAL;
@@ -135,6 +176,15 @@
//! The single subHal that supports directChannel reporting.
ISensorsSubHal* mDirectChannelSubHal = nullptr;
+ //! The mutex for the event queue.
+ std::mutex mEventQueueMutex;
+
+ //! The scoped wakelock ref count.
+ size_t mWakelockRefCount = 0;
+
+ //! The mutex guarding the mWakelockRefCount variable
+ std::mutex mWakelockRefCountMutex;
+
//! The bit mask used to get the subhal index from a sensor handle.
static constexpr uint32_t kSensorHandleSubHalIndexMask = 0xFF000000;
@@ -145,12 +195,22 @@
void initializeSubHalListFromConfigFile(const char* configFileName);
/**
+ * Initialize the HalProxyCallback vector using the list of subhals.
+ */
+ void initializeSubHalCallbacks();
+
+ /**
* Initialize the list of SensorInfo objects in mSensorList by getting sensors from each
* subhal.
*/
void initializeSensorList();
/**
+ * Calls the above two helper methods which are shared in both ctors.
+ */
+ void initializeSubHalCallbacksAndSensorList();
+
+ /**
* Clear direct channel flags if the HalProxy has already chosen a subhal as its direct channel
* subhal. Set the directChannelSubHal pointer to the subHal passed in if this is the first
* direct channel enabled sensor seen.
@@ -179,6 +239,40 @@
static uint32_t clearSubHalIndex(uint32_t sensorHandle);
};
+/**
+ * Callback class used to provide the HalProxy with the index of which subHal is invoking
+ */
+class HalProxyCallback : public IHalProxyCallback {
+ using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
+
+ public:
+ HalProxyCallback(HalProxy* halProxy, int32_t subHalIndex)
+ : mHalProxy(halProxy), mSubHalIndex(subHalIndex) {}
+
+ Return<void> onDynamicSensorsConnected(
+ const hidl_vec<SensorInfo>& dynamicSensorsAdded) override {
+ return mHalProxy->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex);
+ }
+
+ Return<void> onDynamicSensorsDisconnected(
+ const hidl_vec<int32_t>& dynamicSensorHandlesRemoved) override {
+ return mHalProxy->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved, mSubHalIndex);
+ }
+
+ void postEvents(const std::vector<Event>& events, ScopedWakelock wakelock);
+
+ ScopedWakelock createScopedWakelock(bool lock);
+
+ private:
+ HalProxy* mHalProxy;
+ int32_t mSubHalIndex;
+
+ std::vector<Event> processEvents(const std::vector<Event>& events,
+ size_t* numWakeupEvents) const;
+
+ uint32_t setSubHalIndex(uint32_t sensorHandle) const;
+};
+
} // namespace implementation
} // namespace V2_0
} // namespace sensors
diff --git a/sensors/2.0/multihal/include/ScopedWakelock.h b/sensors/2.0/multihal/include/ScopedWakelock.h
new file mode 100644
index 0000000..a151f15
--- /dev/null
+++ b/sensors/2.0/multihal/include/ScopedWakelock.h
@@ -0,0 +1,77 @@
+/*
+ * 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 <mutex>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V2_0 {
+namespace implementation {
+
+class IScopedWakelockRefCounter {
+ public:
+ virtual void incrementRefCountAndMaybeAcquireWakelock() = 0;
+ virtual void decrementRefCountAndMaybeReleaseWakelock() = 0;
+ // Virtual dtor needed for compilation success
+ virtual ~IScopedWakelockRefCounter(){};
+};
+
+/**
+ * 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();
+
+ bool isLocked() const { return mLocked; }
+
+ private:
+ friend class HalProxyCallback;
+ IScopedWakelockRefCounter* mRefCounter;
+ bool mLocked;
+ ScopedWakelock(IScopedWakelockRefCounter* refCounter, bool locked);
+ ScopedWakelock(const ScopedWakelock&) = delete;
+ ScopedWakelock& operator=(const ScopedWakelock&) = delete;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace sensors
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/sensors/2.0/multihal/include/SubHal.h b/sensors/2.0/multihal/include/SubHal.h
index e84cba5..e7eedaa 100644
--- a/sensors/2.0/multihal/include/SubHal.h
+++ b/sensors/2.0/multihal/include/SubHal.h
@@ -16,15 +16,13 @@
#pragma once
+#include "ScopedWakelock.h"
+
#include <android/hardware/sensors/1.0/types.h>
#include <android/hardware/sensors/2.0/ISensors.h>
#include <vector>
-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
@@ -35,44 +33,9 @@
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;
-};
+using ::android::hardware::sensors::V1_0::Event;
+using ::android::hardware::sensors::V1_0::Result;
+using ::android::hardware::sensors::V1_0::SensorInfo;
/**
* Interface that contains several callbacks into the HalProxy class to communicate dynamic sensor
@@ -169,7 +132,9 @@
/**
* 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.
+ * order to communicate with the HalProxy. Method will be called anytime the sensors framework
+ * restarts. Therefore, this method will be responsible for reseting the state of the subhal and
+ * cleaning up and reallocating any previously allocated data.
*
* @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
diff --git a/sensors/2.0/multihal/tests/Android.bp b/sensors/2.0/multihal/tests/Android.bp
index 21ceb0c..ab260a4 100644
--- a/sensors/2.0/multihal/tests/Android.bp
+++ b/sensors/2.0/multihal/tests/Android.bp
@@ -33,6 +33,9 @@
"libpower",
"libutils",
],
+ static_libs: [
+ "android.hardware.sensors@2.0-HalProxy",
+ ],
}
cc_library {
diff --git a/sensors/2.0/multihal/tests/HalProxy_test.cpp b/sensors/2.0/multihal/tests/HalProxy_test.cpp
index 1e1f9e9..4b1a15e 100644
--- a/sensors/2.0/multihal/tests/HalProxy_test.cpp
+++ b/sensors/2.0/multihal/tests/HalProxy_test.cpp
@@ -16,18 +16,29 @@
#include <gtest/gtest.h>
#include <android/hardware/sensors/2.0/types.h>
+#include <fmq/MessageQueue.h>
#include "HalProxy.h"
+#include "ScopedWakelock.h"
#include "SensorsSubHal.h"
#include <vector>
+#undef LOG_TAG
+#define LOG_TAG "HalProxy_test"
+
namespace {
+using ::android::hardware::hidl_vec;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::Return;
+using ::android::hardware::sensors::V1_0::EventPayload;
using ::android::hardware::sensors::V1_0::SensorFlagBits;
using ::android::hardware::sensors::V1_0::SensorInfo;
using ::android::hardware::sensors::V1_0::SensorType;
+using ::android::hardware::sensors::V2_0::ISensorsCallback;
using ::android::hardware::sensors::V2_0::implementation::HalProxy;
+using ::android::hardware::sensors::V2_0::implementation::HalProxyCallback;
using ::android::hardware::sensors::V2_0::subhal::implementation::AllSensorsSubHal;
using ::android::hardware::sensors::V2_0::subhal::implementation::
AllSupportDirectChannelSensorsSubHal;
@@ -36,10 +47,28 @@
DoesNotSupportDirectChannelSensorsSubHal;
using ::android::hardware::sensors::V2_0::subhal::implementation::OnChangeSensorsSubHal;
using ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal;
-
using ::android::hardware::sensors::V2_0::subhal::implementation::
SetOperationModeFailingSensorsSubHal;
+using EventMessageQueue = MessageQueue<Event, ::android::hardware::kSynchronizedReadWrite>;
+using WakeupMessageQueue = MessageQueue<uint32_t, ::android::hardware::kSynchronizedReadWrite>;
+
+// The barebones sensors callback class passed into halproxy initialize calls
+class SensorsCallback : public ISensorsCallback {
+ public:
+ Return<void> onDynamicSensorsConnected(
+ const hidl_vec<SensorInfo>& /*dynamicSensorsAdded*/) override {
+ // Nothing yet
+ return Return<void>();
+ }
+
+ Return<void> onDynamicSensorsDisconnected(
+ const hidl_vec<int32_t>& /*dynamicSensorHandlesRemoved*/) override {
+ // Nothing yet
+ return Return<void>();
+ }
+};
+
// Helper declarations follow
/**
@@ -65,6 +94,22 @@
void testSensorsListForOneDirectChannelEnabledSubHal(const std::vector<SensorInfo>& sensorsList,
size_t enabledSubHalIndex);
+/**
+ * Construct and return a HIDL Event type thats sensorHandle refers to a proximity sensor
+ * which is a wakeup type sensor.
+ *
+ * @ return A proximity event.
+ */
+Event makeProximityEvent();
+
+/**
+ * Construct and return a HIDL Event type thats sensorHandle refers to a proximity sensor
+ * which is a wakeup type sensor.
+ *
+ * @ return A proximity event.
+ */
+Event makeAccelerometerEvent();
+
// Tests follow
TEST(HalProxyTest, GetSensorsListOneSubHalTest) {
AllSensorsSubHal subHal;
@@ -156,6 +201,86 @@
});
}
+TEST(HalProxyTest, PostSingleNonWakeupEvent) {
+ constexpr size_t kQueueSize = 5;
+ AllSensorsSubHal subHal;
+ std::vector<ISensorsSubHal*> subHals{&subHal};
+ HalProxy proxy(subHals);
+ std::unique_ptr<EventMessageQueue> eventQueue =
+ std::make_unique<EventMessageQueue>(kQueueSize, true);
+ std::unique_ptr<WakeupMessageQueue> wakeLockQueue =
+ std::make_unique<WakeupMessageQueue>(kQueueSize, true);
+ ::android::sp<ISensorsCallback> callback = new SensorsCallback();
+ proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback);
+
+ std::vector<Event> events{makeAccelerometerEvent()};
+ subHal.postEvents(events, false /* wakeup */);
+
+ EXPECT_EQ(eventQueue->availableToRead(), 1);
+}
+
+TEST(HalProxyTest, PostMultipleNonWakeupEvent) {
+ constexpr size_t kQueueSize = 5;
+ constexpr size_t kNumEvents = 3;
+ AllSensorsSubHal subHal;
+ std::vector<ISensorsSubHal*> subHals{&subHal};
+ HalProxy proxy(subHals);
+ std::unique_ptr<EventMessageQueue> eventQueue =
+ std::make_unique<EventMessageQueue>(kQueueSize, true);
+ std::unique_ptr<WakeupMessageQueue> wakeLockQueue =
+ std::make_unique<WakeupMessageQueue>(kQueueSize, true);
+ ::android::sp<ISensorsCallback> callback = new SensorsCallback();
+ proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback);
+
+ std::vector<Event> events;
+ for (size_t i = 0; i < kNumEvents; i++) {
+ events.push_back(makeAccelerometerEvent());
+ }
+ subHal.postEvents(events, false /* wakeup */);
+
+ EXPECT_EQ(eventQueue->availableToRead(), kNumEvents);
+}
+
+TEST(HalProxyTest, PostSingleWakeupEvent) {
+ constexpr size_t kQueueSize = 5;
+ AllSensorsSubHal subHal;
+ std::vector<ISensorsSubHal*> subHals{&subHal};
+ HalProxy proxy(subHals);
+ std::unique_ptr<EventMessageQueue> eventQueue =
+ std::make_unique<EventMessageQueue>(kQueueSize, true);
+ std::unique_ptr<WakeupMessageQueue> wakeLockQueue =
+ std::make_unique<WakeupMessageQueue>(kQueueSize, true);
+ ::android::sp<ISensorsCallback> callback = new SensorsCallback();
+ proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback);
+
+ std::vector<Event> events{makeProximityEvent()};
+ subHal.postEvents(events, true /* wakeup */);
+
+ EXPECT_EQ(eventQueue->availableToRead(), 1);
+}
+
+TEST(HalProxyTest, PostMultipleWakeupEvents) {
+ constexpr size_t kQueueSize = 5;
+ constexpr size_t kNumEvents = 3;
+ AllSensorsSubHal subHal;
+ std::vector<ISensorsSubHal*> subHals{&subHal};
+ HalProxy proxy(subHals);
+ std::unique_ptr<EventMessageQueue> eventQueue =
+ std::make_unique<EventMessageQueue>(kQueueSize, true);
+ std::unique_ptr<WakeupMessageQueue> wakeLockQueue =
+ std::make_unique<WakeupMessageQueue>(kQueueSize, true);
+ ::android::sp<ISensorsCallback> callback = new SensorsCallback();
+ proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback);
+
+ std::vector<Event> events;
+ for (size_t i = 0; i < kNumEvents; i++) {
+ events.push_back(makeProximityEvent());
+ }
+ subHal.postEvents(events, true /* wakeup */);
+
+ EXPECT_EQ(eventQueue->availableToRead(), kNumEvents);
+}
+
// Helper implementations follow
void testSensorsListFromProxyAndSubHal(const std::vector<SensorInfo>& proxySensorsList,
const std::vector<SensorInfo>& subHalSensorsList) {
@@ -187,4 +312,24 @@
}
}
+Event makeProximityEvent() {
+ Event event;
+ event.timestamp = 0xFF00FF00;
+ // This is the sensorhandle of proximity, which is wakeup type
+ event.sensorHandle = 0x00000008;
+ event.sensorType = SensorType::PROXIMITY;
+ event.u = EventPayload();
+ return event;
+}
+
+Event makeAccelerometerEvent() {
+ Event event;
+ event.timestamp = 0xFF00FF00;
+ // This is the sensorhandle of proximity, which is wakeup type
+ event.sensorHandle = 0x00000001;
+ event.sensorType = SensorType::ACCELEROMETER;
+ event.u = EventPayload();
+ return event;
+}
+
} // namespace