summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Anh Pham <anhph@google.com> 2021-02-10 14:15:30 +0100
committer Anh Pham <anhph@google.com> 2021-02-16 21:37:16 +0100
commit5198c99c3e8660f26209dde852e539b705ac189d (patch)
tree4c5069f96c54eace190cd573f870a5a108c9dfc5
parentaf91a91c5cce1263895ee804e961975ad7aab3a2 (diff)
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
-rw-r--r--services/sensorservice/SensorDevice.cpp15
-rw-r--r--services/sensorservice/SensorDevice.h4
-rw-r--r--services/sensorservice/SensorDirectConnection.cpp93
-rw-r--r--services/sensorservice/SensorDirectConnection.h9
-rw-r--r--services/sensorservice/SensorEventConnection.cpp69
-rw-r--r--services/sensorservice/SensorEventConnection.h10
-rw-r--r--services/sensorservice/SensorService.cpp90
-rw-r--r--services/sensorservice/SensorService.h19
8 files changed, 300 insertions, 9 deletions
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 2810bffdd3..23893ea1fd 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -914,6 +914,21 @@ bool SensorDevice::isSensorActive(int handle) const {
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() {
if (mSensors == nullptr) return;
Mutex::Autolock _l(mLock);
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 5e7d3da398..75da7bb0a1 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -125,6 +125,10 @@ public:
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
virtual std::string dump() const override;
virtual void dump(util::ProtoOutputStream* proto) const override;
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index b3be72d9b6..af86d09784 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -33,6 +33,7 @@ SensorService::SensorDirectConnection::SensorDirectConnection(const sp<SensorSer
mHalChannelHandle(halChannelHandle),
mOpPackageName(opPackageName), mDestroyed(false) {
mIsRateCappedBasedOnPermission = mService->isRateCappedBasedOnPermission(mOpPackageName);
+ mUserId = multiuser_get_user_id(mUid);
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 {
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) {
stopAll();
+ mMicRateBackup.clear();
return NO_ERROR;
}
@@ -158,6 +168,7 @@ int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int
return INVALID_OPERATION;
}
+ int requestedRateLevel = rateLevel;
if (mService->isSensorInCappedSet(s.getType()) && rateLevel != SENSOR_DIRECT_RATE_STOP) {
status_t err = mService->adjustRateLevelBasedOnMicAndPermission(&rateLevel, mOpPackageName);
if (err != OK) {
@@ -176,18 +187,100 @@ int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int
if (rateLevel == SENSOR_DIRECT_RATE_STOP) {
if (ret == NO_ERROR) {
mActivated.erase(handle);
+ mMicRateBackup.erase(handle);
} else if (ret > 0) {
ret = UNKNOWN_ERROR;
}
} else {
if (ret > 0) {
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;
}
+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) {
Mutex::Autolock _l(mConnectionLock);
stopAllLocked(backupRecord);
diff --git a/services/sensorservice/SensorDirectConnection.h b/services/sensorservice/SensorDirectConnection.h
index 526e66f49d..a3f348b668 100644
--- a/services/sensorservice/SensorDirectConnection.h
+++ b/services/sensorservice/SensorDirectConnection.h
@@ -50,6 +50,8 @@ public:
// regained due to changes in the sensor restricted/privacy mode or the
// app changed to idle/active status.
void onSensorAccessChanged(bool hasAccess);
+ void onMicSensorAccessChanged(bool isMicToggleOn);
+ userid_t getUserId() const { return mUserId; }
protected:
virtual ~SensorDirectConnection();
@@ -82,6 +84,11 @@ private:
// If no requests are backed up by stopAll(), this method is no-op.
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 uid_t mUid;
const sensors_direct_mem_t mMem;
@@ -91,10 +98,12 @@ private:
mutable Mutex mConnectionLock;
std::unordered_map<int, int> mActivated;
std::unordered_map<int, int> mActivatedBackup;
+ std::unordered_map<int, int> mMicRateBackup;
std::atomic_bool mIsRateCappedBasedOnPermission;
mutable Mutex mDestroyLock;
bool mDestroyed;
+ userid_t mUserId;
};
} // namepsace android
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 90e33a9134..46fc34bc7f 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -45,6 +45,7 @@ SensorService::SensorEventConnection::SensorEventConnection(
mPackageName(packageName), mOpPackageName(opPackageName), mTargetSdk(kTargetSdkUnknown),
mDestroyed(false) {
mIsRateCappedBasedOnPermission = mService->isRateCappedBasedOnPermission(mOpPackageName);
+ mUserId = multiuser_get_user_id(mUid);
mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@@ -685,6 +686,7 @@ status_t SensorService::SensorEventConnection::enableDisable(
status_t err;
if (enabled) {
+ nsecs_t requestedSamplingPeriodNs = samplingPeriodNs;
bool isSensorCapped = false;
sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
if (si != nullptr) {
@@ -702,9 +704,18 @@ status_t SensorService::SensorEventConnection::enableDisable(
}
err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
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 {
err = mService->disable(this, handle);
+ mMicSamplingPeriodBackup.erase(handle);
}
return err;
}
@@ -715,6 +726,7 @@ status_t SensorService::SensorEventConnection::setEventRate(int handle, nsecs_t
return DEAD_OBJECT;
}
+ nsecs_t requestedSamplingPeriodNs = samplingPeriodNs;
bool isSensorCapped = false;
sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
if (si != nullptr) {
@@ -730,7 +742,62 @@ status_t SensorService::SensorEventConnection::setEventRate(int handle, nsecs_t
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() {
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 7c8c4f34b4..7acc0e652d 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -68,6 +68,9 @@ public:
String8 getPackageName() const;
uid_t getUid() const { return mUid; }
+ // cap/uncap existing connection depending on the state of the mic toggle.
+ void onMicSensorAccessChanged(bool isMicToggleOn);
+ userid_t getUserId() const { return mUserId; }
private:
virtual ~SensorEventConnection();
@@ -137,6 +140,10 @@ private:
// Call noteOp for the sensor if the sensor requires a permission
bool noteOpIfRequired(const sensors_event_t& event);
+ // Limits all active connections when the mic toggle is flipped to on.
+ void capRates();
+ // Recover sensor connection previously capped by capRates().
+ void uncapRates();
sp<SensorService> const mService;
sp<BitTube> mChannel;
uid_t mUid;
@@ -189,6 +196,9 @@ private:
// Store a mapping of sensor handles to required AppOp for a sensor. This map only contains a
// valid mapping for sensors that require a permission in order to reduce the lookup time.
std::unordered_map<int32_t, int32_t> mHandleToAppOp;
+ // Mapping of sensor handles to its rate before being capped by the mic toggle.
+ std::unordered_map<int, nsecs_t> mMicSamplingPeriodBackup;
+ userid_t mUserId;
};
} // namepsace android
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index cd1521da18..e8aa028fec 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -369,6 +369,9 @@ SensorService::~SensorService() {
}
mUidPolicy->unregisterSelf();
mSensorPrivacyPolicy->unregisterSelf();
+ for (auto const& [userId, policy] : mMicSensorPrivacyPolicies) {
+ policy->unregisterSelf();
+ }
}
status_t SensorService::dump(int fd, const Vector<String16>& args) {
@@ -698,6 +701,35 @@ void SensorService::enableAllSensorsLocked(ConnectionSafeAutolock* connLock) {
}
}
+void SensorService::capRates(userid_t userId) {
+ ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
+ for (const sp<SensorDirectConnection>& conn : connLock.getDirectConnections()) {
+ if (conn->getUserId() == userId) {
+ conn->onMicSensorAccessChanged(true);
+ }
+ }
+
+ for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) {
+ if (conn->getUserId() == userId) {
+ conn->onMicSensorAccessChanged(true);
+ }
+ }
+}
+
+void SensorService::uncapRates(userid_t userId) {
+ ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
+ for (const sp<SensorDirectConnection>& conn : connLock.getDirectConnections()) {
+ if (conn->getUserId() == userId) {
+ conn->onMicSensorAccessChanged(false);
+ }
+ }
+
+ for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) {
+ if (conn->getUserId() == userId) {
+ conn->onMicSensorAccessChanged(false);
+ }
+ }
+}
// NOTE: This is a remote API - make sure all args are validated
status_t SensorService::shellCommand(int in, int out, int err, Vector<String16>& args) {
@@ -2049,7 +2081,7 @@ bool SensorService::isSensorInCappedSet(int sensorType) {
status_t SensorService::adjustSamplingPeriodBasedOnMicAndPermission(nsecs_t* requestedPeriodNs,
const String16& opPackageName) {
-
+ uid_t uid = IPCThreadState::self()->getCallingUid();
bool shouldCapBasedOnPermission = isRateCappedBasedOnPermission(opPackageName);
if (*requestedPeriodNs >= SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS) {
return OK;
@@ -2061,7 +2093,10 @@ status_t SensorService::adjustSamplingPeriodBasedOnMicAndPermission(nsecs_t* req
}
return OK;
}
- // Condition based on mic toggle is added later.
+ if (isMicSensorPrivacyEnabledForUid(uid)) {
+ *requestedPeriodNs = SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS;
+ return OK;
+ }
return OK;
}
@@ -2080,7 +2115,10 @@ status_t SensorService::adjustRateLevelBasedOnMicAndPermission(int* requestedRat
}
return OK;
}
- // Condition based on mic toggle is added later.
+ if (isMicSensorPrivacyEnabledForUid(uid)) {
+ *requestedRateLevel = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL;
+ return OK;
+ }
return OK;
}
@@ -2102,16 +2140,56 @@ bool SensorService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
binder::Status SensorService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
mSensorPrivacyEnabled = enabled;
sp<SensorService> service = mService.promote();
+
if (service != nullptr) {
- if (enabled) {
- service->disableAllSensors();
+ if (mIsIndividualMic) {
+ if (enabled) {
+ service->capRates(mUserId);
+ } else {
+ service->uncapRates(mUserId);
+ }
} else {
- service->enableAllSensors();
+ if (enabled) {
+ service->disableAllSensors();
+ } else {
+ service->enableAllSensors();
+ }
}
}
return binder::Status::ok();
}
+status_t SensorService::SensorPrivacyPolicy::registerSelfForIndividual(int userId) {
+ Mutex::Autolock _l(mSensorPrivacyLock);
+
+ SensorPrivacyManager spm;
+ status_t err = spm.addIndividualSensorPrivacyListener(userId,
+ SensorPrivacyManager::INDIVIDUAL_SENSOR_MICROPHONE, this);
+
+ if (err != OK) {
+ ALOGE("Cannot register a mic listener.");
+ return err;
+ }
+ mSensorPrivacyEnabled = spm.isIndividualSensorPrivacyEnabled(userId,
+ SensorPrivacyManager::INDIVIDUAL_SENSOR_MICROPHONE);
+
+ mIsIndividualMic = true;
+ mUserId = userId;
+ return OK;
+}
+
+bool SensorService::isMicSensorPrivacyEnabledForUid(uid_t uid) {
+ userid_t userId = multiuser_get_user_id(uid);
+ if (mMicSensorPrivacyPolicies.find(userId) == mMicSensorPrivacyPolicies.end()) {
+ sp<SensorPrivacyPolicy> userPolicy = new SensorPrivacyPolicy(this);
+ if (userPolicy->registerSelfForIndividual(userId) != OK) {
+ return false;
+ }
+ mMicSensorPrivacyPolicies[userId] = userPolicy;
+ }
+ return mMicSensorPrivacyPolicies[userId]->isSensorPrivacyEnabled();
+}
+
SensorService::ConnectionSafeAutolock::ConnectionSafeAutolock(
SensorService::SensorConnectionHolder& holder, Mutex& mutex)
: mConnectionHolder(holder), mAutolock(mutex) {}
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index a884a42381..dc1463b711 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -62,8 +62,8 @@
#define SENSOR_REGISTRATIONS_BUF_SIZE 200
// Apps that targets S+ and do not have HIGH_SAMPLING_RATE_SENSORS permission will be capped
-// at 200 Hz. The cap also applies to all requests when the mic toggle is flipped, regardless of
-// their target SDKs and permission.
+// at 200 Hz. The cap also applies to all requests when the mic toggle is flipped to on, regardless
+// of their target SDKs and permission.
// Capped sampling periods for apps that have non-direct sensor connections.
#define SENSOR_SERVICE_CAPPED_SAMPLING_PERIOD_NS (5 * 1000 * 1000)
// Capped sampling rate level for apps that have direct sensor connections.
@@ -227,13 +227,18 @@ private:
void registerSelf();
void unregisterSelf();
+ status_t registerSelfForIndividual(int userId);
+
bool isSensorPrivacyEnabled();
binder::Status onSensorPrivacyChanged(bool enabled);
private:
wp<SensorService> mService;
+ Mutex mSensorPrivacyLock;
std::atomic_bool mSensorPrivacyEnabled;
+ bool mIsIndividualMic;
+ userid_t mUserId;
};
enum Mode {
@@ -403,6 +408,11 @@ private:
void enableAllSensors();
void enableAllSensorsLocked(ConnectionSafeAutolock* connLock);
+ // Caps active direct connections (when the mic toggle is flipped to on)
+ void capRates(userid_t userId);
+ // Removes the capped rate on active direct connections (when the mic toggle is flipped to off)
+ void uncapRates(userid_t userId);
+
static uint8_t sHmacGlobalKey[128];
static bool sHmacGlobalKeyIsValid;
@@ -444,6 +454,11 @@ private:
static std::map<String16, int> sPackageTargetVersion;
static Mutex sPackageTargetVersionLock;
static String16 sSensorInterfaceDescriptorPrefix;
+
+ // Map from user to SensorPrivacyPolicy
+ std::map<userid_t, sp<SensorPrivacyPolicy>> mMicSensorPrivacyPolicies;
+ // Checks if the mic sensor privacy is enabled for the uid
+ bool isMicSensorPrivacyEnabledForUid(uid_t uid);
};
} // namespace android