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/include/android/sensor.h b/include/android/sensor.h
index 9472ad6..5b79d3c 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -207,6 +207,11 @@
   int8_t status;
 } AHeartRateEvent;
 
+typedef struct ADynamicSensorEvent {
+    bool  connected;
+    int   handle;
+} ADynamicSensorEvent;
+
 /* NOTE: Must match hardware/sensors.h */
 typedef struct ASensorEvent {
     int32_t version; /* sizeof(struct ASensorEvent) */
@@ -229,6 +234,7 @@
             AUncalibratedEvent uncalibrated_magnetic;
             AMetaDataEvent meta_data;
             AHeartRateEvent heart_rate;
+            ADynamicSensorEvent dynamic_sensor_meta;
         };
         union {
             uint64_t        data[8];
diff --git a/include/gui/ISensorServer.h b/include/gui/ISensorServer.h
index 3dca2a3..571acb5 100644
--- a/include/gui/ISensorServer.h
+++ b/include/gui/ISensorServer.h
@@ -38,6 +38,8 @@
     DECLARE_META_INTERFACE(SensorServer);
 
     virtual Vector<Sensor> getSensorList(const String16& opPackageName) = 0;
+    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName) = 0;
+
     virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
              int mode, const String16& opPackageName) = 0;
     virtual int32_t isDataInjectionEnabled() = 0;
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index 8142be6..3792540 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -52,9 +52,13 @@
         TYPE_PROXIMITY      = ASENSOR_TYPE_PROXIMITY
     };
 
-            Sensor();
-            Sensor(struct sensor_t const* hwSensor, int halVersion = 0);
-            ~Sensor();
+    typedef struct {
+        uint8_t b[16];
+    } uuid_t;
+
+    Sensor();
+    Sensor(struct sensor_t const* hwSensor, int halVersion = 0);
+    ~Sensor();
 
     const String8& getName() const;
     const String8& getVendor() const;
@@ -77,6 +81,7 @@
     uint32_t getFlags() const;
     bool isWakeUpSensor() const;
     int32_t getReportingMode() const;
+    const uuid_t& getUuid() const;
 
     // LightFlattenable protocol
     inline bool isFixedSize() const { return false; }
@@ -103,6 +108,7 @@
     int32_t mRequiredAppOp;
     int32_t mMaxDelay;
     uint32_t mFlags;
+    uuid_t  mUuid;
     static void flattenString8(void*& buffer, size_t& size, const String8& string8);
     static bool unflattenString8(void const*& buffer, size_t& size, String8& outputString8);
 };
diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h
index 0cff46c..6c6230f 100644
--- a/include/gui/SensorManager.h
+++ b/include/gui/SensorManager.h
@@ -54,7 +54,8 @@
     static SensorManager& getInstanceForPackage(const String16& packageName);
     ~SensorManager();
 
-    ssize_t getSensorList(Sensor const* const** list) const;
+    ssize_t getSensorList(Sensor const* const** list);
+    ssize_t getDynamicSensorList(Vector<Sensor>& list);
     Sensor const* getDefaultSensor(int type);
     sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0);
     bool isDataInjectionEnabled();
@@ -64,17 +65,17 @@
     void sensorManagerDied();
 
     SensorManager(const String16& opPackageName);
-    status_t assertStateLocked() const;
+    status_t assertStateLocked();
 
 private:
     static Mutex sLock;
     static std::map<String16, SensorManager*> sPackageInstances;
 
-    mutable Mutex mLock;
-    mutable sp<ISensorServer> mSensorServer;
-    mutable Sensor const** mSensorList;
-    mutable Vector<Sensor> mSensors;
-    mutable sp<IBinder::DeathRecipient> mDeathObserver;
+    Mutex mLock;
+    sp<ISensorServer> mSensorServer;
+    Sensor const** mSensorList;
+    Vector<Sensor> mSensors;
+    sp<IBinder::DeathRecipient> mDeathObserver;
     const String16 mOpPackageName;
 };
 
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
index f581b5c..3a4c7e4 100644
--- a/libs/gui/ISensorServer.cpp
+++ b/libs/gui/ISensorServer.cpp
@@ -35,7 +35,8 @@
 enum {
     GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
     CREATE_SENSOR_EVENT_CONNECTION,
-    ENABLE_DATA_INJECTION
+    ENABLE_DATA_INJECTION,
+    GET_DYNAMIC_SENSOR_LIST,
 };
 
 class BpSensorServer : public BpInterface<ISensorServer>
@@ -65,6 +66,23 @@
         return v;
     }
 
+    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        data.writeString16(opPackageName);
+        remote()->transact(GET_DYNAMIC_SENSOR_LIST, data, &reply);
+        Sensor s;
+        Vector<Sensor> v;
+        uint32_t n = reply.readUint32();
+        v.setCapacity(n);
+        while (n--) {
+            reply.read(s);
+            v.add(s);
+        }
+        return v;
+    }
+
     virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
              int mode, const String16& opPackageName)
     {
@@ -124,6 +142,17 @@
             reply->writeInt32(static_cast<int32_t>(ret));
             return NO_ERROR;
         }
+        case GET_DYNAMIC_SENSOR_LIST: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            const String16& opPackageName = data.readString16();
+            Vector<Sensor> v(getDynamicSensorList(opPackageName));
+            size_t n = v.size();
+            reply->writeUint32(static_cast<uint32_t>(n));
+            for (size_t i = 0; i < n; i++) {
+                reply->write(v[i]);
+            }
+            return NO_ERROR;
+        }
     }
     return BBinder::onTransact(code, data, reply, flags);
 }
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 0a0fc4b..a6cb908 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -188,7 +188,7 @@
         if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
             mFlags |= SENSOR_FLAG_WAKE_UP;
         }
-         break;
+        break;
     case SENSOR_TYPE_WAKE_GESTURE:
         mStringType = SENSOR_STRING_TYPE_WAKE_GESTURE;
         mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
@@ -217,6 +217,10 @@
             mFlags |= SENSOR_FLAG_WAKE_UP;
         }
         break;
+    case SENSOR_TYPE_DYNAMIC_SENSOR_META:
+        mStringType = SENSOR_STRING_TYPE_DYNAMIC_SENSOR_META;
+        mFlags = SENSOR_FLAG_SPECIAL_REPORTING_MODE; // special trigger and non-wake up
+        break;
     default:
         // Only pipe the stringType, requiredPermission and flags for custom sensors.
         if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->stringType) {
@@ -368,13 +372,18 @@
     return ((mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT);
 }
 
+const Sensor::uuid_t& Sensor::getUuid() const {
+    return mUuid;
+}
+
 size_t Sensor::getFlattenedSize() const
 {
     size_t fixedSize =
-            sizeof(int32_t) * 3 +
-            sizeof(float) * 4 +
-            sizeof(int32_t) * 6 +
-            sizeof(bool);
+            sizeof(mVersion) + sizeof(mHandle) + sizeof(mType) +
+            sizeof(mMinValue) + sizeof(mMaxValue) + sizeof(mResolution) +
+            sizeof(mPower) + sizeof(mMinDelay) + sizeof(mFifoMaxEventCount) +
+            sizeof(mFifoMaxEventCount) + sizeof(mRequiredPermissionRuntime) +
+            sizeof(mRequiredAppOp) + sizeof(mMaxDelay) + sizeof(mFlags) + sizeof(mUuid);
 
     size_t variableSize =
             sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) +
@@ -408,6 +417,7 @@
     FlattenableUtils::write(buffer, size, mRequiredAppOp);
     FlattenableUtils::write(buffer, size, mMaxDelay);
     FlattenableUtils::write(buffer, size, mFlags);
+    FlattenableUtils::write(buffer, size, mUuid);
     return NO_ERROR;
 }
 
@@ -419,11 +429,11 @@
         return NO_MEMORY;
     }
 
-    size_t fixedSize =
-            sizeof(int32_t) * 3 +
-            sizeof(float) * 4 +
-            sizeof(int32_t) * 5;
-    if (size < fixedSize) {
+    size_t fixedSize1 =
+            sizeof(mVersion) + sizeof(mHandle) + sizeof(mType) + sizeof(mMinValue) +
+            sizeof(mMaxValue) + sizeof(mResolution) + sizeof(mPower) + sizeof(mMinDelay) +
+            sizeof(mFifoMaxEventCount) + sizeof(mFifoMaxEventCount);
+    if (size < fixedSize1) {
         return NO_MEMORY;
     }
 
@@ -444,10 +454,19 @@
     if (!unflattenString8(buffer, size, mRequiredPermission)) {
         return NO_MEMORY;
     }
+
+    size_t fixedSize2 =
+            sizeof(mRequiredPermissionRuntime) + sizeof(mRequiredAppOp) + sizeof(mMaxDelay) +
+            sizeof(mFlags) + sizeof(mUuid);
+    if (size < fixedSize2) {
+        return NO_MEMORY;
+    }
+
     FlattenableUtils::read(buffer, size, mRequiredPermissionRuntime);
     FlattenableUtils::read(buffer, size, mRequiredAppOp);
     FlattenableUtils::read(buffer, size, mMaxDelay);
     FlattenableUtils::read(buffer, size, mFlags);
+    FlattenableUtils::read(buffer, size, mUuid);
     return NO_ERROR;
 }
 
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index 33608b5..225bfa8 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -89,19 +89,16 @@
 }
 
 SensorManager::SensorManager(const String16& opPackageName)
-    : mSensorList(0), mOpPackageName(opPackageName)
-{
+    : mSensorList(0), mOpPackageName(opPackageName) {
     // okay we're not locked here, but it's not needed during construction
     assertStateLocked();
 }
 
-SensorManager::~SensorManager()
-{
+SensorManager::~SensorManager() {
     free(mSensorList);
 }
 
-void SensorManager::sensorManagerDied()
-{
+void SensorManager::sensorManagerDied() {
     Mutex::Autolock _l(mLock);
     mSensorServer.clear();
     free(mSensorList);
@@ -109,7 +106,7 @@
     mSensors.clear();
 }
 
-status_t SensorManager::assertStateLocked() const {
+status_t SensorManager::assertStateLocked() {
     bool initSensorManager = false;
     if (mSensorServer == NULL) {
         initSensorManager = true;
@@ -136,13 +133,13 @@
         }
 
         class DeathObserver : public IBinder::DeathRecipient {
-            SensorManager& mSensorManger;
+            SensorManager& mSensorManager;
             virtual void binderDied(const wp<IBinder>& who) {
                 ALOGW("sensorservice died [%p]", who.unsafe_get());
-                mSensorManger.sensorManagerDied();
+                mSensorManager.sensorManagerDied();
             }
         public:
-            DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }
+            DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
         };
 
         LOG_ALWAYS_FATAL_IF(mSensorServer.get() == NULL, "getService(SensorService) NULL");
@@ -164,8 +161,7 @@
     return NO_ERROR;
 }
 
-ssize_t SensorManager::getSensorList(Sensor const* const** list) const
-{
+ssize_t SensorManager::getSensorList(Sensor const* const** list) {
     Mutex::Autolock _l(mLock);
     status_t err = assertStateLocked();
     if (err < 0) {
@@ -175,6 +171,19 @@
     return static_cast<ssize_t>(mSensors.size());
 }
 
+ssize_t SensorManager::getDynamicSensorList(Vector<Sensor> & dynamicSensors) {
+    Mutex::Autolock _l(mLock);
+    status_t err = assertStateLocked();
+    if (err < 0) {
+        return static_cast<ssize_t>(err);
+    }
+
+    dynamicSensors = mSensorServer->getDynamicSensorList(mOpPackageName);
+    size_t count = dynamicSensors.size();
+
+    return static_cast<ssize_t>(count);
+}
+
 Sensor const* SensorManager::getDefaultSensor(int type)
 {
     Mutex::Autolock _l(mLock);
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 40d596f..179b1c5 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -73,6 +73,17 @@
     }
 }
 
+void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
+    if (connected) {
+        Info model;
+        mActivationCount.add(handle, model);
+        mSensorDevice->activate(
+                reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, 0);
+    } else {
+        mActivationCount.removeItem(handle);
+    }
+}
+
 void SensorDevice::dump(String8& result)
 {
     if (!mSensorModule) return;
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index c484849..c12630a 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -89,6 +89,7 @@
     bool isClientDisabledLocked(void* ident);
 public:
     ssize_t getSensorList(sensor_t const** list);
+    void handleDynamicSensorConnection(int handle, bool connected);
     status_t initCheck() const;
     int getHalDeviceVersion() const;
     ssize_t poll(sensors_event_t* buffer, size_t count);
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);
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 080a550..ef4516b 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -149,6 +149,7 @@
 
     // ISensorServer interface
     virtual Vector<Sensor> getSensorList(const String16& opPackageName);
+    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName);
     virtual sp<ISensorEventConnection> createSensorEventConnection(
             const String8& packageName,
             int requestedMode, const String16& opPackageName);
@@ -165,6 +166,8 @@
     static void sortEventBuffer(sensors_event_t* buffer, size_t count);
     Sensor registerSensor(SensorInterface* sensor);
     Sensor registerVirtualSensor(SensorInterface* sensor);
+    Sensor registerDynamicSensor(SensorInterface* sensor);
+    bool unregisterDynamicSensor(int handle);
     status_t cleanupWithoutDisable(const sp<SensorEventConnection>& connection, int handle);
     status_t cleanupWithoutDisableLocked(const sp<SensorEventConnection>& connection, int handle);
     void cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
@@ -212,6 +215,7 @@
     Vector<Sensor> mSensorList;
     Vector<Sensor> mUserSensorListDebug;
     Vector<Sensor> mUserSensorList;
+    Vector<Sensor> mDynamicSensorList;
     DefaultKeyedVector<int, SensorInterface*> mSensorMap;
     Vector<SensorInterface *> mVirtualSensorList;
     status_t mInitCheck;