Merge "Camera: Update camera3.h doc for high speed video batching"
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index 9870913..a416043 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -163,6 +163,10 @@
     uint16_t total_trackable_advertisers;
     bool extended_scan_support;
     bool debug_logging_supported;
+    bool le_2m_phy_supported;
+    bool le_coded_phy_supported;
+    bool le_extended_advertising_supported;
+    bool le_periodic_advertising_supported;
 }bt_local_le_features_t;
 
 /* Bluetooth Adapter and Remote Device property types */
diff --git a/modules/sensors/dynamic_sensor/Android.mk b/modules/sensors/dynamic_sensor/Android.mk
new file mode 100644
index 0000000..07bc5e8
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/Android.mk
@@ -0,0 +1,77 @@
+# Copyright (C) 2017 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.
+
+LOCAL_PATH := $(call my-dir)
+COMMON_CFLAGS := -Wall -Werror -Wextra
+
+#
+# There are two ways to utilize the dynamic sensor module:
+#   1. Use as an extension in an existing hal: declare dependency on libdynamic_sensor_ext shared
+#      library in existing sensor hal.
+#   2. Use as a standalone sensor HAL and configure multihal to combine it with sensor hal that
+#      hosts other sensors: add dependency on sensors.dynamic_sensor_hal in device level makefile and
+#      write multihal configuration file accordingly.
+#
+# Please take only one of these two options to avoid conflict over hardware resource.
+#
+
+#
+# Option 1: sensor extension module
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := libdynamic_sensor_ext
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_OWNER := google
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS) -DLOG_TAG=\"DynamicSensorExt\"
+
+LOCAL_SRC_FILES := \
+    BaseSensorObject.cpp \
+    DynamicSensorManager.cpp \
+    RingBuffer.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    liblog
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+include $(BUILD_SHARED_LIBRARY)
+
+#
+# Option 2: independent sensor hal
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := sensors.dynamic_sensor_hal
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_OWNER := google
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS) -DLOG_TAG=\"DynamicSensorHal\"
+
+LOCAL_SRC_FILES := \
+    BaseSensorObject.cpp \
+    DynamicSensorManager.cpp \
+    RingBuffer.cpp \
+    sensors.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    liblog \
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.h b/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.h
new file mode 100644
index 0000000..29cf7a4
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/BaseDynamicSensorDaemon.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef ANDROID_SENSORHAL_EXT_BASE_DYNAMIC_SENSOR_DAEMON_H
+#define ANDROID_SENSORHAL_EXT_BASE_DYNAMIC_SENSOR_DAEMON_H
+
+#include <utils/RefBase.h>
+
+namespace android {
+namespace SensorHalExt {
+
+class DynamicSensorManager;
+
+class BaseDynamicSensorDaemon : public RefBase {
+public:
+    BaseDynamicSensorDaemon(DynamicSensorManager& manager) : mManager(manager) {}
+    virtual ~BaseDynamicSensorDaemon() = default;
+protected:
+    DynamicSensorManager& mManager;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_BASE_DYNAMIC_SENSOR_DAEMON_H
+
diff --git a/modules/sensors/dynamic_sensor/BaseSensorObject.cpp b/modules/sensors/dynamic_sensor/BaseSensorObject.cpp
new file mode 100644
index 0000000..189e87f
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/BaseSensorObject.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 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 "BaseSensorObject.h"
+#include "SensorEventCallback.h"
+
+#include <utils/Log.h>
+#include <cstring>
+
+namespace android {
+namespace SensorHalExt {
+
+BaseSensorObject::BaseSensorObject() : mCallback(nullptr) {
+}
+
+bool BaseSensorObject::setEventCallback(SensorEventCallback* callback) {
+    if (mCallback != nullptr) {
+        ALOGE("callback is already assigned, cannot change.");
+        return false;
+    }
+    mCallback = callback;
+    return true;
+}
+
+void BaseSensorObject::getUuid(uint8_t* uuid) const {
+    // default uuid denoting uuid feature is not supported on this sensor.
+    memset(uuid, 0, 16);
+}
+
+int BaseSensorObject::flush() {
+    static const sensors_event_t event = {
+        .type = SENSOR_TYPE_META_DATA,
+        .timestamp = TIMESTAMP_AUTO_FILL  // timestamp will be filled at dispatcher
+    };
+    generateEvent(event);
+    return 0;
+}
+
+void BaseSensorObject::generateEvent(const sensors_event_t &e) {
+    if (mCallback) {
+        mCallback->submitEvent(this, e);
+    }
+}
+
+} // namespace SensorHalExt
+} // namespace android
+
diff --git a/modules/sensors/dynamic_sensor/BaseSensorObject.h b/modules/sensors/dynamic_sensor/BaseSensorObject.h
new file mode 100644
index 0000000..326e138
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/BaseSensorObject.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef ANDROID_SENSORHAL_BASE_SENSOR_OBJECT_H
+#define ANDROID_SENSORHAL_BASE_SENSOR_OBJECT_H
+
+#include <utils/RefBase.h>
+#include <utils/Timers.h> // for nsecs_t
+#include <cstdint>
+
+struct sensor_t;
+struct sensors_event_t;
+
+namespace android {
+namespace SensorHalExt {
+
+class SensorEventCallback;
+
+class BaseSensorObject : virtual public RefBase {
+public:
+    BaseSensorObject();
+    virtual ~BaseSensorObject() = default;
+
+    // always called by DynamicSensorManager, callback must point to
+    // valid object throughout life cycle of BaseSensorObject
+    bool setEventCallback(SensorEventCallback* callback);
+
+    // virtual functions to get sensor information and operate sensor
+    virtual const sensor_t* getSensor() const = 0;
+
+    // get uuid of sensor, default implementation set it to all zero, means does not have a uuid.
+    virtual void getUuid(uint8_t* uuid) const;
+
+    // enable sensor
+    virtual int enable(bool enable) = 0;
+
+    // set sample period and batching period of sensor.
+    virtual int batch(nsecs_t samplePeriod, nsecs_t batchPeriod) = 0;
+
+    // flush sensor, default implementation will send a flush complete event back.
+    virtual int flush();
+
+protected:
+    // utility function for sub-class
+    void generateEvent(const sensors_event_t &e);
+private:
+    SensorEventCallback* mCallback;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_BASE_SENSOR_OBJECT_H
+
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
new file mode 100644
index 0000000..d33650c
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.cpp
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2017 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 "BaseDynamicSensorDaemon.h"
+#include "BaseSensorObject.h"
+#include "DynamicSensorManager.h"
+
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+
+#include <cassert>
+
+namespace android {
+namespace SensorHalExt {
+
+DynamicSensorManager* DynamicSensorManager::createInstance(
+        int handleBase, int handleCount, SensorEventCallback *callback) {
+    auto m = new DynamicSensorManager(handleBase, handleBase + handleCount - 1, callback);
+    return m;
+}
+
+DynamicSensorManager::DynamicSensorManager(
+        int handleBase, int handleMax, SensorEventCallback* callback) :
+        mHandleRange(handleBase, handleMax),
+        mCallback(callback),
+        mFifo(callback ? 0 : kFifoSize),
+        mNextHandle(handleBase+1) {
+    assert(handleBase > 0 && handleMax > handleBase + 1); // handleBase is reserved
+
+    mMetaSensor = (const sensor_t) {
+        "Dynamic Sensor Manager",
+        "Google",
+        1,                                          // version
+        handleBase,                                 // handle
+        SENSOR_TYPE_DYNAMIC_SENSOR_META,
+        1,                                          // maxRange
+        1,                                          // resolution
+        1e-6f,                                      // power, very small number instead of 0
+                                                    // to avoid sigularity in app
+        (int32_t)(1000),                            // minDelay
+        0,                                          // fifoReservedEventCount
+        0,                                          // fifoMaxEventCount
+        SENSOR_STRING_TYPE_DYNAMIC_SENSOR_META,
+        "",                                         // requiredPermission
+        (long)(1000),                               // maxDelay
+        SENSOR_FLAG_SPECIAL_REPORTING_MODE | SENSOR_FLAG_WAKE_UP,
+        { NULL, NULL }
+    };
+}
+
+DynamicSensorManager::~DynamicSensorManager() {
+    // free all daemons first
+    mDaemonVector.clear();
+}
+
+bool DynamicSensorManager::owns(int handle) const {
+    return handle >= mHandleRange.first && handle < mHandleRange.second;
+}
+
+int DynamicSensorManager::activate(int handle, bool enable) {
+    if (handle == mHandleRange.first) {
+        // ignored
+        return 0;
+    }
+
+    // in case there is a pending report, now it is time to remove it as it is no longer necessary.
+    {
+        std::lock_guard<std::mutex> lk(mLock);
+        mPendingReport.erase(handle);
+    }
+
+    return operateSensor(handle,
+            [&enable] (sp<BaseSensorObject> s)->int {
+                return s->enable(enable);
+            });
+}
+
+int DynamicSensorManager::batch(int handle, nsecs_t sample_period, nsecs_t batch_period) {
+    if (handle == mHandleRange.first) {
+        // ignored
+        return 0;
+    }
+    return operateSensor(handle,
+            [&sample_period, &batch_period] (sp<BaseSensorObject> s)->int {
+                return s->batch(sample_period, batch_period);
+            });
+}
+
+int DynamicSensorManager::setDelay(int handle, nsecs_t sample_period) {
+    return batch(handle, sample_period, 0);
+}
+
+int DynamicSensorManager::flush(int handle) {
+    if (handle == mHandleRange.first) {
+        // TODO: submit a flush complete here
+        static const sensors_event_t event = {
+            .type = SENSOR_TYPE_META_DATA,
+            .sensor = mHandleRange.first,
+            .timestamp = TIMESTAMP_AUTO_FILL,  // timestamp will be filled at dispatcher
+        };
+        submitEvent(nullptr, event);
+        return 0;
+    }
+    return operateSensor(handle, [] (sp<BaseSensorObject> s)->int {return s->flush();});
+}
+
+int DynamicSensorManager::poll(sensors_event_t * data, int count) {
+    assert(mCallback == nullptr);
+    std::lock_guard<std::mutex> lk(mFifoLock);
+    return mFifo.read(data, count);
+}
+
+bool DynamicSensorManager::registerSensor(sp<BaseSensorObject> sensor) {
+    std::lock_guard<std::mutex> lk(mLock);
+    if (mReverseMap.find(sensor.get()) != mReverseMap.end()) {
+        ALOGE("trying to add the same sensor twice, ignore");
+        return false;
+    }
+    int handle = getNextAvailableHandle();
+    if (handle < 0) {
+        ALOGE("Running out of handle, quit.");
+        return false;
+    }
+
+    // these emplace will always be successful
+    mMap.emplace(handle, sensor);
+    mReverseMap.emplace(sensor.get(), handle);
+    sensor->setEventCallback(this);
+
+    auto entry = mPendingReport.emplace(
+            std::piecewise_construct,
+            std::forward_as_tuple(handle),
+            std::forward_as_tuple(handle, sensor));
+    if (entry.second) {
+        submitEvent(nullptr, entry.first->second.generateConnectionEvent(mHandleRange.first));
+    }
+    return entry.second;
+}
+
+void DynamicSensorManager::unregisterSensor(sp<BaseSensorObject> sensor) {
+    std::lock_guard<std::mutex> lk(mLock);
+    auto i = mReverseMap.find(sensor.get());
+    if (i == mReverseMap.end()) {
+        ALOGE("cannot remove a non-exist sensor");
+        return;
+    }
+    int handle = i->second;
+    mReverseMap.erase(i);
+    mMap.erase(handle);
+
+    // will not clean up mPendingReport here, it will be cleaned up when at first activate call.
+    // sensorservice is guranteed to call activate upon arrival of dynamic sensor meta connection
+    // event.
+
+    // send disconnection event
+    sensors_event_t event;
+    ConnectionReport::fillDisconnectionEvent(&event, mHandleRange.first, handle);
+    submitEvent(nullptr, event);
+}
+
+int DynamicSensorManager::submitEvent(sp<BaseSensorObject> source, const sensors_event_t &e) {
+    int handle;
+    if (source == nullptr) {
+        handle = mHandleRange.first;
+    } else {
+        std::lock_guard<std::mutex> lk(mLock);
+        auto i = mReverseMap.find(source.get());
+        if (i == mReverseMap.end()) {
+            ALOGE("cannot submit event for sensor that has not been registered");
+            return NAME_NOT_FOUND;
+        }
+        handle = i->second;
+    }
+
+    // making a copy of events, prepare for editing
+    sensors_event_t event = e;
+    event.version = sizeof(event);
+
+    // special case of flush complete
+    if (event.type == SENSOR_TYPE_META_DATA) {
+        event.sensor = 0;
+        event.meta_data.sensor = handle;
+    } else {
+        event.sensor = handle;
+    }
+
+    // set timestamp if it is default value
+    if (event.timestamp == TIMESTAMP_AUTO_FILL) {
+        event.timestamp = elapsedRealtimeNano();
+    }
+
+    if (mCallback) {
+        // extention mode, calling callback directly
+        int ret;
+
+        ret = mCallback->submitEvent(nullptr, event);
+        if (ret < 0) {
+            ALOGE("DynamicSensorManager callback failed, ret: %d", ret);
+        }
+    } else {
+        // standalone mode, add event to internal buffer for poll() to pick up
+        std::lock_guard<std::mutex> lk(mFifoLock);
+        if (mFifo.write(&event, 1) < 0) {
+            ALOGE("DynamicSensorManager fifo full");
+        }
+    }
+    return 0;
+}
+
+int DynamicSensorManager::getNextAvailableHandle() {
+    if (mNextHandle == mHandleRange.second) {
+        return -1;
+    }
+    return mNextHandle++;
+}
+
+const sensor_t& DynamicSensorManager::getDynamicMetaSensor() const {
+    return mMetaSensor;
+}
+
+DynamicSensorManager::ConnectionReport::ConnectionReport(
+        int handle, sp<BaseSensorObject> sensor) :
+        mSensor(*(sensor->getSensor())),
+        mName(mSensor.name),
+        mVendor(mSensor.vendor),
+        mPermission(mSensor.requiredPermission),
+        mStringType(mSensor.stringType),
+        mGenerated(false) {
+    mSensor.name = mName.c_str();
+    mSensor.vendor = mVendor.c_str();
+    mSensor.requiredPermission = mPermission.c_str();
+    mSensor.stringType = mStringType.c_str();
+    mSensor.handle = handle;
+    memset(&mEvent, 0, sizeof(mEvent));
+    mEvent.version = sizeof(mEvent);
+    sensor->getUuid(mUuid);
+    ALOGV("Connection report init: name = %s, handle = %d", mSensor.name, mSensor.handle);
+}
+
+DynamicSensorManager::ConnectionReport::~ConnectionReport() {
+    ALOGV("Connection report dtor: name = %s, handle = %d", mSensor.name, mSensor.handle);
+}
+
+const sensors_event_t& DynamicSensorManager::ConnectionReport::
+        generateConnectionEvent(int metaHandle) {
+    if (!mGenerated) {
+        mEvent.sensor = metaHandle;
+        mEvent.type = SENSOR_TYPE_DYNAMIC_SENSOR_META;
+        mEvent.timestamp = elapsedRealtimeNano();
+        mEvent.dynamic_sensor_meta =
+                (dynamic_sensor_meta_event_t) {true, mSensor.handle, &mSensor, {0}};
+        memcpy(&mEvent.dynamic_sensor_meta.uuid, &mUuid, sizeof(mEvent.dynamic_sensor_meta.uuid));
+        mGenerated = true;
+    }
+    return mEvent;
+}
+
+void DynamicSensorManager::ConnectionReport::
+        fillDisconnectionEvent(sensors_event_t* event, int metaHandle, int handle) {
+    memset(event, 0, sizeof(sensors_event_t));
+    event->version = sizeof(sensors_event_t);
+    event->sensor = metaHandle;
+    event->type = SENSOR_TYPE_DYNAMIC_SENSOR_META;
+    event->timestamp = elapsedRealtimeNano();
+    event->dynamic_sensor_meta.connected = false;
+    event->dynamic_sensor_meta.handle = handle;
+}
+
+} // namespace SensorHalExt
+} // namespace android
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorManager.h b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
new file mode 100644
index 0000000..b8fd472
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/DynamicSensorManager.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_MANAGER_H
+#define ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_MANAGER_H
+
+#include "SensorEventCallback.h"
+#include "RingBuffer.h"
+#include <hardware/sensors.h>
+#include <utils/RefBase.h>
+
+#include <mutex>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace android {
+namespace SensorHalExt {
+
+class BaseDynamicSensorDaemon;
+
+class DynamicSensorManager : public SensorEventCallback {
+public:
+    // handleBase is reserved for the dynamic sensor meta sensor.
+    // handleMax must be greater than handleBase + 1.
+    // This class has two operation mode depending on callback: 1) extension, 2) stand-alone.
+    // In extension mode, callback must not be nullptr. Sensor event generated will be submitted to
+    // buffer of primary sensor HAL implementation. In stand-alone mode, callback must be nullptr.
+    // Generated sensor events will be added into internal buffer waiting for poll() function to
+    // pick up.
+    //
+    static DynamicSensorManager* createInstance(
+            int handleBase, int handleCount, SensorEventCallback *callback);
+    virtual ~DynamicSensorManager();
+
+    // calls to add or remove sensor, called from sensor daemon
+    bool registerSensor(sp<BaseSensorObject> sensor);
+    void unregisterSensor(sp<BaseSensorObject> sensor);
+
+    // Determine if a sensor handle is in the range defined in constructor.
+    // It does not test if sensor handle is valid.
+    bool owns(int handle) const;
+
+    // handles sensor hal requests.
+    int activate(int handle, bool enable);
+    int batch(int handle, nsecs_t sample_period, nsecs_t batch_period);
+    int setDelay(int handle, nsecs_t sample_period);
+    int flush(int handle);
+    int poll(sensors_event_t * data, int count);
+
+    // SensorEventCallback
+    virtual int submitEvent(sp<BaseSensorObject>, const sensors_event_t &e) override;
+
+    // get meta sensor struct
+    const sensor_t& getDynamicMetaSensor() const;
+protected:
+    DynamicSensorManager(int handleBase, int handleMax, SensorEventCallback* callback);
+private:
+    // a helper class used for generate connection and disconnection report
+    class ConnectionReport {
+    public:
+        ConnectionReport() {}
+        ConnectionReport(int handle, sp<BaseSensorObject> sensor);
+        ~ConnectionReport();
+        const sensors_event_t& generateConnectionEvent(int metaHandle);
+        static void fillDisconnectionEvent(sensors_event_t* event, int metaHandle, int handle);
+    private:
+        sensor_t mSensor;
+        std::string mName;
+        std::string mVendor;
+        std::string mPermission;
+        std::string mStringType;
+        sensors_event_t mEvent;
+        uint8_t mUuid[16];
+        bool mGenerated;
+        DISALLOW_EVIL_CONSTRUCTORS(ConnectionReport);
+    };
+
+    // returns next available handle to use upon a new sensor connection, or -1 if we run out.
+    int getNextAvailableHandle();
+
+    // TF:  int foo(sp<BaseSensorObject> obj);
+    template <typename TF>
+    int operateSensor(int handle, TF f) const {
+        std::lock_guard<std::mutex> lk(mLock);
+        const auto i = mMap.find(handle);
+        if (i == mMap.end()) {
+            return BAD_VALUE;
+        }
+        sp<BaseSensorObject> s = i->second.promote();
+        if (s == nullptr) {
+            // sensor object is already gone
+            return BAD_VALUE;
+        }
+        return f(s);
+    }
+
+    // available sensor handle space
+    const std::pair<int, int> mHandleRange;
+    sensor_t mMetaSensor;
+
+    // immutable pointer to event callback, used in extention mode.
+    SensorEventCallback * const mCallback;
+
+    // RingBuffer used in standalone mode
+    static constexpr size_t kFifoSize = 4096; //4K events
+    mutable std::mutex mFifoLock;
+    RingBuffer mFifo;
+
+    // mapping between handle and SensorObjects
+    mutable std::mutex mLock;
+    int mNextHandle;
+    std::unordered_map<int, wp<BaseSensorObject> > mMap;
+    std::unordered_map<void *, int> mReverseMap;
+    mutable std::unordered_map<int, ConnectionReport> mPendingReport;
+
+    // daemons
+    std::vector<sp<BaseDynamicSensorDaemon>> mDaemonVector;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_EXT_DYNAMIC_SENSOR_MANAGER_H
diff --git a/modules/sensors/dynamic_sensor/RingBuffer.cpp b/modules/sensors/dynamic_sensor/RingBuffer.cpp
new file mode 100644
index 0000000..5857a7c
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/RingBuffer.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 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 "RingBuffer.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace android {
+
+RingBuffer::RingBuffer(size_t size)
+    : mSize(size),
+      mData((sensors_event_t *)malloc(sizeof(sensors_event_t) * mSize)),
+      mReadPos(0),
+      mWritePos(0) {
+}
+
+RingBuffer::~RingBuffer() {
+    free(mData);
+    mData = NULL;
+}
+
+ssize_t RingBuffer::write(const sensors_event_t *ev, size_t size) {
+    Mutex::Autolock autoLock(mLock);
+
+    size_t numAvailableToRead = mWritePos - mReadPos;
+    size_t numAvailableToWrite = mSize - numAvailableToRead;
+
+    if (size > numAvailableToWrite) {
+        size = numAvailableToWrite;
+    }
+
+    size_t writePos = (mWritePos % mSize);
+    size_t copy = mSize - writePos;
+
+    if (copy > size) {
+        copy = size;
+    }
+
+    memcpy(&mData[writePos], ev, copy * sizeof(sensors_event_t));
+
+    if (size > copy) {
+        memcpy(mData, &ev[copy], (size - copy) * sizeof(sensors_event_t));
+    }
+
+    mWritePos += size;
+
+    if (numAvailableToRead == 0 && size > 0) {
+        mNotEmptyCondition.broadcast();
+    }
+
+    return size;
+}
+
+ssize_t RingBuffer::read(sensors_event_t *ev, size_t size) {
+    Mutex::Autolock autoLock(mLock);
+
+    size_t numAvailableToRead;
+    for (;;) {
+        numAvailableToRead = mWritePos - mReadPos;
+        if (numAvailableToRead > 0) {
+            break;
+        }
+
+        mNotEmptyCondition.wait(mLock);
+    }
+
+    if (size > numAvailableToRead) {
+        size = numAvailableToRead;
+    }
+
+    size_t readPos = (mReadPos % mSize);
+    size_t copy = mSize - readPos;
+
+    if (copy > size) {
+        copy = size;
+    }
+
+    memcpy(ev, &mData[readPos], copy * sizeof(sensors_event_t));
+
+    if (size > copy) {
+        memcpy(&ev[copy], mData, (size - copy) * sizeof(sensors_event_t));
+    }
+
+    mReadPos += size;
+
+    return size;
+}
+
+}  // namespace android
+
diff --git a/modules/sensors/dynamic_sensor/RingBuffer.h b/modules/sensors/dynamic_sensor/RingBuffer.h
new file mode 100644
index 0000000..aa6b8c9
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/RingBuffer.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef RING_BUFFER_H_
+
+#define RING_BUFFER_H_
+
+#include <media/stagefright/foundation/ABase.h>
+
+#include <hardware/sensors.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class RingBuffer {
+public:
+    explicit RingBuffer(size_t size);
+    ~RingBuffer();
+
+    ssize_t write(const sensors_event_t *ev, size_t size);
+    ssize_t read(sensors_event_t *ev, size_t size);
+
+private:
+    Mutex mLock;
+    Condition mNotEmptyCondition;
+
+    size_t mSize;
+    sensors_event_t *mData;
+    size_t mReadPos, mWritePos;
+
+    DISALLOW_EVIL_CONSTRUCTORS(RingBuffer);
+};
+
+}  // namespace android
+
+#endif  // RING_BUFFER_H_
diff --git a/modules/sensors/dynamic_sensor/SensorEventCallback.h b/modules/sensors/dynamic_sensor/SensorEventCallback.h
new file mode 100644
index 0000000..b98cd7f
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/SensorEventCallback.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef ANDROID_SENSORHAL_DSE_SENSOR_EVENT_CALLBACK_H
+#define ANDROID_SENSORHAL_DSE_SENSOR_EVENT_CALLBACK_H
+
+#include <hardware/sensors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+namespace SensorHalExt {
+
+class BaseSensorObject;
+
+// if timestamp in sensors_event_t has this value, it will be filled at dispatcher.
+constexpr int64_t TIMESTAMP_AUTO_FILL = -1;
+
+class SensorEventCallback {
+public:
+    virtual int submitEvent(sp<BaseSensorObject> sensor, const sensors_event_t &e) = 0;
+    virtual ~SensorEventCallback() = default;
+};
+
+} // namespace SensorHalExt
+} // namespace android
+
+#endif // ANDROID_SENSORHAL_DSE_SENSOR_EVENT_CALLBACK_H
diff --git a/modules/sensors/dynamic_sensor/sensors.cpp b/modules/sensors/dynamic_sensor/sensors.cpp
new file mode 100644
index 0000000..7c203b2
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/sensors.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2017 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 "DynamicSensorManager.h"
+#include "sensors.h"
+
+#include <cutils/properties.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <string.h>
+using namespace android;
+
+////////////////////////////////////////////////////////////////////////////////
+
+SensorContext::SensorContext(const struct hw_module_t *module) {
+    memset(&device, 0, sizeof(device));
+
+    device.common.tag = HARDWARE_DEVICE_TAG;
+    device.common.version = SENSORS_DEVICE_API_VERSION_1_3;
+    device.common.module = const_cast<hw_module_t *>(module);
+    device.common.close = CloseWrapper;
+    device.activate = ActivateWrapper;
+    device.setDelay = SetDelayWrapper;
+    device.poll = PollWrapper;
+    device.batch = BatchWrapper;
+    device.flush = FlushWrapper;
+
+    // initialize dynamic sensor manager
+    int32_t base = property_get_int32("sensor.dynamic_sensor_hal.handle_base", kDynamicHandleBase);
+    int32_t count =
+            property_get_int32("sensor.dynamic_sensor_hal.handle_count", kMaxDynamicHandleCount);
+    mDynamicSensorManager.reset(DynamicSensorManager::createInstance(base, count, nullptr));
+}
+
+int SensorContext::close() {
+    delete this;
+    return 0;
+}
+
+int SensorContext::activate(int handle, int enabled) {
+    return mDynamicSensorManager->activate(handle, enabled);
+}
+
+int SensorContext::setDelay(int handle, int64_t delayNs) {
+    return mDynamicSensorManager->setDelay(handle, delayNs);
+}
+
+int SensorContext::poll(sensors_event_t *data, int count) {
+    return mDynamicSensorManager->poll(data, count);
+}
+
+int SensorContext::batch(
+        int handle,
+        int64_t sampling_period_ns,
+        int64_t max_report_latency_ns) {
+    return mDynamicSensorManager->batch(handle, sampling_period_ns, max_report_latency_ns);
+}
+
+int SensorContext::flush(int handle) {
+    return mDynamicSensorManager->flush(handle);
+}
+
+// static
+int SensorContext::CloseWrapper(struct hw_device_t *dev) {
+    return reinterpret_cast<SensorContext *>(dev)->close();
+}
+
+// static
+int SensorContext::ActivateWrapper(
+        struct sensors_poll_device_t *dev, int handle, int enabled) {
+    return reinterpret_cast<SensorContext *>(dev)->activate(handle, enabled);
+}
+
+// static
+int SensorContext::SetDelayWrapper(
+        struct sensors_poll_device_t *dev, int handle, int64_t delayNs) {
+    return reinterpret_cast<SensorContext *>(dev)->setDelay(handle, delayNs);
+}
+
+// static
+int SensorContext::PollWrapper(
+        struct sensors_poll_device_t *dev, sensors_event_t *data, int count) {
+    return reinterpret_cast<SensorContext *>(dev)->poll(data, count);
+}
+
+// static
+int SensorContext::BatchWrapper(
+        struct sensors_poll_device_1 *dev,
+        int handle,
+        int flags,
+        int64_t sampling_period_ns,
+        int64_t max_report_latency_ns) {
+    (void) flags;
+    return reinterpret_cast<SensorContext *>(dev)->batch(
+            handle, sampling_period_ns, max_report_latency_ns);
+}
+
+// static
+int SensorContext::FlushWrapper(struct sensors_poll_device_1 *dev, int handle) {
+    return reinterpret_cast<SensorContext *>(dev)->flush(handle);
+}
+
+size_t SensorContext::getSensorList(sensor_t const **list) {
+    *list = &(mDynamicSensorManager->getDynamicMetaSensor());
+    return 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static sensor_t const *sensor_list;
+
+static int open_sensors(
+        const struct hw_module_t *module,
+        const char *,
+        struct hw_device_t **dev) {
+    SensorContext *ctx = new SensorContext(module);
+    ctx->getSensorList(&sensor_list);
+    *dev = &ctx->device.common;
+    return 0;
+}
+
+static struct hw_module_methods_t sensors_module_methods = {
+    .open = open_sensors
+};
+
+static int get_sensors_list(
+        struct sensors_module_t *,
+        struct sensor_t const **list) {
+    *list = sensor_list;
+    return 1;
+}
+
+static int set_operation_mode(unsigned int mode) {
+    return (mode) ? -EINVAL : 0;
+}
+
+struct sensors_module_t HAL_MODULE_INFO_SYM = {
+    .common = {
+            .tag = HARDWARE_MODULE_TAG,
+            .version_major = 1,
+            .version_minor = 0,
+            .id = SENSORS_HARDWARE_MODULE_ID,
+            .name = "Google Dynamic Sensor Manager",
+            .author = "Google",
+            .methods = &sensors_module_methods,
+            .dso  = NULL,
+            .reserved = {0},
+    },
+    .get_sensors_list = get_sensors_list,
+    .set_operation_mode = set_operation_mode,
+};
diff --git a/modules/sensors/dynamic_sensor/sensors.h b/modules/sensors/dynamic_sensor/sensors.h
new file mode 100644
index 0000000..be42b67
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/sensors.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef SENSORS_H_
+#define SENSORS_H_
+
+#include <hardware/hardware.h>
+#include <hardware/sensors.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/RefBase.h>
+
+#include <memory>
+#include <unordered_set>
+#include <vector>
+
+namespace android {
+    namespace SensorHalExt {
+        class DynamicSensorManager;
+    } // namespace BaseSensorObject
+} // namespace android
+
+using android::SensorHalExt::DynamicSensorManager;
+
+class SensorContext {
+public:
+    struct sensors_poll_device_1 device;
+
+    explicit SensorContext(const struct hw_module_t *module);
+
+    size_t getSensorList(sensor_t const **list);
+
+private:
+
+    int close();
+    int activate(int handle, int enabled);
+    int setDelay(int handle, int64_t delayNs);
+    int poll(sensors_event_t *data, int count);
+
+    int batch(int handle, int64_t sampling_period_ns,
+              int64_t max_report_latency_ns);
+
+    int flush(int handle);
+
+    // static wrappers
+    static int CloseWrapper(struct hw_device_t *dev);
+
+    static int ActivateWrapper(
+            struct sensors_poll_device_t *dev, int handle, int enabled);
+
+    static int SetDelayWrapper(
+            struct sensors_poll_device_t *dev, int handle, int64_t delayNs);
+
+    static int PollWrapper(
+            struct sensors_poll_device_t *dev, sensors_event_t *data, int count);
+
+    static int BatchWrapper(
+            struct sensors_poll_device_1 *dev,
+            int handle,
+            int flags,
+            int64_t sampling_period_ns,
+            int64_t max_report_latency_ns);
+
+    static int FlushWrapper(struct sensors_poll_device_1 *dev, int handle);
+
+    // default ~16 million handles for dynamic sensor use, can be overriden by system property
+    static constexpr int32_t kDynamicHandleBase = 0x10000;
+    static constexpr int32_t kDynamicHandleEnd = 0x1000000;
+    static constexpr int32_t kMaxDynamicHandleCount = kDynamicHandleEnd - kDynamicHandleBase;
+
+    std::unique_ptr<DynamicSensorManager> mDynamicSensorManager;
+
+    DISALLOW_EVIL_CONSTRUCTORS(SensorContext);
+};
+
+#endif  // SENSORS_H_
diff --git a/modules/vibrator/vibrator.c b/modules/vibrator/vibrator.c
index c3c2951..92c46e2 100644
--- a/modules/vibrator/vibrator.c
+++ b/modules/vibrator/vibrator.c
@@ -32,16 +32,20 @@
 
 static const char THE_DEVICE[] = "/sys/class/timed_output/vibrator/enable";
 
-static int vibra_exists() {
+static bool device_exists(const char *file) {
     int fd;
 
-    fd = TEMP_FAILURE_RETRY(open(THE_DEVICE, O_RDWR));
+    fd = TEMP_FAILURE_RETRY(open(file, O_RDWR));
     if(fd < 0) {
-        return 0;
+        return false;
     }
 
     close(fd);
-    return 1;
+    return true;
+}
+
+static bool vibra_exists() {
+    return device_exists(THE_DEVICE);
 }
 
 static int write_value(const char *file, const char *value)
@@ -102,9 +106,13 @@
     return write_value(file_str, value);
 }
 
-static int vibra_led_exists()
+static bool vibra_led_exists()
 {
-    return !write_led_file("trigger", "transient");
+    int fd;
+    char file_str[50];
+
+    snprintf(file_str, sizeof(file_str), "%s/%s", LED_DEVICE, "activate");
+    return device_exists(file_str);
 }
 
 static int vibra_led_on(vibrator_device_t* vibradev __unused, unsigned int timeout_ms)