Block access to sensors when Sensor Privacy Mode enabled
Test: manually verified sensor access based on state of sensor privacy
mode.
Bug: 110842805
Change-Id: I4f2f2496356ff4a407e5c0cd32bc0abcf0c8b48f
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index f87fcdc..33a2747 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -41,6 +41,7 @@
"liblog",
"libbinder",
"libsensor",
+ "libsensorprivacy",
"libcrypto",
"libbase",
"libhidlbase",
@@ -53,8 +54,8 @@
static_libs: ["android.hardware.sensors@1.0-convert"],
- // our public headers depend on libsensor
- export_shared_lib_headers: ["libsensor"],
+ // our public headers depend on libsensor and libsensorprivacy
+ export_shared_lib_headers: ["libsensor", "libsensorprivacy"],
}
cc_binary {
@@ -64,6 +65,7 @@
shared_libs: [
"libsensorservice",
+ "libsensorprivacy",
"libbinder",
"libutils",
],
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 776efab..b66cbcf 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -279,7 +279,7 @@
}
} else {
// Regular sensor event, just copy it to the scratch buffer.
- if (mHasSensorAccess) {
+ if (hasSensorAccess()) {
scratch[count++] = buffer[i];
}
}
@@ -290,7 +290,7 @@
buffer[i].meta_data.sensor == sensor_handle)));
}
} else {
- if (mHasSensorAccess) {
+ if (hasSensorAccess()) {
scratch = const_cast<sensors_event_t *>(buffer);
count = numEvents;
} else {
@@ -321,7 +321,7 @@
}
int index_wake_up_event = -1;
- if (mHasSensorAccess) {
+ if (hasSensorAccess()) {
index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
if (index_wake_up_event >= 0) {
scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
@@ -375,6 +375,10 @@
mHasSensorAccess = hasAccess;
}
+bool SensorService::SensorEventConnection::hasSensorAccess() {
+ return mHasSensorAccess && !mService->mSensorPrivacyPolicy->isSensorPrivacyEnabled();
+}
+
void SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch,
int count) {
sensors_event_t *eventCache_new;
@@ -491,7 +495,7 @@
for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
const int numEventsToWrite = helpers::min(mCacheSize - numEventsSent, maxWriteSize);
int index_wake_up_event = -1;
- if (mHasSensorAccess) {
+ if (hasSensorAccess()) {
index_wake_up_event =
findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite);
if (index_wake_up_event >= 0) {
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 061809f..7077880 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -130,6 +130,10 @@
void updateLooperRegistration(const sp<Looper>& looper); void
updateLooperRegistrationLocked(const sp<Looper>& looper);
+ // Returns whether sensor access is available based on both the uid being active and sensor
+ // privacy not being enabled.
+ bool hasSensorAccess();
+
sp<SensorService> const mService;
sp<BitTube> mChannel;
uid_t mUid;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 85450f8..9a37ff1 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -29,6 +29,7 @@
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <sensor/SensorEventQueue.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
#include <utils/SystemClock.h>
#include "BatteryService.h"
@@ -88,6 +89,7 @@
: mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
mWakeLockAcquired(false) {
mUidPolicy = new UidPolicy(this);
+ mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
}
bool SensorService::initializeHmacKey() {
@@ -286,6 +288,9 @@
// Start watching UID changes to apply policy.
mUidPolicy->registerSelf();
+
+ // Start watching sensor privacy changes
+ mSensorPrivacyPolicy->registerSelf();
}
}
}
@@ -338,6 +343,7 @@
delete entry.second;
}
mUidPolicy->unregisterSelf();
+ mSensorPrivacyPolicy->unregisterSelf();
}
status_t SensorService::dump(int fd, const Vector<String16>& args) {
@@ -364,35 +370,16 @@
}
mCurrentOperatingMode = RESTRICTED;
- // temporarily stop all sensor direct report
- for (auto &i : mDirectConnections) {
- sp<SensorDirectConnection> connection(i.promote());
- if (connection != nullptr) {
- connection->stopAll(true /* backupRecord */);
- }
- }
-
- dev.disableAllSensors();
- // Clear all pending flush connections for all active sensors. If one of the active
- // connections has called flush() and the underlying sensor has been disabled before a
- // flush complete event is returned, we need to remove the connection from this queue.
- for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
- mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
- }
+ // temporarily stop all sensor direct report and disable sensors
+ disableAllSensorsLocked();
mWhiteListedPackage.setTo(String8(args[1]));
return status_t(NO_ERROR);
} else if (args.size() == 1 && args[0] == String16("enable")) {
// If currently in restricted mode, reset back to NORMAL mode else ignore.
if (mCurrentOperatingMode == RESTRICTED) {
mCurrentOperatingMode = NORMAL;
- dev.enableAllSensors();
- // recover all sensor direct report
- for (auto &i : mDirectConnections) {
- sp<SensorDirectConnection> connection(i.promote());
- if (connection != nullptr) {
- connection->recoverAll();
- }
- }
+ // enable sensors and recover all sensor direct report
+ enableAllSensorsLocked();
}
if (mCurrentOperatingMode == DATA_INJECTION) {
resetToNormalModeLocked();
@@ -477,6 +464,8 @@
case DATA_INJECTION:
result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
}
+ result.appendFormat("Sensor Privacy: %s\n",
+ mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled");
result.appendFormat("%zd active connections\n", mActiveConnections.size());
for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
@@ -519,6 +508,52 @@
return NO_ERROR;
}
+void SensorService::disableAllSensors() {
+ Mutex::Autolock _l(mLock);
+ disableAllSensorsLocked();
+}
+
+void SensorService::disableAllSensorsLocked() {
+ SensorDevice& dev(SensorDevice::getInstance());
+ for (auto &i : mDirectConnections) {
+ sp<SensorDirectConnection> connection(i.promote());
+ if (connection != nullptr) {
+ connection->stopAll(true /* backupRecord */);
+ }
+ }
+ dev.disableAllSensors();
+ // Clear all pending flush connections for all active sensors. If one of the active
+ // connections has called flush() and the underlying sensor has been disabled before a
+ // flush complete event is returned, we need to remove the connection from this queue.
+ for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
+ mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
+ }
+}
+
+void SensorService::enableAllSensors() {
+ Mutex::Autolock _l(mLock);
+ enableAllSensorsLocked();
+}
+
+void SensorService::enableAllSensorsLocked() {
+ // sensors should only be enabled if the operating state is not restricted and sensor
+ // privacy is not enabled.
+ if (mCurrentOperatingMode == RESTRICTED || mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+ ALOGW("Sensors cannot be enabled: mCurrentOperatingMode = %d, sensor privacy = %s",
+ mCurrentOperatingMode,
+ mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled");
+ return;
+ }
+ SensorDevice& dev(SensorDevice::getInstance());
+ dev.enableAllSensors();
+ for (auto &i : mDirectConnections) {
+ sp<SensorDirectConnection> connection(i.promote());
+ if (connection != nullptr) {
+ connection->recoverAll();
+ }
+ }
+}
+
// 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) {
if (!checkCallingPermission(sManageSensorsPermission, nullptr, nullptr)) {
@@ -1076,6 +1111,12 @@
const native_handle *resource) {
Mutex::Autolock _l(mLock);
+ // No new direct connections are allowed when sensor privacy is enabled
+ if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+ ALOGE("Cannot create new direct connections when sensor privacy is enabled");
+ return nullptr;
+ }
+
struct sensors_direct_mem_t mem = {
.type = type,
.format = format,
@@ -1753,4 +1794,31 @@
return mActiveUids.find(uid) != mActiveUids.end();
}
+void SensorService::SensorPrivacyPolicy::registerSelf() {
+ SensorPrivacyManager spm;
+ mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
+ spm.addSensorPrivacyListener(this);
+}
+
+void SensorService::SensorPrivacyPolicy::unregisterSelf() {
+ SensorPrivacyManager spm;
+ spm.removeSensorPrivacyListener(this);
+}
+
+bool SensorService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
+ return mSensorPrivacyEnabled;
+}
+
+binder::Status SensorService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
+ mSensorPrivacyEnabled = enabled;
+ sp<SensorService> service = mService.promote();
+ if (service != nullptr) {
+ if (enabled) {
+ service->disableAllSensors();
+ } else {
+ service->enableAllSensors();
+ }
+ }
+ return binder::Status::ok();
+}
}; // namespace android
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 24b0dd7..136ee27 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -26,6 +26,7 @@
#include <sensor/ISensorServer.h>
#include <sensor/ISensorEventConnection.h>
#include <sensor/Sensor.h>
+#include "android/hardware/BnSensorPrivacyListener.h"
#include <utils/AndroidThreads.h>
#include <utils/KeyedVector.h>
@@ -132,6 +133,30 @@
std::unordered_map<uid_t, bool> mOverrideUids;
};
+ // Sensor privacy allows a user to disable access to all sensors on the device. When
+ // enabled sensor privacy will prevent all apps, including active apps, from accessing
+ // sensors, they will not receive trigger nor on-change events, flush event behavior
+ // does not change, and recurring events are the same as the first one delivered when
+ // sensor privacy was enabled. All sensor direct connections will be stopped as well
+ // and new direct connections will not be allowed while sensor privacy is enabled.
+ // Once sensor privacy is disabled access to sensors will be restored for active
+ // apps, previously stopped direct connections will be restarted, and new direct
+ // connections will be allowed again.
+ class SensorPrivacyPolicy : public hardware::BnSensorPrivacyListener {
+ public:
+ explicit SensorPrivacyPolicy(wp<SensorService> service) : mService(service) {}
+ void registerSelf();
+ void unregisterSelf();
+
+ bool isSensorPrivacyEnabled();
+
+ binder::Status onSensorPrivacyChanged(bool enabled);
+
+ private:
+ wp<SensorService> mService;
+ std::atomic_bool mSensorPrivacyEnabled;
+ };
+
enum Mode {
// The regular operating mode where any application can register/unregister/call flush on
// sensors.
@@ -275,6 +300,13 @@
// Prints the shell command help
status_t printHelp(int out);
+ // temporarily stops all active direct connections and disables all sensors
+ void disableAllSensors();
+ void disableAllSensorsLocked();
+ // restarts the previously stopped direct connections and enables all sensors
+ void enableAllSensors();
+ void enableAllSensorsLocked();
+
static uint8_t sHmacGlobalKey[128];
static bool sHmacGlobalKeyIsValid;
@@ -309,6 +341,7 @@
Vector<SensorRegistrationInfo> mLastNSensorRegistrations;
sp<UidPolicy> mUidPolicy;
+ sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
};
} // namespace android