Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 532e655e authored by Anh Pham's avatar Anh Pham
Browse files

Resample sensor events for non-direct connections.

The resampler is to guarantee that apps cannot obtain more than 200 Hz
when their sampling rates are being throttled.

Test: atest CtsSensorTestCases CtsSensorRatePermissionTestCases
Bug: 136069189
Change-Id: I2e7d522f71382a517c7e6708136ac55917486fa5
parent 5198c99c
Loading
Loading
Loading
Loading
+31 −5
Original line number Diff line number Diff line
@@ -287,6 +287,29 @@ bool SensorService::SensorEventConnection::incrementPendingFlushCountIfHasAccess
    }
}

// TODO(b/179649922): A better algorithm to guarantee that capped connections will get a sampling
// rate close to 200 Hz. With the current algorithm, apps might be punished unfairly: E.g.,two apps
// make requests to the sensor service at the same time, one is not capped and uses 250 Hz, and one
//is capped, the capped connection will only get 125 Hz.
void SensorService::SensorEventConnection::addSensorEventsToBuffer(bool shouldResample,
    const sensors_event_t& sensorEvent, sensors_event_t* buffer, int* index) {
    if (!shouldResample || !mService->isSensorInCappedSet(sensorEvent.type)) {
        buffer[(*index)++] = sensorEvent;
    } else {
        int64_t lastTimestamp = -1;
        auto entry = mSensorLastTimestamp.find(sensorEvent.sensor);
        if (entry != mSensorLastTimestamp.end()) {
            lastTimestamp = entry->second;
        }
        // Allow 10% headroom here because the clocks are not perfect.
        if (lastTimestamp == -1  || sensorEvent.timestamp - lastTimestamp
                                        >= 0.9 * SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) {
            mSensorLastTimestamp[sensorEvent.sensor] = sensorEvent.timestamp;
            buffer[(*index)++] = sensorEvent;
        }
    }
}

status_t SensorService::SensorEventConnection::sendEvents(
        sensors_event_t const* buffer, size_t numEvents,
        sensors_event_t* scratch,
@@ -295,6 +318,8 @@ status_t SensorService::SensorEventConnection::sendEvents(

    std::unique_ptr<sensors_event_t[]> sanitizedBuffer;

    bool shouldResample = mService->isMicSensorPrivacyEnabledForUid(mUid) ||
                            mIsRateCappedBasedOnPermission;
    int count = 0;
    Mutex::Autolock _l(mConnectionLock);
    if (scratch) {
@@ -348,7 +373,7 @@ status_t SensorService::SensorEventConnection::sendEvents(
                    // Regular sensor event, just copy it to the scratch buffer after checking
                    // the AppOp.
                    if (hasSensorAccess() && noteOpIfRequired(buffer[i])) {
                        scratch[count++] = buffer[i];
                        addSensorEventsToBuffer(shouldResample, buffer[i], scratch, &count);
                    }
                }
                i++;
@@ -357,13 +382,14 @@ status_t SensorService::SensorEventConnection::sendEvents(
                                       (buffer[i].type == SENSOR_TYPE_META_DATA  &&
                                        buffer[i].meta_data.sensor == sensor_handle)));
        }
    } else {
        if (hasSensorAccess()) {
            scratch = const_cast<sensors_event_t *>(buffer);
            count = numEvents;
    } else {
        sanitizedBuffer.reset(new sensors_event_t[numEvents]);
        scratch = sanitizedBuffer.get();
        if (hasSensorAccess()) {
            for (size_t i = 0; i < numEvents; i++) {
                addSensorEventsToBuffer(shouldResample, buffer[i], scratch, &count);
            }
        } else {
            for (size_t i = 0; i < numEvents; i++) {
                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
                    scratch[count++] = buffer[i++];
+6 −0
Original line number Diff line number Diff line
@@ -144,10 +144,16 @@ private:
    void capRates();
    // Recover sensor connection previously capped by capRates().
    void uncapRates();

    // Add sensorEvent to buffer at position index if the sensorEvent satisfies throttling rules.
    void addSensorEventsToBuffer(bool shouldResample, const sensors_event_t& sensorEvent,
                        sensors_event_t* buffer, int* index);
    sp<SensorService> const mService;
    sp<BitTube> mChannel;
    uid_t mUid;
    std::atomic_bool mIsRateCappedBasedOnPermission;
    // Store a mapping of sensor to the timestamp of their last sensor event.
    std::unordered_map<int, int64_t> mSensorLastTimestamp;
    mutable Mutex mConnectionLock;
    // Number of events from wake up sensors which are still pending and haven't been delivered to
    // the corresponding application. It is incremented by one unit for each write to the socket.