diff options
Diffstat (limited to 'services/sensorservice/SensorEventConnection.cpp')
-rw-r--r-- | services/sensorservice/SensorEventConnection.cpp | 133 |
1 files changed, 124 insertions, 9 deletions
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp index 6c8671289d..9ce8d9bb18 100644 --- a/services/sensorservice/SensorEventConnection.cpp +++ b/services/sensorservice/SensorEventConnection.cpp @@ -29,16 +29,24 @@ #define UNUSED(x) (void)(x) namespace android { +namespace { + +// Used as the default value for the target SDK until it's obtained via getTargetSdkVersion. +constexpr int kTargetSdkUnknown = 0; + +} // namespace SensorService::SensorEventConnection::SensorEventConnection( const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode, - const String16& opPackageName) + const String16& opPackageName, const String16& attributionTag) : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false), mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(nullptr), mCacheSize(0), mMaxCacheSize(0), mTimeOfLastEventDrop(0), mEventsDropped(0), - mPackageName(packageName), mOpPackageName(opPackageName), mDestroyed(false) { + mPackageName(packageName), mOpPackageName(opPackageName), mAttributionTag(attributionTag), + mTargetSdk(kTargetSdkUnknown), mDestroyed(false) { + mIsRateCappedBasedOnPermission = mService->isRateCappedBasedOnPermission(mOpPackageName); + mUserId = multiuser_get_user_id(mUid); mChannel = new BitTube(mService->mSocketBufferSize); - mTargetSdk = SensorService::getTargetSdkVersion(opPackageName); #if DEBUG_CONNECTIONS mEventsReceived = mEventsSentFromCache = mEventsSent = 0; mTotalAcksNeeded = mTotalAcksReceived = 0; @@ -155,7 +163,7 @@ bool SensorService::SensorEventConnection::addSensor(int32_t handle) { Mutex::Autolock _l(mConnectionLock); sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle); if (si == nullptr || - !canAccessSensor(si->getSensor(), "Tried adding", mOpPackageName) || + !canAccessSensor(si->getSensor(), "Add to SensorEventConnection: ", mOpPackageName) || mSensorInfo.count(handle) > 0) { return false; } @@ -439,6 +447,14 @@ bool SensorService::SensorEventConnection::noteOpIfRequired(const sensors_event_ bool success = true; const auto iter = mHandleToAppOp.find(event.sensor); if (iter != mHandleToAppOp.end()) { + if (mTargetSdk == kTargetSdkUnknown) { + // getTargetSdkVersion returns -1 if it fails so this operation should only be run once + // per connection and then cached. Perform this here as opposed to in the constructor to + // avoid log spam for NDK/VNDK clients that don't use sensors guarded with permissions + // and pass in invalid op package names. + mTargetSdk = SensorService::getTargetSdkVersion(mOpPackageName); + } + // Special handling for step count/detect backwards compatibility: if the app's target SDK // is pre-Q, still permit delivering events to the app even if permission isn't granted // (since this permission was only introduced in Q) @@ -446,8 +462,13 @@ bool SensorService::SensorEventConnection::noteOpIfRequired(const sensors_event_ mTargetSdk > 0 && mTargetSdk <= __ANDROID_API_P__) { success = true; } else { + int32_t sensorHandle = event.sensor; + String16 noteMsg("Sensor event ("); + noteMsg.append(String16(mService->getSensorStringType(sensorHandle))); + noteMsg.append(String16(")")); int32_t appOpMode = mService->sAppOpsManager.noteOp(iter->second, mUid, - mOpPackageName); + mOpPackageName, mAttributionTag, + noteMsg); success = (appOpMode == AppOpsManager::MODE_ALLOWED); } } @@ -666,24 +687,118 @@ status_t SensorService::SensorEventConnection::enableDisable( status_t err; if (enabled) { + nsecs_t requestedSamplingPeriodNs = samplingPeriodNs; + bool isSensorCapped = false; + sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle); + if (si != nullptr) { + const Sensor& s = si->getSensor(); + if (mService->isSensorInCappedSet(s.getType())) { + isSensorCapped = true; + } + } + if (isSensorCapped) { + err = mService->adjustSamplingPeriodBasedOnMicAndPermission(&samplingPeriodNs, + String16(mOpPackageName)); + if (err != OK) { + return err; + } + } err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs, reservedFlags, mOpPackageName); + if (err == OK && isSensorCapped) { + if (!mIsRateCappedBasedOnPermission || + requestedSamplingPeriodNs >= SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) { + mMicSamplingPeriodBackup[handle] = requestedSamplingPeriodNs; + } else { + mMicSamplingPeriodBackup[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS; + } + } } else { err = mService->disable(this, handle); + mMicSamplingPeriodBackup.erase(handle); } return err; } -status_t SensorService::SensorEventConnection::setEventRate( - int handle, nsecs_t samplingPeriodNs) -{ +status_t SensorService::SensorEventConnection::setEventRate(int handle, nsecs_t samplingPeriodNs) { if (mDestroyed) { android_errorWriteLog(0x534e4554, "168211968"); return DEAD_OBJECT; } - return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName); + nsecs_t requestedSamplingPeriodNs = samplingPeriodNs; + bool isSensorCapped = false; + sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle); + if (si != nullptr) { + const Sensor& s = si->getSensor(); + if (mService->isSensorInCappedSet(s.getType())) { + isSensorCapped = true; + } + } + if (isSensorCapped) { + status_t err = mService->adjustSamplingPeriodBasedOnMicAndPermission(&samplingPeriodNs, + String16(mOpPackageName)); + if (err != OK) { + return err; + } + } + status_t ret = mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName); + if (ret == OK && isSensorCapped) { + if (!mIsRateCappedBasedOnPermission || + requestedSamplingPeriodNs >= SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) { + mMicSamplingPeriodBackup[handle] = requestedSamplingPeriodNs; + } else { + mMicSamplingPeriodBackup[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS; + } + } + return ret; +} + +void SensorService::SensorEventConnection::onMicSensorAccessChanged(bool isMicToggleOn) { + if (isMicToggleOn) { + capRates(); + } else { + uncapRates(); + } +} + +void SensorService::SensorEventConnection::capRates() { + Mutex::Autolock _l(mConnectionLock); + SensorDevice& dev(SensorDevice::getInstance()); + for (auto &i : mMicSamplingPeriodBackup) { + int handle = i.first; + nsecs_t samplingPeriodNs = i.second; + if (samplingPeriodNs < SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) { + if (hasSensorAccess()) { + mService->setEventRate(this, handle, SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS, + mOpPackageName); + } else { + // Update SensorDevice with the capped rate so that when sensor access is restored, + // the correct event rate is used. + dev.onMicSensorAccessChanged(this, handle, + SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS); + } + } + } +} + +void SensorService::SensorEventConnection::uncapRates() { + Mutex::Autolock _l(mConnectionLock); + SensorDevice& dev(SensorDevice::getInstance()); + for (auto &i : mMicSamplingPeriodBackup) { + int handle = i.first; + nsecs_t samplingPeriodNs = i.second; + if (samplingPeriodNs < SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) { + if (hasSensorAccess()) { + mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName); + } else { + // Update SensorDevice with the uncapped rate so that when sensor access is + // restored, the correct event rate is used. + dev.onMicSensorAccessChanged(this, handle, samplingPeriodNs); + } + } + } } status_t SensorService::SensorEventConnection::flush() { |