1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Sensors"
18
19#include <stdint.h>
20#include <sys/types.h>
21
22#include <utils/Errors.h>
23#include <utils/RefBase.h>
24#include <utils/Singleton.h>
25
26#include <binder/IBinder.h>
27#include <binder/IServiceManager.h>
28
29#include <gui/ISensorServer.h>
30#include <gui/ISensorEventConnection.h>
31#include <gui/Sensor.h>
32#include <gui/SensorManager.h>
33#include <gui/SensorEventQueue.h>
34
35// ----------------------------------------------------------------------------
36namespace android {
37// ----------------------------------------------------------------------------
38
39ANDROID_SINGLETON_STATIC_INSTANCE(SensorManager)
40
41SensorManager::SensorManager()
42    : mSensorList(0)
43{
44    // okay we're not locked here, but it's not needed during construction
45    assertStateLocked();
46}
47
48SensorManager::~SensorManager()
49{
50    free(mSensorList);
51}
52
53void SensorManager::sensorManagerDied()
54{
55    Mutex::Autolock _l(mLock);
56    mSensorServer.clear();
57    free(mSensorList);
58    mSensorList = NULL;
59    mSensors.clear();
60}
61
62status_t SensorManager::assertStateLocked() const {
63    if (mSensorServer == NULL) {
64        // try for one second
65        const String16 name("sensorservice");
66        for (int i=0 ; i<4 ; i++) {
67            status_t err = getService(name, &mSensorServer);
68            if (err == NAME_NOT_FOUND) {
69                usleep(250000);
70                continue;
71            }
72            if (err != NO_ERROR) {
73                return err;
74            }
75            break;
76        }
77
78        class DeathObserver : public IBinder::DeathRecipient {
79            SensorManager& mSensorManger;
80            virtual void binderDied(const wp<IBinder>& who) {
81                LOGW("sensorservice died [%p]", who.unsafe_get());
82                mSensorManger.sensorManagerDied();
83            }
84        public:
85            DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }
86        };
87
88        mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
89        mSensorServer->asBinder()->linkToDeath(mDeathObserver);
90
91        mSensors = mSensorServer->getSensorList();
92        size_t count = mSensors.size();
93        mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));
94        for (size_t i=0 ; i<count ; i++) {
95            mSensorList[i] = mSensors.array() + i;
96        }
97    }
98
99    return NO_ERROR;
100}
101
102
103
104ssize_t SensorManager::getSensorList(Sensor const* const** list) const
105{
106    Mutex::Autolock _l(mLock);
107    status_t err = assertStateLocked();
108    if (err < 0) {
109        return ssize_t(err);
110    }
111    *list = mSensorList;
112    return mSensors.size();
113}
114
115Sensor const* SensorManager::getDefaultSensor(int type)
116{
117    Mutex::Autolock _l(mLock);
118    if (assertStateLocked() == NO_ERROR) {
119        // For now we just return the first sensor of that type we find.
120        // in the future it will make sense to let the SensorService make
121        // that decision.
122        for (size_t i=0 ; i<mSensors.size() ; i++) {
123            if (mSensorList[i]->getType() == type)
124                return mSensorList[i];
125        }
126    }
127    return NULL;
128}
129
130sp<SensorEventQueue> SensorManager::createEventQueue()
131{
132    sp<SensorEventQueue> queue;
133
134    Mutex::Autolock _l(mLock);
135    while (assertStateLocked() == NO_ERROR) {
136        sp<ISensorEventConnection> connection =
137                mSensorServer->createSensorEventConnection();
138        if (connection == NULL) {
139            // SensorService just died.
140            LOGE("createEventQueue: connection is NULL. SensorService died.");
141            continue;
142        }
143        queue = new SensorEventQueue(connection);
144        break;
145    }
146    return queue;
147}
148
149// ----------------------------------------------------------------------------
150}; // namespace android
151