diff options
author | 2015-12-21 12:00:23 -0800 | |
---|---|---|
committer | 2016-04-22 21:54:56 -0700 | |
commit | 6a2d3a06caa337857cf60cfc70a9a78909ad3608 (patch) | |
tree | 86e855d09c2bd6884f86d8aaf85bfec9ba89ae05 | |
parent | 151cc4a91a92447a78a964bf1164b50ac8921f65 (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.h | 13 | ||||
-rw-r--r-- | libs/gui/Sensor.cpp | 134 | ||||
-rw-r--r-- | services/sensorservice/Android.mk | 37 | ||||
-rw-r--r-- | services/sensorservice/MostRecentEventLogger.cpp | 125 | ||||
-rw-r--r-- | services/sensorservice/MostRecentEventLogger.h | 71 | ||||
-rw-r--r-- | services/sensorservice/RecentEventLogger.cpp | 98 | ||||
-rw-r--r-- | services/sensorservice/RecentEventLogger.h | 68 | ||||
-rw-r--r-- | services/sensorservice/RingBuffer.h | 361 | ||||
-rw-r--r-- | services/sensorservice/SensorDevice.cpp | 43 | ||||
-rw-r--r-- | services/sensorservice/SensorDevice.h | 49 | ||||
-rw-r--r-- | services/sensorservice/SensorInterface.cpp | 9 | ||||
-rw-r--r-- | services/sensorservice/SensorInterface.h | 2 | ||||
-rw-r--r-- | services/sensorservice/SensorList.cpp | 35 | ||||
-rw-r--r-- | services/sensorservice/SensorList.h | 17 | ||||
-rw-r--r-- | services/sensorservice/SensorService.cpp | 103 | ||||
-rw-r--r-- | services/sensorservice/SensorService.h | 14 | ||||
-rw-r--r-- | services/sensorservice/SensorServiceUtils.cpp | 65 | ||||
-rw-r--r-- | services/sensorservice/SensorServiceUtils.h | 38 | ||||
-rw-r--r-- | services/sensorservice/tests/sensorservicetest.cpp | 2 |
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); |