summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/gui/SensorManager.h20
-rw-r--r--libs/gui/SensorManager.cpp109
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;
}