Fix sensor uuid, retrofit recent event logger
Fix an issue that causes uuid field not being initialzed in
sensorservice.
MostRecentEventLogger in sensorservice is migrated to use RingBuffer
instead of a custom circular buffer. This is expected to improve
readability and maintainability of code.
Dumpsys print format is retouched to offer more information in easier
to read format.
Bug: 28305085
Change-Id: I190e43350b60a22a9fccb92a95d6eab06a471560
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index 353003c..3f60741 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -52,12 +52,18 @@
TYPE_PROXIMITY = ASENSOR_TYPE_PROXIMITY
};
- typedef struct {
- uint8_t b[16];
- } uuid_t;
+ struct uuid_t{
+ union {
+ uint8_t b[16];
+ int64_t i64[2];
+ };
+ uuid_t(const uint8_t (&uuid)[16]) { memcpy(b, uuid, sizeof(b));}
+ uuid_t() : b{0} {}
+ };
Sensor(const char * name = "");
Sensor(struct sensor_t const* hwSensor, int halVersion = 0);
+ Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersion = 0);
~Sensor();
const String8& getName() const;
@@ -81,6 +87,7 @@
uint32_t getFlags() const;
bool isWakeUpSensor() const;
bool isDynamicSensor() const;
+ bool hasAdditionalInfo() const;
int32_t getReportingMode() const;
const uuid_t& getUuid() const;
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 0340d6b..cc865d1 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -14,69 +14,70 @@
* limitations under the License.
*/
+
+#include <binder/AppOpsManager.h>
+#include <binder/IServiceManager.h>
+#include <gui/Sensor.h>
+#include <hardware/sensors.h>
+#include <log/log.h>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/Flattenable.h>
+
#include <inttypes.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/limits.h>
-#include <utils/Errors.h>
-#include <utils/String8.h>
-#include <utils/Flattenable.h>
-
-#include <hardware/sensors.h>
-
-#include <binder/AppOpsManager.h>
-#include <binder/IServiceManager.h>
-
-#include <gui/Sensor.h>
-#include <log/log.h>
-
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
-Sensor::Sensor(const char * name)
- : mName(name), mHandle(0), mType(0),
- mMinValue(0), mMaxValue(0), mResolution(0),
- mPower(0), mMinDelay(0), mVersion(0), mFifoReservedEventCount(0),
- mFifoMaxEventCount(0), mRequiredAppOp(0),
- mMaxDelay(0), mFlags(0)
-{
+Sensor::Sensor(const char * name) :
+ mName(name), mHandle(0), mType(0),
+ mMinValue(0), mMaxValue(0), mResolution(0),
+ mPower(0), mMinDelay(0), mVersion(0), mFifoReservedEventCount(0),
+ mFifoMaxEventCount(0), mRequiredAppOp(0),
+ mMaxDelay(0), mFlags(0) {
}
-Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
-{
- mName = hwSensor->name;
- mVendor = hwSensor->vendor;
- mVersion = hwSensor->version;
- mHandle = hwSensor->handle;
- mType = hwSensor->type;
+Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion) :
+ Sensor(*hwSensor, uuid_t(), halVersion) {
+}
+
+Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersion) {
+ mName = hwSensor.name;
+ mVendor = hwSensor.vendor;
+ mVersion = hwSensor.version;
+ mHandle = hwSensor.handle;
+ mType = hwSensor.type;
mMinValue = 0; // FIXME: minValue
- mMaxValue = hwSensor->maxRange; // FIXME: maxValue
- mResolution = hwSensor->resolution;
- mPower = hwSensor->power;
- mMinDelay = hwSensor->minDelay;
+ mMaxValue = hwSensor.maxRange; // FIXME: maxValue
+ mResolution = hwSensor.resolution;
+ mPower = hwSensor.power;
+ mMinDelay = hwSensor.minDelay;
mFlags = 0;
+ mUuid = uuid;
// Set fifo event count zero for older devices which do not support batching. Fused
// sensors also have their fifo counts set to zero.
if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) {
- mFifoReservedEventCount = hwSensor->fifoReservedEventCount;
- mFifoMaxEventCount = hwSensor->fifoMaxEventCount;
+ mFifoReservedEventCount = hwSensor.fifoReservedEventCount;
+ mFifoMaxEventCount = hwSensor.fifoMaxEventCount;
} else {
mFifoReservedEventCount = 0;
mFifoMaxEventCount = 0;
}
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
- if (hwSensor->maxDelay > INT_MAX) {
+ if (hwSensor.maxDelay > INT_MAX) {
// Max delay is declared as a 64 bit integer for 64 bit architectures. But it should
// always fit in a 32 bit integer, log error and cap it to INT_MAX.
ALOGE("Sensor maxDelay overflow error %s %" PRId64, mName.string(),
- static_cast<int64_t>(hwSensor->maxDelay));
+ static_cast<int64_t>(hwSensor.maxDelay));
mMaxDelay = INT_MAX;
} else {
- mMaxDelay = static_cast<int32_t>(hwSensor->maxDelay);
+ mMaxDelay = static_cast<int32_t>(hwSensor.maxDelay);
}
} else {
// For older hals set maxDelay to 0.
@@ -245,11 +246,11 @@
break;
default:
// Only pipe the stringType, requiredPermission and flags for custom sensors.
- if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->stringType) {
- mStringType = hwSensor->stringType;
+ if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor.stringType) {
+ mStringType = hwSensor.stringType;
}
- if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->requiredPermission) {
- mRequiredPermission = hwSensor->requiredPermission;
+ if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor.requiredPermission) {
+ mRequiredPermission = hwSensor.requiredPermission;
if (!strcmp(mRequiredPermission, SENSOR_PERMISSION_BODY_SENSORS)) {
AppOpsManager appOps;
mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS));
@@ -257,7 +258,7 @@
}
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
- mFlags = static_cast<uint32_t>(hwSensor->flags);
+ mFlags = static_cast<uint32_t>(hwSensor.flags);
} else {
// This is an OEM defined sensor on an older HAL. Use minDelay to determine the
// reporting mode of the sensor.
@@ -272,31 +273,28 @@
break;
}
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
+ // Wake-up flag of HAL 1.3 and above is set here
+ mFlags |= (hwSensor.flags & SENSOR_FLAG_WAKE_UP);
+
+ // Log error if the reporting mode is not as expected, but respect HAL setting.
+ int actualReportingMode = (hwSensor.flags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT;
+ int expectedReportingMode = (mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT;
+ if (actualReportingMode != expectedReportingMode) {
+ ALOGE("Reporting Mode incorrect: sensor %s handle=%#010" PRIx32 " type=%" PRId32 " "
+ "actual=%d expected=%d",
+ mName.string(), mHandle, mType, actualReportingMode, expectedReportingMode);
+ }
+ }
+
+ // Feature flags
// Set DYNAMIC_SENSOR_MASK and ADDITIONAL_INFO_MASK flag here. Compatible with HAL 1_3.
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
- mFlags |= (hwSensor->flags & (DYNAMIC_SENSOR_MASK | ADDITIONAL_INFO_MASK));
+ mFlags |= (hwSensor.flags & (DYNAMIC_SENSOR_MASK | ADDITIONAL_INFO_MASK));
}
-
// Set DATA_INJECTION flag here. Defined in HAL 1_4.
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_4) {
- mFlags |= (hwSensor->flags & DATA_INJECTION_MASK);
- }
-
- // For the newer HALs log errors if reporting mask flags are set incorrectly.
- if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
- // Wake-up flag is set here.
- mFlags |= (hwSensor->flags & SENSOR_FLAG_WAKE_UP);
- if (mFlags != hwSensor->flags) {
- int actualReportingMode =
- (hwSensor->flags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT;
- int expectedReportingMode = (mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT;
- if (actualReportingMode != expectedReportingMode) {
- ALOGE("Reporting Mode incorrect: sensor %s handle=%d type=%d "
- "actual=%d expected=%d",
- mName.string(), mHandle, mType, actualReportingMode, expectedReportingMode);
- }
-
- }
+ mFlags |= (hwSensor.flags & DATA_INJECTION_MASK);
}
if (mRequiredPermission.length() > 0) {
@@ -311,8 +309,7 @@
}
}
-Sensor::~Sensor()
-{
+Sensor::~Sensor() {
}
const String8& Sensor::getName() const {
@@ -392,11 +389,15 @@
}
bool Sensor::isWakeUpSensor() const {
- return mFlags & SENSOR_FLAG_WAKE_UP;
+ return (mFlags & SENSOR_FLAG_WAKE_UP) != 0;
}
bool Sensor::isDynamicSensor() const {
- return mFlags & SENSOR_FLAG_DYNAMIC_SENSOR;
+ return (mFlags & SENSOR_FLAG_DYNAMIC_SENSOR) != 0;
+}
+
+bool Sensor::hasAdditionalInfo() const {
+ return (mFlags & SENSOR_FLAG_ADDITIONAL_INFO) != 0;
}
int32_t Sensor::getReportingMode() const {
@@ -407,8 +408,7 @@
return mUuid;
}
-size_t Sensor::getFlattenedSize() const
-{
+size_t Sensor::getFlattenedSize() const {
size_t fixedSize =
sizeof(mVersion) + sizeof(mHandle) + sizeof(mType) +
sizeof(mMinValue) + sizeof(mMaxValue) + sizeof(mResolution) +
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
index 85e96d6..5a36961 100644
--- a/services/sensorservice/Android.mk
+++ b/services/sensorservice/Android.mk
@@ -2,21 +2,22 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- BatteryService.cpp \
- CorrectedGyroSensor.cpp \
+ BatteryService.cpp \
+ CorrectedGyroSensor.cpp \
Fusion.cpp \
GravitySensor.cpp \
LinearAccelerationSensor.cpp \
OrientationSensor.cpp \
+ RecentEventLogger.cpp \
RotationVectorSensor.cpp \
SensorDevice.cpp \
+ SensorEventConnection.cpp \
SensorFusion.cpp \
SensorInterface.cpp \
- SensorService.cpp \
- SensorEventConnection.cpp \
- MostRecentEventLogger.cpp \
- SensorRecord.cpp \
SensorList.cpp \
+ SensorRecord.cpp \
+ SensorService.cpp \
+ SensorServiceUtils.cpp \
LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\"
@@ -26,14 +27,14 @@
LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libhardware \
- libhardware_legacy \
- libutils \
- liblog \
- libbinder \
- libui \
- libgui
+ libcutils \
+ libhardware \
+ libhardware_legacy \
+ libutils \
+ liblog \
+ libbinder \
+ libui \
+ libgui
LOCAL_MODULE:= libsensorservice
@@ -44,12 +45,12 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- main_sensorservice.cpp
+ main_sensorservice.cpp
LOCAL_SHARED_LIBRARIES := \
- libsensorservice \
- libbinder \
- libutils
+ libsensorservice \
+ libbinder \
+ libutils
LOCAL_CFLAGS := -Wall -Werror -Wextra
diff --git a/services/sensorservice/MostRecentEventLogger.cpp b/services/sensorservice/MostRecentEventLogger.cpp
deleted file mode 100644
index a5d8456..0000000
--- a/services/sensorservice/MostRecentEventLogger.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2010 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 "MostRecentEventLogger.h"
-
-#include <inttypes.h>
-
-namespace android {
-
-SensorService::MostRecentEventLogger::MostRecentEventLogger(int sensorType) :
- mNextInd(0), mSensorType(sensorType) {
-
- mBufSize = (sensorType == SENSOR_TYPE_STEP_COUNTER ||
- sensorType == SENSOR_TYPE_SIGNIFICANT_MOTION ||
- sensorType == SENSOR_TYPE_ACCELEROMETER) ? LOG_SIZE : LOG_SIZE_LARGE;
-
- mTrimmedSensorEventArr = new TrimmedSensorEvent *[mBufSize];
- mSensorType = sensorType;
- for (int i = 0; i < mBufSize; ++i) {
- mTrimmedSensorEventArr[i] = new TrimmedSensorEvent(mSensorType);
- }
-}
-
-void SensorService::MostRecentEventLogger::addEvent(const sensors_event_t& event) {
- TrimmedSensorEvent *curr_event = mTrimmedSensorEventArr[mNextInd];
- curr_event->mTimestamp = event.timestamp;
- if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
- curr_event->mStepCounter = event.u64.step_counter;
- } else {
- memcpy(curr_event->mData, event.data,
- sizeof(float) * SensorService::getNumEventsForSensorType(mSensorType));
- }
- time_t rawtime = time(NULL);
- struct tm * timeinfo = localtime(&rawtime);
- curr_event->mHour = timeinfo->tm_hour;
- curr_event->mMin = timeinfo->tm_min;
- curr_event->mSec = timeinfo->tm_sec;
- mNextInd = (mNextInd + 1) % mBufSize;
-}
-
-void SensorService::MostRecentEventLogger::printBuffer(String8& result) const {
- const int numData = SensorService::getNumEventsForSensorType(mSensorType);
- int i = mNextInd, eventNum = 1;
- result.appendFormat("last %d events = < ", mBufSize);
- do {
- if (TrimmedSensorEvent::isSentinel(*mTrimmedSensorEventArr[i])) {
- // Sentinel, ignore.
- i = (i + 1) % mBufSize;
- continue;
- }
- result.appendFormat("%d) ", eventNum++);
- if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
- result.appendFormat("%" PRIu64 ",", mTrimmedSensorEventArr[i]->mStepCounter);
- } else {
- for (int j = 0; j < numData; ++j) {
- result.appendFormat("%5.1f,", mTrimmedSensorEventArr[i]->mData[j]);
- }
- }
- result.appendFormat("%" PRId64 " %02d:%02d:%02d ", mTrimmedSensorEventArr[i]->mTimestamp,
- mTrimmedSensorEventArr[i]->mHour, mTrimmedSensorEventArr[i]->mMin,
- mTrimmedSensorEventArr[i]->mSec);
- i = (i + 1) % mBufSize;
- } while (i != mNextInd);
- result.appendFormat(">\n");
-}
-
-bool SensorService::MostRecentEventLogger::populateLastEvent(sensors_event_t *event) {
- int lastEventInd = (mNextInd - 1 + mBufSize) % mBufSize;
- // Check if the buffer is empty.
- if (TrimmedSensorEvent::isSentinel(*mTrimmedSensorEventArr[lastEventInd])) {
- return false;
- }
- event->version = sizeof(sensors_event_t);
- event->type = mSensorType;
- event->timestamp = mTrimmedSensorEventArr[lastEventInd]->mTimestamp;
- if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
- event->u64.step_counter = mTrimmedSensorEventArr[lastEventInd]->mStepCounter;
- } else {
- memcpy(event->data, mTrimmedSensorEventArr[lastEventInd]->mData,
- sizeof(float) * SensorService::getNumEventsForSensorType(mSensorType));
- }
- return true;
-}
-
-SensorService::MostRecentEventLogger::~MostRecentEventLogger() {
- for (int i = 0; i < mBufSize; ++i) {
- delete mTrimmedSensorEventArr[i];
- }
- delete [] mTrimmedSensorEventArr;
-}
-
-// -----------------------------------------------------------------------------
-SensorService::MostRecentEventLogger::TrimmedSensorEvent::TrimmedSensorEvent(int sensorType) {
- mTimestamp = -1;
- const int numData = SensorService::getNumEventsForSensorType(sensorType);
- if (sensorType == SENSOR_TYPE_STEP_COUNTER) {
- mStepCounter = 0;
- } else {
- mData = new float[numData];
- for (int i = 0; i < numData; ++i) {
- mData[i] = -1.0;
- }
- }
- mHour = mMin = mSec = INT32_MIN;
-}
-
-bool SensorService::MostRecentEventLogger::TrimmedSensorEvent::
- isSentinel(const TrimmedSensorEvent& event) {
- return (event.mHour == INT32_MIN && event.mMin == INT32_MIN && event.mSec == INT32_MIN);
-}
-
-} // namespace android
diff --git a/services/sensorservice/MostRecentEventLogger.h b/services/sensorservice/MostRecentEventLogger.h
deleted file mode 100644
index 68c1661..0000000
--- a/services/sensorservice/MostRecentEventLogger.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 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_MOST_RECENT_EVENT_LOGGER_H
-#define ANDROID_MOST_RECENT_EVENT_LOGGER_H
-
-#include "SensorService.h"
-
-namespace android {
-
-class SensorService;
-
-// A circular buffer of TrimmedSensorEvents. The size of this buffer is typically 10. The last N
-// events generated from the sensor are stored in this buffer. The buffer is NOT cleared when the
-// sensor unregisters and as a result very old data in the dumpsys output can be seen, which is an
-// intended behavior.
-class SensorService::MostRecentEventLogger {
-public:
- MostRecentEventLogger(int sensorType);
- void addEvent(const sensors_event_t& event);
- void printBuffer(String8& buffer) const;
- bool populateLastEvent(sensors_event_t *event);
- ~MostRecentEventLogger();
-
-private:
- // sensor_event_t with only the data and the timestamp.
- static const size_t LOG_SIZE = 10;
- static const size_t LOG_SIZE_LARGE = 50;
-
- struct TrimmedSensorEvent {
- union {
- float *mData;
- uint64_t mStepCounter;
- };
- // Timestamp from the sensors_event_t.
- int64_t mTimestamp;
- // HH:MM:SS local time at which this sensor event is read at SensorService. Useful
- // for debugging.
- int32_t mHour, mMin, mSec;
-
- TrimmedSensorEvent(int sensorType);
- static bool isSentinel(const TrimmedSensorEvent& event);
-
- ~TrimmedSensorEvent() {
- delete [] mData;
- }
- };
-
- int mNextInd;
- int mSensorType;
- int mBufSize;
- TrimmedSensorEvent ** mTrimmedSensorEventArr;
-};
-
-} // namespace android;
-
-#endif // ANDROID_MOST_RECENT_EVENT_LOGGER_H
-
diff --git a/services/sensorservice/RecentEventLogger.cpp b/services/sensorservice/RecentEventLogger.cpp
new file mode 100644
index 0000000..dba7211
--- /dev/null
+++ b/services/sensorservice/RecentEventLogger.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2016 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 "RecentEventLogger.h"
+#include "SensorServiceUtils.h"
+
+#include <utils/Timers.h>
+
+#include <inttypes.h>
+
+namespace android {
+namespace SensorServiceUtil {
+
+namespace {
+ constexpr size_t LOG_SIZE = 10;
+ constexpr size_t LOG_SIZE_LARGE = 50; // larger samples for debugging
+}// unnamed namespace
+
+RecentEventLogger::RecentEventLogger(int sensorType) :
+ mSensorType(sensorType), mEventSize(eventSizeBySensorType(mSensorType)),
+ mRecentEvents(logSizeBySensorType(sensorType)) {
+ // blank
+}
+
+void RecentEventLogger::addEvent(const sensors_event_t& event) {
+ std::lock_guard<std::mutex> lk(mLock);
+ mRecentEvents.emplace(event);
+}
+
+bool RecentEventLogger::isEmpty() const {
+ return mRecentEvents.size() == 0;
+}
+
+std::string RecentEventLogger::dump() const {
+ std::lock_guard<std::mutex> lk(mLock);
+
+ //TODO: replace String8 with std::string completely in this function
+ String8 buffer;
+
+ buffer.appendFormat("last %zu events\n", mRecentEvents.size());
+ int j = 0;
+ for (int i = mRecentEvents.size() - 1; i >= 0; --i) {
+ const auto& ev = mRecentEvents[i];
+ struct tm * timeinfo = localtime(&(ev.mWallTime.tv_sec));
+ buffer.appendFormat("\t%2d (ts=%.9f, wall=%02d:%02d:%02d.%03d) ",
+ ++j, ev.mEvent.timestamp/1e9, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec,
+ (int) ns2ms(ev.mWallTime.tv_nsec));
+
+ // data
+ if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
+ buffer.appendFormat("%" PRIu64 ", ", ev.mEvent.u64.step_counter);
+ } else {
+ for (size_t k = 0; k < mEventSize; ++k) {
+ buffer.appendFormat("%.2f, ", ev.mEvent.data[k]);
+ }
+ }
+ buffer.append("\n");
+ }
+ return std::string(buffer.string());
+}
+
+bool RecentEventLogger::populateLastEvent(sensors_event_t *event) const {
+ std::lock_guard<std::mutex> lk(mLock);
+
+ if (mRecentEvents.size()) {
+ *event = mRecentEvents[mRecentEvents.size()-1].mEvent;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+size_t RecentEventLogger::logSizeBySensorType(int sensorType) {
+ return (sensorType == SENSOR_TYPE_STEP_COUNTER ||
+ sensorType == SENSOR_TYPE_SIGNIFICANT_MOTION ||
+ sensorType == SENSOR_TYPE_ACCELEROMETER) ? LOG_SIZE_LARGE : LOG_SIZE;
+}
+
+RecentEventLogger::SensorEventLog::SensorEventLog(const sensors_event_t& e) : mEvent(e) {
+ clock_gettime(CLOCK_REALTIME, &mWallTime);
+}
+
+} // namespace SensorServiceUtil
+} // namespace android
diff --git a/services/sensorservice/RecentEventLogger.h b/services/sensorservice/RecentEventLogger.h
new file mode 100644
index 0000000..4f9bc4a
--- /dev/null
+++ b/services/sensorservice/RecentEventLogger.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 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_SENSOR_SERVICE_UTIL_RECENT_EVENT_LOGGER_H
+#define ANDROID_SENSOR_SERVICE_UTIL_RECENT_EVENT_LOGGER_H
+
+#include "RingBuffer.h"
+#include "SensorServiceUtils.h"
+
+#include <hardware/sensors.h>
+#include <utils/String8.h>
+
+#include <mutex>
+
+namespace android {
+namespace SensorServiceUtil {
+
+// A circular buffer that record the last N events of a sensor type for debugging. The size of this
+// buffer depends on sensor type and is controlled by logSizeBySensorType(). The last N events
+// generated from the sensor are stored in this buffer. The buffer is NOT cleared when the sensor
+// unregisters and as a result very old data in the dumpsys output can be seen, which is an intended
+// behavior.
+class RecentEventLogger : public Dumpable {
+public:
+ RecentEventLogger(int sensorType);
+ void addEvent(const sensors_event_t& event);
+ bool populateLastEvent(sensors_event_t *event) const;
+ bool isEmpty() const;
+ virtual ~RecentEventLogger() {}
+
+ // Dumpable interface
+ virtual std::string dump() const override;
+
+protected:
+ struct SensorEventLog {
+ SensorEventLog(const sensors_event_t& e);
+ timespec mWallTime;
+ sensors_event_t mEvent;
+ };
+
+ const int mSensorType;
+ const size_t mEventSize;
+
+ mutable std::mutex mLock;
+ RingBuffer<SensorEventLog> mRecentEvents;
+
+private:
+ static size_t logSizeBySensorType(int sensorType);
+};
+
+} // namespace SensorServiceUtil
+} // namespace android;
+
+#endif // ANDROID_SENSOR_SERVICE_UTIL_RECENT_EVENT_LOGGER_H
+
diff --git a/services/sensorservice/RingBuffer.h b/services/sensorservice/RingBuffer.h
new file mode 100644
index 0000000..ec98a01
--- /dev/null
+++ b/services/sensorservice/RingBuffer.h
@@ -0,0 +1,361 @@
+/*
+ * 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 ANDROID_SENSOR_SERVICE_UTIL_RING_BUFFER_H
+#define ANDROID_SENSOR_SERVICE_UTIL_RING_BUFFER_H
+
+#include <utils/Log.h>
+#include <cutils/compiler.h>
+
+#include <iterator>
+#include <utility>
+#include <vector>
+
+namespace android {
+namespace SensorServiceUtil {
+
+/**
+ * A RingBuffer class that maintains an array of objects that can grow up to a certain size.
+ * Elements added to the RingBuffer are inserted in the logical front of the buffer, and
+ * invalidate all current iterators for that RingBuffer object.
+ */
+template <class T>
+class RingBuffer final {
+public:
+
+ /**
+ * Construct a RingBuffer that can grow up to the given length.
+ */
+ RingBuffer(size_t length);
+
+ /**
+ * Forward iterator to this class. Implements an std:forward_iterator.
+ */
+ class iterator : public std::iterator<std::forward_iterator_tag, T> {
+ public:
+ iterator(T* ptr, size_t size, size_t pos, size_t ctr);
+
+ iterator& operator++();
+
+ iterator operator++(int);
+
+ bool operator==(const iterator& rhs);
+
+ bool operator!=(const iterator& rhs);
+
+ T& operator*();
+
+ T* operator->();
+
+ private:
+ T* mPtr;
+ size_t mSize;
+ size_t mPos;
+ size_t mCtr;
+ };
+
+ /**
+ * Constant forward iterator to this class. Implements an std:forward_iterator.
+ */
+ class const_iterator : public std::iterator<std::forward_iterator_tag, T> {
+ public:
+ const_iterator(const T* ptr, size_t size, size_t pos, size_t ctr);
+
+ const_iterator& operator++();
+
+ const_iterator operator++(int);
+
+ bool operator==(const const_iterator& rhs);
+
+ bool operator!=(const const_iterator& rhs);
+
+ const T& operator*();
+
+ const T* operator->();
+
+ private:
+ const T* mPtr;
+ size_t mSize;
+ size_t mPos;
+ size_t mCtr;
+ };
+
+ /**
+ * Adds item to the front of this RingBuffer. If the RingBuffer is at its maximum length,
+ * this will result in the last element being replaced (this is done using the element's
+ * assignment operator).
+ *
+ * All current iterators are invalidated.
+ */
+ void add(const T& item);
+
+ /**
+ * Moves item to the front of this RingBuffer. Following a call to this, item should no
+ * longer be used. If the RingBuffer is at its maximum length, this will result in the
+ * last element being replaced (this is done using the element's assignment operator).
+ *
+ * All current iterators are invalidated.
+ */
+ void add(T&& item);
+
+ /**
+ * Construct item in-place in the front of this RingBuffer using the given arguments. If
+ * the RingBuffer is at its maximum length, this will result in the last element being
+ * replaced (this is done using the element's assignment operator).
+ *
+ * All current iterators are invalidated.
+ */
+ template <class... Args>
+ void emplace(Args&&... args);
+
+ /**
+ * Get an iterator to the front of this RingBuffer.
+ */
+ iterator begin();
+
+ /**
+ * Get an iterator to the end of this RingBuffer.
+ */
+ iterator end();
+
+ /**
+ * Get a const_iterator to the front of this RingBuffer.
+ */
+ const_iterator begin() const;
+
+ /**
+ * Get a const_iterator to the end of this RingBuffer.
+ */
+ const_iterator end() const;
+
+ /**
+ * Return a reference to the element at a given index. If the index is out of range for
+ * this ringbuffer, [0, size), the behavior for this is undefined.
+ */
+ T& operator[](size_t index);
+
+ /**
+ * Return a const reference to the element at a given index. If the index is out of range
+ * for this ringbuffer, [0, size), the behavior for this is undefined.
+ */
+ const T& operator[](size_t index) const;
+
+ /**
+ * Return the current size of this RingBuffer.
+ */
+ size_t size() const;
+
+ /**
+ * Remove all elements from this RingBuffer and set the size to 0.
+ */
+ void clear();
+
+private:
+ size_t mFrontIdx;
+ size_t mMaxBufferSize;
+ std::vector<T> mBuffer;
+}; // class RingBuffer
+
+
+template <class T>
+RingBuffer<T>::RingBuffer(size_t length) : mFrontIdx{0}, mMaxBufferSize{length} {}
+
+template <class T>
+RingBuffer<T>::iterator::iterator(T* ptr, size_t size, size_t pos, size_t ctr) :
+ mPtr{ptr}, mSize{size}, mPos{pos}, mCtr{ctr} {}
+
+template <class T>
+typename RingBuffer<T>::iterator& RingBuffer<T>::iterator::operator++() {
+ ++mCtr;
+
+ if (CC_UNLIKELY(mCtr == mSize)) {
+ mPos = mSize;
+ return *this;
+ }
+
+ mPos = ((CC_UNLIKELY(mPos == 0)) ? mSize - 1 : mPos - 1);
+ return *this;
+}
+
+template <class T>
+typename RingBuffer<T>::iterator RingBuffer<T>::iterator::operator++(int) {
+ iterator tmp{mPtr, mSize, mPos, mCtr};
+ ++(*this);
+ return tmp;
+}
+
+template <class T>
+bool RingBuffer<T>::iterator::operator==(const iterator& rhs) {
+ return (mPtr + mPos) == (rhs.mPtr + rhs.mPos);
+}
+
+template <class T>
+bool RingBuffer<T>::iterator::operator!=(const iterator& rhs) {
+ return (mPtr + mPos) != (rhs.mPtr + rhs.mPos);
+}
+
+template <class T>
+T& RingBuffer<T>::iterator::operator*() {
+ return *(mPtr + mPos);
+}
+
+template <class T>
+T* RingBuffer<T>::iterator::operator->() {
+ return mPtr + mPos;
+}
+
+template <class T>
+RingBuffer<T>::const_iterator::const_iterator(const T* ptr, size_t size, size_t pos, size_t ctr) :
+ mPtr{ptr}, mSize{size}, mPos{pos}, mCtr{ctr} {}
+
+template <class T>
+typename RingBuffer<T>::const_iterator& RingBuffer<T>::const_iterator::operator++() {
+ ++mCtr;
+
+ if (CC_UNLIKELY(mCtr == mSize)) {
+ mPos = mSize;
+ return *this;
+ }
+
+ mPos = ((CC_UNLIKELY(mPos == 0)) ? mSize - 1 : mPos - 1);
+ return *this;
+}
+
+template <class T>
+typename RingBuffer<T>::const_iterator RingBuffer<T>::const_iterator::operator++(int) {
+ const_iterator tmp{mPtr, mSize, mPos, mCtr};
+ ++(*this);
+ return tmp;
+}
+
+template <class T>
+bool RingBuffer<T>::const_iterator::operator==(const const_iterator& rhs) {
+ return (mPtr + mPos) == (rhs.mPtr + rhs.mPos);
+}
+
+template <class T>
+bool RingBuffer<T>::const_iterator::operator!=(const const_iterator& rhs) {
+ return (mPtr + mPos) != (rhs.mPtr + rhs.mPos);
+}
+
+template <class T>
+const T& RingBuffer<T>::const_iterator::operator*() {
+ return *(mPtr + mPos);
+}
+
+template <class T>
+const T* RingBuffer<T>::const_iterator::operator->() {
+ return mPtr + mPos;
+}
+
+template <class T>
+void RingBuffer<T>::add(const T& item) {
+ if (mBuffer.size() < mMaxBufferSize) {
+ mBuffer.push_back(item);
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+ return;
+ }
+
+ mBuffer[mFrontIdx] = item;
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+}
+
+template <class T>
+void RingBuffer<T>::add(T&& item) {
+ if (mBuffer.size() != mMaxBufferSize) {
+ mBuffer.push_back(std::forward<T>(item));
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+ return;
+ }
+
+ // Only works for types with move assignment operator
+ mBuffer[mFrontIdx] = std::forward<T>(item);
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+}
+
+template <class T>
+template <class... Args>
+void RingBuffer<T>::emplace(Args&&... args) {
+ if (mBuffer.size() != mMaxBufferSize) {
+ mBuffer.emplace_back(std::forward<Args>(args)...);
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+ return;
+ }
+
+ // Only works for types with move assignment operator
+ mBuffer[mFrontIdx] = T(std::forward<Args>(args)...);
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+}
+
+template <class T>
+typename RingBuffer<T>::iterator RingBuffer<T>::begin() {
+ size_t tmp = (mBuffer.size() == 0) ? 0 : mBuffer.size() - 1;
+ return iterator(mBuffer.data(), mBuffer.size(), (mFrontIdx == 0) ? tmp : mFrontIdx - 1, 0);
+}
+
+template <class T>
+typename RingBuffer<T>::iterator RingBuffer<T>::end() {
+ size_t s = mBuffer.size();
+ return iterator(mBuffer.data(), s, s, s);
+}
+
+template <class T>
+typename RingBuffer<T>::const_iterator RingBuffer<T>::begin() const {
+ size_t tmp = (mBuffer.size() == 0) ? 0 : mBuffer.size() - 1;
+ return const_iterator(mBuffer.data(), mBuffer.size(),
+ (mFrontIdx == 0) ? tmp : mFrontIdx - 1, 0);
+}
+
+template <class T>
+typename RingBuffer<T>::const_iterator RingBuffer<T>::end() const {
+ size_t s = mBuffer.size();
+ return const_iterator(mBuffer.data(), s, s, s);
+}
+
+template <class T>
+T& RingBuffer<T>::operator[](size_t index) {
+ LOG_ALWAYS_FATAL_IF(index >= mBuffer.size(), "Index %zu out of bounds, size is %zu.",
+ index, mBuffer.size());
+ size_t pos = (index >= mFrontIdx) ?
+ mBuffer.size() - 1 - (index - mFrontIdx) : mFrontIdx - 1 - index;
+ return mBuffer[pos];
+}
+
+template <class T>
+const T& RingBuffer<T>::operator[](size_t index) const {
+ LOG_ALWAYS_FATAL_IF(index >= mBuffer.size(), "Index %zu out of bounds, size is %zu.",
+ index, mBuffer.size());
+ size_t pos = (index >= mFrontIdx) ?
+ mBuffer.size() - 1 - (index - mFrontIdx) : mFrontIdx - 1 - index;
+ return mBuffer[pos];
+}
+
+template <class T>
+size_t RingBuffer<T>::size() const {
+ return mBuffer.size();
+}
+
+template <class T>
+void RingBuffer<T>::clear() {
+ mBuffer.clear();
+ mFrontIdx = 0;
+}
+
+} // namespace SensorServiceUtil
+}; // namespace android
+
+#endif // ANDROID_SENSOR_SERVICE_UTIL_RING_BUFFER_H
+
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 179b1c5..4fbaa50 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -39,8 +39,7 @@
SensorDevice::SensorDevice()
: mSensorDevice(0),
- mSensorModule(0)
-{
+ mSensorModule(0) {
status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
(hw_module_t const**)&mSensorModule);
@@ -84,37 +83,43 @@
}
}
-void SensorDevice::dump(String8& result)
-{
- if (!mSensorModule) return;
- sensor_t const* list;
- ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
+std::string SensorDevice::dump() const {
+ if (!mSensorModule) return "HAL not initialized\n";
- result.appendFormat("halVersion 0x%08x\n", getHalDeviceVersion());
- result.appendFormat("%d h/w sensors:\n", int(count));
+ String8 result;
+ sensor_t const* list;
+ int count = mSensorModule->get_sensors_list(mSensorModule, &list);
+
+ result.appendFormat("HAL: %s (%s), version %#010x\n",
+ mSensorModule->common.name,
+ mSensorModule->common.author,
+ getHalDeviceVersion());
+ result.appendFormat("Total %d h/w sensors, %zu running:\n", count, mActivationCount.size());
Mutex::Autolock _l(mLock);
- for (size_t i=0 ; i<size_t(count) ; i++) {
+ for (int i = 0 ; i < count ; i++) {
const Info& info = mActivationCount.valueFor(list[i].handle);
if (info.batchParams.isEmpty()) continue;
- result.appendFormat("handle=0x%08x, active-count=%zu, batch_period(ms)={ ", list[i].handle,
+ result.appendFormat("0x%08x) active-count = %zu; ", list[i].handle,
info.batchParams.size());
+
+ result.append("sampling_period(ms) = {");
for (size_t j = 0; j < info.batchParams.size(); j++) {
const BatchParams& params = info.batchParams.valueAt(j);
- result.appendFormat("%4.1f%s", params.batchDelay / 1e6f,
+ result.appendFormat("%.1f%s", params.batchDelay / 1e6f,
j < info.batchParams.size() - 1 ? ", " : "");
}
- result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchDelay / 1e6f);
+ result.appendFormat("}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f);
- result.appendFormat("handle=0x%08x, active-count=%zu, batch_timeout(ms)={ ", list[i].handle,
- info.batchParams.size());
+ result.append("batching_period(ms) = {");
for (size_t j = 0; j < info.batchParams.size(); j++) {
BatchParams params = info.batchParams.valueAt(j);
- result.appendFormat("%4.1f%s", params.batchTimeout / 1e6f,
+ result.appendFormat("%.1f%s", params.batchTimeout / 1e6f,
j < info.batchParams.size() - 1 ? ", " : "");
}
- result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
+ result.appendFormat("}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
}
+ return result.string();
}
ssize_t SensorDevice::getSensorList(sensor_t const** list) {
@@ -143,8 +148,7 @@
info.removeBatchParamsForIdent(ident);
}
-status_t SensorDevice::activate(void* ident, int handle, int enabled)
-{
+status_t SensorDevice::activate(void* ident, int handle, int enabled) {
if (!mSensorDevice) return NO_INIT;
status_t err(NO_ERROR);
bool actuateHardware = false;
@@ -293,8 +297,7 @@
return err;
}
-status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs)
-{
+status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
if (!mSensorDevice) return NO_INIT;
if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index c12630a..68bb853 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -17,21 +17,44 @@
#ifndef ANDROID_SENSOR_DEVICE_H
#define ANDROID_SENSOR_DEVICE_H
-#include <stdint.h>
-#include <sys/types.h>
+#include "SensorServiceUtils.h"
+#include <gui/Sensor.h>
#include <utils/KeyedVector.h>
#include <utils/Singleton.h>
#include <utils/String8.h>
-#include <gui/Sensor.h>
+#include <stdint.h>
+#include <sys/types.h>
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
+using SensorServiceUtil::Dumpable;
-class SensorDevice : public Singleton<SensorDevice> {
+class SensorDevice : public Singleton<SensorDevice>, public Dumpable {
+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);
+ status_t activate(void* ident, int handle, int enabled);
+ status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs);
+ // Call batch with timeout zero instead of calling setDelay() for newer devices.
+ status_t setDelay(void* ident, int handle, int64_t ns);
+ status_t flush(void* ident, int handle);
+ status_t setMode(uint32_t mode);
+ void disableAllSensors();
+ void enableAllSensors();
+ void autoDisable(void *ident, int handle);
+ status_t injectSensorData(const sensors_event_t *event);
+
+ // Dumpable
+ virtual std::string dump() const;
+private:
friend class Singleton<SensorDevice>;
sensors_poll_device_1_t* mSensorDevice;
struct sensors_module_t* mSensorModule;
@@ -87,24 +110,6 @@
bool isClientDisabled(void* ident);
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);
- status_t activate(void* ident, int handle, int enabled);
- status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
- int64_t maxBatchReportLatencyNs);
- // Call batch with timeout zero instead of calling setDelay() for newer devices.
- status_t setDelay(void* ident, int handle, int64_t ns);
- status_t flush(void* ident, int handle);
- status_t setMode(uint32_t mode);
- void disableAllSensors();
- void enableAllSensors();
- void autoDisable(void *ident, int handle);
- status_t injectSensorData(const sensors_event_t *event);
- void dump(String8& result);
};
// ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorInterface.cpp b/services/sensorservice/SensorInterface.cpp
index cb24229..73a6db5 100644
--- a/services/sensorservice/SensorInterface.cpp
+++ b/services/sensorservice/SensorInterface.cpp
@@ -34,12 +34,21 @@
mSensor(&sensor, mSensorDevice.getHalDeviceVersion()) {
}
+BaseSensor::BaseSensor(const sensor_t& sensor, const uint8_t (&uuid)[16]) :
+ mSensorDevice(SensorDevice::getInstance()),
+ mSensor(sensor, Sensor::uuid_t(uuid), mSensorDevice.getHalDeviceVersion()) {
+}
+
// ---------------------------------------------------------------------------
HardwareSensor::HardwareSensor(const sensor_t& sensor):
BaseSensor(sensor) {
}
+HardwareSensor::HardwareSensor(const sensor_t& sensor, const uint8_t (&uuid)[16]):
+ BaseSensor(sensor, uuid) {
+}
+
HardwareSensor::~HardwareSensor() {
}
diff --git a/services/sensorservice/SensorInterface.h b/services/sensorservice/SensorInterface.h
index d1cee41..dafcf2d 100644
--- a/services/sensorservice/SensorInterface.h
+++ b/services/sensorservice/SensorInterface.h
@@ -48,6 +48,7 @@
class BaseSensor : public SensorInterface {
public:
BaseSensor(const sensor_t& sensor);
+ BaseSensor(const sensor_t& sensor, const uint8_t (&uuid)[16]);
// Not all sensors need to support batching.
virtual status_t batch(void* ident, int handle, int, int64_t samplingPeriodNs,
@@ -74,6 +75,7 @@
class HardwareSensor : public BaseSensor {
public:
HardwareSensor(const sensor_t& sensor);
+ HardwareSensor(const sensor_t& sensor, const uint8_t (&uuid)[16]);
virtual ~HardwareSensor();
diff --git a/services/sensorservice/SensorList.cpp b/services/sensorservice/SensorList.cpp
index c23e21f..f6d3d94 100644
--- a/services/sensorservice/SensorList.cpp
+++ b/services/sensorservice/SensorList.cpp
@@ -19,6 +19,8 @@
#include <hardware/sensors.h>
#include <utils/String8.h>
+#include <cinttypes>
+
namespace android {
namespace SensorServiceUtil {
@@ -119,17 +121,17 @@
std::string SensorList::dump() const {
String8 result;
- result.append("Sensor List:\n");
forEachSensor([&result] (const Sensor& s) -> bool {
result.appendFormat(
- "%-15s| %-10s| version=%d |%-20s| 0x%08x | \"%s\" | type=%d |",
+ "%#010x) %-25s | %-15s | ver: %" PRId32 " | type: %20s(%" PRId32
+ ") | perm: %s\n\t",
+ s.getHandle(),
s.getName().string(),
s.getVendor().string(),
s.getVersion(),
s.getStringType().string(),
- s.getHandle(),
- s.getRequiredPermission().string(),
- s.getType());
+ s.getType(),
+ s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a");
const int reportingMode = s.getReportingMode();
if (reportingMode == AREPORTING_MODE_CONTINUOUS) {
@@ -147,18 +149,19 @@
if (s.getMaxDelay() > 0) {
result.appendFormat("minRate=%.2fHz | ", 1e6f / s.getMaxDelay());
} else {
- result.appendFormat("maxDelay=%dus | ", s.getMaxDelay());
+ result.appendFormat("maxDelay=%" PRId32 "us | ", s.getMaxDelay());
}
if (s.getMinDelay() > 0) {
result.appendFormat("maxRate=%.2fHz | ", 1e6f / s.getMinDelay());
} else {
- result.appendFormat("minDelay=%dus | ", s.getMinDelay());
+ result.appendFormat("minDelay=%" PRId32 "us | ", s.getMinDelay());
}
if (s.getFifoMaxEventCount() > 0) {
- result.appendFormat("FifoMax=%d events | ",
- s.getFifoMaxEventCount());
+ result.appendFormat("FIFO (max,reserved) = (%" PRIu32 ", %" PRIu32 ") events | ",
+ s.getFifoMaxEventCount(),
+ s.getFifoReservedEventCount());
} else {
result.append("no batching | ");
}
@@ -169,6 +172,20 @@
result.appendFormat("non-wakeUp | ");
}
+ if (s.isDynamicSensor()) {
+ result.appendFormat("dynamic, ");
+ }
+ if (s.hasAdditionalInfo()) {
+ result.appendFormat("has-additional-info, ");
+ }
+ result.append("| ");
+
+ if (s.isDynamicSensor()) {
+ result.append("uuid: ");
+ for (uint8_t i : s.getUuid().b) {
+ result.appendFormat("%02x", i);
+ }
+ }
result.append("\n");
return true;
});
diff --git a/services/sensorservice/SensorList.h b/services/sensorservice/SensorList.h
index ffde619..8209d96 100644
--- a/services/sensorservice/SensorList.h
+++ b/services/sensorservice/SensorList.h
@@ -14,18 +14,18 @@
* limitations under the License.
*/
-#ifndef ANDROID_SENSOR_LIST_H
-#define ANDROID_SENSOR_LIST_H
+#ifndef ANDROID_SENSOR_SERVICE_UTIL_SENSOR_LIST_H
+#define ANDROID_SENSOR_SERVICE_UTIL_SENSOR_LIST_H
#include "SensorInterface.h"
+#include "SensorServiceUtils.h"
#include <gui/Sensor.h>
#include <utils/String8.h>
#include <utils/Vector.h>
-#include <mutex>
#include <map>
-#include <string>
+#include <mutex>
#include <unordered_set>
#include <vector>
@@ -34,13 +34,6 @@
namespace SensorServiceUtil {
-class Dumpable {
-public:
- virtual std::string dump() const;
- virtual void setFormat(std::string ) {}
- virtual ~Dumpable() {}
-};
-
class SensorList : public Dumpable {
public:
// After SensorInterface * is added into SensorList, it can be assumed that SensorList own the
@@ -142,4 +135,4 @@
} // namespace SensorServiceUtil
} // namespace android
-#endif // ANDROID_SENSOR_LIST_H
+#endif // ANDROID_SENSOR_SERVICE_UTIL_SENSOR_LIST_H
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index b7a8740..6caa85b 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -36,11 +36,10 @@
#include "SensorInterface.h"
#include "SensorService.h"
-#include "SensorEventConnection.h"
#include "SensorEventAckReceiver.h"
+#include "SensorEventConnection.h"
#include "SensorRecord.h"
#include "SensorRegistrationInfo.h"
-#include "MostRecentEventLogger.h"
#include <inttypes.h>
#include <math.h>
@@ -86,7 +85,6 @@
(1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) |
(1<<SENSOR_TYPE_GAME_ROTATION_VECTOR);
- mLastEventSeen.setCapacity(count);
for (ssize_t i=0 ; i<count ; i++) {
bool useThisSensor=true;
@@ -218,25 +216,27 @@
const Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug, bool isVirtual) {
int handle = s->getSensor().getHandle();
+ int type = s->getSensor().getType();
if (mSensors.add(handle, s, isDebug, isVirtual)){
- mLastEventSeen.add(handle, nullptr);
+ mRecentEvent.emplace(handle, new RecentEventLogger(type));
return s->getSensor();
} else {
return mSensors.getNonSensor();
}
}
-const Sensor& SensorService::registerDynamicSensor(SensorInterface* s, bool isDebug) {
+const Sensor& SensorService::registerDynamicSensorLocked(SensorInterface* s, bool isDebug) {
return registerSensor(s, isDebug);
}
-bool SensorService::unregisterDynamicSensor(int handle) {
+bool SensorService::unregisterDynamicSensorLocked(int handle) {
bool ret = mSensors.remove(handle);
- MostRecentEventLogger *buf = mLastEventSeen.valueFor(handle);
- if (buf) {
- delete buf;
+
+ const auto i = mRecentEvent.find(handle);
+ if (i != mRecentEvent.end()) {
+ delete i->second;
+ mRecentEvent.erase(i);
}
- mLastEventSeen.removeItem(handle);
return ret;
}
@@ -245,6 +245,9 @@
}
SensorService::~SensorService() {
+ for (auto && entry : mRecentEvent) {
+ delete entry.second;
+ }
}
status_t SensorService::dump(int fd, const Vector<String16>& args) {
@@ -313,25 +316,25 @@
} else {
// Default dump the sensor list and debugging information.
//
+ result.append("Sensor Device:\n");
+ result.append(SensorDevice::getInstance().dump().c_str());
+
+ result.append("Sensor List:\n");
result.append(mSensors.dump().c_str());
+ result.append("Fusion States:\n");
SensorFusion::getInstance().dump(result);
- SensorDevice::getInstance().dump(result);
result.append("Recent Sensor events:\n");
- auto& lastEvents = mLastEventSeen;
- mSensors.forEachSensor([&result, &lastEvents] (const Sensor& s) -> bool {
- int bufIndex = lastEvents.indexOfKey(s.getHandle());
- if (bufIndex >= 0) {
- const MostRecentEventLogger* buf = lastEvents.valueAt(bufIndex);
- if (buf != nullptr && s.getRequiredPermission().isEmpty()) {
- result.appendFormat("%s (handle:0x%08x): ",
- s.getName().string(), s.getHandle());
- buf->printBuffer(result);
- }
- }
- return true;
- });
+ for (auto&& i : mRecentEvent) {
+ sp<SensorInterface> s = mSensors.getInterface(i.first);
+ if (!i.second->isEmpty() &&
+ s->getSensor().getRequiredPermission().isEmpty()) {
+ // if there is events and sensor does not need special permission.
+ result.appendFormat("%s: ", s->getSensor().getName().string());
+ result.append(i.second->dump().c_str());
+ }
+ }
result.append("Active sensors:\n");
for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
@@ -554,17 +557,19 @@
handle, dynamicSensor.type, dynamicSensor.name);
if (mSensors.isNewHandle(handle)) {
+ const auto& uuid = mSensorEventBuffer[i].dynamic_sensor_meta.uuid;
sensor_t s = dynamicSensor;
// make sure the dynamic sensor flag is set
s.flags |= DYNAMIC_SENSOR_MASK;
// force the handle to be consistent
s.handle = handle;
- SensorInterface *si = new HardwareSensor(s);
+
+ SensorInterface *si = new HardwareSensor(s, uuid);
// This will release hold on dynamic sensor meta, so it should be called
// after Sensor object is created.
device.handleDynamicSensorConnection(handle, true /*connected*/);
- registerDynamicSensor(si);
+ registerDynamicSensorLocked(si);
} else {
ALOGE("Handle %d has been used, cannot use again before reboot.", handle);
}
@@ -573,7 +578,7 @@
ALOGI("Dynamic sensor handle 0x%x disconnected", handle);
device.handleDynamicSensorConnection(handle, false /*connected*/);
- if (!unregisterDynamicSensor(handle)) {
+ if (!unregisterDynamicSensorLocked(handle)) {
ALOGE("Dynamic sensor release error.");
}
@@ -674,16 +679,14 @@
for (size_t i = 0; i < count; i++) {
if (buffer[i].type == SENSOR_TYPE_META_DATA ||
buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META ||
- buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO ||
- mLastEventSeen.indexOfKey(buffer[i].sensor) <0 ) {
+ buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
continue;
}
- MostRecentEventLogger* &circular_buf = mLastEventSeen.editValueFor(buffer[i].sensor);
- if (circular_buf == NULL) {
- circular_buf = new MostRecentEventLogger(buffer[i].type);
+ auto logger = mRecentEvent.find(buffer[i].sensor);
+ if (logger != mRecentEvent.end()) {
+ logger->second->addEvent(buffer[i]);
}
- circular_buf->addEvent(buffer[i]);
}
}
@@ -881,14 +884,14 @@
if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
// NOTE: The wake_up flag of this event may get set to
// WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
- MostRecentEventLogger *circular_buf = mLastEventSeen.valueFor(handle);
- if (circular_buf) {
+
+ auto logger = mRecentEvent.find(handle);
+ if (logger != mRecentEvent.end()) {
sensors_event_t event;
- memset(&event, 0, sizeof(event));
// It is unlikely that this buffer is empty as the sensor is already active.
// One possible corner case may be two applications activating an on-change
// sensor at the same time.
- if(circular_buf->populateLastEvent(&event)) {
+ if(logger->second->populateLastEvent(&event)) {
event.sensor = handle;
if (event.version == sizeof(sensors_event_t)) {
if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
@@ -1179,31 +1182,5 @@
return (packageName.contains(mWhiteListedPackage.string()));
}
-int SensorService::getNumEventsForSensorType(int sensor_event_type) {
- if (sensor_event_type >= SENSOR_TYPE_DEVICE_PRIVATE_BASE) {
- return 16;
- }
- switch (sensor_event_type) {
- case SENSOR_TYPE_ROTATION_VECTOR:
- case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
- return 5;
-
- case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
- case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
- return 6;
-
- case SENSOR_TYPE_GAME_ROTATION_VECTOR:
- return 4;
-
- case SENSOR_TYPE_SIGNIFICANT_MOTION:
- case SENSOR_TYPE_STEP_DETECTOR:
- case SENSOR_TYPE_STEP_COUNTER:
- return 1;
-
- default:
- return 3;
- }
-}
-
}; // namespace android
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 6473edb..0d04478 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -18,6 +18,7 @@
#define ANDROID_SENSOR_SERVICE_H
#include "SensorList.h"
+#include "RecentEventLogger.h"
#include <binder/BinderService.h>
#include <cutils/compiler.h>
@@ -35,6 +36,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <unordered_map>
#include <unordered_set>
#if __clang__
@@ -56,6 +58,7 @@
namespace android {
// ---------------------------------------------------------------------------
class SensorInterface;
+using namespace SensorServiceUtil;
class SensorService :
public BinderService<SensorService>,
@@ -86,8 +89,6 @@
// nested class/struct for internal use
class SensorRecord;
class SensorEventAckReceiver;
- struct TrimmedSensorEvent;
- class MostRecentEventLogger;
struct SensorRegistrationInfo;
enum Mode {
@@ -155,7 +156,6 @@
virtual int isDataInjectionEnabled();
virtual status_t dump(int fd, const Vector<String16>& args);
- static int getNumEventsForSensorType(int sensor_event_type);
String8 getSensorName(int handle) const;
bool isVirtualSensor(int handle) const;
sp<SensorInterface> getSensorInterfaceFromHandle(int handle) const;
@@ -165,8 +165,8 @@
const Sensor& registerSensor(SensorInterface* sensor,
bool isDebug = false, bool isVirtual = false);
const Sensor& registerVirtualSensor(SensorInterface* sensor, bool isDebug = false);
- const Sensor& registerDynamicSensor(SensorInterface* sensor, bool isDebug = false);
- bool unregisterDynamicSensor(int handle);
+ const Sensor& registerDynamicSensorLocked(SensorInterface* sensor, bool isDebug = false);
+ bool unregisterDynamicSensorLocked(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,
@@ -208,7 +208,7 @@
status_t resetToNormalMode();
status_t resetToNormalModeLocked();
- SensorServiceUtil::SensorList mSensors;
+ SensorList mSensors;
status_t mInitCheck;
// Socket buffersize used to initialize BitTube. This size depends on whether batching is
@@ -225,7 +225,7 @@
bool mWakeLockAcquired;
sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
SensorEventConnection const **mMapFlushEventsToConnections;
- KeyedVector<int32_t, MostRecentEventLogger*> mLastEventSeen;
+ std::unordered_map<int, RecentEventLogger*> mRecentEvent;
Mode mCurrentOperatingMode;
// This packagaName is set when SensorService is in RESTRICTED or DATA_INJECTION mode. Only
diff --git a/services/sensorservice/SensorServiceUtils.cpp b/services/sensorservice/SensorServiceUtils.cpp
new file mode 100644
index 0000000..1996a00
--- /dev/null
+++ b/services/sensorservice/SensorServiceUtils.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2016 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 "SensorServiceUtils.h"
+
+#include <hardware/sensors.h>
+
+namespace android {
+namespace SensorServiceUtil {
+
+// Keep in sync with sSensorReportingMode in Sensor.java
+size_t eventSizeBySensorType(int type) {
+ if (type >= SENSOR_TYPE_DEVICE_PRIVATE_BASE) {
+ return 16;
+ }
+ switch (type) {
+ case SENSOR_TYPE_POSE_6DOF:
+ return 16;
+
+ case SENSOR_TYPE_ROTATION_VECTOR:
+ case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+ return 5;
+
+ case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+ case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+ return 6;
+
+ case SENSOR_TYPE_GAME_ROTATION_VECTOR:
+ return 4;
+
+ case SENSOR_TYPE_SIGNIFICANT_MOTION:
+ case SENSOR_TYPE_STEP_DETECTOR:
+ case SENSOR_TYPE_STEP_COUNTER:
+ case SENSOR_TYPE_HEART_RATE:
+ case SENSOR_TYPE_TILT_DETECTOR:
+ case SENSOR_TYPE_WAKE_GESTURE:
+ case SENSOR_TYPE_GLANCE_GESTURE:
+ case SENSOR_TYPE_PICK_UP_GESTURE:
+ case SENSOR_TYPE_WRIST_TILT_GESTURE:
+ case SENSOR_TYPE_DEVICE_ORIENTATION:
+ case SENSOR_TYPE_STATIONARY_DETECT:
+ case SENSOR_TYPE_MOTION_DETECT:
+ case SENSOR_TYPE_HEART_BEAT:
+ return 1;
+
+ default:
+ return 3;
+ }
+}
+
+} // namespace SensorServiceUtil
+} // namespace android;
diff --git a/services/sensorservice/SensorServiceUtils.h b/services/sensorservice/SensorServiceUtils.h
new file mode 100644
index 0000000..1558feb
--- /dev/null
+++ b/services/sensorservice/SensorServiceUtils.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 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_SENSOR_SERVICE_UTIL
+#define ANDROID_SENSOR_SERVICE_UTIL
+
+#include <cstddef>
+#include <string>
+
+namespace android {
+namespace SensorServiceUtil {
+
+class Dumpable {
+public:
+ virtual std::string dump() const = 0;
+ virtual void setFormat(std::string ) {}
+ virtual ~Dumpable() {}
+};
+
+size_t eventSizeBySensorType(int type);
+
+} // namespace SensorServiceUtil
+} // namespace android;
+
+#endif // ANDROID_SENSOR_SERVICE_UTIL
diff --git a/services/sensorservice/tests/sensorservicetest.cpp b/services/sensorservice/tests/sensorservicetest.cpp
index cfdf6a3..186b60c 100644
--- a/services/sensorservice/tests/sensorservicetest.cpp
+++ b/services/sensorservice/tests/sensorservicetest.cpp
@@ -62,7 +62,7 @@
int main()
{
- SensorManager mgr(String16("Sensor Service Test"));
+ SensorManager& mgr = SensorManager::getInstanceForPackage(String16("Sensor Service Test"));
Sensor const* const* list;
ssize_t count = mgr.getSensorList(&list);