Dynamic Sensor Discovery implementation

Defined the dynamic sensor meta data type and UUID of sensor.

Implementation in sensorservice and the native SensorManager to
support Dynamic sensor discovery.

Change-Id: I9df2f2ae51d46cd946a9757393f7a60b52cc4fb8
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index acad61c..9f8c21b 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -246,9 +246,6 @@
 
 Sensor SensorService::registerSensor(SensorInterface* s)
 {
-    sensors_event_t event;
-    memset(&event, 0, sizeof(event));
-
     const Sensor sensor(s->getSensor());
     // add to the sensor list (returned to clients)
     mSensorList.add(sensor);
@@ -260,6 +257,37 @@
     return sensor;
 }
 
+Sensor SensorService::registerDynamicSensor(SensorInterface* s)
+{
+    Sensor sensor = registerSensor(s);
+    mDynamicSensorList.add(sensor);
+    return sensor;
+}
+
+bool SensorService::unregisterDynamicSensor(int handle) {
+    bool found = false;
+
+    for (size_t i=0 ; i<mSensorList.size() ; i++) {
+        if (mSensorList[i].getHandle() == handle) {
+            mSensorList.removeAt(i);
+            found = true;
+            break;
+        }
+    }
+
+    if (found) {
+        for (size_t i=0 ; i<mDynamicSensorList.size() ; i++) {
+            if (mDynamicSensorList[i].getHandle() == handle) {
+                mDynamicSensorList.removeAt(i);
+            }
+        }
+
+        mSensorMap.removeItem(handle);
+        mLastEventSeen.removeItem(handle);
+    }
+    return found;
+}
+
 Sensor SensorService::registerVirtualSensor(SensorInterface* s)
 {
     Sensor sensor = registerSensor(s);
@@ -593,11 +621,11 @@
             }
         }
 
-        // Map flush_complete_events in the buffer to SensorEventConnections which called flush on
-        // the hardware sensor. mapFlushEventsToConnections[i] will be the SensorEventConnection
-        // mapped to the corresponding flush_complete_event in mSensorEventBuffer[i] if such a
-        // mapping exists (NULL otherwise).
         for (int i = 0; i < count; ++i) {
+            // Map flush_complete_events in the buffer to SensorEventConnections which called flush on
+            // the hardware sensor. mapFlushEventsToConnections[i] will be the SensorEventConnection
+            // mapped to the corresponding flush_complete_event in mSensorEventBuffer[i] if such a
+            // mapping exists (NULL otherwise).
             mMapFlushEventsToConnections[i] = NULL;
             if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
                 const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
@@ -607,8 +635,40 @@
                     rec->removeFirstPendingFlushConnection();
                 }
             }
+
+            // handle dynamic sensor meta events, process registration and unregistration of dynamic
+            // sensor based on content of event.
+            if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
+                if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) {
+                    int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
+                    const sensor_t& dynamicSensor =
+                            *(mSensorEventBuffer[i].dynamic_sensor_meta.sensor);
+                    ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s",
+                          handle, dynamicSensor.type, dynamicSensor.name);
+
+                    device.handleDynamicSensorConnection(handle, true /*connected*/);
+                    registerDynamicSensor(new HardwareSensor(dynamicSensor));
+
+                } else {
+                    int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
+                    ALOGI("Dynamic sensor handle 0x%x disconnected", handle);
+
+                    device.handleDynamicSensorConnection(handle, false /*connected*/);
+                    if (!unregisterDynamicSensor(handle)) {
+                        ALOGE("Dynamic sensor release error.");
+                    }
+
+                    size_t numConnections = activeConnections.size();
+                    for (size_t i=0 ; i < numConnections; ++i) {
+                        if (activeConnections[i] != NULL) {
+                            activeConnections[i]->removeSensor(handle);
+                        }
+                    }
+                }
+            }
         }
 
+
         // Send our events to clients. Check the state of wake lock for each client and release the
         // lock if none of the clients need it.
         bool needsWakeLock = false;
@@ -693,13 +753,17 @@
 void SensorService::recordLastValueLocked(
         const sensors_event_t* buffer, size_t count) {
     for (size_t i = 0; i < count; i++) {
-        if (buffer[i].type != SENSOR_TYPE_META_DATA) {
-            MostRecentEventLogger* &circular_buf = mLastEventSeen.editValueFor(buffer[i].sensor);
-            if (circular_buf == NULL) {
-                circular_buf = new MostRecentEventLogger(buffer[i].type);
-            }
-            circular_buf->addEvent(buffer[i]);
+        if (buffer[i].type == SENSOR_TYPE_META_DATA ||
+            buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META ||
+            mLastEventSeen.indexOfKey(buffer[i].sensor) <0 ) {
+            continue;
         }
+
+        MostRecentEventLogger* &circular_buf = mLastEventSeen.editValueFor(buffer[i].sensor);
+        if (circular_buf == NULL) {
+            circular_buf = new MostRecentEventLogger(buffer[i].type);
+        }
+        circular_buf->addEvent(buffer[i]);
     }
 }
 
@@ -729,7 +793,7 @@
 
 bool SensorService::isVirtualSensor(int handle) const {
     SensorInterface* sensor = mSensorMap.valueFor(handle);
-    return sensor->isVirtual();
+    return sensor != NULL && sensor->isVirtual();
 }
 
 bool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
@@ -766,6 +830,23 @@
     return accessibleSensorList;
 }
 
+Vector<Sensor> SensorService::getDynamicSensorList(const String16& opPackageName)
+{
+    Vector<Sensor> accessibleSensorList;
+    for (size_t i = 0; i < mDynamicSensorList.size(); i++) {
+        Sensor sensor = mDynamicSensorList[i];
+        if (canAccessSensor(sensor, "getDynamicSensorList", opPackageName)) {
+            accessibleSensorList.add(sensor);
+        } else {
+            ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
+                  sensor.getName().string(),
+                  sensor.getRequiredPermission().string(),
+                  sensor.getRequiredAppOp());
+        }
+    }
+    return accessibleSensorList;
+}
+
 sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
         int requestedMode, const String16& opPackageName) {
     // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
@@ -950,8 +1031,7 @@
     // one should be trigger by a change in value). Also if this sensor isn't
     // already active, don't call flush().
     if (err == NO_ERROR &&
-            sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT &&
-            sensor->getSensor().getReportingMode() != AREPORTING_MODE_ON_CHANGE &&
+            sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS &&
             rec->getNumConnections() > 1) {
         connection->setFirstFlushPending(handle, true);
         status_t err_flush = sensor->flush(connection.get(), handle);