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

Commit 283bb209 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "direct_uid_idle" into rvc-dev

* changes:
  Handle backgrounded apps for direct sensor connections
  Disable sensors when an app goes to background v2
parents 85c2ee61 e3ed3d2d
Loading
Loading
Loading
Loading
+96 −29
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@
#include "android/hardware/sensors/2.1/ISensorsCallback.h"
#include "android/hardware/sensors/2.1/types.h"
#include "convertV2_1.h"
#include "SensorService.h"

#include <android-base/logging.h>
#include <android/util/ProtoOutputStream.h>
@@ -30,6 +29,7 @@
#include <utils/Errors.h>
#include <utils/Singleton.h>

#include <cstddef>
#include <chrono>
#include <cinttypes>
#include <thread>
@@ -403,8 +403,8 @@ std::string SensorDevice::dump() const {
    if (mSensors == nullptr) return "HAL not initialized\n";

    String8 result;
    result.appendFormat("Total %zu h/w sensors, %zu running:\n",
                        mSensorList.size(), mActivationCount.size());
    result.appendFormat("Total %zu h/w sensors, %zu running %zu disabled clients:\n",
                        mSensorList.size(), mActivationCount.size(), mDisabledClients.size());

    Mutex::Autolock _l(mLock);
    for (const auto & s : mSensorList) {
@@ -417,16 +417,18 @@ std::string SensorDevice::dump() const {
        result.append("sampling_period(ms) = {");
        for (size_t j = 0; j < info.batchParams.size(); j++) {
            const BatchParams& params = info.batchParams[j];
            result.appendFormat("%.1f%s", params.mTSample / 1e6f,
                j < info.batchParams.size() - 1 ? ", " : "");
            result.appendFormat("%.1f%s%s", params.mTSample / 1e6f,
                isClientDisabledLocked(info.batchParams.keyAt(j)) ? "(disabled)" : "",
                (j < info.batchParams.size() - 1) ? ", " : "");
        }
        result.appendFormat("}, selected = %.2f ms; ", info.bestBatchParams.mTSample / 1e6f);

        result.append("batching_period(ms) = {");
        for (size_t j = 0; j < info.batchParams.size(); j++) {
            const BatchParams& params = info.batchParams[j];
            result.appendFormat("%.1f%s", params.mTBatch / 1e6f,
                    j < info.batchParams.size() - 1 ? ", " : "");
            result.appendFormat("%.1f%s%s", params.mTBatch / 1e6f,
                    isClientDisabledLocked(info.batchParams.keyAt(j)) ? "(disabled)" : "",
                    (j < info.batchParams.size() - 1) ? ", " : "");
        }
        result.appendFormat("}, selected = %.2f ms\n", info.bestBatchParams.mTBatch / 1e6f);
    }
@@ -641,7 +643,7 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) {
}

status_t SensorDevice::activateLocked(void* ident, int handle, int enabled) {
    bool actuateHardware = false;
    bool activateHardware = false;

    status_t err(NO_ERROR);

@@ -667,7 +669,7 @@ status_t SensorDevice::activateLocked(void* ident, int handle, int enabled) {

        if (info.batchParams.indexOfKey(ident) >= 0) {
            if (info.numActiveClients() > 0 && !info.isActive) {
                actuateHardware = true;
                activateHardware = true;
            }
        } else {
            // Log error. Every activate call should be preceded by a batch() call.
@@ -687,7 +689,7 @@ status_t SensorDevice::activateLocked(void* ident, int handle, int enabled) {
        if (info.removeBatchParamsForIdent(ident) >= 0) {
            if (info.numActiveClients() == 0) {
                // This is the last connection, we need to de-activate the underlying h/w sensor.
                actuateHardware = true;
                activateHardware = true;
            } else {
                // Call batch for this sensor with the previously calculated best effort
                // batch_rate and timeout. One of the apps has unregistered for sensor
@@ -707,12 +709,8 @@ status_t SensorDevice::activateLocked(void* ident, int handle, int enabled) {
        }
    }

    if (actuateHardware) {
        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
                 enabled);
        err = checkReturnAndGetStatus(mSensors->activate(handle, enabled));
        ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
                 strerror(-err));
    if (activateHardware) {
        err = doActivateHardwareLocked(handle, enabled);

        if (err != NO_ERROR && enabled) {
            // Failure when enabling the sensor. Clean up on failure.
@@ -728,6 +726,15 @@ status_t SensorDevice::activateLocked(void* ident, int handle, int enabled) {
    return err;
}

status_t SensorDevice::doActivateHardwareLocked(int handle, bool enabled) {
    ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
             enabled);
    status_t err = checkReturnAndGetStatus(mSensors->activate(handle, enabled));
    ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
             strerror(-err));
    return err;
}

status_t SensorDevice::batch(
        void* ident,
        int handle,
@@ -768,6 +775,18 @@ status_t SensorDevice::batchLocked(void* ident, int handle, int flags, int64_t s
        info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
    }

    status_t err =  updateBatchParamsLocked(handle, info);
    if (err != NO_ERROR) {
        ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s",
              mSensors.get(), handle, info.bestBatchParams.mTSample,
              info.bestBatchParams.mTBatch, strerror(-err));
        info.removeBatchParamsForIdent(ident);
    }

    return err;
}

status_t SensorDevice::updateBatchParamsLocked(int handle, Info &info) {
    BatchParams prevBestBatchParams = info.bestBatchParams;
    // Find the minimum of all timeouts and batch_rates for this sensor.
    info.selectBatchParams();
@@ -785,13 +804,8 @@ status_t SensorDevice::batchLocked(void* ident, int handle, int flags, int64_t s
                 info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
        err = checkReturnAndGetStatus(mSensors->batch(
                handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
        if (err != NO_ERROR) {
            ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s",
                  mSensors.get(), handle, info.bestBatchParams.mTSample,
                  info.bestBatchParams.mTBatch, strerror(-err));
            info.removeBatchParamsForIdent(ident);
        }
    }

    return err;
}

@@ -811,13 +825,61 @@ status_t SensorDevice::flush(void* ident, int handle) {
    return checkReturnAndGetStatus(mSensors->flush(handle));
}

bool SensorDevice::isClientDisabled(void* ident) {
bool SensorDevice::isClientDisabled(void* ident) const {
    Mutex::Autolock _l(mLock);
    return isClientDisabledLocked(ident);
}

bool SensorDevice::isClientDisabledLocked(void* ident) {
    return mDisabledClients.indexOf(ident) >= 0;
bool SensorDevice::isClientDisabledLocked(void* ident) const {
    return mDisabledClients.count(ident) > 0;
}

std::vector<void *> SensorDevice::getDisabledClientsLocked() const {
    std::vector<void *> vec;
    for (const auto& it : mDisabledClients) {
        vec.push_back(it.first);
    }

    return vec;
}

void SensorDevice::addDisabledReasonForIdentLocked(void* ident, DisabledReason reason) {
    mDisabledClients[ident] |= 1 << reason;
}

void SensorDevice::removeDisabledReasonForIdentLocked(void* ident, DisabledReason reason) {
    if (isClientDisabledLocked(ident)) {
        mDisabledClients[ident] &= ~(1 << reason);
        if (mDisabledClients[ident] == 0) {
            mDisabledClients.erase(ident);
        }
    }
}

void SensorDevice::setUidStateForConnection(void* ident, SensorService::UidState state) {
    Mutex::Autolock _l(mLock);
    if (state == SensorService::UID_STATE_ACTIVE) {
        removeDisabledReasonForIdentLocked(ident, DisabledReason::DISABLED_REASON_UID_IDLE);
    } else {
        addDisabledReasonForIdentLocked(ident, DisabledReason::DISABLED_REASON_UID_IDLE);
    }

    for (size_t i = 0; i< mActivationCount.size(); ++i) {
        int handle = mActivationCount.keyAt(i);
        Info& info = mActivationCount.editValueAt(i);

        if (info.hasBatchParamsForIdent(ident)) {
            if (updateBatchParamsLocked(handle, info) != NO_ERROR) {
                bool enable = info.numActiveClients() == 0 && info.isActive;
                bool disable = info.numActiveClients() > 0 && !info.isActive;

                if ((enable || disable) &&
                    doActivateHardwareLocked(handle, enable) == NO_ERROR) {
                    info.isActive = enable;
                }
            }
        }
    }
}

bool SensorDevice::isSensorActive(int handle) const {
@@ -832,8 +894,12 @@ bool SensorDevice::isSensorActive(int handle) const {
void SensorDevice::enableAllSensors() {
    if (mSensors == nullptr) return;
    Mutex::Autolock _l(mLock);
    mDisabledClients.clear();
    ALOGI("cleared mDisabledClients");

    for (void *client : getDisabledClientsLocked()) {
        removeDisabledReasonForIdentLocked(
            client, DisabledReason::DISABLED_REASON_SERVICE_RESTRICTED);
    }

    for (size_t i = 0; i< mActivationCount.size(); ++i) {
        Info& info = mActivationCount.editValueAt(i);
        if (info.batchParams.isEmpty()) continue;
@@ -873,7 +939,8 @@ void SensorDevice::disableAllSensors() {
           // Add all the connections that were registered for this sensor to the disabled
           // clients list.
           for (size_t j = 0; j < info.batchParams.size(); ++j) {
               mDisabledClients.add(info.batchParams.keyAt(j));
               addDisabledReasonForIdentLocked(
                   info.batchParams.keyAt(j), DisabledReason::DISABLED_REASON_SERVICE_RESTRICTED);
               ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
           }

@@ -1048,7 +1115,7 @@ ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {

void SensorDevice::notifyConnectionDestroyed(void* ident) {
    Mutex::Autolock _l(mLock);
    mDisabledClients.remove(ident);
    mDisabledClients.erase(ident);
}

bool SensorDevice::isDirectReportSupported() const {
+38 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define ANDROID_SENSOR_DEVICE_H

#include "SensorDeviceUtils.h"
#include "SensorService.h"
#include "SensorServiceUtils.h"
#include "ISensorsWrapper.h"

@@ -116,6 +117,8 @@ public:
    hardware::Return<void> onDynamicSensorsDisconnected(
            const hardware::hidl_vec<int32_t> &dynamicSensorHandlesRemoved);

    void setUidStateForConnection(void* ident, SensorService::UidState state);

    bool isReconnecting() const {
        return mReconnecting;
    }
@@ -179,6 +182,13 @@ private:
        // the removed ident. If index >=0, ident is present and successfully removed.
        ssize_t removeBatchParamsForIdent(void* ident);

        bool hasBatchParamsForIdent(void* ident) const {
            return batchParams.indexOfKey(ident) >= 0;
        }

        /**
         * @return The number of active clients of this sensor.
         */
        int numActiveClients() const;
    };
    DefaultKeyedVector<int, Info> mActivationCount;
@@ -187,8 +197,26 @@ private:
    SensorServiceUtil::RingBuffer<HidlTransportErrorLog> mHidlTransportErrors;
    int mTotalHidlTransportErrors;

    // Use this vector to determine which client is activated or deactivated.
    SortedVector<void *> mDisabledClients;
    /**
     * Enums describing the reason why a client was disabled.
     */
    enum DisabledReason : uint8_t {
        // UID becomes idle (e.g. app goes to background).
        DISABLED_REASON_UID_IDLE = 0,

        // Sensors are restricted for all clients.
        DISABLED_REASON_SERVICE_RESTRICTED,
        DISABLED_REASON_MAX,
    };

    static_assert(DisabledReason::DISABLED_REASON_MAX < sizeof(uint8_t) * CHAR_BIT);

    // Use this map to determine which client is activated or deactivated.
    std::unordered_map<void *, uint8_t> mDisabledClients;

    void addDisabledReasonForIdentLocked(void* ident, DisabledReason reason);
    void removeDisabledReasonForIdentLocked(void* ident, DisabledReason reason);

    SensorDevice();
    bool connectHidlService();
    void initializeSensorList();
@@ -214,6 +242,9 @@ private:
    status_t batchLocked(void* ident, int handle, int flags, int64_t samplingPeriodNs,
                         int64_t maxBatchReportLatencyNs);

    status_t updateBatchParamsLocked(int handle, Info& info);
    status_t doActivateHardwareLocked(int handle, bool enable);

    void handleHidlDeath(const std::string &detail);
    template<typename T>
    void checkReturn(const Return<T>& ret) {
@@ -225,8 +256,11 @@ private:
    //TODO(b/67425500): remove waiter after bug is resolved.
    sp<SensorDeviceUtils::HidlServiceRegistrationWaiter> mRestartWaiter;

    bool isClientDisabled(void* ident);
    bool isClientDisabledLocked(void* ident);
    bool isClientDisabled(void* ident) const;
    bool isClientDisabledLocked(void* ident) const;
    std::vector<void *> getDisabledClientsLocked() const;

    bool clientHasNoAccessLocked(void* ident) const;

    using Event = hardware::sensors::V2_1::Event;
    using SensorInfo = hardware::sensors::V2_1::SensorInfo;
+35 −16
Original line number Diff line number Diff line
@@ -93,6 +93,18 @@ sp<BitTube> SensorService::SensorDirectConnection::getSensorChannel() const {
    return nullptr;
}

void SensorService::SensorDirectConnection::onSensorAccessChanged(bool hasAccess) {
    if (!hasAccess) {
        stopAll(true /* backupRecord */);
    } else {
        recoverAll();
    }
}

bool SensorService::SensorDirectConnection::hasSensorAccess() const {
    return mService->hasSensorAccess(mUid, mOpPackageName);
}

status_t SensorService::SensorDirectConnection::enableDisable(
        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
        int reservedFlags) {
@@ -125,7 +137,7 @@ int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int
        return NO_ERROR;
    }

    if (!mService->isOperationPermitted(mOpPackageName)) {
    if (!hasSensorAccess()) {
        return PERMISSION_DENIED;
    }

@@ -169,12 +181,15 @@ int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int
}

void SensorService::SensorDirectConnection::stopAll(bool backupRecord) {
    Mutex::Autolock _l(mConnectionLock);
    stopAllLocked(backupRecord);
}

void SensorService::SensorDirectConnection::stopAllLocked(bool backupRecord) {
    struct sensors_direct_cfg_t config = {
        .rate_level = SENSOR_DIRECT_RATE_STOP
    };

    Mutex::Autolock _l(mConnectionLock);
    SensorDevice& dev(SensorDevice::getInstance());
    for (auto &i : mActivated) {
        dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
@@ -187,12 +202,15 @@ void SensorService::SensorDirectConnection::stopAll(bool backupRecord) {
}

void SensorService::SensorDirectConnection::recoverAll() {
    stopAll(false);

    Mutex::Autolock _l(mConnectionLock);
    if (!mActivatedBackup.empty()) {
        stopAllLocked(false);

        SensorDevice& dev(SensorDevice::getInstance());

        // recover list of report from backup
        ALOG_ASSERT(mActivated.empty(),
                    "mActivated must be empty if mActivatedBackup was non-empty");
        mActivated = mActivatedBackup;
        mActivatedBackup.clear();

@@ -204,6 +222,7 @@ void SensorService::SensorDirectConnection::recoverAll() {
            dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
        }
    }
}

int32_t SensorService::SensorDirectConnection::getHalChannelHandle() const {
    return mHalChannelHandle;
+24 −8
Original line number Diff line number Diff line
@@ -42,17 +42,14 @@ public:
    void dump(String8& result) const;
    void dump(util::ProtoOutputStream* proto) const;
    uid_t getUid() const { return mUid; }
    const String16& getOpPackageName() const { return mOpPackageName; }
    int32_t getHalChannelHandle() const;
    bool isEquivalent(const sensors_direct_mem_t *mem) const;

    // stop all active sensor report. if backupRecord is set to false,
    // those report can be recovered by recoverAll
    // called by SensorService when enter restricted mode
    void stopAll(bool backupRecord = false);

    // recover sensor reports previously stopped by stopAll(true)
    // called by SensorService when return to NORMAL mode.
    void recoverAll();
    // Invoked when access to sensors for this connection has changed, e.g. lost or
    // regained due to changes in the sensor restricted/privacy mode or the
    // app changed to idle/active status.
    void onSensorAccessChanged(bool hasAccess);

protected:
    virtual ~SensorDirectConnection();
@@ -66,6 +63,25 @@ protected:
    virtual int32_t configureChannel(int handle, int rateLevel);
    virtual void destroy();
private:
    bool hasSensorAccess() const;

    // Stops all active sensor direct report requests.
    //
    // If backupRecord is true, stopped requests can be recovered
    // by a subsequent recoverAll() call (e.g. when temporarily stopping
    // sensors for sensor privacy/restrict mode or when an app becomes
    // idle).
    void stopAll(bool backupRecord = false);
    // Same as stopAll() but with mConnectionLock held.
    void stopAllLocked(bool backupRecord);

    // Recover sensor requests previously stopped by stopAll(true).
    // This method can be called when a sensor access resumes (e.g.
    // sensor privacy/restrict mode lifted or app becomes active).
    //
    // If no requests are backed up by stopAll(), this method is no-op.
    void recoverAll();

    const sp<SensorService> mService;
    const uid_t mUid;
    const sensors_direct_mem_t mMem;
+4 −9
Original line number Diff line number Diff line
@@ -31,12 +31,11 @@ namespace android {

SensorService::SensorEventConnection::SensorEventConnection(
        const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
        const String16& opPackageName, bool hasSensorAccess)
        const String16& opPackageName)
    : 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),
      mHasSensorAccess(hasSensorAccess) {
      mPackageName(packageName), mOpPackageName(opPackageName), mDestroyed(false) {
    mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
    mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@@ -431,13 +430,9 @@ status_t SensorService::SensorEventConnection::sendEvents(
    return size < 0 ? status_t(size) : status_t(NO_ERROR);
}

void SensorService::SensorEventConnection::setSensorAccess(const bool hasAccess) {
    Mutex::Autolock _l(mConnectionLock);
    mHasSensorAccess = hasAccess;
}

bool SensorService::SensorEventConnection::hasSensorAccess() {
    return mHasSensorAccess && !mService->mSensorPrivacyPolicy->isSensorPrivacyEnabled();
    return mService->isUidActive(mUid)
        && !mService->mSensorPrivacyPolicy->isSensorPrivacyEnabled();
}

bool SensorService::SensorEventConnection::noteOpIfRequired(const sensors_event_t& event) {
Loading