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)