Disable sensors when an app goes to background v2
This change is a revision of a previous version of the
implementation in ag/10737391. In this version, we
perform the book-keeping of backgrounded apps in the
SensorDevice.cpp (rather than SensorEventConnection.cpp),
to avoid unintended problems with the locking assumptions
in the Sensor Service code.
Bug: 74395023
Test: 1) Subscribe to sensor on sensorlogger
2) Put app to background and wait
3) Verify subscription is disabled once app is idle
4) Put app to foreground and verify app can receive sensor samples
Test: Verify above test while a_sns_test streaming samples
Test: Verify above test with sensor service restrict and privacy mode
Change-Id: Ic44058e606868a665d5aa88a75211d1eba8d4950
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 3b68e0e..e3b5743 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -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 @@
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 @@
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::activateLocked(void* ident, int handle, int enabled) {
- bool actuateHardware = false;
+ bool activateHardware = false;
status_t err(NO_ERROR);
@@ -667,7 +669,7 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
void SensorDevice::notifyConnectionDestroyed(void* ident) {
Mutex::Autolock _l(mLock);
- mDisabledClients.remove(ident);
+ mDisabledClients.erase(ident);
}
bool SensorDevice::isDirectReportSupported() const {