summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Peng Xu <pengxu@google.com> 2015-12-21 12:00:23 -0800
committer Peng Xu <pengxu@google.com> 2016-04-22 21:54:56 -0700
commit6a2d3a06caa337857cf60cfc70a9a78909ad3608 (patch)
tree86e855d09c2bd6884f86d8aaf85bfec9ba89ae05
parent151cc4a91a92447a78a964bf1164b50ac8921f65 (diff)
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
-rw-r--r--include/gui/Sensor.h13
-rw-r--r--libs/gui/Sensor.cpp134
-rw-r--r--services/sensorservice/Android.mk37
-rw-r--r--services/sensorservice/MostRecentEventLogger.cpp125
-rw-r--r--services/sensorservice/MostRecentEventLogger.h71
-rw-r--r--services/sensorservice/RecentEventLogger.cpp98
-rw-r--r--services/sensorservice/RecentEventLogger.h68
-rw-r--r--services/sensorservice/RingBuffer.h361
-rw-r--r--services/sensorservice/SensorDevice.cpp43
-rw-r--r--services/sensorservice/SensorDevice.h49
-rw-r--r--services/sensorservice/SensorInterface.cpp9
-rw-r--r--services/sensorservice/SensorInterface.h2
-rw-r--r--services/sensorservice/SensorList.cpp35
-rw-r--r--services/sensorservice/SensorList.h17
-rw-r--r--services/sensorservice/SensorService.cpp103
-rw-r--r--services/sensorservice/SensorService.h14
-rw-r--r--services/sensorservice/SensorServiceUtils.cpp65
-rw-r--r--services/sensorservice/SensorServiceUtils.h38
-rw-r--r--services/sensorservice/tests/sensorservicetest.cpp2
19 files changed, 866 insertions, 418 deletions
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index 353003c717..3f60741e47 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -52,12 +52,18 @@ public:
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 @@ public:
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 0340d6bd6f..cc865d16dd 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -14,69 +14,70 @@
* limitations under the License.
*/
-#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 <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>
// ----------------------------------------------------------------------------
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(struct sensor_t const* hwSensor, int halVersion)
-{
- mName = hwSensor->name;
- mVendor = hwSensor->vendor;
- mVersion = hwSensor->version;
- mHandle = hwSensor->handle;
- mType = hwSensor->type;
+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) :
+ 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 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
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 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
}
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 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
break;
}
- // 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));
+ // 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));
+ }
// 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(struct sensor_t const* hwSensor, int halVersion)
}
}
-Sensor::~Sensor()
-{
+Sensor::~Sensor() {
}
const String8& Sensor::getName() const {
@@ -392,11 +389,15 @@ uint32_t Sensor::getFlags() const {
}
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 @@ const Sensor::uuid_t& Sensor::getUuid() const {
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 85e96d6b84..5a369613ae 100644
--- a/services/sensorservice/Android.mk
+++ b/services/sensorservice/Android.mk
@@ -2,21 +2,22 @@ LOCAL_PATH:= $(call my-dir)
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 += -Wall -Werror -Wextra
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 $(BUILD_SHARED_LIBRARY)
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 a5d8456b38..0000000000
--- 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 68c1661611..0000000000
--- 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 0000000000..dba7211192
--- /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 0000000000..4f9bc4af1a
--- /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 0000000000..ec98a01413
--- /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 179b1c5f0f..4fbaa502d2 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -39,8 +39,7 @@ ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
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::handleDynamicSensorConnection(int handle, bool connected) {
}
}
-void SensorDevice::dump(String8& result)
-{
- if (!mSensorModule) return;
+std::string SensorDevice::dump() const {
+ if (!mSensorModule) return "HAL not initialized\n";
+
+ String8 result;
sensor_t const* list;
- ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
+ int count = mSensorModule->get_sensors_list(mSensorModule, &list);
- result.appendFormat("halVersion 0x%08x\n", getHalDeviceVersion());
- result.appendFormat("%d h/w sensors:\n", int(count));
+ 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 @@ void SensorDevice::autoDisable(void *ident, int handle) {
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 @@ status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplin
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 c12630a3fb..68bb853ac9 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 @@ class SensorDevice : public Singleton<SensorDevice> {
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 cb2422934a..73a6db5128 100644
--- a/services/sensorservice/SensorInterface.cpp
+++ b/services/sensorservice/SensorInterface.cpp
@@ -34,12 +34,21 @@ BaseSensor::BaseSensor(const sensor_t& sensor) :
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 d1cee41e84..dafcf2ddca 100644
--- a/services/sensorservice/SensorInterface.h
+++ b/services/sensorservice/SensorInterface.h
@@ -48,6 +48,7 @@ public:
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 @@ protected:
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 c23e21fb99..f6d3d9418c 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 @@ const Vector<Sensor> SensorList::getVirtualSensors() const {
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 @@ std::string SensorList::dump() const {
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 @@ std::string SensorList::dump() const {
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 ffde619ff2..8209d96815 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 @@ class SensorInterface;
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 @@ T SensorList::getOne(int handle, const TF& accessor, T def) const {
} // 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 b7a8740cea..6caa85bff8 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 @@ void SensorService::onFirstRef() {
(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 @@ void SensorService::onFirstRef() {
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 @@ const Sensor& SensorService::registerVirtualSensor(SensorInterface* s, bool isDe
}
SensorService::~SensorService() {
+ for (auto && entry : mRecentEvent) {
+ delete entry.second;
+ }
}
status_t SensorService::dump(int fd, const Vector<String16>& args) {
@@ -313,25 +316,25 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) {
} 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 @@ bool SensorService::threadLoop() {
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 @@ bool SensorService::threadLoop() {
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 @@ void SensorService::recordLastValueLocked(
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 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
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 @@ bool SensorService::isWhiteListedPackage(const String8& packageName) {
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 6473edbd6f..0d04478083 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 @@ private:
// nested class/struct for internal use
class SensorRecord;
class SensorEventAckReceiver;
- struct TrimmedSensorEvent;
- class MostRecentEventLogger;
struct SensorRegistrationInfo;
enum Mode {
@@ -155,7 +156,6 @@ private:
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 @@ private:
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 @@ private:
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 @@ private:
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 0000000000..1996a00ed7
--- /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 0000000000..1558feb75e
--- /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 cfdf6a38e5..186b60cb1e 100644
--- a/services/sensorservice/tests/sensorservicetest.cpp
+++ b/services/sensorservice/tests/sensorservicetest.cpp
@@ -62,7 +62,7 @@ int receiver(__unused int fd, __unused int events, void* data)
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);