MH2 | Implement dynamic sensors callbacks on HalProxy

Additionally, have HalProxyCallback::processEvents use
HalProxy::setSubHalIndex static method instead of its own helper.
Add unit tests to test the dynamic sensor methods.

Bug: 136511617
Test: New unit tests are passing.
Change-Id: Ib903291a83df2fafa480082f9305c594bd325f79
diff --git a/sensors/2.0/multihal/HalProxy.cpp b/sensors/2.0/multihal/HalProxy.cpp
index 1fbc787..5aa3b3d 100644
--- a/sensors/2.0/multihal/HalProxy.cpp
+++ b/sensors/2.0/multihal/HalProxy.cpp
@@ -38,6 +38,18 @@
 
 typedef ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*);
 
+/**
+ * Set the subhal index as first byte of sensor handle and return this modified version.
+ *
+ * @param sensorHandle The sensor handle to modify.
+ * @param subHalIndex The index in the hal proxy of the sub hal this sensor belongs to.
+ *
+ * @return The modified sensor handle.
+ */
+uint32_t setSubHalIndex(uint32_t sensorHandle, size_t subHalIndex) {
+    return sensorHandle | (subHalIndex << 24);
+}
+
 HalProxy::HalProxy() {
     const char* kMultiHalConfigFile = "/vendor/etc/sensors/hals.conf";
     initializeSubHalListFromConfigFile(kMultiHalConfigFile);
@@ -206,15 +218,45 @@
     return Return<void>();
 }
 
-Return<void> HalProxy::onDynamicSensorsConnected(
-        const hidl_vec<SensorInfo>& /* dynamicSensorsAdded */, int32_t /* subHalIndex */) {
-    // TODO: Map the SensorInfo to the global list and then invoke the framework's callback.
+Return<void> HalProxy::onDynamicSensorsConnected(const hidl_vec<SensorInfo>& dynamicSensorsAdded,
+                                                 int32_t subHalIndex) {
+    std::vector<SensorInfo> sensors;
+    {
+        std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
+        for (SensorInfo sensor : dynamicSensorsAdded) {
+            if (!subHalIndexIsClear(sensor.sensorHandle)) {
+                ALOGE("Dynamic sensor added %s had sensorHandle with first byte not 0.",
+                      sensor.name.c_str());
+            } else {
+                sensor.sensorHandle = setSubHalIndex(sensor.sensorHandle, subHalIndex);
+                mDynamicSensors[sensor.sensorHandle] = sensor;
+                sensors.push_back(sensor);
+            }
+        }
+    }
+    mDynamicSensorsCallback->onDynamicSensorsConnected(sensors);
     return Return<void>();
 }
 
 Return<void> HalProxy::onDynamicSensorsDisconnected(
-        const hidl_vec<int32_t>& /* dynamicSensorHandlesRemoved */, int32_t /* subHalIndex */) {
-    // TODO: Unmap the SensorInfo from the global list and then invoke the framework's callback.
+        const hidl_vec<int32_t>& dynamicSensorHandlesRemoved, int32_t subHalIndex) {
+    // TODO: Block this call until all pending events are flushed from queue
+    std::vector<int32_t> sensorHandles;
+    {
+        std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
+        for (int32_t sensorHandle : dynamicSensorHandlesRemoved) {
+            if (!subHalIndexIsClear(sensorHandle)) {
+                ALOGE("Dynamic sensorHandle removed had first byte not 0.");
+            } else {
+                sensorHandle = setSubHalIndex(sensorHandle, subHalIndex);
+                if (mDynamicSensors.find(sensorHandle) != mDynamicSensors.end()) {
+                    mDynamicSensors.erase(sensorHandle);
+                    sensorHandles.push_back(sensorHandle);
+                }
+            }
+        }
+    }
+    mDynamicSensorsCallback->onDynamicSensorsDisconnected(sensorHandles);
     return Return<void>();
 }
 
@@ -264,7 +306,7 @@
         ISensorsSubHal* subHal = mSubHalList[subHalIndex];
         auto result = subHal->getSensorsList([&](const auto& list) {
             for (SensorInfo sensor : list) {
-                if ((sensor.sensorHandle & kSensorHandleSubHalIndexMask) != 0) {
+                if (!subHalIndexIsClear(sensor.sensorHandle)) {
                     ALOGE("SubHal sensorHandle's first byte was not 0");
                 } else {
                     ALOGV("Loaded sensor: %s", sensor.name.c_str());
@@ -389,6 +431,10 @@
     return sensorHandle & (~kSensorHandleSubHalIndexMask);
 }
 
+bool HalProxy::subHalIndexIsClear(uint32_t sensorHandle) {
+    return (sensorHandle & kSensorHandleSubHalIndexMask) == 0;
+}
+
 void HalProxyCallback::postEvents(const std::vector<Event>& events, ScopedWakelock wakelock) {
     (void)wakelock;
     size_t numWakeupEvents;
@@ -418,7 +464,7 @@
     std::vector<Event> eventsOut;
     *numWakeupEvents = 0;
     for (Event event : events) {
-        event.sensorHandle = setSubHalIndex(event.sensorHandle);
+        event.sensorHandle = setSubHalIndex(event.sensorHandle, mSubHalIndex);
         eventsOut.push_back(event);
         if ((mHalProxy->getSensorInfo(event.sensorHandle).flags & V1_0::SensorFlagBits::WAKE_UP) !=
             0) {
@@ -428,10 +474,6 @@
     return eventsOut;
 }
 
-uint32_t HalProxyCallback::setSubHalIndex(uint32_t sensorHandle) const {
-    return sensorHandle | mSubHalIndex << 24;
-}
-
 }  // namespace implementation
 }  // namespace V2_0
 }  // namespace sensors