Handle backgrounded apps for direct sensor connections

Uses the stopAll()/recoverAll() logic to temporarily stop/enable
sensors for direct connections when an app becomes idle/active.

Bug: 74395023
Test: CTS SensorDirectReportTest and verify pass
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: Id1981213fc13a9012fa756b8cd35fae6f144c105
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index 106efd6..e4c33da 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -93,6 +93,18 @@
     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 @@
         return NO_ERROR;
     }
 
-    if (!mService->isOperationPermitted(mOpPackageName)) {
+    if (!hasSensorAccess()) {
         return PERMISSION_DENIED;
     }
 
@@ -169,12 +181,15 @@
 }
 
 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,21 +202,25 @@
 }
 
 void SensorService::SensorDirectConnection::recoverAll() {
-    stopAll(false);
-
     Mutex::Autolock _l(mConnectionLock);
-    SensorDevice& dev(SensorDevice::getInstance());
+    if (!mActivatedBackup.empty()) {
+        stopAllLocked(false);
 
-    // recover list of report from backup
-    mActivated = mActivatedBackup;
-    mActivatedBackup.clear();
+        SensorDevice& dev(SensorDevice::getInstance());
 
-    // re-enable them
-    for (auto &i : mActivated) {
-        struct sensors_direct_cfg_t config = {
-            .rate_level = i.second
-        };
-        dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
+        // recover list of report from backup
+        ALOG_ASSERT(mActivated.empty(),
+                    "mActivated must be empty if mActivatedBackup was non-empty");
+        mActivated = mActivatedBackup;
+        mActivatedBackup.clear();
+
+        // re-enable them
+        for (auto &i : mActivated) {
+            struct sensors_direct_cfg_t config = {
+                .rate_level = i.second
+            };
+            dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
+        }
     }
 }