blob: e204e0402aaa357e9b3af880b2a21f34a6425fbf [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 Agopianc4a930d2010-07-22 22:19:43 -070027#include <utils/String16.h>
Mathias Agopianfc328812010-07-14 23:41:37 -070028
29#include <binder/BinderService.h>
Mathias Agopian451beee2010-07-19 15:03:55 -070030#include <binder/IServiceManager.h>
Mathias Agopianfc328812010-07-14 23:41:37 -070031
32#include <gui/ISensorServer.h>
33#include <gui/ISensorEventConnection.h>
34
35#include <hardware/sensors.h>
36
37#include "SensorService.h"
38
39namespace android {
40// ---------------------------------------------------------------------------
41
Mathias Agopian451beee2010-07-19 15:03:55 -070042class BatteryService : public Singleton<BatteryService> {
Mathias Agopianc4a930d2010-07-22 22:19:43 -070043 static const int TRANSACTION_noteStartSensor = IBinder::FIRST_CALL_TRANSACTION + 3;
44 static const int TRANSACTION_noteStopSensor = IBinder::FIRST_CALL_TRANSACTION + 4;
45 static const String16 DESCRIPTOR;
46
Mathias Agopian451beee2010-07-19 15:03:55 -070047 friend class Singleton<BatteryService>;
48 sp<IBinder> mBatteryStatService;
Mathias Agopianc4a930d2010-07-22 22:19:43 -070049
Mathias Agopian451beee2010-07-19 15:03:55 -070050 BatteryService() {
Mathias Agopianc4a930d2010-07-22 22:19:43 -070051 const sp<IServiceManager> sm(defaultServiceManager());
52 if (sm != NULL) {
53 const String16 name("batteryinfo");
54 mBatteryStatService = sm->getService(name);
55 }
Mathias Agopian451beee2010-07-19 15:03:55 -070056 }
Mathias Agopianc4a930d2010-07-22 22:19:43 -070057
58 status_t noteStartSensor(int uid, int handle) {
59 Parcel data, reply;
60 data.writeInterfaceToken(DESCRIPTOR);
61 data.writeInt32(uid);
62 data.writeInt32(handle);
63 status_t err = mBatteryStatService->transact(
64 TRANSACTION_noteStartSensor, data, &reply, 0);
65 err = reply.readExceptionCode();
66 return err;
67 }
68
69 status_t noteStopSensor(int uid, int handle) {
70 Parcel data, reply;
71 data.writeInterfaceToken(DESCRIPTOR);
72 data.writeInt32(uid);
73 data.writeInt32(handle);
74 status_t err = mBatteryStatService->transact(
75 TRANSACTION_noteStopSensor, data, &reply, 0);
76 err = reply.readExceptionCode();
77 return err;
78 }
79
Mathias Agopian451beee2010-07-19 15:03:55 -070080public:
81 void enableSensor(int handle) {
82 if (mBatteryStatService != 0) {
83 int uid = IPCThreadState::self()->getCallingUid();
Mathias Agopianc4a930d2010-07-22 22:19:43 -070084 int64_t identity = IPCThreadState::self()->clearCallingIdentity();
85 noteStartSensor(uid, handle);
86 IPCThreadState::self()->restoreCallingIdentity(identity);
Mathias Agopian451beee2010-07-19 15:03:55 -070087 }
88 }
89 void disableSensor(int handle) {
90 if (mBatteryStatService != 0) {
91 int uid = IPCThreadState::self()->getCallingUid();
Mathias Agopianc4a930d2010-07-22 22:19:43 -070092 int64_t identity = IPCThreadState::self()->clearCallingIdentity();
93 noteStopSensor(uid, handle);
94 IPCThreadState::self()->restoreCallingIdentity(identity);
Mathias Agopian451beee2010-07-19 15:03:55 -070095 }
96 }
97};
98
Mathias Agopianc4a930d2010-07-22 22:19:43 -070099const String16 BatteryService::DESCRIPTOR("com.android.internal.app.IBatteryStats");
100
Mathias Agopian451beee2010-07-19 15:03:55 -0700101ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
102
103// ---------------------------------------------------------------------------
104
Mathias Agopian1cd70002010-07-21 15:59:50 -0700105// 100 events/s max
106static const nsecs_t MINIMUM_EVENT_PERIOD = ms2ns(10);
107
Mathias Agopianfc328812010-07-14 23:41:37 -0700108SensorService::SensorService()
109 : Thread(false),
Mathias Agopian50df2952010-07-19 19:09:10 -0700110 mSensorDevice(0),
111 mSensorModule(0),
112 mDump("android.permission.DUMP"),
113 mInitCheck(NO_INIT)
Mathias Agopianfc328812010-07-14 23:41:37 -0700114{
115}
116
117void SensorService::onFirstRef()
118{
Mathias Agopian50df2952010-07-19 19:09:10 -0700119 LOGD("nuSensorService starting...");
120
Mathias Agopianfc328812010-07-14 23:41:37 -0700121 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
122 (hw_module_t const**)&mSensorModule);
123
124 LOGE_IF(err, "couldn't load %s module (%s)",
125 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
126
Mathias Agopian50df2952010-07-19 19:09:10 -0700127 if (mSensorModule) {
128 err = sensors_open(&mSensorModule->common, &mSensorDevice);
Mathias Agopianfc328812010-07-14 23:41:37 -0700129
Mathias Agopian50df2952010-07-19 19:09:10 -0700130 LOGE_IF(err, "couldn't open device for module %s (%s)",
131 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
Mathias Agopianfc328812010-07-14 23:41:37 -0700132
Mathias Agopian3560fb22010-07-22 21:24:39 -0700133 sensors_event_t event;
134 memset(&event, 0, sizeof(event));
135
Mathias Agopian50df2952010-07-19 19:09:10 -0700136 struct sensor_t const* list;
137 int count = mSensorModule->get_sensors_list(mSensorModule, &list);
Mathias Agopian3560fb22010-07-22 21:24:39 -0700138 mLastEventSeen.setCapacity(count);
Mathias Agopian50df2952010-07-19 19:09:10 -0700139 for (int i=0 ; i<count ; i++) {
140 Sensor sensor(list + i);
141 LOGI("%s", sensor.getName().string());
142 mSensorList.add(sensor);
143 if (mSensorDevice) {
144 mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0);
145 }
Mathias Agopian3560fb22010-07-22 21:24:39 -0700146 mLastEventSeen.add(sensor.getHandle(), event);
Mathias Agopian50df2952010-07-19 19:09:10 -0700147 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700148
Mathias Agopian50df2952010-07-19 19:09:10 -0700149 if (mSensorDevice) {
150 run("SensorService", PRIORITY_URGENT_DISPLAY);
151 mInitCheck = NO_ERROR;
152 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700153 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700154}
155
156SensorService::~SensorService()
157{
158}
159
160status_t SensorService::dump(int fd, const Vector<String16>& args)
161{
162 const size_t SIZE = 1024;
163 char buffer[SIZE];
164 String8 result;
165 if (!mDump.checkCalling()) {
166 snprintf(buffer, SIZE, "Permission Denial: "
167 "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
168 IPCThreadState::self()->getCallingPid(),
169 IPCThreadState::self()->getCallingUid());
170 result.append(buffer);
171 } else {
172 Mutex::Autolock _l(mLock);
Mathias Agopian3560fb22010-07-22 21:24:39 -0700173 snprintf(buffer, SIZE, "Sensor List:\n");
174 result.append(buffer);
175 for (size_t i=0 ; i<mSensorList.size() ; i++) {
176 const Sensor& s(mSensorList[i]);
177 const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
178 snprintf(buffer, SIZE, "%s (vendor=%s, handle=%d, last=<%5.1f,%5.1f,%5.1f>)\n",
179 s.getName().string(),
180 s.getVendor().string(),
181 s.getHandle(),
182 e.data[0], e.data[1], e.data[2]);
183 result.append(buffer);
184 }
185
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700186 snprintf(buffer, SIZE, "%d active connections\n",
187 mActiveConnections.size());
Mathias Agopianfc328812010-07-14 23:41:37 -0700188 result.append(buffer);
189 snprintf(buffer, SIZE, "Active sensors:\n");
190 result.append(buffer);
191 for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
Mathias Agopian5d270722010-07-19 15:20:39 -0700192 int handle = mActiveSensors.keyAt(i);
193 snprintf(buffer, SIZE, "%s (handle=%d, connections=%d)\n",
194 getSensorName(handle).string(),
195 handle,
Mathias Agopianfc328812010-07-14 23:41:37 -0700196 mActiveSensors.valueAt(i)->getNumConnections());
197 result.append(buffer);
198 }
199 }
200 write(fd, result.string(), result.size());
201 return NO_ERROR;
202}
203
204bool SensorService::threadLoop()
205{
206 LOGD("nuSensorService thread starting...");
207
208 sensors_event_t buffer[16];
Mathias Agopiancf510012010-07-22 16:18:10 -0700209 sensors_event_t scratch[16];
Mathias Agopianfc328812010-07-14 23:41:37 -0700210 struct sensors_poll_device_t* device = mSensorDevice;
211 ssize_t count;
212
213 do {
214 count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer));
215 if (count<0) {
216 LOGE("sensor poll failed (%s)", strerror(-count));
217 break;
218 }
219
220 const SortedVector< wp<SensorEventConnection> > activeConnections(
221 getActiveConnections());
222
223 size_t numConnections = activeConnections.size();
224 if (numConnections) {
Mathias Agopiancf510012010-07-22 16:18:10 -0700225 Mutex::Autolock _l(mLock);
Mathias Agopian3560fb22010-07-22 21:24:39 -0700226
227 // record the last event for each sensor
228 int32_t prev = buffer[0].sensor;
229 for (ssize_t i=1 ; i<count ; i++) {
230 // record the last event of each sensor type in this buffer
231 int32_t curr = buffer[i].sensor;
232 if (curr != prev) {
233 mLastEventSeen.editValueFor(prev) = buffer[i-1];
234 prev = curr;
235 }
236 }
237 mLastEventSeen.editValueFor(prev) = buffer[count-1];
238
Mathias Agopianfc328812010-07-14 23:41:37 -0700239 for (size_t i=0 ; i<numConnections ; i++) {
240 sp<SensorEventConnection> connection(activeConnections[i].promote());
241 if (connection != 0) {
Mathias Agopiancf510012010-07-22 16:18:10 -0700242 connection->sendEvents(buffer, count, scratch);
Mathias Agopianfc328812010-07-14 23:41:37 -0700243 }
244 }
245 }
246
247 } while (count >= 0 || Thread::exitPending());
248
249 LOGW("Exiting SensorService::threadLoop!");
250 return false;
251}
252
253SortedVector< wp<SensorService::SensorEventConnection> >
254SensorService::getActiveConnections() const
255{
256 Mutex::Autolock _l(mLock);
257 return mActiveConnections;
258}
259
Mathias Agopian5d270722010-07-19 15:20:39 -0700260String8 SensorService::getSensorName(int handle) const {
261 size_t count = mSensorList.size();
262 for (size_t i=0 ; i<count ; i++) {
263 const Sensor& sensor(mSensorList[i]);
264 if (sensor.getHandle() == handle) {
265 return sensor.getName();
266 }
267 }
268 String8 result("unknown");
269 return result;
270}
271
Mathias Agopianfc328812010-07-14 23:41:37 -0700272Vector<Sensor> SensorService::getSensorList()
273{
274 return mSensorList;
275}
276
277sp<ISensorEventConnection> SensorService::createSensorEventConnection()
278{
279 sp<SensorEventConnection> result(new SensorEventConnection(this));
Mathias Agopianfc328812010-07-14 23:41:37 -0700280 return result;
281}
282
283void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection)
284{
285 Mutex::Autolock _l(mLock);
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700286 size_t size = mActiveSensors.size();
287 for (size_t i=0 ; i<size ; ) {
288 SensorRecord* rec = mActiveSensors.valueAt(i);
289 if (rec && rec->removeConnection(connection)) {
290 mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0);
291 mActiveSensors.removeItemsAt(i, 1);
292 delete rec;
293 size--;
294 } else {
295 i++;
Mathias Agopianfc328812010-07-14 23:41:37 -0700296 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700297 }
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700298 mActiveConnections.remove(connection);
Mathias Agopianfc328812010-07-14 23:41:37 -0700299}
300
301status_t SensorService::enable(const sp<SensorEventConnection>& connection,
302 int handle)
303{
Mathias Agopian50df2952010-07-19 19:09:10 -0700304 if (mInitCheck != NO_ERROR)
305 return mInitCheck;
306
Mathias Agopianfc328812010-07-14 23:41:37 -0700307 status_t err = NO_ERROR;
308 Mutex::Autolock _l(mLock);
309 SensorRecord* rec = mActiveSensors.valueFor(handle);
310 if (rec == 0) {
311 rec = new SensorRecord(connection);
312 mActiveSensors.add(handle, rec);
313 err = mSensorDevice->activate(mSensorDevice, handle, 1);
314 LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
Mathias Agopian451beee2010-07-19 15:03:55 -0700315 if (err == 0) {
316 BatteryService::getInstance().enableSensor(handle);
317 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700318 } else {
Mathias Agopian3560fb22010-07-22 21:24:39 -0700319 if (rec->addConnection(connection)) {
320 // this sensor is already activated, but we are adding a
321 // connection that uses it. Immediately send down the last
322 // known value of the requested sensor.
323 sensors_event_t scratch;
324 sensors_event_t& event(mLastEventSeen.editValueFor(handle));
325 if (event.version == sizeof(sensors_event_t)) {
326 connection->sendEvents(&event, 1);
327 }
328 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700329 }
330 if (err == NO_ERROR) {
331 // connection now active
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700332 if (connection->addSensor(handle)) {
333 // the sensor was added (which means it wasn't already there)
334 // so, see if this connection becomes active
335 if (mActiveConnections.indexOf(connection) < 0) {
336 mActiveConnections.add(connection);
337 }
338 // this could change the sensor event delivery speed
339 recomputeEventsPeriodLocked(handle);
Mathias Agopianfc328812010-07-14 23:41:37 -0700340 }
341 }
342 return err;
343}
344
345status_t SensorService::disable(const sp<SensorEventConnection>& connection,
346 int handle)
347{
Mathias Agopian50df2952010-07-19 19:09:10 -0700348 if (mInitCheck != NO_ERROR)
349 return mInitCheck;
350
Mathias Agopianfc328812010-07-14 23:41:37 -0700351 status_t err = NO_ERROR;
352 Mutex::Autolock _l(mLock);
353 SensorRecord* rec = mActiveSensors.valueFor(handle);
Mathias Agopianfc328812010-07-14 23:41:37 -0700354 if (rec) {
355 // see if this connection becomes inactive
356 connection->removeSensor(handle);
357 if (connection->hasAnySensor() == false) {
358 mActiveConnections.remove(connection);
359 }
360 // see if this sensor becomes inactive
361 if (rec->removeConnection(connection)) {
362 mActiveSensors.removeItem(handle);
363 delete rec;
364 err = mSensorDevice->activate(mSensorDevice, handle, 0);
Mathias Agopian451beee2010-07-19 15:03:55 -0700365 if (err == 0) {
366 BatteryService::getInstance().disableSensor(handle);
367 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700368 }
369 }
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700370 if (err == NO_ERROR) {
371 recomputeEventsPeriodLocked(handle);
372 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700373 return err;
374}
375
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700376status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
Mathias Agopianfc328812010-07-14 23:41:37 -0700377 int handle, nsecs_t ns)
378{
Mathias Agopian50df2952010-07-19 19:09:10 -0700379 if (mInitCheck != NO_ERROR)
380 return mInitCheck;
381
Mathias Agopian1cd70002010-07-21 15:59:50 -0700382 if (ns < 0)
383 return BAD_VALUE;
384
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700385 if (ns < MINIMUM_EVENTS_PERIOD)
386 ns = MINIMUM_EVENTS_PERIOD;
Mathias Agopian1cd70002010-07-21 15:59:50 -0700387
Mathias Agopianfc328812010-07-14 23:41:37 -0700388 Mutex::Autolock _l(mLock);
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700389 status_t err = connection->setEventRateLocked(handle, ns);
390 if (err == NO_ERROR) {
391 recomputeEventsPeriodLocked(handle);
392 }
393 return err;
394}
Mathias Agopianfc328812010-07-14 23:41:37 -0700395
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700396status_t SensorService::recomputeEventsPeriodLocked(int32_t handle)
397{
398 status_t err = NO_ERROR;
399 nsecs_t wanted = ms2ns(1000);
400 size_t count = mActiveConnections.size();
401 for (size_t i=0 ; i<count ; i++) {
402 sp<SensorEventConnection> connection(mActiveConnections[i].promote());
403 if (connection != NULL) {
404 nsecs_t ns = connection->getEventRateForSensor(handle);
405 if (ns) {
406 wanted = wanted < ns ? wanted : ns;
407 }
408 }
409 }
410 err = mSensorDevice->setDelay(mSensorDevice, handle, wanted);
Mathias Agopianfc328812010-07-14 23:41:37 -0700411 return err;
412}
413
414// ---------------------------------------------------------------------------
415
416SensorService::SensorRecord::SensorRecord(
417 const sp<SensorEventConnection>& connection)
418{
419 mConnections.add(connection);
420}
421
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700422bool SensorService::SensorRecord::addConnection(
Mathias Agopianfc328812010-07-14 23:41:37 -0700423 const sp<SensorEventConnection>& connection)
424{
425 if (mConnections.indexOf(connection) < 0) {
426 mConnections.add(connection);
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700427 return true;
Mathias Agopianfc328812010-07-14 23:41:37 -0700428 }
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700429 return false;
Mathias Agopianfc328812010-07-14 23:41:37 -0700430}
431
432bool SensorService::SensorRecord::removeConnection(
433 const wp<SensorEventConnection>& connection)
434{
435 ssize_t index = mConnections.indexOf(connection);
436 if (index >= 0) {
437 mConnections.removeItemsAt(index, 1);
438 }
439 return mConnections.size() ? false : true;
440}
441
442// ---------------------------------------------------------------------------
443
444SensorService::SensorEventConnection::SensorEventConnection(
445 const sp<SensorService>& service)
446 : mService(service), mChannel(new SensorChannel())
447{
448}
449
450SensorService::SensorEventConnection::~SensorEventConnection()
451{
452 mService->cleanupConnection(this);
453}
454
455void SensorService::SensorEventConnection::onFirstRef()
456{
457}
458
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700459bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
460 if (mSensorInfo.indexOfKey(handle) <= 0) {
461 SensorInfo info;
462 mSensorInfo.add(handle, info);
463 return true;
Mathias Agopianfc328812010-07-14 23:41:37 -0700464 }
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700465 return false;
Mathias Agopianfc328812010-07-14 23:41:37 -0700466}
467
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700468bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
469 if (mSensorInfo.removeItem(handle) >= 0) {
470 return true;
471 }
472 return false;
Mathias Agopianfc328812010-07-14 23:41:37 -0700473}
474
475bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700476 return mSensorInfo.indexOfKey(handle) >= 0;
Mathias Agopianfc328812010-07-14 23:41:37 -0700477}
478
479bool SensorService::SensorEventConnection::hasAnySensor() const {
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700480 return mSensorInfo.size() ? true : false;
481}
482
483status_t SensorService::SensorEventConnection::setEventRateLocked(
484 int handle, nsecs_t ns)
485{
486 ssize_t index = mSensorInfo.indexOfKey(handle);
487 if (index >= 0) {
488 SensorInfo& info = mSensorInfo.editValueFor(handle);
489 info.ns = ns;
490 return NO_ERROR;
491 }
492 return status_t(index);
Mathias Agopianfc328812010-07-14 23:41:37 -0700493}
494
495status_t SensorService::SensorEventConnection::sendEvents(
Mathias Agopiancf510012010-07-22 16:18:10 -0700496 sensors_event_t const* buffer, size_t numEvents,
497 sensors_event_t* scratch)
Mathias Agopianfc328812010-07-14 23:41:37 -0700498{
Mathias Agopiancf510012010-07-22 16:18:10 -0700499 // filter out events not for this connection
Mathias Agopian3560fb22010-07-22 21:24:39 -0700500 size_t count = 0;
501 if (scratch) {
502 size_t i=0;
503 while (i<numEvents) {
504 const int32_t curr = buffer[i].sensor;
505 if (mSensorInfo.indexOfKey(curr) >= 0) {
506 do {
507 scratch[count++] = buffer[i++];
508 } while ((i<numEvents) && (buffer[i].sensor == curr));
509 } else {
510 i++;
511 }
Mathias Agopiancf510012010-07-22 16:18:10 -0700512 }
Mathias Agopian3560fb22010-07-22 21:24:39 -0700513 } else {
514 scratch = const_cast<sensors_event_t *>(buffer);
515 count = numEvents;
Mathias Agopiancf510012010-07-22 16:18:10 -0700516 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700517
Mathias Agopian3560fb22010-07-22 21:24:39 -0700518 if (count == 0)
519 return 0;
520
Mathias Agopiancf510012010-07-22 16:18:10 -0700521 ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t));
Mathias Agopianfc328812010-07-14 23:41:37 -0700522 if (size == -EAGAIN) {
523 // the destination doesn't accept events anymore, it's probably
524 // full. For now, we just drop the events on the floor.
525 LOGW("dropping %d events on the floor", count);
526 return size;
527 }
528
529 LOGE_IF(size<0, "dropping %d events on the floor (%s)",
530 count, strerror(-size));
531
Jeff Brown1e0b1e82010-09-13 23:17:30 -0700532 return size < 0 ? status_t(size) : status_t(NO_ERROR);
Mathias Agopianfc328812010-07-14 23:41:37 -0700533}
534
535sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const
536{
537 return mChannel;
538}
539
540status_t SensorService::SensorEventConnection::enableDisable(
541 int handle, bool enabled)
542{
543 status_t err;
544 if (enabled) {
545 err = mService->enable(this, handle);
546 } else {
547 err = mService->disable(this, handle);
548 }
549 return err;
550}
551
552status_t SensorService::SensorEventConnection::setEventRate(
553 int handle, nsecs_t ns)
554{
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700555 return mService->setEventRate(this, handle, ns);
Mathias Agopianfc328812010-07-14 23:41:37 -0700556}
557
558// ---------------------------------------------------------------------------
559}; // namespace android
560