diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-08-28 07:34:24 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-08-28 07:34:24 +0000 |
commit | 0de3b76a018a1674a80c4ed8a8b59ac2cdfdeaee (patch) | |
tree | 4dcb1d3c444c069be5fc15b4c8860d2abfdd9f17 | |
parent | 5d6c5fd2685b62a2f0ef3db029ecd8a6958e45d7 (diff) | |
parent | c49ff6febb721b79d19bbffa2ae04ce49fe12919 (diff) | |
download | contexthub-0de3b76a018a1674a80c4ed8a8b59ac2cdfdeaee.tar.gz |
release-request-c924aaac-f0a2-4215-8dc4-e314f22460d9-for-git_oc-mr1-release-4301796 snap-temp-L23200000097143969
Change-Id: I4c958bd4b7b999502074782752420833e6dbaa49
-rw-r--r-- | firmware/os/drivers/bosch_bmi160/bosch_bmi160.c | 14 | ||||
-rw-r--r-- | sensorhal/directchannel.cpp | 35 | ||||
-rw-r--r-- | sensorhal/directchannel.h | 9 | ||||
-rw-r--r-- | sensorhal/hubconnection.cpp | 323 | ||||
-rw-r--r-- | sensorhal/hubconnection.h | 18 | ||||
-rw-r--r-- | util/common/ring.cpp | 13 |
6 files changed, 303 insertions, 109 deletions
diff --git a/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c b/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c index 61c3d23a..e8d88422 100644 --- a/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c +++ b/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c @@ -107,7 +107,7 @@ #define DBG_WM_CALC 0 #define TIMESTAMP_DBG 0 -#define BMI160_APP_VERSION 15 +#define BMI160_APP_VERSION 16 // fixme: to list required definitions for a slave mag #ifdef USE_BMM150 @@ -4203,10 +4203,10 @@ static size_t calcFifoSize(const int* iPeriod, const int* iLatency, const int* f for (i = 0; i < n; i++) { if (iPeriod[i] > 0) { anyActive = true; - size_t t = minLatency / iPeriod[i]; + size_t t = minLatency / iPeriod[i]; head = t > head ? t : head; s += t * factor[i]; - DEBUG_PRINT_IF(DBG_WM_CALC, "cfifo: %d, s+= %d*%d, head = %d", i, t, factor[i], head); + DEBUG_PRINT_IF(DBG_WM_CALC, "cfifo %d: s += %d * %d, head = %d", i, t, factor[i], head); } } @@ -4216,7 +4216,7 @@ static size_t calcFifoSize(const int* iPeriod, const int* iLatency, const int* f /** * Calculate the watermark setting from sensor registration information * - * It is assumed that all sensor period share a common denominator (true for BMI160) and the + * It is assumed that all sensor periods share a common denominator (true for BMI160) and the * latency of sensor will be lower bounded by its sampling period. * * @return watermark register setting @@ -4228,12 +4228,12 @@ static uint8_t calcWatermark2_(TASK) { int i; for (i = FIRST_CONT_SENSOR; i < NUM_CONT_SENSOR; ++i) { - if (T(sensors[i]).configed) { + if (T(sensors[i]).configed && T(sensors[i]).latency != SENSOR_LATENCY_NODATA) { period[i - ACC] = SENSOR_HZ((float)WATERMARK_MAX_SENSOR_RATE) / T(sensors[i]).rate; latency[i - ACC] = U64_DIV_BY_U64_CONSTANT( T(sensors[i]).latency + WATERMARK_TIME_UNIT_NS/2, WATERMARK_TIME_UNIT_NS); - DEBUG_PRINT_IF(DBG_WM_CALC, "cwm2: f %dHz, l %dus => T %d unit, L %d unit", - (int) T(sensors[i]).rate/1024, + DEBUG_PRINT_IF(DBG_WM_CALC, "cwm2 %d: f %dHz, l %dus => T %d unit, L %d unit", + i, (int) T(sensors[i]).rate/1024, (int) U64_DIV_BY_U64_CONSTANT(T(sensors[i]).latency, 1000), period[i-ACC], latency[i-ACC]); } diff --git a/sensorhal/directchannel.cpp b/sensorhal/directchannel.cpp index 8d87782d..b0df24c8 100644 --- a/sensorhal/directchannel.cpp +++ b/sensorhal/directchannel.cpp @@ -74,6 +74,10 @@ AshmemDirectChannel::~AshmemDirectChannel() { ::close(mAshmemFd); } +bool AshmemDirectChannel::memoryMatches(const struct sensors_direct_mem_t * /*mem*/) const { + return false; +} + ANDROID_SINGLETON_STATIC_INSTANCE(GrallocHalWrapper); GrallocHalWrapper::GrallocHalWrapper() @@ -128,10 +132,15 @@ GrallocHalWrapper::GrallocHalWrapper() GRALLOC1_FUNCTION_LOCK)); mPfnUnlock = (GRALLOC1_PFN_UNLOCK)(mGralloc1Device->getFunction(mGralloc1Device, GRALLOC1_FUNCTION_UNLOCK)); + mPfnGetBackingStore = (GRALLOC1_PFN_GET_BACKING_STORE) + (mGralloc1Device->getFunction(mGralloc1Device, + GRALLOC1_FUNCTION_GET_BACKING_STORE)); if (mPfnRetain == nullptr || mPfnRelease == nullptr - || mPfnLock == nullptr || mPfnUnlock == nullptr) { - ALOGE("Function pointer for retain, release, lock and unlock are %p, %p, %p, %p", - mPfnRetain, mPfnRelease, mPfnLock, mPfnUnlock); + || mPfnLock == nullptr || mPfnUnlock == nullptr + || mPfnGetBackingStore == nullptr) { + ALOGE("Function pointer for retain, release, lock, unlock and getBackingStore are " + "%p, %p, %p, %p, %p", + mPfnRetain, mPfnRelease, mPfnLock, mPfnUnlock, mPfnGetBackingStore); err = BAD_VALUE; break; } @@ -223,6 +232,21 @@ int GrallocHalWrapper::unlock(const native_handle_t *handle) { } } +bool GrallocHalWrapper::isSameMemory(const native_handle_t *h1, const native_handle_t *h2) { + switch (mVersion) { + case 0: + return false; // version 1.0 cannot compare two memory + case 1: { + gralloc1_backing_store_t s1, s2; + + return mPfnGetBackingStore(mGralloc1Device, h1, &s1) == GRALLOC1_ERROR_NONE + && mPfnGetBackingStore(mGralloc1Device, h2, &s2) == GRALLOC1_ERROR_NONE + && s1 == s2; + } + } + return false; +} + int GrallocHalWrapper::mapGralloc1Error(int grallocError) { switch (grallocError) { case GRALLOC1_ERROR_NONE: @@ -302,4 +326,9 @@ GrallocDirectChannel::~GrallocDirectChannel() { } } +bool GrallocDirectChannel::memoryMatches(const struct sensors_direct_mem_t *mem) const { + return mem->type == SENSOR_DIRECT_MEM_TYPE_GRALLOC && + GrallocHalWrapper::getInstance().isSameMemory(mem->handle, mNativeHandle); +} + } // namespace android diff --git a/sensorhal/directchannel.h b/sensorhal/directchannel.h index 4842ffcc..70d86456 100644 --- a/sensorhal/directchannel.h +++ b/sensorhal/directchannel.h @@ -31,6 +31,7 @@ class DirectChannelBase { public: DirectChannelBase() : mError(NO_INIT), mSize(0), mBase(nullptr) { } virtual ~DirectChannelBase() {} + virtual bool memoryMatches(const struct sensors_direct_mem_t *mem) const = 0; bool isValid(); int getError(); @@ -47,7 +48,8 @@ protected: class AshmemDirectChannel : public DirectChannelBase { public: AshmemDirectChannel(const struct sensors_direct_mem_t *mem); - virtual ~AshmemDirectChannel(); + ~AshmemDirectChannel() override; + bool memoryMatches(const struct sensors_direct_mem_t *mem) const override; private: int mAshmemFd; }; @@ -58,6 +60,7 @@ public: int unregisterBuffer(const native_handle_t *handle); int lock(const native_handle_t *handle, int usage, int l, int t, int w, int h, void **vaddr); int unlock(const native_handle_t *handle); + bool isSameMemory(const native_handle_t *h1, const native_handle_t *h2); bool unregisterImplyDelete() { return mUnregisterImplyDelete; } private: friend class Singleton<GrallocHalWrapper>; @@ -77,13 +80,15 @@ private: GRALLOC1_PFN_RELEASE mPfnRelease; GRALLOC1_PFN_LOCK mPfnLock; GRALLOC1_PFN_UNLOCK mPfnUnlock; + GRALLOC1_PFN_GET_BACKING_STORE mPfnGetBackingStore; bool mUnregisterImplyDelete; }; class GrallocDirectChannel : public DirectChannelBase { public: GrallocDirectChannel(const struct sensors_direct_mem_t *mem); - virtual ~GrallocDirectChannel(); + ~GrallocDirectChannel() override; + bool memoryMatches(const struct sensors_direct_mem_t *mem) const override; private: native_handle_t *mNativeHandle; }; diff --git a/sensorhal/hubconnection.cpp b/sensorhal/hubconnection.cpp index 42366c47..01b95df4 100644 --- a/sensorhal/hubconnection.cpp +++ b/sensorhal/hubconnection.cpp @@ -277,9 +277,18 @@ HubConnection::HubConnection() #ifdef DIRECT_REPORT_ENABLED mDirectChannelHandle = 1; - mSensorToChannel.emplace(COMMS_SENSOR_ACCEL, std::unordered_map<int32_t, int32_t>()); - mSensorToChannel.emplace(COMMS_SENSOR_GYRO, std::unordered_map<int32_t, int32_t>()); - mSensorToChannel.emplace(COMMS_SENSOR_MAG, std::unordered_map<int32_t, int32_t>()); + mSensorToChannel.emplace(COMMS_SENSOR_ACCEL, + std::unordered_map<int32_t, DirectChannelTimingInfo>()); + mSensorToChannel.emplace(COMMS_SENSOR_GYRO, + std::unordered_map<int32_t, DirectChannelTimingInfo>()); + mSensorToChannel.emplace(COMMS_SENSOR_MAG, + std::unordered_map<int32_t, DirectChannelTimingInfo>()); + mSensorToChannel.emplace(COMMS_SENSOR_ACCEL_UNCALIBRATED, + std::unordered_map<int32_t, DirectChannelTimingInfo>()); + mSensorToChannel.emplace(COMMS_SENSOR_GYRO_UNCALIBRATED, + std::unordered_map<int32_t, DirectChannelTimingInfo>()); + mSensorToChannel.emplace(COMMS_SENSOR_MAG_UNCALIBRATED, + std::unordered_map<int32_t, DirectChannelTimingInfo>()); #endif // DIRECT_REPORT_ENABLED } @@ -736,25 +745,30 @@ void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t se sv->y = sample->iy * mScaleAccel; sv->z = sample->iz * mScaleAccel; sv->status = SENSOR_STATUS_ACCURACY_HIGH; - sendDirectReportEvent(&nev[cnt], 1); - if (mSensorState[sensor].enable) { + sendDirectReportEvent(&nev[cnt], 1); + if (mSensorState[sensor].enable && isSampleIntervalSatisfied(sensor, timestamp)) { ++cnt; } - if (mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].enable) { - ue = &initEv(&nev[cnt++], timestamp, - SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED, - COMMS_SENSOR_ACCEL_UNCALIBRATED)->uncalibrated_accelerometer; - ue->x_uncalib = sample->ix * mScaleAccel + mAccelBias[0]; - ue->y_uncalib = sample->iy * mScaleAccel + mAccelBias[1]; - ue->z_uncalib = sample->iz * mScaleAccel + mAccelBias[2]; - ue->x_bias = mAccelBias[0]; - ue->y_bias = mAccelBias[1]; - ue->z_bias = mAccelBias[2]; + ue = &initEv(&nev[cnt], timestamp, + SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED, + COMMS_SENSOR_ACCEL_UNCALIBRATED)->uncalibrated_accelerometer; + ue->x_uncalib = sample->ix * mScaleAccel + mAccelBias[0]; + ue->y_uncalib = sample->iy * mScaleAccel + mAccelBias[1]; + ue->z_uncalib = sample->iz * mScaleAccel + mAccelBias[2]; + ue->x_bias = mAccelBias[0]; + ue->y_bias = mAccelBias[1]; + ue->z_bias = mAccelBias[2]; + + sendDirectReportEvent(&nev[cnt], 1); + if (mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].enable + && isSampleIntervalSatisfied(COMMS_SENSOR_ACCEL_UNCALIBRATED, timestamp)) { + ++cnt; } - if (mSensorState[COMMS_SENSOR_ACCEL_WRIST_AWARE].enable) { + if (mSensorState[COMMS_SENSOR_ACCEL_WRIST_AWARE].enable + && isSampleIntervalSatisfied(COMMS_SENSOR_ACCEL_WRIST_AWARE, timestamp)) { sv = &initEv(&nev[cnt++], timestamp, SENSOR_TYPE_ACCELEROMETER_WRIST_AWARE, COMMS_SENSOR_ACCEL_WRIST_AWARE)->acceleration; @@ -770,22 +784,26 @@ void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t se sv->y = sample->iy * mScaleMag; sv->z = sample->iz * mScaleMag; sv->status = magAccuracyUpdate(sv); - sendDirectReportEvent(&nev[cnt], 1); - if (mSensorState[sensor].enable) { + sendDirectReportEvent(&nev[cnt], 1); + if (mSensorState[sensor].enable && isSampleIntervalSatisfied(sensor, timestamp)) { ++cnt; } - if (mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].enable) { - ue = &initEv(&nev[cnt++], timestamp, - SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, - COMMS_SENSOR_MAG_UNCALIBRATED)->uncalibrated_magnetic; - ue->x_uncalib = sample->ix * mScaleMag + mMagBias[0]; - ue->y_uncalib = sample->iy * mScaleMag + mMagBias[1]; - ue->z_uncalib = sample->iz * mScaleMag + mMagBias[2]; - ue->x_bias = mMagBias[0]; - ue->y_bias = mMagBias[1]; - ue->z_bias = mMagBias[2]; + ue = &initEv(&nev[cnt], timestamp, + SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, + COMMS_SENSOR_MAG_UNCALIBRATED)->uncalibrated_magnetic; + ue->x_uncalib = sample->ix * mScaleMag + mMagBias[0]; + ue->y_uncalib = sample->iy * mScaleMag + mMagBias[1]; + ue->z_uncalib = sample->iz * mScaleMag + mMagBias[2]; + ue->x_bias = mMagBias[0]; + ue->y_bias = mMagBias[1]; + ue->z_bias = mMagBias[2]; + + sendDirectReportEvent(&nev[cnt], 1); + if (mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].enable + && isSampleIntervalSatisfied(COMMS_SENSOR_MAG_UNCALIBRATED, timestamp)) { + ++cnt; } default: break; @@ -815,32 +833,38 @@ void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t se sv->y = sample->y; sv->z = sample->z; sv->status = SENSOR_STATUS_ACCURACY_HIGH; - sendDirectReportEvent(&nev[cnt], 1); - if (mSensorState[sensor].enable) { + sendDirectReportEvent(&nev[cnt], 1); + if (mSensorState[sensor].enable && isSampleIntervalSatisfied(sensor, timestamp)) { ++cnt; } - if (mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].enable) { - ue = &initEv(&nev[cnt++], timestamp, - SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED, - COMMS_SENSOR_ACCEL_UNCALIBRATED)->uncalibrated_accelerometer; - ue->x_uncalib = sample->x + mAccelBias[0]; - ue->y_uncalib = sample->y + mAccelBias[1]; - ue->z_uncalib = sample->z + mAccelBias[2]; - ue->x_bias = mAccelBias[0]; - ue->y_bias = mAccelBias[1]; - ue->z_bias = mAccelBias[2]; + ue = &initEv(&nev[cnt], timestamp, + SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED, + COMMS_SENSOR_ACCEL_UNCALIBRATED)->uncalibrated_accelerometer; + ue->x_uncalib = sample->x + mAccelBias[0]; + ue->y_uncalib = sample->y + mAccelBias[1]; + ue->z_uncalib = sample->z + mAccelBias[2]; + ue->x_bias = mAccelBias[0]; + ue->y_bias = mAccelBias[1]; + ue->z_bias = mAccelBias[2]; + + sendDirectReportEvent(&nev[cnt], 1); + if (mSensorState[COMMS_SENSOR_ACCEL_UNCALIBRATED].enable + && isSampleIntervalSatisfied(COMMS_SENSOR_ACCEL_UNCALIBRATED, timestamp)) { + ++cnt; } - if (mSensorState[COMMS_SENSOR_ACCEL_WRIST_AWARE].enable) { - sv = &initEv(&nev[cnt++], timestamp, + if (mSensorState[COMMS_SENSOR_ACCEL_WRIST_AWARE].enable + && isSampleIntervalSatisfied(COMMS_SENSOR_ACCEL_WRIST_AWARE, timestamp)) { + sv = &initEv(&nev[cnt], timestamp, SENSOR_TYPE_ACCELEROMETER_WRIST_AWARE, COMMS_SENSOR_ACCEL_WRIST_AWARE)->acceleration; sv->x = sample->x; sv->y = (mLefty.accel ? -sample->y : sample->y); sv->z = sample->z; sv->status = SENSOR_STATUS_ACCURACY_HIGH; + ++cnt; } break; case COMMS_SENSOR_GYRO: @@ -849,32 +873,38 @@ void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t se sv->y = sample->y; sv->z = sample->z; sv->status = SENSOR_STATUS_ACCURACY_HIGH; - sendDirectReportEvent(&nev[cnt], 1); - if (mSensorState[sensor].enable) { + sendDirectReportEvent(&nev[cnt], 1); + if (mSensorState[sensor].enable && isSampleIntervalSatisfied(sensor, timestamp)) { ++cnt; } - if (mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].enable) { - ue = &initEv(&nev[cnt++], timestamp, - SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, - COMMS_SENSOR_GYRO_UNCALIBRATED)->uncalibrated_gyro; - ue->x_uncalib = sample->x + mGyroBias[0]; - ue->y_uncalib = sample->y + mGyroBias[1]; - ue->z_uncalib = sample->z + mGyroBias[2]; - ue->x_bias = mGyroBias[0]; - ue->y_bias = mGyroBias[1]; - ue->z_bias = mGyroBias[2]; + ue = &initEv(&nev[cnt], timestamp, + SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, + COMMS_SENSOR_GYRO_UNCALIBRATED)->uncalibrated_gyro; + ue->x_uncalib = sample->x + mGyroBias[0]; + ue->y_uncalib = sample->y + mGyroBias[1]; + ue->z_uncalib = sample->z + mGyroBias[2]; + ue->x_bias = mGyroBias[0]; + ue->y_bias = mGyroBias[1]; + ue->z_bias = mGyroBias[2]; + sendDirectReportEvent(&nev[cnt], 1); + + if (mSensorState[COMMS_SENSOR_GYRO_UNCALIBRATED].enable + && isSampleIntervalSatisfied(COMMS_SENSOR_GYRO_UNCALIBRATED, timestamp)) { + ++cnt; } - if (mSensorState[COMMS_SENSOR_GYRO_WRIST_AWARE].enable) { - sv = &initEv(&nev[cnt++], timestamp, + if (mSensorState[COMMS_SENSOR_GYRO_WRIST_AWARE].enable + && isSampleIntervalSatisfied(COMMS_SENSOR_GYRO_WRIST_AWARE, timestamp)) { + sv = &initEv(&nev[cnt], timestamp, SENSOR_TYPE_GYROSCOPE_WRIST_AWARE, COMMS_SENSOR_GYRO_WRIST_AWARE)->gyro; sv->x = (mLefty.gyro ? -sample->x : sample->x); sv->y = sample->y; sv->z = (mLefty.gyro ? -sample->z : sample->z); sv->status = SENSOR_STATUS_ACCURACY_HIGH; + ++cnt; } break; case COMMS_SENSOR_ACCEL_BIAS: @@ -897,20 +927,24 @@ void HubConnection::processSample(uint64_t timestamp, uint32_t type, uint32_t se sv->status = magAccuracyUpdate(sv); sendDirectReportEvent(&nev[cnt], 1); - if (mSensorState[sensor].enable) { + if (mSensorState[sensor].enable && isSampleIntervalSatisfied(sensor, timestamp)) { ++cnt; } - if (mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].enable) { - ue = &initEv(&nev[cnt++], timestamp, - SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, - COMMS_SENSOR_MAG_UNCALIBRATED)->uncalibrated_magnetic; - ue->x_uncalib = sample->x + mMagBias[0]; - ue->y_uncalib = sample->y + mMagBias[1]; - ue->z_uncalib = sample->z + mMagBias[2]; - ue->x_bias = mMagBias[0]; - ue->y_bias = mMagBias[1]; - ue->z_bias = mMagBias[2]; + ue = &initEv(&nev[cnt], timestamp, + SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, + COMMS_SENSOR_MAG_UNCALIBRATED)->uncalibrated_magnetic; + ue->x_uncalib = sample->x + mMagBias[0]; + ue->y_uncalib = sample->y + mMagBias[1]; + ue->z_uncalib = sample->z + mMagBias[2]; + ue->x_bias = mMagBias[0]; + ue->y_bias = mMagBias[1]; + ue->z_bias = mMagBias[2]; + sendDirectReportEvent(&nev[cnt], 1); + + if (mSensorState[COMMS_SENSOR_MAG_UNCALIBRATED].enable + && isSampleIntervalSatisfied(COMMS_SENSOR_MAG_UNCALIBRATED, timestamp)) { + ++cnt; } break; case COMMS_SENSOR_MAG_BIAS: @@ -1404,6 +1438,9 @@ ssize_t HubConnection::processBuf(uint8_t *buf, size_t len) ev.sensor = 0; ev.meta_data.what = META_DATA_FLUSH_COMPLETE; ev.meta_data.sensor = flush.handle; + if (mSensorState[flush.handle].enable) { + updateSampleRate(flush.handle, CONFIG_CMD_FLUSH); + } if (flush.internal) { if (flush.handle == COMMS_SENSOR_ACCEL_WRIST_AWARE) @@ -1657,9 +1694,11 @@ void HubConnection::queueActivate(int handle, bool enable) initConfigCmd(&cmd, handle); ret = TEMP_FAILURE_RETRY(::write(mFd, &cmd, sizeof(cmd))); - if (ret == sizeof(cmd)) + if (ret == sizeof(cmd)) { + updateSampleRate(handle, enable ? CONFIG_CMD_ENABLE : CONFIG_CMD_DISABLE); ALOGV("queueActivate: sensor=%d, handle=%d, enable=%d", cmd.sensorType, handle, enable); + } else ALOGW("queueActivate: failed to send command: sensor=%d, handle=%d, enable=%d", cmd.sensorType, handle, enable); @@ -1971,7 +2010,14 @@ void HubConnection::sendDirectReportEvent(const sensors_event_t *nev, size_t n) auto i = mSensorToChannel.find(nev->sensor); if (i != mSensorToChannel.end()) { for (auto &j : i->second) { - mDirectChannel[j.first]->write(nev); + if ((uint64_t)nev->timestamp > j.second.lastTimestamp + && intervalLargeEnough( + nev->timestamp - j.second.lastTimestamp, + rateLevelToDeviceSamplingPeriodNs( + nev->sensor, j.second.rateLevel))) { + mDirectChannel[j.first]->write(nev); + j.second.lastTimestamp = nev->timestamp; + } } } ++nev; @@ -1981,35 +2027,31 @@ void HubConnection::sendDirectReportEvent(const sensors_event_t *nev, size_t n) } void HubConnection::mergeDirectReportRequest(struct ConfigCmd *cmd, int handle) { + int maxRateLevel = SENSOR_DIRECT_RATE_STOP; + auto j = mSensorToChannel.find(handle); if (j != mSensorToChannel.end()) { - bool enable = false; - rate_q10_t rate; - - if (!j->second.empty()) { - int maxRateLevel = SENSOR_DIRECT_RATE_STOP; + for (auto &i : j->second) { + maxRateLevel = std::max(i.second.rateLevel, maxRateLevel); + } + } + for (auto handle : mSensorState[handle].alt) { + auto j = mSensorToChannel.find(handle); + if (j != mSensorToChannel.end()) { for (auto &i : j->second) { - maxRateLevel = (i.second) > maxRateLevel ? i.second : maxRateLevel; - } - switch(maxRateLevel) { - case SENSOR_DIRECT_RATE_NORMAL: - enable = true; - rate = period_ns_to_frequency_q10(20000000ull); // NORMAL = 50Hz - break; - case SENSOR_DIRECT_RATE_FAST: - enable = true; - rate = period_ns_to_frequency_q10(5000000ull); // FAST = 200Hz - break; - default: - break; + maxRateLevel = std::max(i.second.rateLevel, maxRateLevel); } } + } - if (enable) { - cmd->rate = (rate > cmd->rate || cmd->cmd == CONFIG_CMD_DISABLE) ? rate : cmd->rate; - cmd->latency = 0; - cmd->cmd = CONFIG_CMD_ENABLE; - } + uint64_t period = rateLevelToDeviceSamplingPeriodNs(handle, maxRateLevel); + if (period != INT64_MAX) { + rate_q10_t rate; + rate = period_ns_to_frequency_q10(period); + + cmd->rate = (rate > cmd->rate || cmd->cmd == CONFIG_CMD_DISABLE) ? rate : cmd->rate; + cmd->latency = 0; + cmd->cmd = CONFIG_CMD_ENABLE; } } @@ -2017,6 +2059,13 @@ int HubConnection::addDirectChannel(const struct sensors_direct_mem_t *mem) { std::unique_ptr<DirectChannelBase> ch; int ret = NO_MEMORY; + Mutex::Autolock autoLock(mDirectChannelLock); + for (const auto& c : mDirectChannel) { + if (c.second->memoryMatches(mem)) { + // cannot reusing same memory + return BAD_VALUE; + } + } switch(mem->type) { case SENSOR_DIRECT_MEM_TYPE_ASHMEM: ch = std::make_unique<AshmemDirectChannel>(mem); @@ -2030,7 +2079,6 @@ int HubConnection::addDirectChannel(const struct sensors_direct_mem_t *mem) { if (ch) { if (ch->isValid()) { - Mutex::Autolock autoLock(mDirectChannelLock); ret = mDirectChannelHandle++; mDirectChannel.insert(std::make_pair(ret, std::move(ch))); } else { @@ -2126,7 +2174,7 @@ int HubConnection::configDirectReport(int sensor_handle, int channel_handle, int j->second.erase(channel_handle); if (rate_level != SENSOR_DIRECT_RATE_STOP) { - j->second.insert(std::make_pair(channel_handle, rate_level)); + j->second.insert(std::make_pair(channel_handle, (DirectChannelTimingInfo){0, rate_level})); } Mutex::Autolock autoLock2(mLock); @@ -2146,6 +2194,86 @@ int HubConnection::configDirectReport(int sensor_handle, int channel_handle, int bool HubConnection::isDirectReportSupported() const { return true; } + +void HubConnection::updateSampleRate(int handle, int reason) { + bool affected = mSensorToChannel.find(handle) != mSensorToChannel.end(); + for (size_t i = 0; i < MAX_ALTERNATES && !affected; ++i) { + if (mSensorState[handle].alt[i] != COMMS_SENSOR_INVALID) { + affected |= + mSensorToChannel.find(mSensorState[handle].alt[i]) != mSensorToChannel.end(); + } + } + if (!affected) { + return; + } + + switch (reason) { + case CONFIG_CMD_ENABLE: + // filter out duplicated enable + if (mSensorState[handle].desiredTSample != INT64_MAX) { + break; + } + // fall through + case CONFIG_CMD_FLUSH: { + constexpr uint64_t PERIOD_800HZ = 1250000; + uint64_t period_multiplier = + (frequency_q10_to_period_ns(mSensorState[handle].rate) + PERIOD_800HZ / 2) + / PERIOD_800HZ; + uint64_t desiredTSample = PERIOD_800HZ; + while (period_multiplier /= 2) { + desiredTSample *= 2; + } + mSensorState[handle].desiredTSample = desiredTSample; + ALOGV("DesiredTSample for handle 0x%x set to %" PRIu64, handle, desiredTSample); + break; + } + case CONFIG_CMD_DISABLE: + mSensorState[handle].desiredTSample = INT64_MAX; + ALOGV("DesiredTSample 0x%x set to disable", handle); + break; + default: + ALOGW("%s: unexpected reason = %d, no-op", __FUNCTION__, reason); + break; + } +} + +bool HubConnection::isSampleIntervalSatisfied(int handle, uint64_t timestamp) { + if (mSensorToChannel.find(handle) == mSensorToChannel.end()) { + return true; + } + + if (mSensorState[handle].lastTimestamp >= timestamp + || mSensorState[handle].desiredTSample == INT64_MAX) { + return false; + } else if (intervalLargeEnough(timestamp - mSensorState[handle].lastTimestamp, + mSensorState[handle].desiredTSample)) { + mSensorState[handle].lastTimestamp = timestamp; + return true; + } else { + return false; + } +} + +uint64_t HubConnection::rateLevelToDeviceSamplingPeriodNs(int handle, int rateLevel) const { + if (mSensorToChannel.find(handle) == mSensorToChannel.end()) { + return INT64_MAX; + } + + switch (rateLevel) { + case SENSOR_DIRECT_RATE_VERY_FAST: + // No sensor support VERY_FAST, fall through + case SENSOR_DIRECT_RATE_FAST: + if (handle != COMMS_SENSOR_MAG && handle != COMMS_SENSOR_MAG_UNCALIBRATED) { + return 2500*1000; // 400Hz + } + // fall through + case SENSOR_DIRECT_RATE_NORMAL: + return 20*1000*1000; // 50 Hz + // fall through + default: + return INT64_MAX; + } +} #else // DIRECT_REPORT_ENABLED // nop functions if feature is turned off int HubConnection::addDirectChannel(const struct sensors_direct_mem_t *) { @@ -2169,6 +2297,13 @@ void HubConnection::mergeDirectReportRequest(struct ConfigCmd *, int) { bool HubConnection::isDirectReportSupported() const { return false; } + +void HubConnection::updateSampleRate(int, int) { +} + +bool HubConnection::isSampleIntervalSatisfied(int, uint64_t) { + return true; +} #endif // DIRECT_REPORT_ENABLED } // namespace android diff --git a/sensorhal/hubconnection.h b/sensorhal/hubconnection.h index 3f0a4f9c..7be18aec 100644 --- a/sensorhal/hubconnection.h +++ b/sensorhal/hubconnection.h @@ -173,6 +173,8 @@ private: struct SensorState { uint64_t latency; + uint64_t lastTimestamp; + uint64_t desiredTSample; rate_q10_t rate; uint8_t sensorType; uint8_t primary; @@ -329,12 +331,24 @@ public: private: void sendDirectReportEvent(const sensors_event_t *nev, size_t n); void mergeDirectReportRequest(struct ConfigCmd *cmd, int handle); + bool isSampleIntervalSatisfied(int handle, uint64_t timestamp); + void updateSampleRate(int handle, int reason); #ifdef DIRECT_REPORT_ENABLED int stopAllDirectReportOnChannel( int channel_handle, std::vector<int32_t> *unstoppedSensors); + uint64_t rateLevelToDeviceSamplingPeriodNs(int handle, int rateLevel) const; + inline static bool intervalLargeEnough(uint64_t actual, uint64_t desired) { + return (actual + (actual >> 4)) >= desired; // >= 94.11% of desired + } + + struct DirectChannelTimingInfo{ + uint64_t lastTimestamp; + int rateLevel; + }; Mutex mDirectChannelLock; - //sensor_handle=>(channel_handle, rate_level) - std::unordered_map<int32_t, std::unordered_map<int32_t, int32_t> > mSensorToChannel; + //sensor_handle=>(channel_handle => DirectChannelTimingInfo) + std::unordered_map<int32_t, + std::unordered_map<int32_t, DirectChannelTimingInfo> > mSensorToChannel; //channel_handle=>ptr of Channel obj std::unordered_map<int32_t, std::unique_ptr<DirectChannelBase>> mDirectChannel; int32_t mDirectChannelHandle; diff --git a/util/common/ring.cpp b/util/common/ring.cpp index 26d44d62..245f3d03 100644 --- a/util/common/ring.cpp +++ b/util/common/ring.cpp @@ -22,6 +22,7 @@ #include <stdlib.h> #include <string.h> +#include <atomic> namespace android { @@ -120,8 +121,18 @@ void LockfreeBuffer::write(const sensors_event_t *ev, size_t size) { } while(size--) { - mData[mWritePos] = *(ev++); + // part before reserved0 field + memcpy(&mData[mWritePos], ev, offsetof(sensors_event_t, reserved0)); + // part after reserved0 field + memcpy(reinterpret_cast<char *>(&mData[mWritePos]) + offsetof(sensors_event_t, timestamp), + reinterpret_cast<const char *>(ev) + offsetof(sensors_event_t, timestamp), + sizeof(sensors_event_t) - offsetof(sensors_event_t, timestamp)); + // barrier before writing the atomic counter + std::atomic_thread_fence(std::memory_order_release); mData[mWritePos].reserved0 = mCounter++; + // barrier after writing the atomic counter + std::atomic_thread_fence(std::memory_order_release); + ++ev; if (++mWritePos >= mSize) { mWritePos = 0; |