From 3da3b8436c743e4ba16ce6802b499a5bb7cd07bd Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Fri, 29 Aug 2014 16:16:26 -0700 Subject: [PATCH 1/5] Fix type for temp variable Change-Id: I8e2d229da326e5182692f94660336169fb249da7 --- services/inputflinger/InputReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp index b7c7ff420..8634e4272 100644 --- a/services/inputflinger/InputReader.cpp +++ b/services/inputflinger/InputReader.cpp @@ -1851,7 +1851,7 @@ void SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) { void SwitchInputMapper::sync(nsecs_t when) { if (mUpdatedSwitchMask) { - int32_t updatedSwitchValues = mSwitchValues & mUpdatedSwitchMask; + uint32_t updatedSwitchValues = mSwitchValues & mUpdatedSwitchMask; NotifySwitchArgs args(when, 0, updatedSwitchValues, mUpdatedSwitchMask); getListener()->notifySwitch(&args); From 9e3adfcebf28c5c76085108dffe98c74df56857d Mon Sep 17 00:00:00 2001 From: Aravind Akella Date: Wed, 3 Sep 2014 15:48:05 -0700 Subject: [PATCH 2/5] SensorService flush fixes. i) Fix a possible race condition when adding a pending flush connection to mActiveSensors data structure. ii) Invalidate flush_complete_events as soon as they are consumed by a connection so that they are not used by other connections which are registered for the same sensor. Change-Id: I1491bea8c2081c4aab1feacc60add13b7aa26bb7 --- include/gui/SensorEventQueue.h | 2 +- services/sensorservice/SensorService.cpp | 103 ++++++++++++----------- services/sensorservice/SensorService.h | 13 ++- 3 files changed, 64 insertions(+), 54 deletions(-) diff --git a/include/gui/SensorEventQueue.h b/include/gui/SensorEventQueue.h index 019308d0c..5402f37d8 100644 --- a/include/gui/SensorEventQueue.h +++ b/include/gui/SensorEventQueue.h @@ -27,7 +27,7 @@ #include // ---------------------------------------------------------------------------- -#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 31) +#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 30) struct ALooper; struct ASensorEvent; diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 6c3144b80..ef87e5c9f 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -807,29 +807,36 @@ status_t SensorService::setEventRate(const sp& connection return sensor->setDelay(connection.get(), handle, ns); } -status_t SensorService::flushSensor(const sp& connection, - int handle) { +status_t SensorService::flushSensor(const sp& connection) { if (mInitCheck != NO_ERROR) return mInitCheck; - SensorInterface* sensor = mSensorMap.valueFor(handle); - if (sensor == NULL) { - return BAD_VALUE; + SensorDevice& dev(SensorDevice::getInstance()); + const int halVersion = dev.getHalDeviceVersion(); + status_t err(NO_ERROR); + Mutex::Autolock _l(mLock); + // Loop through all sensors for this connection and call flush on each of them. + for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) { + const int handle = connection->mSensorInfo.keyAt(i); + SensorInterface* sensor = mSensorMap.valueFor(handle); + if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { + ALOGE("flush called on a one-shot sensor"); + err = INVALID_OPERATION; + continue; + } + SensorEventConnection::FlushInfo& flushInfo = connection->mSensorInfo.editValueFor(handle); + if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || isVirtualSensor(handle)) { + // For older devices just increment pending flush count which will send a trivial + // flush complete event. + flushInfo.mPendingFlushEventsToSend++; + } else { + status_t err_flush = sensor->flush(connection.get(), handle); + if (err_flush == NO_ERROR) { + SensorRecord* rec = mActiveSensors.valueFor(handle); + if (rec != NULL) rec->addPendingFlushConnection(connection); + } + err = (err_flush != NO_ERROR) ? err_flush : err; + } } - - if (!verifyCanAccessSensor(sensor->getSensor(), "Tried flushing")) { - return BAD_VALUE; - } - - if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { - ALOGE("flush called on a one-shot sensor"); - return INVALID_OPERATION; - } - - status_t ret = sensor->flush(connection.get(), handle); - if (ret == NO_ERROR) { - SensorRecord* rec = mActiveSensors.valueFor(handle); - if (rec != NULL) rec->addPendingFlushConnection(connection); - } - return ret; + return err; } bool SensorService::canAccessSensor(const Sensor& sensor) { @@ -1034,7 +1041,7 @@ void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle, } status_t SensorService::SensorEventConnection::sendEvents( - sensors_event_t const* buffer, size_t numEvents, + sensors_event_t* buffer, size_t numEvents, sensors_event_t* scratch) { // filter out events not for this connection size_t count = 0; @@ -1042,10 +1049,16 @@ status_t SensorService::SensorEventConnection::sendEvents( if (scratch) { size_t i=0; while (igetFirstPendingFlushConnection() == this) { rec->removeFirstPendingFlushConnection(); flushInfo.mFirstFlushPending = false; - ++i; + // Invalidate this flush_complete_event so that it cannot be used by other + // connections. + buffer[i].flags |= SENSOR_EVENT_INVALID_FLAG; ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ", - buffer[i].meta_data.sensor); + buffer[i].meta_data.sensor); + ++i; continue; } } @@ -1080,13 +1096,20 @@ status_t SensorService::SensorEventConnection::sendEvents( } do { + if (buffer[i].flags & SENSOR_EVENT_INVALID_FLAG) { + ++i; + continue; + } if (buffer[i].type == SENSOR_TYPE_META_DATA) { - // Check if this connection has called flush() on this sensor. Only if - // a flush() has been explicitly called, send a flush_complete_event. - SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle); - if (rec && rec->getFirstPendingFlushConnection() == this) { + // Check if this connection has called flush() on this sensor. Only if + // a flush() has been explicitly called, send a flush_complete_event. + SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle); + if (rec && rec->getFirstPendingFlushConnection() == this) { rec->removeFirstPendingFlushConnection(); scratch[count++] = buffer[i]; + // Invalidate this flush_complete_event so that it cannot be used by + // other connections. + buffer[i].flags |= SENSOR_EVENT_INVALID_FLAG; } ++i; } else { @@ -1333,27 +1356,7 @@ status_t SensorService::SensorEventConnection::setEventRate( } status_t SensorService::SensorEventConnection::flush() { - SensorDevice& dev(SensorDevice::getInstance()); - const int halVersion = dev.getHalDeviceVersion(); - Mutex::Autolock _l(mConnectionLock); - status_t err(NO_ERROR); - // Loop through all sensors for this connection and call flush on each of them. - for (size_t i = 0; i < mSensorInfo.size(); ++i) { - const int handle = mSensorInfo.keyAt(i); - FlushInfo& flushInfo = mSensorInfo.editValueFor(handle); - if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || mService->isVirtualSensor(handle)) { - // For older devices just increment pending flush count which will send a trivial - // flush complete event. - flushInfo.mPendingFlushEventsToSend++; - } else { - status_t err_flush = mService->flushSensor(this, handle); - if (err_flush != NO_ERROR) { - ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush)); - } - err = (err_flush != NO_ERROR) ? err_flush : err; - } - } - return err; + return mService->flushSensor(this); } int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* data) { diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h index 3717fcb6a..0887f28b5 100644 --- a/services/sensorservice/SensorService.h +++ b/services/sensorservice/SensorService.h @@ -45,6 +45,14 @@ // For older HALs which don't support batching, use a smaller socket buffer size. #define SOCKET_BUFFER_SIZE_NON_BATCHED 4 * 1024 +// Flags for sensors_event_t.flag. Using only the most significant two bits for flags. +// MSB is to invalidate a sensor_event (typically a flush_complete_event) so that +// it won't be used by other connections. +// MSB 2nd bit is used to indicate whether the event needs to be acknowledged or not. +// This is typically used for WAKE_UP sensors. WAKE_UP_SENSOR_EVENT_NEEDS_ACK is defined +// in SensorEveneQueue.h +#define SENSOR_EVENT_INVALID_FLAG (1U << 31) + struct sensors_poll_device_t; struct sensors_module_t; @@ -148,7 +156,7 @@ class SensorService : public: SensorEventConnection(const sp& service, uid_t uid); - status_t sendEvents(sensors_event_t const* buffer, size_t count, + status_t sendEvents(sensors_event_t* buffer, size_t count, sensors_event_t* scratch); bool hasSensor(int32_t handle) const; bool hasAnySensor() const; @@ -229,7 +237,6 @@ class SensorService : DefaultKeyedVector mActiveVirtualSensors; SortedVector< wp > mActiveConnections; bool mWakeLockAcquired; - // The size of this vector is constant, only the items are mutable KeyedVector mLastEventSeen; @@ -239,7 +246,7 @@ public: nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags); status_t disable(const sp& connection, int handle); status_t setEventRate(const sp& connection, int handle, nsecs_t ns); - status_t flushSensor(const sp& connection, int handle); + status_t flushSensor(const sp& connection); }; // --------------------------------------------------------------------------- From 457296ad6c8bf3533a90780a8c28ced84a2301e7 Mon Sep 17 00:00:00 2001 From: Stephen Hines Date: Thu, 4 Sep 2014 08:28:54 -0700 Subject: [PATCH 3/5] Fix undefined behavior (not returning a value from a function with return). Bug: 17379740 This function was missing a return statement, even though it declares a return type. This is undefined behavior, which clang miscompiled into just falling through to a later function in some cases. Adding the return statement fixes the undefined behavior (and probably fixes a bug too). Change-Id: I05c03b6473b831769dc4fa8b5ba43fb4249f7626 --- include/ui/mat4.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/ui/mat4.h b/include/ui/mat4.h index d9647cc1a..4fd1effd7 100644 --- a/include/ui/mat4.h +++ b/include/ui/mat4.h @@ -322,6 +322,7 @@ tmat44 tmat44::rotate(A radian, const tvec3& about) { r[ 1] = xy*nc + zs; r[ 5] = y*y*nc + c; r[ 9] = yz*nc - xs; r[ 2] = zx*nc - ys; r[ 6] = yz*nc + xs; r[10] = z*z*nc + c; } + return rotation; } // ---------------------------------------------------------------------------------------- From 8c967b9bea7c80a8bd7d085fa9c9e390495dd1e8 Mon Sep 17 00:00:00 2001 From: Vinod Krishnan Date: Thu, 4 Sep 2014 15:24:12 -0700 Subject: [PATCH 4/5] DO NOT MERGE: Removing android prefix for ECG feature Bug: 17272904 Change-Id: Ia476bd8853e098600b681bb769536774596b9345 --- ...xml => com.google.android.hardware.sensor.heartrate.ecg.xml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename data/etc/{android.hardware.sensor.heartrate.ecg.xml => com.google.android.hardware.sensor.heartrate.ecg.xml} (91%) diff --git a/data/etc/android.hardware.sensor.heartrate.ecg.xml b/data/etc/com.google.android.hardware.sensor.heartrate.ecg.xml similarity index 91% rename from data/etc/android.hardware.sensor.heartrate.ecg.xml rename to data/etc/com.google.android.hardware.sensor.heartrate.ecg.xml index 62a0de5b4..a4c617644 100644 --- a/data/etc/android.hardware.sensor.heartrate.ecg.xml +++ b/data/etc/com.google.android.hardware.sensor.heartrate.ecg.xml @@ -16,5 +16,5 @@ - + From f20c329a8a1fb578f5842f4056d3ebb39403d01f Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Sun, 10 Aug 2014 10:46:52 -0700 Subject: [PATCH 5/5] IPowerManager: make all binder call one way make all binder call to power manager service one way so that they don't block calling thread and are processed in the incoming order. Bug: 16408906. Change-Id: I94034df7f0a36d967e085b53fdc37fff7b44757b --- services/powermanager/IPowerManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/powermanager/IPowerManager.cpp b/services/powermanager/IPowerManager.cpp index ee730d6ec..926c050ae 100644 --- a/services/powermanager/IPowerManager.cpp +++ b/services/powermanager/IPowerManager.cpp @@ -56,7 +56,7 @@ public: data.writeString16(packageName); data.writeInt32(0); // no WorkSource data.writeString16(NULL, 0); // no history tag - return remote()->transact(ACQUIRE_WAKE_LOCK, data, &reply); + return remote()->transact(ACQUIRE_WAKE_LOCK, data, &reply, IBinder::FLAG_ONEWAY); } virtual status_t acquireWakeLockWithUid(int flags, const sp& lock, const String16& tag, @@ -70,7 +70,7 @@ public: data.writeString16(tag); data.writeString16(packageName); data.writeInt32(uid); // uid to blame for the work - return remote()->transact(ACQUIRE_WAKE_LOCK_UID, data, &reply); + return remote()->transact(ACQUIRE_WAKE_LOCK_UID, data, &reply, IBinder::FLAG_ONEWAY); } virtual status_t releaseWakeLock(const sp& lock, int flags) @@ -79,7 +79,7 @@ public: data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor()); data.writeStrongBinder(lock); data.writeInt32(flags); - return remote()->transact(RELEASE_WAKE_LOCK, data, &reply); + return remote()->transact(RELEASE_WAKE_LOCK, data, &reply, IBinder::FLAG_ONEWAY); } virtual status_t updateWakeLockUids(const sp& lock, int len, const int *uids) {