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

Commit 5198c99c authored by Anh Pham's avatar Anh Pham
Browse files

Subscribe to the microphone toggle state.

When the microphone toggle is on, all connections are clamped down to
200 Hz. When the microphone toggle is off, the original rates of
connections are recovered.

Test: atest CtsSensorTestCases CtsSensorRatePermissionTestCases
Bug: 136069189
Change-Id: Ifc446b726c4200e1a1dae5d7c3026238928383dc
parent af91a91c
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -914,6 +914,21 @@ bool SensorDevice::isSensorActive(int handle) const {
    return mActivationCount.valueAt(activationIndex).numActiveClients() > 0;
    return mActivationCount.valueAt(activationIndex).numActiveClients() > 0;
}
}


void SensorDevice::onMicSensorAccessChanged(void* ident, int handle, nsecs_t samplingPeriodNs) {
    Mutex::Autolock _l(mLock);
    ssize_t activationIndex = mActivationCount.indexOfKey(handle);
    if (activationIndex < 0) {
        ALOGW("Handle %d cannot be found in activation record", handle);
        return;
    }
    Info& info(mActivationCount.editValueAt(activationIndex));
    if (info.hasBatchParamsForIdent(ident)) {
        ssize_t index = info.batchParams.indexOfKey(ident);
        BatchParams& params = info.batchParams.editValueAt(index);
        params.mTSample = samplingPeriodNs;
    }
}

void SensorDevice::enableAllSensors() {
void SensorDevice::enableAllSensors() {
    if (mSensors == nullptr) return;
    if (mSensors == nullptr) return;
    Mutex::Autolock _l(mLock);
    Mutex::Autolock _l(mLock);
+4 −0
Original line number Original line Diff line number Diff line
@@ -125,6 +125,10 @@ public:


    bool isSensorActive(int handle) const;
    bool isSensorActive(int handle) const;


    // To update the BatchParams of a SensorEventConnection when the mic toggle changes its state
    // while the Sensors Off toggle is on.
    void onMicSensorAccessChanged(void* ident, int handle, nsecs_t samplingPeriodNs);

    // Dumpable
    // Dumpable
    virtual std::string dump() const override;
    virtual std::string dump() const override;
    virtual void dump(util::ProtoOutputStream* proto) const override;
    virtual void dump(util::ProtoOutputStream* proto) const override;
+93 −0
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@ SensorService::SensorDirectConnection::SensorDirectConnection(const sp<SensorSer
        mHalChannelHandle(halChannelHandle),
        mHalChannelHandle(halChannelHandle),
        mOpPackageName(opPackageName), mDestroyed(false) {
        mOpPackageName(opPackageName), mDestroyed(false) {
    mIsRateCappedBasedOnPermission = mService->isRateCappedBasedOnPermission(mOpPackageName);
    mIsRateCappedBasedOnPermission = mService->isRateCappedBasedOnPermission(mOpPackageName);
    mUserId = multiuser_get_user_id(mUid);
    ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection");
    ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection");
}
}


@@ -102,6 +103,14 @@ void SensorService::SensorDirectConnection::onSensorAccessChanged(bool hasAccess
    }
    }
}
}


void SensorService::SensorDirectConnection::onMicSensorAccessChanged(bool isMicToggleOn) {
    if (isMicToggleOn) {
        capRates();
    } else {
        uncapRates();
    }
}

bool SensorService::SensorDirectConnection::hasSensorAccess() const {
bool SensorService::SensorDirectConnection::hasSensorAccess() const {
    return mService->hasSensorAccess(mUid, mOpPackageName);
    return mService->hasSensorAccess(mUid, mOpPackageName);
}
}
@@ -135,6 +144,7 @@ int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int


    if (handle == -1 && rateLevel == SENSOR_DIRECT_RATE_STOP) {
    if (handle == -1 && rateLevel == SENSOR_DIRECT_RATE_STOP) {
        stopAll();
        stopAll();
        mMicRateBackup.clear();
        return NO_ERROR;
        return NO_ERROR;
    }
    }


@@ -158,6 +168,7 @@ int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int
        return INVALID_OPERATION;
        return INVALID_OPERATION;
    }
    }


    int requestedRateLevel = rateLevel;
    if (mService->isSensorInCappedSet(s.getType()) && rateLevel != SENSOR_DIRECT_RATE_STOP) {
    if (mService->isSensorInCappedSet(s.getType()) && rateLevel != SENSOR_DIRECT_RATE_STOP) {
        status_t err = mService->adjustRateLevelBasedOnMicAndPermission(&rateLevel, mOpPackageName);
        status_t err = mService->adjustRateLevelBasedOnMicAndPermission(&rateLevel, mOpPackageName);
        if (err != OK) {
        if (err != OK) {
@@ -176,18 +187,100 @@ int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int
    if (rateLevel == SENSOR_DIRECT_RATE_STOP) {
    if (rateLevel == SENSOR_DIRECT_RATE_STOP) {
        if (ret == NO_ERROR) {
        if (ret == NO_ERROR) {
            mActivated.erase(handle);
            mActivated.erase(handle);
            mMicRateBackup.erase(handle);
        } else if (ret > 0) {
        } else if (ret > 0) {
            ret = UNKNOWN_ERROR;
            ret = UNKNOWN_ERROR;
        }
        }
    } else {
    } else {
        if (ret > 0) {
        if (ret > 0) {
            mActivated[handle] = rateLevel;
            mActivated[handle] = rateLevel;
            if (mService->isSensorInCappedSet(s.getType())) {
                // Back up the rates that the app is allowed to have if the mic toggle is off
                // This is used in the uncapRates() function.
                if (!mIsRateCappedBasedOnPermission ||
                            requestedRateLevel <= SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL) {
                    mMicRateBackup[handle] = requestedRateLevel;
                } else {
                    mMicRateBackup[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL;
                }
            }
        }
        }
    }
    }


    return ret;
    return ret;
}
}


void SensorService::SensorDirectConnection::capRates() {
    Mutex::Autolock _l(mConnectionLock);
    const struct sensors_direct_cfg_t capConfig = {
        .rate_level = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL
    };

    const struct sensors_direct_cfg_t stopConfig = {
        .rate_level = SENSOR_DIRECT_RATE_STOP
    };

    // If our requests are in the backup, then we shouldn't activate sensors from here
    bool temporarilyStopped = mActivated.empty() && !mActivatedBackup.empty();
    std::unordered_map<int, int>& existingConnections =
                    (!temporarilyStopped) ? mActivated : mActivatedBackup;

    SensorDevice& dev(SensorDevice::getInstance());
    for (auto &i : existingConnections) {
        int handle = i.first;
        int rateLevel = i.second;
        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
        if (si != nullptr) {
            const Sensor& s = si->getSensor();
            if (mService->isSensorInCappedSet(s.getType()) &&
                        rateLevel > SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL) {
                mMicRateBackup[handle] = rateLevel;
                // Modify the rate kept by the existing map
                existingConnections[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL;
                // Only reconfigure the channel if it's ongoing
                if (!temporarilyStopped) {
                    // Stopping before reconfiguring is the well-tested path in CTS
                    dev.configureDirectChannel(handle, getHalChannelHandle(), &stopConfig);
                    dev.configureDirectChannel(handle, getHalChannelHandle(), &capConfig);
                }
            }
        }
    }
}

void SensorService::SensorDirectConnection::uncapRates() {
    Mutex::Autolock _l(mConnectionLock);

    // If our requests are in the backup, then we shouldn't activate sensors from here
    bool temporarilyStopped = mActivated.empty() && !mActivatedBackup.empty();
    std::unordered_map<int, int>& existingConnections =
                    (!temporarilyStopped) ? mActivated : mActivatedBackup;

    const struct sensors_direct_cfg_t stopConfig = {
        .rate_level = SENSOR_DIRECT_RATE_STOP
    };
    SensorDevice& dev(SensorDevice::getInstance());
    for (auto &i : mMicRateBackup) {
        int handle = i.first;
        int rateLevel = i.second;

        const struct sensors_direct_cfg_t config = {
            .rate_level = rateLevel
        };

        // Modify the rate kept by the existing map
        existingConnections[handle] = rateLevel;

        // Only reconfigure the channel if it's ongoing
        if (!temporarilyStopped) {
            // Stopping before reconfiguring is the well-tested path in CTS
            dev.configureDirectChannel(handle, getHalChannelHandle(), &stopConfig);
            dev.configureDirectChannel(handle, getHalChannelHandle(), &config);
        }
    }
    mMicRateBackup.clear();
}

void SensorService::SensorDirectConnection::stopAll(bool backupRecord) {
void SensorService::SensorDirectConnection::stopAll(bool backupRecord) {
    Mutex::Autolock _l(mConnectionLock);
    Mutex::Autolock _l(mConnectionLock);
    stopAllLocked(backupRecord);
    stopAllLocked(backupRecord);
+9 −0
Original line number Original line Diff line number Diff line
@@ -50,6 +50,8 @@ public:
    // regained due to changes in the sensor restricted/privacy mode or the
    // regained due to changes in the sensor restricted/privacy mode or the
    // app changed to idle/active status.
    // app changed to idle/active status.
    void onSensorAccessChanged(bool hasAccess);
    void onSensorAccessChanged(bool hasAccess);
    void onMicSensorAccessChanged(bool isMicToggleOn);
    userid_t getUserId() const { return mUserId; }


protected:
protected:
    virtual ~SensorDirectConnection();
    virtual ~SensorDirectConnection();
@@ -82,6 +84,11 @@ private:
    // If no requests are backed up by stopAll(), this method is no-op.
    // If no requests are backed up by stopAll(), this method is no-op.
    void recoverAll();
    void recoverAll();


    // Limits all active sensor direct report requests when the mic toggle is flipped to on.
    void capRates();
    // Recover sensor requests previously capped by capRates().
    void uncapRates();

    const sp<SensorService> mService;
    const sp<SensorService> mService;
    const uid_t mUid;
    const uid_t mUid;
    const sensors_direct_mem_t mMem;
    const sensors_direct_mem_t mMem;
@@ -91,10 +98,12 @@ private:
    mutable Mutex mConnectionLock;
    mutable Mutex mConnectionLock;
    std::unordered_map<int, int> mActivated;
    std::unordered_map<int, int> mActivated;
    std::unordered_map<int, int> mActivatedBackup;
    std::unordered_map<int, int> mActivatedBackup;
    std::unordered_map<int, int> mMicRateBackup;


    std::atomic_bool mIsRateCappedBasedOnPermission;
    std::atomic_bool mIsRateCappedBasedOnPermission;
    mutable Mutex mDestroyLock;
    mutable Mutex mDestroyLock;
    bool mDestroyed;
    bool mDestroyed;
    userid_t mUserId;
};
};


} // namepsace android
} // namepsace android
+68 −1
Original line number Original line Diff line number Diff line
@@ -45,6 +45,7 @@ SensorService::SensorEventConnection::SensorEventConnection(
      mPackageName(packageName), mOpPackageName(opPackageName), mTargetSdk(kTargetSdkUnknown),
      mPackageName(packageName), mOpPackageName(opPackageName), mTargetSdk(kTargetSdkUnknown),
      mDestroyed(false) {
      mDestroyed(false) {
    mIsRateCappedBasedOnPermission = mService->isRateCappedBasedOnPermission(mOpPackageName);
    mIsRateCappedBasedOnPermission = mService->isRateCappedBasedOnPermission(mOpPackageName);
    mUserId = multiuser_get_user_id(mUid);
    mChannel = new BitTube(mService->mSocketBufferSize);
    mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
#if DEBUG_CONNECTIONS
    mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
    mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@@ -685,6 +686,7 @@ status_t SensorService::SensorEventConnection::enableDisable(


    status_t err;
    status_t err;
    if (enabled) {
    if (enabled) {
        nsecs_t requestedSamplingPeriodNs = samplingPeriodNs;
        bool isSensorCapped = false;
        bool isSensorCapped = false;
        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
        if (si != nullptr) {
        if (si != nullptr) {
@@ -702,9 +704,18 @@ status_t SensorService::SensorEventConnection::enableDisable(
        }
        }
        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
                               reservedFlags, mOpPackageName);
                               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 {
    } else {
        err = mService->disable(this, handle);
        err = mService->disable(this, handle);
        mMicSamplingPeriodBackup.erase(handle);
    }
    }
    return err;
    return err;
}
}
@@ -715,6 +726,7 @@ status_t SensorService::SensorEventConnection::setEventRate(int handle, nsecs_t
        return DEAD_OBJECT;
        return DEAD_OBJECT;
    }
    }


    nsecs_t requestedSamplingPeriodNs = samplingPeriodNs;
    bool isSensorCapped = false;
    bool isSensorCapped = false;
    sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
    sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
    if (si != nullptr) {
    if (si != nullptr) {
@@ -730,7 +742,62 @@ status_t SensorService::SensorEventConnection::setEventRate(int handle, nsecs_t
            return err;
            return err;
        }
        }
    }
    }
    return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
    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() {
status_t  SensorService::SensorEventConnection::flush() {
Loading