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;