Loading services/sensorservice/SensorService.cpp +127 −119 Original line number Original line Diff line number Diff line Loading @@ -299,14 +299,10 @@ void SensorService::onFirstRef() { } } void SensorService::setSensorAccess(uid_t uid, bool hasAccess) { void SensorService::setSensorAccess(uid_t uid, bool hasAccess) { SortedVector< sp<SensorEventConnection> > activeConnections; ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); populateActiveConnections(&activeConnections); for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) { { if (conn->getUid() == uid) { Mutex::Autolock _l(mLock); conn->setSensorAccess(hasAccess); for (size_t i = 0 ; i < activeConnections.size(); i++) { if (activeConnections[i] != nullptr && activeConnections[i]->getUid() == uid) { activeConnections[i]->setSensorAccess(hasAccess); } } } } } } } Loading Loading @@ -360,7 +356,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { if (args.size() > 2) { if (args.size() > 2) { return INVALID_OPERATION; return INVALID_OPERATION; } } Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance()); if (args.size() == 2 && args[0] == String16("restrict")) { if (args.size() == 2 && args[0] == String16("restrict")) { // If already in restricted mode. Ignore. // If already in restricted mode. Ignore. Loading @@ -374,7 +370,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { mCurrentOperatingMode = RESTRICTED; mCurrentOperatingMode = RESTRICTED; // temporarily stop all sensor direct report and disable sensors // temporarily stop all sensor direct report and disable sensors disableAllSensorsLocked(); disableAllSensorsLocked(&connLock); mWhiteListedPackage.setTo(String8(args[1])); mWhiteListedPackage.setTo(String8(args[1])); return status_t(NO_ERROR); return status_t(NO_ERROR); } else if (args.size() == 1 && args[0] == String16("enable")) { } else if (args.size() == 1 && args[0] == String16("enable")) { Loading @@ -382,7 +378,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { if (mCurrentOperatingMode == RESTRICTED) { if (mCurrentOperatingMode == RESTRICTED) { mCurrentOperatingMode = NORMAL; mCurrentOperatingMode = NORMAL; // enable sensors and recover all sensor direct report // enable sensors and recover all sensor direct report enableAllSensorsLocked(); enableAllSensorsLocked(&connLock); } } if (mCurrentOperatingMode == DATA_INJECTION) { if (mCurrentOperatingMode == DATA_INJECTION) { resetToNormalModeLocked(); resetToNormalModeLocked(); Loading Loading @@ -473,22 +469,18 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { result.appendFormat("Sensor Privacy: %s\n", result.appendFormat("Sensor Privacy: %s\n", mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled"); mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled"); result.appendFormat("%zd active connections\n", mActiveConnections.size()); const auto& activeConnections = connLock.getActiveConnections(); for (size_t i=0 ; i < mActiveConnections.size() ; i++) { result.appendFormat("%zd active connections\n", activeConnections.size()); sp<SensorEventConnection> connection(mActiveConnections[i].promote()); for (size_t i=0 ; i < activeConnections.size() ; i++) { if (connection != nullptr) { result.appendFormat("Connection Number: %zu \n", i); result.appendFormat("Connection Number: %zu \n", i); connection->dump(result); activeConnections[i]->dump(result); } } } result.appendFormat("%zd direct connections\n", mDirectConnections.size()); const auto& directConnections = connLock.getDirectConnections(); for (size_t i = 0 ; i < mDirectConnections.size() ; i++) { result.appendFormat("%zd direct connections\n", directConnections.size()); sp<SensorDirectConnection> connection(mDirectConnections[i].promote()); for (size_t i = 0 ; i < directConnections.size() ; i++) { if (connection != nullptr) { result.appendFormat("Direct connection %zu:\n", i); result.appendFormat("Direct connection %zu:\n", i); connection->dump(result); directConnections[i]->dump(result); } } } result.appendFormat("Previous Registrations:\n"); result.appendFormat("Previous Registrations:\n"); Loading @@ -515,18 +507,15 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { } } void SensorService::disableAllSensors() { void SensorService::disableAllSensors() { Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); disableAllSensorsLocked(); disableAllSensorsLocked(&connLock); } } void SensorService::disableAllSensorsLocked() { void SensorService::disableAllSensorsLocked(ConnectionSafeAutolock* connLock) { SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance()); for (auto &i : mDirectConnections) { for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) { sp<SensorDirectConnection> connection(i.promote()); if (connection != nullptr) { connection->stopAll(true /* backupRecord */); connection->stopAll(true /* backupRecord */); } } } dev.disableAllSensors(); dev.disableAllSensors(); // Clear all pending flush connections for all active sensors. If one of the active // 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 // connections has called flush() and the underlying sensor has been disabled before a Loading @@ -537,11 +526,11 @@ void SensorService::disableAllSensorsLocked() { } } void SensorService::enableAllSensors() { void SensorService::enableAllSensors() { Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); enableAllSensorsLocked(); enableAllSensorsLocked(&connLock); } } void SensorService::enableAllSensorsLocked() { void SensorService::enableAllSensorsLocked(ConnectionSafeAutolock* connLock) { // sensors should only be enabled if the operating state is not restricted and sensor // sensors should only be enabled if the operating state is not restricted and sensor // privacy is not enabled. // privacy is not enabled. if (mCurrentOperatingMode == RESTRICTED || mSensorPrivacyPolicy->isSensorPrivacyEnabled()) { if (mCurrentOperatingMode == RESTRICTED || mSensorPrivacyPolicy->isSensorPrivacyEnabled()) { Loading @@ -552,13 +541,11 @@ void SensorService::enableAllSensorsLocked() { } } SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance()); dev.enableAllSensors(); dev.enableAllSensors(); for (auto &i : mDirectConnections) { for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) { sp<SensorDirectConnection> connection(i.promote()); if (connection != nullptr) { connection->recoverAll(); connection->recoverAll(); } } } } } // NOTE: This is a remote API - make sure all args are validated // 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) { status_t SensorService::shellCommand(int in, int out, int err, Vector<String16>& args) { Loading Loading @@ -734,17 +721,8 @@ bool SensorService::threadLoop() { for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) { mSensorEventBuffer[i].flags = 0; mSensorEventBuffer[i].flags = 0; } } ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); // Make a copy of the connection vector as some connections may be removed during the course // of this loop (especially when one-shot sensor events are present in the sensor_event // buffer). Promote all connections to StrongPointers before the lock is acquired. If the // destructor of the sp gets called when the lock is acquired, it may result in a deadlock // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the // strongPointers to a vector before the lock is acquired. SortedVector< sp<SensorEventConnection> > activeConnections; populateActiveConnections(&activeConnections); Mutex::Autolock _l(mLock); // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should Loading Loading @@ -818,6 +796,10 @@ bool SensorService::threadLoop() { } } } } // Cache the list of active connections, since we use it in multiple places below but won't // modify it here const std::vector<sp<SensorEventConnection>> activeConnections = connLock.getActiveConnections(); for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) { // Map flush_complete_events in the buffer to SensorEventConnections which called flush // Map flush_complete_events in the buffer to SensorEventConnections which called flush // on the hardware sensor. mapFlushEventsToConnections[i] will be the // on the hardware sensor. mapFlushEventsToConnections[i] will be the Loading Loading @@ -869,11 +851,8 @@ bool SensorService::threadLoop() { ALOGE("Dynamic sensor release error."); ALOGE("Dynamic sensor release error."); } } size_t numConnections = activeConnections.size(); for (const sp<SensorEventConnection>& connection : activeConnections) { for (size_t i=0 ; i < numConnections; ++i) { connection->removeSensor(handle); if (activeConnections[i] != nullptr) { activeConnections[i]->removeSensor(handle); } } } } } } } Loading @@ -882,18 +861,14 @@ bool SensorService::threadLoop() { // Send our events to clients. Check the state of wake lock for each client and release the // Send our events to clients. Check the state of wake lock for each client and release the // lock if none of the clients need it. // lock if none of the clients need it. bool needsWakeLock = false; bool needsWakeLock = false; size_t numConnections = activeConnections.size(); for (const sp<SensorEventConnection>& connection : activeConnections) { for (size_t i=0 ; i < numConnections; ++i) { connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, if (activeConnections[i] != nullptr) { activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, mMapFlushEventsToConnections); mMapFlushEventsToConnections); needsWakeLock |= activeConnections[i]->needsWakeLock(); needsWakeLock |= connection->needsWakeLock(); // If the connection has one-shot sensors, it may be cleaned up after first trigger. // If the connection has one-shot sensors, it may be cleaned up after first trigger. // Early check for one-shot sensors. // Early check for one-shot sensors. if (activeConnections[i]->hasOneShotSensors()) { if (connection->hasOneShotSensors()) { cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer, cleanupAutoDisabledSensorLocked(connection, mSensorEventBuffer, count); count); } } } } } Loading @@ -912,18 +887,12 @@ sp<Looper> SensorService::getLooper() const { } } void SensorService::resetAllWakeLockRefCounts() { void SensorService::resetAllWakeLockRefCounts() { SortedVector< sp<SensorEventConnection> > activeConnections; ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); populateActiveConnections(&activeConnections); for (const sp<SensorEventConnection>& connection : connLock.getActiveConnections()) { { connection->resetWakeLockRefCount(); Mutex::Autolock _l(mLock); for (size_t i=0 ; i < activeConnections.size(); ++i) { if (activeConnections[i] != nullptr) { activeConnections[i]->resetWakeLockRefCount(); } } } setWakeLockAcquiredLocked(false); setWakeLockAcquiredLocked(false); } } } void SensorService::setWakeLockAcquiredLocked(bool acquire) { void SensorService::setWakeLockAcquiredLocked(bool acquire) { if (acquire) { if (acquire) { Loading Loading @@ -1144,9 +1113,7 @@ sp<ISensorEventConnection> SensorService::createSensorEventConnection(const Stri sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName, sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName, requestedMode == DATA_INJECTION, connOpPackageName, hasSensorAccess)); requestedMode == DATA_INJECTION, connOpPackageName, hasSensorAccess)); if (requestedMode == DATA_INJECTION) { if (requestedMode == DATA_INJECTION) { if (mActiveConnections.indexOf(result) < 0) { mConnectionHolder.addEventConnectionIfNotPresent(result); mActiveConnections.add(result); } // Add the associated file descriptor to the Looper for polling whenever there is data to // Add the associated file descriptor to the Looper for polling whenever there is data to // be injected. // be injected. result->updateLooperRegistration(mLooper); result->updateLooperRegistration(mLooper); Loading @@ -1162,7 +1129,7 @@ int SensorService::isDataInjectionEnabled() { sp<ISensorEventConnection> SensorService::createSensorDirectConnection( sp<ISensorEventConnection> SensorService::createSensorDirectConnection( const String16& opPackageName, uint32_t size, int32_t type, int32_t format, const String16& opPackageName, uint32_t size, int32_t type, int32_t format, const native_handle *resource) { const native_handle *resource) { Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); // No new direct connections are allowed when sensor privacy is enabled // No new direct connections are allowed when sensor privacy is enabled if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) { if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) { Loading Loading @@ -1190,9 +1157,8 @@ sp<ISensorEventConnection> SensorService::createSensorDirectConnection( } } // check for duplication // check for duplication for (auto &i : mDirectConnections) { for (const sp<SensorDirectConnection>& connection : connLock.getDirectConnections()) { sp<SensorDirectConnection> connection(i.promote()); if (connection->isEquivalent(&mem)) { if (connection != nullptr && connection->isEquivalent(&mem)) { ALOGE("Duplicate create channel request for the same share memory"); ALOGE("Duplicate create channel request for the same share memory"); return nullptr; return nullptr; } } Loading Loading @@ -1229,7 +1195,7 @@ sp<ISensorEventConnection> SensorService::createSensorDirectConnection( return nullptr; return nullptr; } } SensorDirectConnection* conn = nullptr; sp<SensorDirectConnection> conn; SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance()); int channelHandle = dev.registerDirectChannel(&mem); int channelHandle = dev.registerDirectChannel(&mem); Loading @@ -1246,7 +1212,7 @@ sp<ISensorEventConnection> SensorService::createSensorDirectConnection( } else { } else { // add to list of direct connections // add to list of direct connections // sensor service should never hold pointer or sp of SensorDirectConnection object. // sensor service should never hold pointer or sp of SensorDirectConnection object. mDirectConnections.add(wp<SensorDirectConnection>(conn)); mConnectionHolder.addDirectConnection(conn); } } return conn; return conn; } } Loading Loading @@ -1358,7 +1324,7 @@ status_t SensorService::resetToNormalModeLocked() { } } void SensorService::cleanupConnection(SensorEventConnection* c) { void SensorService::cleanupConnection(SensorEventConnection* c) { Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); const wp<SensorEventConnection> connection(c); const wp<SensorEventConnection> connection(c); size_t size = mActiveSensors.size(); size_t size = mActiveSensors.size(); ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size); ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size); Loading Loading @@ -1391,10 +1357,10 @@ void SensorService::cleanupConnection(SensorEventConnection* c) { } } } } c->updateLooperRegistration(mLooper); c->updateLooperRegistration(mLooper); mActiveConnections.remove(connection); mConnectionHolder.removeEventConnection(connection); BatteryService::cleanup(c->getUid()); BatteryService::cleanup(c->getUid()); if (c->needsWakeLock()) { if (c->needsWakeLock()) { checkWakeLockStateLocked(); checkWakeLockStateLocked(&connLock); } } { { Loading @@ -1414,7 +1380,7 @@ void SensorService::cleanupConnection(SensorDirectConnection* c) { SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance()); dev.unregisterDirectChannel(c->getHalChannelHandle()); dev.unregisterDirectChannel(c->getHalChannelHandle()); mDirectConnections.remove(c); mConnectionHolder.removeDirectConnection(c); } } sp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const { sp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const { Loading @@ -1433,7 +1399,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, return BAD_VALUE; return BAD_VALUE; } } Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); if (mCurrentOperatingMode != NORMAL if (mCurrentOperatingMode != NORMAL && !isWhiteListedPackage(connection->getPackageName())) { && !isWhiteListedPackage(connection->getPackageName())) { return INVALID_OPERATION; return INVALID_OPERATION; Loading Loading @@ -1484,7 +1450,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, } } connection->sendEvents(&event, 1, nullptr); connection->sendEvents(&event, 1, nullptr); if (!connection->needsWakeLock() && mWakeLockAcquired) { if (!connection->needsWakeLock() && mWakeLockAcquired) { checkWakeLockStateLocked(); checkWakeLockStateLocked(&connLock); } } } } } } Loading @@ -1497,9 +1463,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, BatteryService::enableSensor(connection->getUid(), handle); BatteryService::enableSensor(connection->getUid(), handle); // the sensor was added (which means it wasn't already there) // the sensor was added (which means it wasn't already there) // so, see if this connection becomes active // so, see if this connection becomes active if (mActiveConnections.indexOf(connection) < 0) { mConnectionHolder.addEventConnectionIfNotPresent(connection); mActiveConnections.add(connection); } } else { } else { ALOGW("sensor %08x already enabled in connection %p (ignoring)", ALOGW("sensor %08x already enabled in connection %p (ignoring)", handle, connection.get()); handle, connection.get()); Loading Loading @@ -1603,7 +1567,7 @@ status_t SensorService::cleanupWithoutDisableLocked( } } if (connection->hasAnySensor() == false) { if (connection->hasAnySensor() == false) { connection->updateLooperRegistration(mLooper); connection->updateLooperRegistration(mLooper); mActiveConnections.remove(connection); mConnectionHolder.removeEventConnection(connection); } } // see if this sensor becomes inactive // see if this sensor becomes inactive if (rec->removeConnection(connection)) { if (rec->removeConnection(connection)) { Loading Loading @@ -1762,24 +1726,21 @@ int SensorService::getTargetSdkVersion(const String16& opPackageName) { } } void SensorService::checkWakeLockState() { void SensorService::checkWakeLockState() { Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); checkWakeLockStateLocked(); checkWakeLockStateLocked(&connLock); } } void SensorService::checkWakeLockStateLocked() { void SensorService::checkWakeLockStateLocked(ConnectionSafeAutolock* connLock) { if (!mWakeLockAcquired) { if (!mWakeLockAcquired) { return; return; } } bool releaseLock = true; bool releaseLock = true; for (size_t i=0 ; i<mActiveConnections.size() ; i++) { for (const sp<SensorEventConnection>& connection : connLock->getActiveConnections()) { sp<SensorEventConnection> connection(mActiveConnections[i].promote()); if (connection != nullptr) { if (connection->needsWakeLock()) { if (connection->needsWakeLock()) { releaseLock = false; releaseLock = false; break; break; } } } } } if (releaseLock) { if (releaseLock) { setWakeLockAcquiredLocked(false); setWakeLockAcquiredLocked(false); } } Loading @@ -1793,17 +1754,6 @@ void SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connect } } } } void SensorService::populateActiveConnections( SortedVector< sp<SensorEventConnection> >* activeConnections) { Mutex::Autolock _l(mLock); for (size_t i=0 ; i < mActiveConnections.size(); ++i) { sp<SensorEventConnection> connection(mActiveConnections[i].promote()); if (connection != nullptr) { activeConnections->add(connection); } } } bool SensorService::isWhiteListedPackage(const String8& packageName) { bool SensorService::isWhiteListedPackage(const String8& packageName) { return (packageName.contains(mWhiteListedPackage.string())); return (packageName.contains(mWhiteListedPackage.string())); } } Loading Loading @@ -1938,4 +1888,62 @@ binder::Status SensorService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool e } } return binder::Status::ok(); return binder::Status::ok(); } } }; // namespace android SensorService::ConnectionSafeAutolock::ConnectionSafeAutolock( SensorService::SensorConnectionHolder& holder, Mutex& mutex) : mConnectionHolder(holder), mAutolock(mutex) {} template<typename ConnectionType> const std::vector<sp<ConnectionType>>& SensorService::ConnectionSafeAutolock::getConnectionsHelper( const SortedVector<wp<ConnectionType>>& connectionList, std::vector<std::vector<sp<ConnectionType>>>* referenceHolder) { referenceHolder->emplace_back(); std::vector<sp<ConnectionType>>& connections = referenceHolder->back(); for (const wp<ConnectionType>& weakConnection : connectionList){ sp<ConnectionType> connection = weakConnection.promote(); if (connection != nullptr) { connections.push_back(std::move(connection)); } } return connections; } const std::vector<sp<SensorService::SensorEventConnection>>& SensorService::ConnectionSafeAutolock::getActiveConnections() { return getConnectionsHelper(mConnectionHolder.mActiveConnections, &mReferencedActiveConnections); } const std::vector<sp<SensorService::SensorDirectConnection>>& SensorService::ConnectionSafeAutolock::getDirectConnections() { return getConnectionsHelper(mConnectionHolder.mDirectConnections, &mReferencedDirectConnections); } void SensorService::SensorConnectionHolder::addEventConnectionIfNotPresent( const sp<SensorService::SensorEventConnection>& connection) { if (mActiveConnections.indexOf(connection) < 0) { mActiveConnections.add(connection); } } void SensorService::SensorConnectionHolder::removeEventConnection( const wp<SensorService::SensorEventConnection>& connection) { mActiveConnections.remove(connection); } void SensorService::SensorConnectionHolder::addDirectConnection( const sp<SensorService::SensorDirectConnection>& connection) { mDirectConnections.add(connection); } void SensorService::SensorConnectionHolder::removeDirectConnection( const wp<SensorService::SensorDirectConnection>& connection) { mDirectConnections.remove(connection); } SensorService::ConnectionSafeAutolock SensorService::SensorConnectionHolder::lock(Mutex& mutex) { return ConnectionSafeAutolock(*this, mutex); } } // namespace android services/sensorservice/SensorService.h +66 −10 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "SensorList.h" #include "SensorList.h" #include "RecentEventLogger.h" #include "RecentEventLogger.h" #include <android-base/macros.h> #include <binder/AppOpsManager.h> #include <binder/AppOpsManager.h> #include <binder/BinderService.h> #include <binder/BinderService.h> #include <binder/IUidObserver.h> #include <binder/IUidObserver.h> Loading @@ -42,6 +43,7 @@ #include <sys/types.h> #include <sys/types.h> #include <unordered_map> #include <unordered_map> #include <unordered_set> #include <unordered_set> #include <vector> #if __clang__ #if __clang__ // Clang warns about SensorEventConnection::dump hiding BBinder::dump. The cause isn't fixable // Clang warns about SensorEventConnection::dump hiding BBinder::dump. The cause isn't fixable Loading Loading @@ -95,10 +97,67 @@ private: friend class BinderService<SensorService>; friend class BinderService<SensorService>; // nested class/struct for internal use // nested class/struct for internal use class SensorRecord; class ConnectionSafeAutolock; class SensorConnectionHolder; class SensorEventAckReceiver; class SensorEventAckReceiver; class SensorRecord; class SensorRegistrationInfo; class SensorRegistrationInfo; // Promoting a SensorEventConnection or SensorDirectConnection from wp to sp must be done with // mLock held, but destroying that sp must be done unlocked to avoid a race condition that // causes a deadlock (remote dies while we hold a local sp, then our decStrong() call invokes // the dtor -> cleanupConnection() tries to re-lock the mutex). This class ensures safe usage // by wrapping a Mutex::Autolock on SensorService's mLock, plus vectors that hold promoted sp<> // references until the lock is released, when they are safely destroyed. // All read accesses to the connection lists in mConnectionHolder must be done via this class. class ConnectionSafeAutolock final { public: // Returns a list of non-null promoted connection references const std::vector<sp<SensorEventConnection>>& getActiveConnections(); const std::vector<sp<SensorDirectConnection>>& getDirectConnections(); private: // Constructed via SensorConnectionHolder::lock() friend class SensorConnectionHolder; explicit ConnectionSafeAutolock(SensorConnectionHolder& holder, Mutex& mutex); DISALLOW_IMPLICIT_CONSTRUCTORS(ConnectionSafeAutolock); // NOTE: Order of these members is important, as the destructor for non-static members // get invoked in the reverse order of their declaration. Here we are relying on the // Autolock to be destroyed *before* the vectors, so the sp<> objects are destroyed without // the lock held, which avoids the deadlock. SensorConnectionHolder& mConnectionHolder; std::vector<std::vector<sp<SensorEventConnection>>> mReferencedActiveConnections; std::vector<std::vector<sp<SensorDirectConnection>>> mReferencedDirectConnections; Mutex::Autolock mAutolock; template<typename ConnectionType> const std::vector<sp<ConnectionType>>& getConnectionsHelper( const SortedVector<wp<ConnectionType>>& connectionList, std::vector<std::vector<sp<ConnectionType>>>* referenceHolder); }; // Encapsulates the collection of active SensorEventConection and SensorDirectConnection // references. Write access is done through this class with mLock held, but all read access // must be routed through ConnectionSafeAutolock. class SensorConnectionHolder { public: void addEventConnectionIfNotPresent(const sp<SensorEventConnection>& connection); void removeEventConnection(const wp<SensorEventConnection>& connection); void addDirectConnection(const sp<SensorDirectConnection>& connection); void removeDirectConnection(const wp<SensorDirectConnection>& connection); // Pass in the mutex that protects this connection holder; acquires the lock and returns an // object that can be used to safely read the lists of connections ConnectionSafeAutolock lock(Mutex& mutex); private: friend class ConnectionSafeAutolock; SortedVector< wp<SensorEventConnection> > mActiveConnections; SortedVector< wp<SensorDirectConnection> > mDirectConnections; }; // If accessing a sensor we need to make sure the UID has access to it. If // If accessing a sensor we need to make sure the UID has access to it. If // the app UID is idle then it cannot access sensors and gets no trigger // the app UID is idle then it cannot access sensors and gets no trigger // events, no on-change events, flush event behavior does not change, and // events, no on-change events, flush event behavior does not change, and Loading Loading @@ -250,7 +309,7 @@ private: // method checks whether all the events from these wake up sensors have been delivered to the // method checks whether all the events from these wake up sensors have been delivered to the // corresponding applications, if yes the wakelock is released. // corresponding applications, if yes the wakelock is released. void checkWakeLockState(); void checkWakeLockState(); void checkWakeLockStateLocked(); void checkWakeLockStateLocked(ConnectionSafeAutolock* connLock); bool isWakeLockAcquired(); bool isWakeLockAcquired(); bool isWakeUpSensorEvent(const sensors_event_t& event) const; bool isWakeUpSensorEvent(const sensors_event_t& event) const; Loading @@ -268,10 +327,6 @@ private: // Send events from the event cache for this particular connection. // Send events from the event cache for this particular connection. void sendEventsFromCache(const sp<SensorEventConnection>& connection); void sendEventsFromCache(const sp<SensorEventConnection>& connection); // Promote all weak referecences in mActiveConnections vector to strong references and add them // to the output vector. void populateActiveConnections( SortedVector< sp<SensorEventConnection> >* activeConnections); // If SensorService is operating in RESTRICTED mode, only select whitelisted packages are // If SensorService is operating in RESTRICTED mode, only select whitelisted packages are // allowed to register for or call flush on sensors. Typically only cts test packages are // allowed to register for or call flush on sensors. Typically only cts test packages are // allowed. // allowed. Loading Loading @@ -306,10 +361,10 @@ private: // temporarily stops all active direct connections and disables all sensors // temporarily stops all active direct connections and disables all sensors void disableAllSensors(); void disableAllSensors(); void disableAllSensorsLocked(); void disableAllSensorsLocked(ConnectionSafeAutolock* connLock); // restarts the previously stopped direct connections and enables all sensors // restarts the previously stopped direct connections and enables all sensors void enableAllSensors(); void enableAllSensors(); void enableAllSensorsLocked(); void enableAllSensorsLocked(ConnectionSafeAutolock* connLock); static uint8_t sHmacGlobalKey[128]; static uint8_t sHmacGlobalKey[128]; static bool sHmacGlobalKeyIsValid; static bool sHmacGlobalKeyIsValid; Loading @@ -327,12 +382,13 @@ private: mutable Mutex mLock; mutable Mutex mLock; DefaultKeyedVector<int, SensorRecord*> mActiveSensors; DefaultKeyedVector<int, SensorRecord*> mActiveSensors; std::unordered_set<int> mActiveVirtualSensors; std::unordered_set<int> mActiveVirtualSensors; SortedVector< wp<SensorEventConnection> > mActiveConnections; SensorConnectionHolder mConnectionHolder; bool mWakeLockAcquired; bool mWakeLockAcquired; sensors_event_t *mSensorEventBuffer, *mSensorEventScratch; sensors_event_t *mSensorEventBuffer, *mSensorEventScratch; // WARNING: these SensorEventConnection instances must not be promoted to sp, except via // modification to add support for them in ConnectionSafeAutolock wp<const SensorEventConnection> * mMapFlushEventsToConnections; wp<const SensorEventConnection> * mMapFlushEventsToConnections; std::unordered_map<int, SensorServiceUtil::RecentEventLogger*> mRecentEvent; std::unordered_map<int, SensorServiceUtil::RecentEventLogger*> mRecentEvent; SortedVector< wp<SensorDirectConnection> > mDirectConnections; Mode mCurrentOperatingMode; Mode mCurrentOperatingMode; // This packagaName is set when SensorService is in RESTRICTED or DATA_INJECTION mode. Only // This packagaName is set when SensorService is in RESTRICTED or DATA_INJECTION mode. Only Loading Loading
services/sensorservice/SensorService.cpp +127 −119 Original line number Original line Diff line number Diff line Loading @@ -299,14 +299,10 @@ void SensorService::onFirstRef() { } } void SensorService::setSensorAccess(uid_t uid, bool hasAccess) { void SensorService::setSensorAccess(uid_t uid, bool hasAccess) { SortedVector< sp<SensorEventConnection> > activeConnections; ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); populateActiveConnections(&activeConnections); for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) { { if (conn->getUid() == uid) { Mutex::Autolock _l(mLock); conn->setSensorAccess(hasAccess); for (size_t i = 0 ; i < activeConnections.size(); i++) { if (activeConnections[i] != nullptr && activeConnections[i]->getUid() == uid) { activeConnections[i]->setSensorAccess(hasAccess); } } } } } } } Loading Loading @@ -360,7 +356,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { if (args.size() > 2) { if (args.size() > 2) { return INVALID_OPERATION; return INVALID_OPERATION; } } Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance()); if (args.size() == 2 && args[0] == String16("restrict")) { if (args.size() == 2 && args[0] == String16("restrict")) { // If already in restricted mode. Ignore. // If already in restricted mode. Ignore. Loading @@ -374,7 +370,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { mCurrentOperatingMode = RESTRICTED; mCurrentOperatingMode = RESTRICTED; // temporarily stop all sensor direct report and disable sensors // temporarily stop all sensor direct report and disable sensors disableAllSensorsLocked(); disableAllSensorsLocked(&connLock); mWhiteListedPackage.setTo(String8(args[1])); mWhiteListedPackage.setTo(String8(args[1])); return status_t(NO_ERROR); return status_t(NO_ERROR); } else if (args.size() == 1 && args[0] == String16("enable")) { } else if (args.size() == 1 && args[0] == String16("enable")) { Loading @@ -382,7 +378,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { if (mCurrentOperatingMode == RESTRICTED) { if (mCurrentOperatingMode == RESTRICTED) { mCurrentOperatingMode = NORMAL; mCurrentOperatingMode = NORMAL; // enable sensors and recover all sensor direct report // enable sensors and recover all sensor direct report enableAllSensorsLocked(); enableAllSensorsLocked(&connLock); } } if (mCurrentOperatingMode == DATA_INJECTION) { if (mCurrentOperatingMode == DATA_INJECTION) { resetToNormalModeLocked(); resetToNormalModeLocked(); Loading Loading @@ -473,22 +469,18 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { result.appendFormat("Sensor Privacy: %s\n", result.appendFormat("Sensor Privacy: %s\n", mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled"); mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled"); result.appendFormat("%zd active connections\n", mActiveConnections.size()); const auto& activeConnections = connLock.getActiveConnections(); for (size_t i=0 ; i < mActiveConnections.size() ; i++) { result.appendFormat("%zd active connections\n", activeConnections.size()); sp<SensorEventConnection> connection(mActiveConnections[i].promote()); for (size_t i=0 ; i < activeConnections.size() ; i++) { if (connection != nullptr) { result.appendFormat("Connection Number: %zu \n", i); result.appendFormat("Connection Number: %zu \n", i); connection->dump(result); activeConnections[i]->dump(result); } } } result.appendFormat("%zd direct connections\n", mDirectConnections.size()); const auto& directConnections = connLock.getDirectConnections(); for (size_t i = 0 ; i < mDirectConnections.size() ; i++) { result.appendFormat("%zd direct connections\n", directConnections.size()); sp<SensorDirectConnection> connection(mDirectConnections[i].promote()); for (size_t i = 0 ; i < directConnections.size() ; i++) { if (connection != nullptr) { result.appendFormat("Direct connection %zu:\n", i); result.appendFormat("Direct connection %zu:\n", i); connection->dump(result); directConnections[i]->dump(result); } } } result.appendFormat("Previous Registrations:\n"); result.appendFormat("Previous Registrations:\n"); Loading @@ -515,18 +507,15 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { } } void SensorService::disableAllSensors() { void SensorService::disableAllSensors() { Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); disableAllSensorsLocked(); disableAllSensorsLocked(&connLock); } } void SensorService::disableAllSensorsLocked() { void SensorService::disableAllSensorsLocked(ConnectionSafeAutolock* connLock) { SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance()); for (auto &i : mDirectConnections) { for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) { sp<SensorDirectConnection> connection(i.promote()); if (connection != nullptr) { connection->stopAll(true /* backupRecord */); connection->stopAll(true /* backupRecord */); } } } dev.disableAllSensors(); dev.disableAllSensors(); // Clear all pending flush connections for all active sensors. If one of the active // 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 // connections has called flush() and the underlying sensor has been disabled before a Loading @@ -537,11 +526,11 @@ void SensorService::disableAllSensorsLocked() { } } void SensorService::enableAllSensors() { void SensorService::enableAllSensors() { Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); enableAllSensorsLocked(); enableAllSensorsLocked(&connLock); } } void SensorService::enableAllSensorsLocked() { void SensorService::enableAllSensorsLocked(ConnectionSafeAutolock* connLock) { // sensors should only be enabled if the operating state is not restricted and sensor // sensors should only be enabled if the operating state is not restricted and sensor // privacy is not enabled. // privacy is not enabled. if (mCurrentOperatingMode == RESTRICTED || mSensorPrivacyPolicy->isSensorPrivacyEnabled()) { if (mCurrentOperatingMode == RESTRICTED || mSensorPrivacyPolicy->isSensorPrivacyEnabled()) { Loading @@ -552,13 +541,11 @@ void SensorService::enableAllSensorsLocked() { } } SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance()); dev.enableAllSensors(); dev.enableAllSensors(); for (auto &i : mDirectConnections) { for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) { sp<SensorDirectConnection> connection(i.promote()); if (connection != nullptr) { connection->recoverAll(); connection->recoverAll(); } } } } } // NOTE: This is a remote API - make sure all args are validated // 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) { status_t SensorService::shellCommand(int in, int out, int err, Vector<String16>& args) { Loading Loading @@ -734,17 +721,8 @@ bool SensorService::threadLoop() { for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) { mSensorEventBuffer[i].flags = 0; mSensorEventBuffer[i].flags = 0; } } ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); // Make a copy of the connection vector as some connections may be removed during the course // of this loop (especially when one-shot sensor events are present in the sensor_event // buffer). Promote all connections to StrongPointers before the lock is acquired. If the // destructor of the sp gets called when the lock is acquired, it may result in a deadlock // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the // strongPointers to a vector before the lock is acquired. SortedVector< sp<SensorEventConnection> > activeConnections; populateActiveConnections(&activeConnections); Mutex::Autolock _l(mLock); // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should Loading Loading @@ -818,6 +796,10 @@ bool SensorService::threadLoop() { } } } } // Cache the list of active connections, since we use it in multiple places below but won't // modify it here const std::vector<sp<SensorEventConnection>> activeConnections = connLock.getActiveConnections(); for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) { // Map flush_complete_events in the buffer to SensorEventConnections which called flush // Map flush_complete_events in the buffer to SensorEventConnections which called flush // on the hardware sensor. mapFlushEventsToConnections[i] will be the // on the hardware sensor. mapFlushEventsToConnections[i] will be the Loading Loading @@ -869,11 +851,8 @@ bool SensorService::threadLoop() { ALOGE("Dynamic sensor release error."); ALOGE("Dynamic sensor release error."); } } size_t numConnections = activeConnections.size(); for (const sp<SensorEventConnection>& connection : activeConnections) { for (size_t i=0 ; i < numConnections; ++i) { connection->removeSensor(handle); if (activeConnections[i] != nullptr) { activeConnections[i]->removeSensor(handle); } } } } } } } Loading @@ -882,18 +861,14 @@ bool SensorService::threadLoop() { // Send our events to clients. Check the state of wake lock for each client and release the // Send our events to clients. Check the state of wake lock for each client and release the // lock if none of the clients need it. // lock if none of the clients need it. bool needsWakeLock = false; bool needsWakeLock = false; size_t numConnections = activeConnections.size(); for (const sp<SensorEventConnection>& connection : activeConnections) { for (size_t i=0 ; i < numConnections; ++i) { connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, if (activeConnections[i] != nullptr) { activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, mMapFlushEventsToConnections); mMapFlushEventsToConnections); needsWakeLock |= activeConnections[i]->needsWakeLock(); needsWakeLock |= connection->needsWakeLock(); // If the connection has one-shot sensors, it may be cleaned up after first trigger. // If the connection has one-shot sensors, it may be cleaned up after first trigger. // Early check for one-shot sensors. // Early check for one-shot sensors. if (activeConnections[i]->hasOneShotSensors()) { if (connection->hasOneShotSensors()) { cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer, cleanupAutoDisabledSensorLocked(connection, mSensorEventBuffer, count); count); } } } } } Loading @@ -912,18 +887,12 @@ sp<Looper> SensorService::getLooper() const { } } void SensorService::resetAllWakeLockRefCounts() { void SensorService::resetAllWakeLockRefCounts() { SortedVector< sp<SensorEventConnection> > activeConnections; ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); populateActiveConnections(&activeConnections); for (const sp<SensorEventConnection>& connection : connLock.getActiveConnections()) { { connection->resetWakeLockRefCount(); Mutex::Autolock _l(mLock); for (size_t i=0 ; i < activeConnections.size(); ++i) { if (activeConnections[i] != nullptr) { activeConnections[i]->resetWakeLockRefCount(); } } } setWakeLockAcquiredLocked(false); setWakeLockAcquiredLocked(false); } } } void SensorService::setWakeLockAcquiredLocked(bool acquire) { void SensorService::setWakeLockAcquiredLocked(bool acquire) { if (acquire) { if (acquire) { Loading Loading @@ -1144,9 +1113,7 @@ sp<ISensorEventConnection> SensorService::createSensorEventConnection(const Stri sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName, sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName, requestedMode == DATA_INJECTION, connOpPackageName, hasSensorAccess)); requestedMode == DATA_INJECTION, connOpPackageName, hasSensorAccess)); if (requestedMode == DATA_INJECTION) { if (requestedMode == DATA_INJECTION) { if (mActiveConnections.indexOf(result) < 0) { mConnectionHolder.addEventConnectionIfNotPresent(result); mActiveConnections.add(result); } // Add the associated file descriptor to the Looper for polling whenever there is data to // Add the associated file descriptor to the Looper for polling whenever there is data to // be injected. // be injected. result->updateLooperRegistration(mLooper); result->updateLooperRegistration(mLooper); Loading @@ -1162,7 +1129,7 @@ int SensorService::isDataInjectionEnabled() { sp<ISensorEventConnection> SensorService::createSensorDirectConnection( sp<ISensorEventConnection> SensorService::createSensorDirectConnection( const String16& opPackageName, uint32_t size, int32_t type, int32_t format, const String16& opPackageName, uint32_t size, int32_t type, int32_t format, const native_handle *resource) { const native_handle *resource) { Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); // No new direct connections are allowed when sensor privacy is enabled // No new direct connections are allowed when sensor privacy is enabled if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) { if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) { Loading Loading @@ -1190,9 +1157,8 @@ sp<ISensorEventConnection> SensorService::createSensorDirectConnection( } } // check for duplication // check for duplication for (auto &i : mDirectConnections) { for (const sp<SensorDirectConnection>& connection : connLock.getDirectConnections()) { sp<SensorDirectConnection> connection(i.promote()); if (connection->isEquivalent(&mem)) { if (connection != nullptr && connection->isEquivalent(&mem)) { ALOGE("Duplicate create channel request for the same share memory"); ALOGE("Duplicate create channel request for the same share memory"); return nullptr; return nullptr; } } Loading Loading @@ -1229,7 +1195,7 @@ sp<ISensorEventConnection> SensorService::createSensorDirectConnection( return nullptr; return nullptr; } } SensorDirectConnection* conn = nullptr; sp<SensorDirectConnection> conn; SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance()); int channelHandle = dev.registerDirectChannel(&mem); int channelHandle = dev.registerDirectChannel(&mem); Loading @@ -1246,7 +1212,7 @@ sp<ISensorEventConnection> SensorService::createSensorDirectConnection( } else { } else { // add to list of direct connections // add to list of direct connections // sensor service should never hold pointer or sp of SensorDirectConnection object. // sensor service should never hold pointer or sp of SensorDirectConnection object. mDirectConnections.add(wp<SensorDirectConnection>(conn)); mConnectionHolder.addDirectConnection(conn); } } return conn; return conn; } } Loading Loading @@ -1358,7 +1324,7 @@ status_t SensorService::resetToNormalModeLocked() { } } void SensorService::cleanupConnection(SensorEventConnection* c) { void SensorService::cleanupConnection(SensorEventConnection* c) { Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); const wp<SensorEventConnection> connection(c); const wp<SensorEventConnection> connection(c); size_t size = mActiveSensors.size(); size_t size = mActiveSensors.size(); ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size); ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size); Loading Loading @@ -1391,10 +1357,10 @@ void SensorService::cleanupConnection(SensorEventConnection* c) { } } } } c->updateLooperRegistration(mLooper); c->updateLooperRegistration(mLooper); mActiveConnections.remove(connection); mConnectionHolder.removeEventConnection(connection); BatteryService::cleanup(c->getUid()); BatteryService::cleanup(c->getUid()); if (c->needsWakeLock()) { if (c->needsWakeLock()) { checkWakeLockStateLocked(); checkWakeLockStateLocked(&connLock); } } { { Loading @@ -1414,7 +1380,7 @@ void SensorService::cleanupConnection(SensorDirectConnection* c) { SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance()); dev.unregisterDirectChannel(c->getHalChannelHandle()); dev.unregisterDirectChannel(c->getHalChannelHandle()); mDirectConnections.remove(c); mConnectionHolder.removeDirectConnection(c); } } sp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const { sp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const { Loading @@ -1433,7 +1399,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, return BAD_VALUE; return BAD_VALUE; } } Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); if (mCurrentOperatingMode != NORMAL if (mCurrentOperatingMode != NORMAL && !isWhiteListedPackage(connection->getPackageName())) { && !isWhiteListedPackage(connection->getPackageName())) { return INVALID_OPERATION; return INVALID_OPERATION; Loading Loading @@ -1484,7 +1450,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, } } connection->sendEvents(&event, 1, nullptr); connection->sendEvents(&event, 1, nullptr); if (!connection->needsWakeLock() && mWakeLockAcquired) { if (!connection->needsWakeLock() && mWakeLockAcquired) { checkWakeLockStateLocked(); checkWakeLockStateLocked(&connLock); } } } } } } Loading @@ -1497,9 +1463,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, BatteryService::enableSensor(connection->getUid(), handle); BatteryService::enableSensor(connection->getUid(), handle); // the sensor was added (which means it wasn't already there) // the sensor was added (which means it wasn't already there) // so, see if this connection becomes active // so, see if this connection becomes active if (mActiveConnections.indexOf(connection) < 0) { mConnectionHolder.addEventConnectionIfNotPresent(connection); mActiveConnections.add(connection); } } else { } else { ALOGW("sensor %08x already enabled in connection %p (ignoring)", ALOGW("sensor %08x already enabled in connection %p (ignoring)", handle, connection.get()); handle, connection.get()); Loading Loading @@ -1603,7 +1567,7 @@ status_t SensorService::cleanupWithoutDisableLocked( } } if (connection->hasAnySensor() == false) { if (connection->hasAnySensor() == false) { connection->updateLooperRegistration(mLooper); connection->updateLooperRegistration(mLooper); mActiveConnections.remove(connection); mConnectionHolder.removeEventConnection(connection); } } // see if this sensor becomes inactive // see if this sensor becomes inactive if (rec->removeConnection(connection)) { if (rec->removeConnection(connection)) { Loading Loading @@ -1762,24 +1726,21 @@ int SensorService::getTargetSdkVersion(const String16& opPackageName) { } } void SensorService::checkWakeLockState() { void SensorService::checkWakeLockState() { Mutex::Autolock _l(mLock); ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); checkWakeLockStateLocked(); checkWakeLockStateLocked(&connLock); } } void SensorService::checkWakeLockStateLocked() { void SensorService::checkWakeLockStateLocked(ConnectionSafeAutolock* connLock) { if (!mWakeLockAcquired) { if (!mWakeLockAcquired) { return; return; } } bool releaseLock = true; bool releaseLock = true; for (size_t i=0 ; i<mActiveConnections.size() ; i++) { for (const sp<SensorEventConnection>& connection : connLock->getActiveConnections()) { sp<SensorEventConnection> connection(mActiveConnections[i].promote()); if (connection != nullptr) { if (connection->needsWakeLock()) { if (connection->needsWakeLock()) { releaseLock = false; releaseLock = false; break; break; } } } } } if (releaseLock) { if (releaseLock) { setWakeLockAcquiredLocked(false); setWakeLockAcquiredLocked(false); } } Loading @@ -1793,17 +1754,6 @@ void SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connect } } } } void SensorService::populateActiveConnections( SortedVector< sp<SensorEventConnection> >* activeConnections) { Mutex::Autolock _l(mLock); for (size_t i=0 ; i < mActiveConnections.size(); ++i) { sp<SensorEventConnection> connection(mActiveConnections[i].promote()); if (connection != nullptr) { activeConnections->add(connection); } } } bool SensorService::isWhiteListedPackage(const String8& packageName) { bool SensorService::isWhiteListedPackage(const String8& packageName) { return (packageName.contains(mWhiteListedPackage.string())); return (packageName.contains(mWhiteListedPackage.string())); } } Loading Loading @@ -1938,4 +1888,62 @@ binder::Status SensorService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool e } } return binder::Status::ok(); return binder::Status::ok(); } } }; // namespace android SensorService::ConnectionSafeAutolock::ConnectionSafeAutolock( SensorService::SensorConnectionHolder& holder, Mutex& mutex) : mConnectionHolder(holder), mAutolock(mutex) {} template<typename ConnectionType> const std::vector<sp<ConnectionType>>& SensorService::ConnectionSafeAutolock::getConnectionsHelper( const SortedVector<wp<ConnectionType>>& connectionList, std::vector<std::vector<sp<ConnectionType>>>* referenceHolder) { referenceHolder->emplace_back(); std::vector<sp<ConnectionType>>& connections = referenceHolder->back(); for (const wp<ConnectionType>& weakConnection : connectionList){ sp<ConnectionType> connection = weakConnection.promote(); if (connection != nullptr) { connections.push_back(std::move(connection)); } } return connections; } const std::vector<sp<SensorService::SensorEventConnection>>& SensorService::ConnectionSafeAutolock::getActiveConnections() { return getConnectionsHelper(mConnectionHolder.mActiveConnections, &mReferencedActiveConnections); } const std::vector<sp<SensorService::SensorDirectConnection>>& SensorService::ConnectionSafeAutolock::getDirectConnections() { return getConnectionsHelper(mConnectionHolder.mDirectConnections, &mReferencedDirectConnections); } void SensorService::SensorConnectionHolder::addEventConnectionIfNotPresent( const sp<SensorService::SensorEventConnection>& connection) { if (mActiveConnections.indexOf(connection) < 0) { mActiveConnections.add(connection); } } void SensorService::SensorConnectionHolder::removeEventConnection( const wp<SensorService::SensorEventConnection>& connection) { mActiveConnections.remove(connection); } void SensorService::SensorConnectionHolder::addDirectConnection( const sp<SensorService::SensorDirectConnection>& connection) { mDirectConnections.add(connection); } void SensorService::SensorConnectionHolder::removeDirectConnection( const wp<SensorService::SensorDirectConnection>& connection) { mDirectConnections.remove(connection); } SensorService::ConnectionSafeAutolock SensorService::SensorConnectionHolder::lock(Mutex& mutex) { return ConnectionSafeAutolock(*this, mutex); } } // namespace android
services/sensorservice/SensorService.h +66 −10 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "SensorList.h" #include "SensorList.h" #include "RecentEventLogger.h" #include "RecentEventLogger.h" #include <android-base/macros.h> #include <binder/AppOpsManager.h> #include <binder/AppOpsManager.h> #include <binder/BinderService.h> #include <binder/BinderService.h> #include <binder/IUidObserver.h> #include <binder/IUidObserver.h> Loading @@ -42,6 +43,7 @@ #include <sys/types.h> #include <sys/types.h> #include <unordered_map> #include <unordered_map> #include <unordered_set> #include <unordered_set> #include <vector> #if __clang__ #if __clang__ // Clang warns about SensorEventConnection::dump hiding BBinder::dump. The cause isn't fixable // Clang warns about SensorEventConnection::dump hiding BBinder::dump. The cause isn't fixable Loading Loading @@ -95,10 +97,67 @@ private: friend class BinderService<SensorService>; friend class BinderService<SensorService>; // nested class/struct for internal use // nested class/struct for internal use class SensorRecord; class ConnectionSafeAutolock; class SensorConnectionHolder; class SensorEventAckReceiver; class SensorEventAckReceiver; class SensorRecord; class SensorRegistrationInfo; class SensorRegistrationInfo; // Promoting a SensorEventConnection or SensorDirectConnection from wp to sp must be done with // mLock held, but destroying that sp must be done unlocked to avoid a race condition that // causes a deadlock (remote dies while we hold a local sp, then our decStrong() call invokes // the dtor -> cleanupConnection() tries to re-lock the mutex). This class ensures safe usage // by wrapping a Mutex::Autolock on SensorService's mLock, plus vectors that hold promoted sp<> // references until the lock is released, when they are safely destroyed. // All read accesses to the connection lists in mConnectionHolder must be done via this class. class ConnectionSafeAutolock final { public: // Returns a list of non-null promoted connection references const std::vector<sp<SensorEventConnection>>& getActiveConnections(); const std::vector<sp<SensorDirectConnection>>& getDirectConnections(); private: // Constructed via SensorConnectionHolder::lock() friend class SensorConnectionHolder; explicit ConnectionSafeAutolock(SensorConnectionHolder& holder, Mutex& mutex); DISALLOW_IMPLICIT_CONSTRUCTORS(ConnectionSafeAutolock); // NOTE: Order of these members is important, as the destructor for non-static members // get invoked in the reverse order of their declaration. Here we are relying on the // Autolock to be destroyed *before* the vectors, so the sp<> objects are destroyed without // the lock held, which avoids the deadlock. SensorConnectionHolder& mConnectionHolder; std::vector<std::vector<sp<SensorEventConnection>>> mReferencedActiveConnections; std::vector<std::vector<sp<SensorDirectConnection>>> mReferencedDirectConnections; Mutex::Autolock mAutolock; template<typename ConnectionType> const std::vector<sp<ConnectionType>>& getConnectionsHelper( const SortedVector<wp<ConnectionType>>& connectionList, std::vector<std::vector<sp<ConnectionType>>>* referenceHolder); }; // Encapsulates the collection of active SensorEventConection and SensorDirectConnection // references. Write access is done through this class with mLock held, but all read access // must be routed through ConnectionSafeAutolock. class SensorConnectionHolder { public: void addEventConnectionIfNotPresent(const sp<SensorEventConnection>& connection); void removeEventConnection(const wp<SensorEventConnection>& connection); void addDirectConnection(const sp<SensorDirectConnection>& connection); void removeDirectConnection(const wp<SensorDirectConnection>& connection); // Pass in the mutex that protects this connection holder; acquires the lock and returns an // object that can be used to safely read the lists of connections ConnectionSafeAutolock lock(Mutex& mutex); private: friend class ConnectionSafeAutolock; SortedVector< wp<SensorEventConnection> > mActiveConnections; SortedVector< wp<SensorDirectConnection> > mDirectConnections; }; // If accessing a sensor we need to make sure the UID has access to it. If // If accessing a sensor we need to make sure the UID has access to it. If // the app UID is idle then it cannot access sensors and gets no trigger // the app UID is idle then it cannot access sensors and gets no trigger // events, no on-change events, flush event behavior does not change, and // events, no on-change events, flush event behavior does not change, and Loading Loading @@ -250,7 +309,7 @@ private: // method checks whether all the events from these wake up sensors have been delivered to the // method checks whether all the events from these wake up sensors have been delivered to the // corresponding applications, if yes the wakelock is released. // corresponding applications, if yes the wakelock is released. void checkWakeLockState(); void checkWakeLockState(); void checkWakeLockStateLocked(); void checkWakeLockStateLocked(ConnectionSafeAutolock* connLock); bool isWakeLockAcquired(); bool isWakeLockAcquired(); bool isWakeUpSensorEvent(const sensors_event_t& event) const; bool isWakeUpSensorEvent(const sensors_event_t& event) const; Loading @@ -268,10 +327,6 @@ private: // Send events from the event cache for this particular connection. // Send events from the event cache for this particular connection. void sendEventsFromCache(const sp<SensorEventConnection>& connection); void sendEventsFromCache(const sp<SensorEventConnection>& connection); // Promote all weak referecences in mActiveConnections vector to strong references and add them // to the output vector. void populateActiveConnections( SortedVector< sp<SensorEventConnection> >* activeConnections); // If SensorService is operating in RESTRICTED mode, only select whitelisted packages are // If SensorService is operating in RESTRICTED mode, only select whitelisted packages are // allowed to register for or call flush on sensors. Typically only cts test packages are // allowed to register for or call flush on sensors. Typically only cts test packages are // allowed. // allowed. Loading Loading @@ -306,10 +361,10 @@ private: // temporarily stops all active direct connections and disables all sensors // temporarily stops all active direct connections and disables all sensors void disableAllSensors(); void disableAllSensors(); void disableAllSensorsLocked(); void disableAllSensorsLocked(ConnectionSafeAutolock* connLock); // restarts the previously stopped direct connections and enables all sensors // restarts the previously stopped direct connections and enables all sensors void enableAllSensors(); void enableAllSensors(); void enableAllSensorsLocked(); void enableAllSensorsLocked(ConnectionSafeAutolock* connLock); static uint8_t sHmacGlobalKey[128]; static uint8_t sHmacGlobalKey[128]; static bool sHmacGlobalKeyIsValid; static bool sHmacGlobalKeyIsValid; Loading @@ -327,12 +382,13 @@ private: mutable Mutex mLock; mutable Mutex mLock; DefaultKeyedVector<int, SensorRecord*> mActiveSensors; DefaultKeyedVector<int, SensorRecord*> mActiveSensors; std::unordered_set<int> mActiveVirtualSensors; std::unordered_set<int> mActiveVirtualSensors; SortedVector< wp<SensorEventConnection> > mActiveConnections; SensorConnectionHolder mConnectionHolder; bool mWakeLockAcquired; bool mWakeLockAcquired; sensors_event_t *mSensorEventBuffer, *mSensorEventScratch; sensors_event_t *mSensorEventBuffer, *mSensorEventScratch; // WARNING: these SensorEventConnection instances must not be promoted to sp, except via // modification to add support for them in ConnectionSafeAutolock wp<const SensorEventConnection> * mMapFlushEventsToConnections; wp<const SensorEventConnection> * mMapFlushEventsToConnections; std::unordered_map<int, SensorServiceUtil::RecentEventLogger*> mRecentEvent; std::unordered_map<int, SensorServiceUtil::RecentEventLogger*> mRecentEvent; SortedVector< wp<SensorDirectConnection> > mDirectConnections; Mode mCurrentOperatingMode; Mode mCurrentOperatingMode; // This packagaName is set when SensorService is in RESTRICTED or DATA_INJECTION mode. Only // This packagaName is set when SensorService is in RESTRICTED or DATA_INJECTION mode. Only Loading