blob: 3fe3a5d30b79fdbaf7a5226bd5e7c16c0b8a45e3 [file] [log] [blame]
Mathias Agopianfc328812010-07-14 23:41:37 -07001/*
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#include <stdint.h>
18#include <sys/types.h>
19
20#include <utils/SortedVector.h>
21#include <utils/KeyedVector.h>
22#include <utils/threads.h>
23#include <utils/Atomic.h>
24#include <utils/Errors.h>
25#include <utils/RefBase.h>
Mathias Agopian451beee2010-07-19 15:03:55 -070026#include <utils/Singleton.h>
Mathias Agopianfc328812010-07-14 23:41:37 -070027
28#include <binder/BinderService.h>
Mathias Agopian451beee2010-07-19 15:03:55 -070029#include <binder/IServiceManager.h>
Mathias Agopianfc328812010-07-14 23:41:37 -070030
31#include <gui/ISensorServer.h>
32#include <gui/ISensorEventConnection.h>
33
34#include <hardware/sensors.h>
35
36#include "SensorService.h"
37
38namespace android {
39// ---------------------------------------------------------------------------
40
41/*
42 * TODO:
43 * - handle per-connection event rate
44 * - filter events per connection
45 * - make sure to keep the last value of each event type so we can quickly
46 * send something to application when they enable a sensor that is already
47 * active (the issue here is that it can take time before a value is
48 * produced by the h/w if the rate is low or if it's a one-shot sensor).
Mathias Agopian451beee2010-07-19 15:03:55 -070049 * - send sensor info to battery service
Mathias Agopianfc328812010-07-14 23:41:37 -070050 */
51
Mathias Agopian451beee2010-07-19 15:03:55 -070052// ---------------------------------------------------------------------------
53
54class BatteryService : public Singleton<BatteryService> {
55 friend class Singleton<BatteryService>;
56 sp<IBinder> mBatteryStatService;
57 BatteryService() {
58 const String16 name("batteryinfo");
59 //getService(name, &mBatteryStatService);
60 }
61public:
62 void enableSensor(int handle) {
63 if (mBatteryStatService != 0) {
64 int uid = IPCThreadState::self()->getCallingUid();
65 //mBatteryStatService->noteStartSensor(uid, handle);
66 }
67 }
68 void disableSensor(int handle) {
69 if (mBatteryStatService != 0) {
70 int uid = IPCThreadState::self()->getCallingUid();
71 //mBatteryStatService->noteStopSensor(uid, handle);
72 }
73 }
74};
75
76ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
77
78// ---------------------------------------------------------------------------
79
Mathias Agopianfc328812010-07-14 23:41:37 -070080SensorService::SensorService()
81 : Thread(false),
82 mDump("android.permission.DUMP")
83{
84}
85
86void SensorService::onFirstRef()
87{
88 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
89 (hw_module_t const**)&mSensorModule);
90
91 LOGE_IF(err, "couldn't load %s module (%s)",
92 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
93
94 err = sensors_open(&mSensorModule->common, &mSensorDevice);
95
96 LOGE_IF(err, "couldn't open device for module %s (%s)",
97 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
98
99 LOGD("nuSensorService starting...");
100
101 struct sensor_t const* list;
102 int count = mSensorModule->get_sensors_list(mSensorModule, &list);
103 for (int i=0 ; i<count ; i++) {
104 Sensor sensor(list + i);
105 LOGI("%s", sensor.getName().string());
106 mSensorList.add(sensor);
107 mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0);
108 }
109
110 run("SensorService", PRIORITY_URGENT_DISPLAY);
111}
112
113SensorService::~SensorService()
114{
115}
116
117status_t SensorService::dump(int fd, const Vector<String16>& args)
118{
119 const size_t SIZE = 1024;
120 char buffer[SIZE];
121 String8 result;
122 if (!mDump.checkCalling()) {
123 snprintf(buffer, SIZE, "Permission Denial: "
124 "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
125 IPCThreadState::self()->getCallingPid(),
126 IPCThreadState::self()->getCallingUid());
127 result.append(buffer);
128 } else {
129 Mutex::Autolock _l(mLock);
130 snprintf(buffer, SIZE, "%d connections / %d active\n",
131 mConnections.size(), mActiveConnections.size());
132 result.append(buffer);
133 snprintf(buffer, SIZE, "Active sensors:\n");
134 result.append(buffer);
135 for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
Mathias Agopian5d270722010-07-19 15:20:39 -0700136 int handle = mActiveSensors.keyAt(i);
137 snprintf(buffer, SIZE, "%s (handle=%d, connections=%d)\n",
138 getSensorName(handle).string(),
139 handle,
Mathias Agopianfc328812010-07-14 23:41:37 -0700140 mActiveSensors.valueAt(i)->getNumConnections());
141 result.append(buffer);
142 }
143 }
144 write(fd, result.string(), result.size());
145 return NO_ERROR;
146}
147
148bool SensorService::threadLoop()
149{
150 LOGD("nuSensorService thread starting...");
151
152 sensors_event_t buffer[16];
153 struct sensors_poll_device_t* device = mSensorDevice;
154 ssize_t count;
155
156 do {
157 count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer));
158 if (count<0) {
159 LOGE("sensor poll failed (%s)", strerror(-count));
160 break;
161 }
162
163 const SortedVector< wp<SensorEventConnection> > activeConnections(
164 getActiveConnections());
165
166 size_t numConnections = activeConnections.size();
167 if (numConnections) {
168 for (size_t i=0 ; i<numConnections ; i++) {
169 sp<SensorEventConnection> connection(activeConnections[i].promote());
170 if (connection != 0) {
171 connection->sendEvents(buffer, count);
172 }
173 }
174 }
175
176 } while (count >= 0 || Thread::exitPending());
177
178 LOGW("Exiting SensorService::threadLoop!");
179 return false;
180}
181
182SortedVector< wp<SensorService::SensorEventConnection> >
183SensorService::getActiveConnections() const
184{
185 Mutex::Autolock _l(mLock);
186 return mActiveConnections;
187}
188
Mathias Agopian5d270722010-07-19 15:20:39 -0700189String8 SensorService::getSensorName(int handle) const {
190 size_t count = mSensorList.size();
191 for (size_t i=0 ; i<count ; i++) {
192 const Sensor& sensor(mSensorList[i]);
193 if (sensor.getHandle() == handle) {
194 return sensor.getName();
195 }
196 }
197 String8 result("unknown");
198 return result;
199}
200
Mathias Agopianfc328812010-07-14 23:41:37 -0700201Vector<Sensor> SensorService::getSensorList()
202{
203 return mSensorList;
204}
205
206sp<ISensorEventConnection> SensorService::createSensorEventConnection()
207{
208 sp<SensorEventConnection> result(new SensorEventConnection(this));
209 Mutex::Autolock _l(mLock);
210 mConnections.add(result);
211 return result;
212}
213
214void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection)
215{
216 Mutex::Autolock _l(mLock);
217 ssize_t index = mConnections.indexOf(connection);
218 if (index >= 0) {
219
220 size_t size = mActiveSensors.size();
221 for (size_t i=0 ; i<size ; ) {
222 SensorRecord* rec = mActiveSensors.valueAt(i);
223 if (rec && rec->removeConnection(connection)) {
224 mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0);
225 mActiveSensors.removeItemsAt(i, 1);
226 delete rec;
227 size--;
228 } else {
229 i++;
230 }
231 }
232
233 mActiveConnections.remove(connection);
234 mConnections.removeItemsAt(index, 1);
235 }
236}
237
238status_t SensorService::enable(const sp<SensorEventConnection>& connection,
239 int handle)
240{
241 status_t err = NO_ERROR;
242 Mutex::Autolock _l(mLock);
243 SensorRecord* rec = mActiveSensors.valueFor(handle);
244 if (rec == 0) {
245 rec = new SensorRecord(connection);
246 mActiveSensors.add(handle, rec);
247 err = mSensorDevice->activate(mSensorDevice, handle, 1);
248 LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
Mathias Agopian451beee2010-07-19 15:03:55 -0700249 if (err == 0) {
250 BatteryService::getInstance().enableSensor(handle);
251 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700252 } else {
253 err = rec->addConnection(connection);
254 }
255 if (err == NO_ERROR) {
256 // connection now active
257 connection->addSensor(handle);
258 if (mActiveConnections.indexOf(connection) < 0) {
259 mActiveConnections.add(connection);
260 }
261 }
262 return err;
263}
264
265status_t SensorService::disable(const sp<SensorEventConnection>& connection,
266 int handle)
267{
268 status_t err = NO_ERROR;
269 Mutex::Autolock _l(mLock);
270 SensorRecord* rec = mActiveSensors.valueFor(handle);
271 LOGW("sensor (handle=%d) is not enabled", handle);
272 if (rec) {
273 // see if this connection becomes inactive
274 connection->removeSensor(handle);
275 if (connection->hasAnySensor() == false) {
276 mActiveConnections.remove(connection);
277 }
278 // see if this sensor becomes inactive
279 if (rec->removeConnection(connection)) {
280 mActiveSensors.removeItem(handle);
281 delete rec;
282 err = mSensorDevice->activate(mSensorDevice, handle, 0);
Mathias Agopian451beee2010-07-19 15:03:55 -0700283 if (err == 0) {
284 BatteryService::getInstance().disableSensor(handle);
285 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700286 }
287 }
288 return err;
289}
290
291status_t SensorService::setRate(const sp<SensorEventConnection>& connection,
292 int handle, nsecs_t ns)
293{
294 status_t err = NO_ERROR;
295 Mutex::Autolock _l(mLock);
296
297 err = mSensorDevice->setDelay(mSensorDevice, handle, ns);
298
299 // TODO: handle rate per connection
300 return err;
301}
302
303// ---------------------------------------------------------------------------
304
305SensorService::SensorRecord::SensorRecord(
306 const sp<SensorEventConnection>& connection)
307{
308 mConnections.add(connection);
309}
310
311status_t SensorService::SensorRecord::addConnection(
312 const sp<SensorEventConnection>& connection)
313{
314 if (mConnections.indexOf(connection) < 0) {
315 mConnections.add(connection);
316 }
317 return NO_ERROR;
318}
319
320bool SensorService::SensorRecord::removeConnection(
321 const wp<SensorEventConnection>& connection)
322{
323 ssize_t index = mConnections.indexOf(connection);
324 if (index >= 0) {
325 mConnections.removeItemsAt(index, 1);
326 }
327 return mConnections.size() ? false : true;
328}
329
330// ---------------------------------------------------------------------------
331
332SensorService::SensorEventConnection::SensorEventConnection(
333 const sp<SensorService>& service)
334 : mService(service), mChannel(new SensorChannel())
335{
336}
337
338SensorService::SensorEventConnection::~SensorEventConnection()
339{
340 mService->cleanupConnection(this);
341}
342
343void SensorService::SensorEventConnection::onFirstRef()
344{
345}
346
347void SensorService::SensorEventConnection::addSensor(int32_t handle) {
348 if (mSensorList.indexOf(handle) <= 0) {
349 mSensorList.add(handle);
350 }
351}
352
353void SensorService::SensorEventConnection::removeSensor(int32_t handle) {
354 mSensorList.remove(handle);
355}
356
357bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
358 return mSensorList.indexOf(handle) >= 0;
359}
360
361bool SensorService::SensorEventConnection::hasAnySensor() const {
362 return mSensorList.size() ? true : false;
363}
364
365status_t SensorService::SensorEventConnection::sendEvents(
366 sensors_event_t const* buffer, size_t count)
367{
368 // TODO: we should only send the events for the sensors this connection
369 // is registered for.
370
371 ssize_t size = mChannel->write(buffer, count*sizeof(sensors_event_t));
372 if (size == -EAGAIN) {
373 // the destination doesn't accept events anymore, it's probably
374 // full. For now, we just drop the events on the floor.
375 LOGW("dropping %d events on the floor", count);
376 return size;
377 }
378
379 LOGE_IF(size<0, "dropping %d events on the floor (%s)",
380 count, strerror(-size));
381
382 return size < 0 ? size : NO_ERROR;
383}
384
385sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const
386{
387 return mChannel;
388}
389
390status_t SensorService::SensorEventConnection::enableDisable(
391 int handle, bool enabled)
392{
393 status_t err;
394 if (enabled) {
395 err = mService->enable(this, handle);
396 } else {
397 err = mService->disable(this, handle);
398 }
399 return err;
400}
401
402status_t SensorService::SensorEventConnection::setEventRate(
403 int handle, nsecs_t ns)
404{
405 return mService->setRate(this, handle, ns);
406}
407
408// ---------------------------------------------------------------------------
409}; // namespace android
410