blob: fec915362ea19db6a5c43440dc27c047bee7dc76 [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),
Mathias Agopian50df2952010-07-19 19:09:10 -070082 mSensorDevice(0),
83 mSensorModule(0),
84 mDump("android.permission.DUMP"),
85 mInitCheck(NO_INIT)
Mathias Agopianfc328812010-07-14 23:41:37 -070086{
87}
88
89void SensorService::onFirstRef()
90{
Mathias Agopian50df2952010-07-19 19:09:10 -070091 LOGD("nuSensorService starting...");
92
Mathias Agopianfc328812010-07-14 23:41:37 -070093 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
94 (hw_module_t const**)&mSensorModule);
95
96 LOGE_IF(err, "couldn't load %s module (%s)",
97 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
98
Mathias Agopian50df2952010-07-19 19:09:10 -070099 if (mSensorModule) {
100 err = sensors_open(&mSensorModule->common, &mSensorDevice);
Mathias Agopianfc328812010-07-14 23:41:37 -0700101
Mathias Agopian50df2952010-07-19 19:09:10 -0700102 LOGE_IF(err, "couldn't open device for module %s (%s)",
103 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
Mathias Agopianfc328812010-07-14 23:41:37 -0700104
Mathias Agopian50df2952010-07-19 19:09:10 -0700105 struct sensor_t const* list;
106 int count = mSensorModule->get_sensors_list(mSensorModule, &list);
107 for (int i=0 ; i<count ; i++) {
108 Sensor sensor(list + i);
109 LOGI("%s", sensor.getName().string());
110 mSensorList.add(sensor);
111 if (mSensorDevice) {
112 mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0);
113 }
114 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700115
Mathias Agopian50df2952010-07-19 19:09:10 -0700116 if (mSensorDevice) {
117 run("SensorService", PRIORITY_URGENT_DISPLAY);
118 mInitCheck = NO_ERROR;
119 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700120 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700121}
122
123SensorService::~SensorService()
124{
125}
126
127status_t SensorService::dump(int fd, const Vector<String16>& args)
128{
129 const size_t SIZE = 1024;
130 char buffer[SIZE];
131 String8 result;
132 if (!mDump.checkCalling()) {
133 snprintf(buffer, SIZE, "Permission Denial: "
134 "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
135 IPCThreadState::self()->getCallingPid(),
136 IPCThreadState::self()->getCallingUid());
137 result.append(buffer);
138 } else {
139 Mutex::Autolock _l(mLock);
140 snprintf(buffer, SIZE, "%d connections / %d active\n",
141 mConnections.size(), mActiveConnections.size());
142 result.append(buffer);
143 snprintf(buffer, SIZE, "Active sensors:\n");
144 result.append(buffer);
145 for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
Mathias Agopian5d270722010-07-19 15:20:39 -0700146 int handle = mActiveSensors.keyAt(i);
147 snprintf(buffer, SIZE, "%s (handle=%d, connections=%d)\n",
148 getSensorName(handle).string(),
149 handle,
Mathias Agopianfc328812010-07-14 23:41:37 -0700150 mActiveSensors.valueAt(i)->getNumConnections());
151 result.append(buffer);
152 }
153 }
154 write(fd, result.string(), result.size());
155 return NO_ERROR;
156}
157
158bool SensorService::threadLoop()
159{
160 LOGD("nuSensorService thread starting...");
161
162 sensors_event_t buffer[16];
163 struct sensors_poll_device_t* device = mSensorDevice;
164 ssize_t count;
165
166 do {
167 count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer));
168 if (count<0) {
169 LOGE("sensor poll failed (%s)", strerror(-count));
170 break;
171 }
172
173 const SortedVector< wp<SensorEventConnection> > activeConnections(
174 getActiveConnections());
175
176 size_t numConnections = activeConnections.size();
177 if (numConnections) {
178 for (size_t i=0 ; i<numConnections ; i++) {
179 sp<SensorEventConnection> connection(activeConnections[i].promote());
180 if (connection != 0) {
181 connection->sendEvents(buffer, count);
182 }
183 }
184 }
185
186 } while (count >= 0 || Thread::exitPending());
187
188 LOGW("Exiting SensorService::threadLoop!");
189 return false;
190}
191
192SortedVector< wp<SensorService::SensorEventConnection> >
193SensorService::getActiveConnections() const
194{
195 Mutex::Autolock _l(mLock);
196 return mActiveConnections;
197}
198
Mathias Agopian5d270722010-07-19 15:20:39 -0700199String8 SensorService::getSensorName(int handle) const {
200 size_t count = mSensorList.size();
201 for (size_t i=0 ; i<count ; i++) {
202 const Sensor& sensor(mSensorList[i]);
203 if (sensor.getHandle() == handle) {
204 return sensor.getName();
205 }
206 }
207 String8 result("unknown");
208 return result;
209}
210
Mathias Agopianfc328812010-07-14 23:41:37 -0700211Vector<Sensor> SensorService::getSensorList()
212{
213 return mSensorList;
214}
215
216sp<ISensorEventConnection> SensorService::createSensorEventConnection()
217{
218 sp<SensorEventConnection> result(new SensorEventConnection(this));
219 Mutex::Autolock _l(mLock);
220 mConnections.add(result);
221 return result;
222}
223
224void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection)
225{
226 Mutex::Autolock _l(mLock);
227 ssize_t index = mConnections.indexOf(connection);
228 if (index >= 0) {
229
230 size_t size = mActiveSensors.size();
231 for (size_t i=0 ; i<size ; ) {
232 SensorRecord* rec = mActiveSensors.valueAt(i);
233 if (rec && rec->removeConnection(connection)) {
234 mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0);
235 mActiveSensors.removeItemsAt(i, 1);
236 delete rec;
237 size--;
238 } else {
239 i++;
240 }
241 }
242
243 mActiveConnections.remove(connection);
244 mConnections.removeItemsAt(index, 1);
245 }
246}
247
248status_t SensorService::enable(const sp<SensorEventConnection>& connection,
249 int handle)
250{
Mathias Agopian50df2952010-07-19 19:09:10 -0700251 if (mInitCheck != NO_ERROR)
252 return mInitCheck;
253
Mathias Agopianfc328812010-07-14 23:41:37 -0700254 status_t err = NO_ERROR;
255 Mutex::Autolock _l(mLock);
256 SensorRecord* rec = mActiveSensors.valueFor(handle);
257 if (rec == 0) {
258 rec = new SensorRecord(connection);
259 mActiveSensors.add(handle, rec);
260 err = mSensorDevice->activate(mSensorDevice, handle, 1);
261 LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
Mathias Agopian451beee2010-07-19 15:03:55 -0700262 if (err == 0) {
263 BatteryService::getInstance().enableSensor(handle);
264 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700265 } else {
266 err = rec->addConnection(connection);
267 }
268 if (err == NO_ERROR) {
269 // connection now active
270 connection->addSensor(handle);
271 if (mActiveConnections.indexOf(connection) < 0) {
272 mActiveConnections.add(connection);
273 }
274 }
275 return err;
276}
277
278status_t SensorService::disable(const sp<SensorEventConnection>& connection,
279 int handle)
280{
Mathias Agopian50df2952010-07-19 19:09:10 -0700281 if (mInitCheck != NO_ERROR)
282 return mInitCheck;
283
Mathias Agopianfc328812010-07-14 23:41:37 -0700284 status_t err = NO_ERROR;
285 Mutex::Autolock _l(mLock);
286 SensorRecord* rec = mActiveSensors.valueFor(handle);
287 LOGW("sensor (handle=%d) is not enabled", handle);
288 if (rec) {
289 // see if this connection becomes inactive
290 connection->removeSensor(handle);
291 if (connection->hasAnySensor() == false) {
292 mActiveConnections.remove(connection);
293 }
294 // see if this sensor becomes inactive
295 if (rec->removeConnection(connection)) {
296 mActiveSensors.removeItem(handle);
297 delete rec;
298 err = mSensorDevice->activate(mSensorDevice, handle, 0);
Mathias Agopian451beee2010-07-19 15:03:55 -0700299 if (err == 0) {
300 BatteryService::getInstance().disableSensor(handle);
301 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700302 }
303 }
304 return err;
305}
306
307status_t SensorService::setRate(const sp<SensorEventConnection>& connection,
308 int handle, nsecs_t ns)
309{
Mathias Agopian50df2952010-07-19 19:09:10 -0700310 if (mInitCheck != NO_ERROR)
311 return mInitCheck;
312
Mathias Agopianfc328812010-07-14 23:41:37 -0700313 status_t err = NO_ERROR;
314 Mutex::Autolock _l(mLock);
315
316 err = mSensorDevice->setDelay(mSensorDevice, handle, ns);
317
318 // TODO: handle rate per connection
319 return err;
320}
321
322// ---------------------------------------------------------------------------
323
324SensorService::SensorRecord::SensorRecord(
325 const sp<SensorEventConnection>& connection)
326{
327 mConnections.add(connection);
328}
329
330status_t SensorService::SensorRecord::addConnection(
331 const sp<SensorEventConnection>& connection)
332{
333 if (mConnections.indexOf(connection) < 0) {
334 mConnections.add(connection);
335 }
336 return NO_ERROR;
337}
338
339bool SensorService::SensorRecord::removeConnection(
340 const wp<SensorEventConnection>& connection)
341{
342 ssize_t index = mConnections.indexOf(connection);
343 if (index >= 0) {
344 mConnections.removeItemsAt(index, 1);
345 }
346 return mConnections.size() ? false : true;
347}
348
349// ---------------------------------------------------------------------------
350
351SensorService::SensorEventConnection::SensorEventConnection(
352 const sp<SensorService>& service)
353 : mService(service), mChannel(new SensorChannel())
354{
355}
356
357SensorService::SensorEventConnection::~SensorEventConnection()
358{
359 mService->cleanupConnection(this);
360}
361
362void SensorService::SensorEventConnection::onFirstRef()
363{
364}
365
366void SensorService::SensorEventConnection::addSensor(int32_t handle) {
367 if (mSensorList.indexOf(handle) <= 0) {
368 mSensorList.add(handle);
369 }
370}
371
372void SensorService::SensorEventConnection::removeSensor(int32_t handle) {
373 mSensorList.remove(handle);
374}
375
376bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
377 return mSensorList.indexOf(handle) >= 0;
378}
379
380bool SensorService::SensorEventConnection::hasAnySensor() const {
381 return mSensorList.size() ? true : false;
382}
383
384status_t SensorService::SensorEventConnection::sendEvents(
385 sensors_event_t const* buffer, size_t count)
386{
387 // TODO: we should only send the events for the sensors this connection
388 // is registered for.
389
390 ssize_t size = mChannel->write(buffer, count*sizeof(sensors_event_t));
391 if (size == -EAGAIN) {
392 // the destination doesn't accept events anymore, it's probably
393 // full. For now, we just drop the events on the floor.
394 LOGW("dropping %d events on the floor", count);
395 return size;
396 }
397
398 LOGE_IF(size<0, "dropping %d events on the floor (%s)",
399 count, strerror(-size));
400
401 return size < 0 ? size : NO_ERROR;
402}
403
404sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const
405{
406 return mChannel;
407}
408
409status_t SensorService::SensorEventConnection::enableDisable(
410 int handle, bool enabled)
411{
412 status_t err;
413 if (enabled) {
414 err = mService->enable(this, handle);
415 } else {
416 err = mService->disable(this, handle);
417 }
418 return err;
419}
420
421status_t SensorService::SensorEventConnection::setEventRate(
422 int handle, nsecs_t ns)
423{
424 return mService->setRate(this, handle, ns);
425}
426
427// ---------------------------------------------------------------------------
428}; // namespace android
429