diff options
-rw-r--r-- | include/gui/SensorManager.h | 20 | ||||
-rw-r--r-- | libs/gui/SensorManager.cpp | 109 |
2 files changed, 95 insertions, 34 deletions
diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h index e1b1a7b..3176462 100644 --- a/include/gui/SensorManager.h +++ b/include/gui/SensorManager.h @@ -20,6 +20,8 @@ #include <stdint.h> #include <sys/types.h> +#include <binder/IBinder.h> + #include <utils/Errors.h> #include <utils/RefBase.h> #include <utils/Singleton.h> @@ -41,7 +43,9 @@ class SensorEventQueue; // ---------------------------------------------------------------------------- -class SensorManager : public ASensorManager, public Singleton<SensorManager> +class SensorManager : + public ASensorManager, + public Singleton<SensorManager> { public: SensorManager(); @@ -52,9 +56,17 @@ public: sp<SensorEventQueue> createEventQueue(); private: - sp<ISensorServer> mSensorServer; - Sensor const** mSensorList; - Vector<Sensor> mSensors; + // DeathRecipient interface + void sensorManagerDied(); + + status_t assertStateLocked() const; + +private: + mutable Mutex mLock; + mutable sp<ISensorServer> mSensorServer; + mutable Sensor const** mSensorList; + mutable Vector<Sensor> mSensors; + mutable sp<IBinder::DeathRecipient> mDeathObserver; }; // ---------------------------------------------------------------------------- diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp index 4774a58..dafcdea 100644 --- a/libs/gui/SensorManager.cpp +++ b/libs/gui/SensorManager.cpp @@ -23,6 +23,7 @@ #include <utils/RefBase.h> #include <utils/Singleton.h> +#include <binder/IBinder.h> #include <binder/IServiceManager.h> #include <gui/ISensorServer.h> @@ -40,17 +41,8 @@ ANDROID_SINGLETON_STATIC_INSTANCE(SensorManager) SensorManager::SensorManager() : mSensorList(0) { - const String16 name("sensorservice"); - while (getService(name, &mSensorServer) != NO_ERROR) { - usleep(250000); - } - - mSensors = mSensorServer->getSensorList(); - size_t count = mSensors.size(); - mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*)); - for (size_t i=0 ; i<count ; i++) { - mSensorList[i] = mSensors.array() + i; - } + // okay we're not locked here, but it's not needed during construction + assertStateLocked(); } SensorManager::~SensorManager() @@ -58,20 +50,79 @@ SensorManager::~SensorManager() free(mSensorList); } +void SensorManager::sensorManagerDied() +{ + Mutex::Autolock _l(mLock); + mSensorServer.clear(); + free(mSensorList); + mSensorList = NULL; + mSensors.clear(); +} + +status_t SensorManager::assertStateLocked() const { + if (mSensorServer == NULL) { + // try for one second + const String16 name("sensorservice"); + for (int i=0 ; i<4 ; i++) { + status_t err = getService(name, &mSensorServer); + if (err == NAME_NOT_FOUND) { + usleep(250000); + continue; + } + if (err != NO_ERROR) { + return err; + } + break; + } + + class DeathObserver : public IBinder::DeathRecipient { + SensorManager& mSensorManger; + virtual void binderDied(const wp<IBinder>& who) { + LOGW("sensorservice died [%p]", who.unsafe_get()); + mSensorManger.sensorManagerDied(); + } + public: + DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { } + }; + + mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this)); + mSensorServer->asBinder()->linkToDeath(mDeathObserver); + + mSensors = mSensorServer->getSensorList(); + size_t count = mSensors.size(); + mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*)); + for (size_t i=0 ; i<count ; i++) { + mSensorList[i] = mSensors.array() + i; + } + } + + return NO_ERROR; +} + + + ssize_t SensorManager::getSensorList(Sensor const* const** list) const { + Mutex::Autolock _l(mLock); + status_t err = assertStateLocked(); + if (err < 0) { + return ssize_t(err); + } *list = mSensorList; return mSensors.size(); } Sensor const* SensorManager::getDefaultSensor(int type) { - // For now we just return the first sensor of that type we find. - // in the future it will make sense to let the SensorService make - // that decision. - for (size_t i=0 ; i<mSensors.size() ; i++) { - if (mSensorList[i]->getType() == type) - return mSensorList[i]; + Mutex::Autolock _l(mLock); + if (assertStateLocked() == NO_ERROR) { + // For now we just return the first sensor of that type we find. + // in the future it will make sense to let the SensorService make + // that decision. + for (size_t i=0 ; i<mSensors.size() ; i++) { + if (mSensorList[i]->getType() == type) + return mSensorList[i]; + } } return NULL; } @@ -80,20 +131,18 @@ sp<SensorEventQueue> SensorManager::createEventQueue() { sp<SensorEventQueue> queue; - if (mSensorServer == NULL) { - LOGE("createEventQueue: mSensorSever is NULL"); - return queue; - } - - sp<ISensorEventConnection> connection = - mSensorServer->createSensorEventConnection(); - if (connection == NULL) { - LOGE("createEventQueue: connection is NULL"); - return queue; + Mutex::Autolock _l(mLock); + while (assertStateLocked() == NO_ERROR) { + sp<ISensorEventConnection> connection = + mSensorServer->createSensorEventConnection(); + if (connection == NULL) { + // SensorService just died. + LOGE("createEventQueue: connection is NULL. SensorService died."); + continue; + } + queue = new SensorEventQueue(connection); + break; } - - queue = new SensorEventQueue(connection); - return queue; } |