Loading services/sensorservice/SensorService.cpp +65 −30 Original line number Diff line number Diff line Loading @@ -63,8 +63,10 @@ #include <sys/types.h> #include <unistd.h> #include <condition_variable> #include <ctime> #include <future> #include <mutex> #include <string> #include <private/android_filesystem_config.h> Loading Loading @@ -196,6 +198,16 @@ int SensorService::registerRuntimeSensor( if (mRuntimeSensorCallbacks.find(deviceId) == mRuntimeSensorCallbacks.end()) { mRuntimeSensorCallbacks.emplace(deviceId, callback); } if (mRuntimeSensorHandler == nullptr) { mRuntimeSensorEventBuffer = new sensors_event_t[SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT]; mRuntimeSensorHandler = new RuntimeSensorHandler(this); // Use PRIORITY_URGENT_DISPLAY as the injected sensor events should be dispatched as soon as // possible, and also for consistency within the SensorService. mRuntimeSensorHandler->run("RuntimeSensorHandler", PRIORITY_URGENT_DISPLAY); } return handle; } Loading Loading @@ -232,8 +244,9 @@ status_t SensorService::unregisterRuntimeSensor(int handle) { } status_t SensorService::sendRuntimeSensorEvent(const sensors_event_t& event) { Mutex::Autolock _l(mLock); std::unique_lock<std::mutex> lock(mRutimeSensorThreadMutex); mRuntimeSensorEventQueue.push(event); mRuntimeSensorsCv.notify_all(); return OK; } Loading Loading @@ -458,6 +471,7 @@ void SensorService::onFirstRef() { const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; mSensorEventBuffer = new sensors_event_t[minBufferSize]; mSensorEventScratch = new sensors_event_t[minBufferSize]; mRuntimeSensorEventBuffer = nullptr; mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize]; mCurrentOperatingMode = NORMAL; Loading Loading @@ -1089,7 +1103,6 @@ bool SensorService::threadLoop() { recordLastValueLocked(mSensorEventBuffer, count); // handle virtual sensors bool bufferNeedsSorting = false; if (count && vcount) { sensors_event_t const * const event = mSensorEventBuffer; if (!mActiveVirtualSensors.empty()) { Loading Loading @@ -1125,35 +1138,9 @@ bool SensorService::threadLoop() { // record the last synthesized values recordLastValueLocked(&mSensorEventBuffer[count], k); count += k; bufferNeedsSorting = true; } } } // handle runtime sensors { size_t k = 0; while (!mRuntimeSensorEventQueue.empty()) { if (count + k >= minBufferSize) { ALOGE("buffer too small to hold all events: count=%zd, k=%zu, size=%zu", count, k, minBufferSize); break; } mSensorEventBuffer[count + k] = mRuntimeSensorEventQueue.front(); mRuntimeSensorEventQueue.pop(); k++; } if (k) { // record the last synthesized values recordLastValueLocked(&mSensorEventBuffer[count], k); count += k; bufferNeedsSorting = true; sortEventBuffer(mSensorEventBuffer, count); } } if (bufferNeedsSorting) { // sort the buffer by time-stamps sortEventBuffer(mSensorEventBuffer, count); } // handle backward compatibility for RotationVector sensor Loading Loading @@ -1253,6 +1240,46 @@ bool SensorService::threadLoop() { return false; } void SensorService::processRuntimeSensorEvents() { size_t count = 0; const size_t maxBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; { std::unique_lock<std::mutex> lock(mRutimeSensorThreadMutex); if (mRuntimeSensorEventQueue.empty()) { mRuntimeSensorsCv.wait(lock, [this] { return !mRuntimeSensorEventQueue.empty(); }); } // Pop the events from the queue into the buffer until it's empty or the buffer is full. while (!mRuntimeSensorEventQueue.empty()) { if (count >= maxBufferSize) { ALOGE("buffer too small to hold all events: count=%zd, size=%zu", count, maxBufferSize); break; } mRuntimeSensorEventBuffer[count] = mRuntimeSensorEventQueue.front(); mRuntimeSensorEventQueue.pop(); count++; } } if (count) { ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); recordLastValueLocked(mRuntimeSensorEventBuffer, count); sortEventBuffer(mRuntimeSensorEventBuffer, count); for (const sp<SensorEventConnection>& connection : connLock.getActiveConnections()) { connection->sendEvents(mRuntimeSensorEventBuffer, count, /* scratch= */ nullptr, /* mapFlushEventsToConnections= */ nullptr); if (connection->hasOneShotSensors()) { cleanupAutoDisabledSensorLocked(connection, mRuntimeSensorEventBuffer, count); } } } } sp<Looper> SensorService::getLooper() const { return mLooper; } Loading Loading @@ -1300,6 +1327,14 @@ bool SensorService::SensorEventAckReceiver::threadLoop() { return false; } bool SensorService::RuntimeSensorHandler::threadLoop() { ALOGD("new thread RuntimeSensorHandler"); do { mService->processRuntimeSensorEvents(); } while (!Thread::exitPending()); return false; } void SensorService::recordLastValueLocked( const sensors_event_t* buffer, size_t count) { for (size_t i = 0; i < count; i++) { Loading services/sensorservice/SensorService.h +18 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ #include <stdint.h> #include <sys/types.h> #include <condition_variable> #include <mutex> #include <queue> #include <unordered_map> #include <unordered_set> Loading Loading @@ -208,6 +210,7 @@ private: class SensorEventAckReceiver; class SensorRecord; class SensorRegistrationInfo; class RuntimeSensorHandler; // 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 Loading Loading @@ -264,6 +267,14 @@ private: SortedVector< wp<SensorDirectConnection> > mDirectConnections; }; class RuntimeSensorHandler : public Thread { sp<SensorService> const mService; public: virtual bool threadLoop(); explicit RuntimeSensorHandler(const sp<SensorService>& service) : mService(service) { } }; // 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 // events, no on-change events, flush event behavior does not change, and Loading Loading @@ -368,6 +379,8 @@ private: // Thread interface virtual bool threadLoop(); void processRuntimeSensorEvents(); // ISensorServer interface virtual Vector<Sensor> getSensorList(const String16& opPackageName); virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName); Loading Loading @@ -512,6 +525,10 @@ private: uint32_t mSocketBufferSize; sp<Looper> mLooper; sp<SensorEventAckReceiver> mAckReceiver; sp<RuntimeSensorHandler> mRuntimeSensorHandler; // Mutex and CV used to notify the mRuntimeSensorHandler thread that there are new events. std::mutex mRutimeSensorThreadMutex; std::condition_variable mRuntimeSensorsCv; // protected by mLock mutable Mutex mLock; Loading @@ -519,7 +536,7 @@ private: std::unordered_set<int> mActiveVirtualSensors; SensorConnectionHolder mConnectionHolder; bool mWakeLockAcquired; sensors_event_t *mSensorEventBuffer, *mSensorEventScratch; sensors_event_t *mSensorEventBuffer, *mSensorEventScratch, *mRuntimeSensorEventBuffer; // WARNING: these SensorEventConnection instances must not be promoted to sp, except via // modification to add support for them in ConnectionSafeAutolock wp<const SensorEventConnection> * mMapFlushEventsToConnections; Loading Loading
services/sensorservice/SensorService.cpp +65 −30 Original line number Diff line number Diff line Loading @@ -63,8 +63,10 @@ #include <sys/types.h> #include <unistd.h> #include <condition_variable> #include <ctime> #include <future> #include <mutex> #include <string> #include <private/android_filesystem_config.h> Loading Loading @@ -196,6 +198,16 @@ int SensorService::registerRuntimeSensor( if (mRuntimeSensorCallbacks.find(deviceId) == mRuntimeSensorCallbacks.end()) { mRuntimeSensorCallbacks.emplace(deviceId, callback); } if (mRuntimeSensorHandler == nullptr) { mRuntimeSensorEventBuffer = new sensors_event_t[SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT]; mRuntimeSensorHandler = new RuntimeSensorHandler(this); // Use PRIORITY_URGENT_DISPLAY as the injected sensor events should be dispatched as soon as // possible, and also for consistency within the SensorService. mRuntimeSensorHandler->run("RuntimeSensorHandler", PRIORITY_URGENT_DISPLAY); } return handle; } Loading Loading @@ -232,8 +244,9 @@ status_t SensorService::unregisterRuntimeSensor(int handle) { } status_t SensorService::sendRuntimeSensorEvent(const sensors_event_t& event) { Mutex::Autolock _l(mLock); std::unique_lock<std::mutex> lock(mRutimeSensorThreadMutex); mRuntimeSensorEventQueue.push(event); mRuntimeSensorsCv.notify_all(); return OK; } Loading Loading @@ -458,6 +471,7 @@ void SensorService::onFirstRef() { const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; mSensorEventBuffer = new sensors_event_t[minBufferSize]; mSensorEventScratch = new sensors_event_t[minBufferSize]; mRuntimeSensorEventBuffer = nullptr; mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize]; mCurrentOperatingMode = NORMAL; Loading Loading @@ -1089,7 +1103,6 @@ bool SensorService::threadLoop() { recordLastValueLocked(mSensorEventBuffer, count); // handle virtual sensors bool bufferNeedsSorting = false; if (count && vcount) { sensors_event_t const * const event = mSensorEventBuffer; if (!mActiveVirtualSensors.empty()) { Loading Loading @@ -1125,35 +1138,9 @@ bool SensorService::threadLoop() { // record the last synthesized values recordLastValueLocked(&mSensorEventBuffer[count], k); count += k; bufferNeedsSorting = true; } } } // handle runtime sensors { size_t k = 0; while (!mRuntimeSensorEventQueue.empty()) { if (count + k >= minBufferSize) { ALOGE("buffer too small to hold all events: count=%zd, k=%zu, size=%zu", count, k, minBufferSize); break; } mSensorEventBuffer[count + k] = mRuntimeSensorEventQueue.front(); mRuntimeSensorEventQueue.pop(); k++; } if (k) { // record the last synthesized values recordLastValueLocked(&mSensorEventBuffer[count], k); count += k; bufferNeedsSorting = true; sortEventBuffer(mSensorEventBuffer, count); } } if (bufferNeedsSorting) { // sort the buffer by time-stamps sortEventBuffer(mSensorEventBuffer, count); } // handle backward compatibility for RotationVector sensor Loading Loading @@ -1253,6 +1240,46 @@ bool SensorService::threadLoop() { return false; } void SensorService::processRuntimeSensorEvents() { size_t count = 0; const size_t maxBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; { std::unique_lock<std::mutex> lock(mRutimeSensorThreadMutex); if (mRuntimeSensorEventQueue.empty()) { mRuntimeSensorsCv.wait(lock, [this] { return !mRuntimeSensorEventQueue.empty(); }); } // Pop the events from the queue into the buffer until it's empty or the buffer is full. while (!mRuntimeSensorEventQueue.empty()) { if (count >= maxBufferSize) { ALOGE("buffer too small to hold all events: count=%zd, size=%zu", count, maxBufferSize); break; } mRuntimeSensorEventBuffer[count] = mRuntimeSensorEventQueue.front(); mRuntimeSensorEventQueue.pop(); count++; } } if (count) { ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); recordLastValueLocked(mRuntimeSensorEventBuffer, count); sortEventBuffer(mRuntimeSensorEventBuffer, count); for (const sp<SensorEventConnection>& connection : connLock.getActiveConnections()) { connection->sendEvents(mRuntimeSensorEventBuffer, count, /* scratch= */ nullptr, /* mapFlushEventsToConnections= */ nullptr); if (connection->hasOneShotSensors()) { cleanupAutoDisabledSensorLocked(connection, mRuntimeSensorEventBuffer, count); } } } } sp<Looper> SensorService::getLooper() const { return mLooper; } Loading Loading @@ -1300,6 +1327,14 @@ bool SensorService::SensorEventAckReceiver::threadLoop() { return false; } bool SensorService::RuntimeSensorHandler::threadLoop() { ALOGD("new thread RuntimeSensorHandler"); do { mService->processRuntimeSensorEvents(); } while (!Thread::exitPending()); return false; } void SensorService::recordLastValueLocked( const sensors_event_t* buffer, size_t count) { for (size_t i = 0; i < count; i++) { Loading
services/sensorservice/SensorService.h +18 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ #include <stdint.h> #include <sys/types.h> #include <condition_variable> #include <mutex> #include <queue> #include <unordered_map> #include <unordered_set> Loading Loading @@ -208,6 +210,7 @@ private: class SensorEventAckReceiver; class SensorRecord; class SensorRegistrationInfo; class RuntimeSensorHandler; // 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 Loading Loading @@ -264,6 +267,14 @@ private: SortedVector< wp<SensorDirectConnection> > mDirectConnections; }; class RuntimeSensorHandler : public Thread { sp<SensorService> const mService; public: virtual bool threadLoop(); explicit RuntimeSensorHandler(const sp<SensorService>& service) : mService(service) { } }; // 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 // events, no on-change events, flush event behavior does not change, and Loading Loading @@ -368,6 +379,8 @@ private: // Thread interface virtual bool threadLoop(); void processRuntimeSensorEvents(); // ISensorServer interface virtual Vector<Sensor> getSensorList(const String16& opPackageName); virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName); Loading Loading @@ -512,6 +525,10 @@ private: uint32_t mSocketBufferSize; sp<Looper> mLooper; sp<SensorEventAckReceiver> mAckReceiver; sp<RuntimeSensorHandler> mRuntimeSensorHandler; // Mutex and CV used to notify the mRuntimeSensorHandler thread that there are new events. std::mutex mRutimeSensorThreadMutex; std::condition_variable mRuntimeSensorsCv; // protected by mLock mutable Mutex mLock; Loading @@ -519,7 +536,7 @@ private: std::unordered_set<int> mActiveVirtualSensors; SensorConnectionHolder mConnectionHolder; bool mWakeLockAcquired; sensors_event_t *mSensorEventBuffer, *mSensorEventScratch; sensors_event_t *mSensorEventBuffer, *mSensorEventScratch, *mRuntimeSensorEventBuffer; // WARNING: these SensorEventConnection instances must not be promoted to sp, except via // modification to add support for them in ConnectionSafeAutolock wp<const SensorEventConnection> * mMapFlushEventsToConnections; Loading