blob: fad046cf5397fec3702052219df7a03f51cc4d94 [file] [log] [blame]
Peng Xueb4d6282015-12-10 18:02:41 -08001/*
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 <sys/socket.h>
18#include <utils/threads.h>
19
Mathias Agopian801ea092017-03-06 15:05:04 -080020#include <sensor/SensorEventQueue.h>
Peng Xueb4d6282015-12-10 18:02:41 -080021
22#include "vec.h"
23#include "SensorEventConnection.h"
Peng Xu755c4512016-04-07 23:15:14 -070024#include "SensorDevice.h"
Peng Xueb4d6282015-12-10 18:02:41 -080025
Peng Xue36e3472016-11-03 11:57:10 -070026#define UNUSED(x) (void)(x)
27
Peng Xueb4d6282015-12-10 18:02:41 -080028namespace android {
29
30SensorService::SensorEventConnection::SensorEventConnection(
31 const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
32 const String16& opPackageName)
33 : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
34 mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
35 mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName) {
36 mChannel = new BitTube(mService->mSocketBufferSize);
37#if DEBUG_CONNECTIONS
38 mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
39 mTotalAcksNeeded = mTotalAcksReceived = 0;
40#endif
41}
42
43SensorService::SensorEventConnection::~SensorEventConnection() {
44 ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
45 mService->cleanupConnection(this);
46 if (mEventCache != NULL) {
47 delete mEventCache;
48 }
49}
50
51void SensorService::SensorEventConnection::onFirstRef() {
52 LooperCallback::onFirstRef();
53}
54
55bool SensorService::SensorEventConnection::needsWakeLock() {
56 Mutex::Autolock _l(mConnectionLock);
57 return !mDead && mWakeLockRefCount > 0;
58}
59
60void SensorService::SensorEventConnection::resetWakeLockRefCount() {
61 Mutex::Autolock _l(mConnectionLock);
62 mWakeLockRefCount = 0;
63}
64
65void SensorService::SensorEventConnection::dump(String8& result) {
66 Mutex::Autolock _l(mConnectionLock);
67 result.appendFormat("\tOperating Mode: %s\n",mDataInjectionMode ? "DATA_INJECTION" : "NORMAL");
68 result.appendFormat("\t %s | WakeLockRefCount %d | uid %d | cache size %d | "
69 "max cache size %d\n", mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize,
70 mMaxCacheSize);
71 for (size_t i = 0; i < mSensorInfo.size(); ++i) {
72 const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
73 result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
74 mService->getSensorName(mSensorInfo.keyAt(i)).string(),
75 mSensorInfo.keyAt(i),
76 flushInfo.mFirstFlushPending ? "First flush pending" :
77 "active",
78 flushInfo.mPendingFlushEventsToSend);
79 }
80#if DEBUG_CONNECTIONS
81 result.appendFormat("\t events recvd: %d | sent %d | cache %d | dropped %d |"
82 " total_acks_needed %d | total_acks_recvd %d\n",
83 mEventsReceived,
84 mEventsSent,
85 mEventsSentFromCache,
86 mEventsReceived - (mEventsSentFromCache + mEventsSent + mCacheSize),
87 mTotalAcksNeeded,
88 mTotalAcksReceived);
89#endif
90}
91
92bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
93 Mutex::Autolock _l(mConnectionLock);
Peng Xu755c4512016-04-07 23:15:14 -070094 sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
95 if (si == nullptr ||
96 !canAccessSensor(si->getSensor(), "Tried adding", mOpPackageName) ||
97 mSensorInfo.indexOfKey(handle) >= 0) {
Peng Xueb4d6282015-12-10 18:02:41 -080098 return false;
99 }
Peng Xu755c4512016-04-07 23:15:14 -0700100 mSensorInfo.add(handle, FlushInfo());
101 return true;
Peng Xueb4d6282015-12-10 18:02:41 -0800102}
103
104bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
105 Mutex::Autolock _l(mConnectionLock);
106 if (mSensorInfo.removeItem(handle) >= 0) {
107 return true;
108 }
109 return false;
110}
111
112bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
113 Mutex::Autolock _l(mConnectionLock);
114 return mSensorInfo.indexOfKey(handle) >= 0;
115}
116
117bool SensorService::SensorEventConnection::hasAnySensor() const {
118 Mutex::Autolock _l(mConnectionLock);
119 return mSensorInfo.size() ? true : false;
120}
121
122bool SensorService::SensorEventConnection::hasOneShotSensors() const {
123 Mutex::Autolock _l(mConnectionLock);
124 for (size_t i = 0; i < mSensorInfo.size(); ++i) {
125 const int handle = mSensorInfo.keyAt(i);
Peng Xu755c4512016-04-07 23:15:14 -0700126 sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
127 if (si != nullptr && si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
Peng Xueb4d6282015-12-10 18:02:41 -0800128 return true;
129 }
130 }
131 return false;
132}
133
134String8 SensorService::SensorEventConnection::getPackageName() const {
135 return mPackageName;
136}
137
138void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
139 bool value) {
140 Mutex::Autolock _l(mConnectionLock);
141 ssize_t index = mSensorInfo.indexOfKey(handle);
142 if (index >= 0) {
143 FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
144 flushInfo.mFirstFlushPending = value;
145 }
146}
147
148void SensorService::SensorEventConnection::updateLooperRegistration(const sp<Looper>& looper) {
149 Mutex::Autolock _l(mConnectionLock);
150 updateLooperRegistrationLocked(looper);
151}
152
153void SensorService::SensorEventConnection::updateLooperRegistrationLocked(
154 const sp<Looper>& looper) {
155 bool isConnectionActive = (mSensorInfo.size() > 0 && !mDataInjectionMode) ||
156 mDataInjectionMode;
157 // If all sensors are unregistered OR Looper has encountered an error, we can remove the Fd from
158 // the Looper if it has been previously added.
159 if (!isConnectionActive || mDead) { if (mHasLooperCallbacks) {
160 ALOGD_IF(DEBUG_CONNECTIONS, "%p removeFd fd=%d", this,
161 mChannel->getSendFd());
162 looper->removeFd(mChannel->getSendFd()); mHasLooperCallbacks = false; }
163 return; }
164
165 int looper_flags = 0;
166 if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
167 if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
168 for (size_t i = 0; i < mSensorInfo.size(); ++i) {
169 const int handle = mSensorInfo.keyAt(i);
Peng Xu755c4512016-04-07 23:15:14 -0700170 sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
171 if (si != nullptr && si->getSensor().isWakeUpSensor()) {
Peng Xueb4d6282015-12-10 18:02:41 -0800172 looper_flags |= ALOOPER_EVENT_INPUT;
Peng Xueb4d6282015-12-10 18:02:41 -0800173 }
174 }
175
176 // If flags is still set to zero, we don't need to add this fd to the Looper, if the fd has
177 // already been added, remove it. This is likely to happen when ALL the events stored in the
178 // cache have been sent to the corresponding app.
179 if (looper_flags == 0) {
180 if (mHasLooperCallbacks) {
181 ALOGD_IF(DEBUG_CONNECTIONS, "removeFd fd=%d", mChannel->getSendFd());
182 looper->removeFd(mChannel->getSendFd());
183 mHasLooperCallbacks = false;
184 }
185 return;
186 }
187
188 // Add the file descriptor to the Looper for receiving acknowledegments if the app has
189 // registered for wake-up sensors OR for sending events in the cache.
190 int ret = looper->addFd(mChannel->getSendFd(), 0, looper_flags, this, NULL);
191 if (ret == 1) {
192 ALOGD_IF(DEBUG_CONNECTIONS, "%p addFd fd=%d", this, mChannel->getSendFd());
193 mHasLooperCallbacks = true;
194 } else {
195 ALOGE("Looper::addFd failed ret=%d fd=%d", ret, mChannel->getSendFd());
196 }
197}
198
199void SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t handle) {
200 Mutex::Autolock _l(mConnectionLock);
201 ssize_t index = mSensorInfo.indexOfKey(handle);
202 if (index >= 0) {
203 FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
204 flushInfo.mPendingFlushEventsToSend++;
205 }
206}
207
208status_t SensorService::SensorEventConnection::sendEvents(
209 sensors_event_t const* buffer, size_t numEvents,
210 sensors_event_t* scratch,
Peng Xuded526e2016-08-12 16:39:44 -0700211 wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
Peng Xueb4d6282015-12-10 18:02:41 -0800212 // filter out events not for this connection
213 int count = 0;
214 Mutex::Autolock _l(mConnectionLock);
215 if (scratch) {
216 size_t i=0;
217 while (i<numEvents) {
218 int32_t sensor_handle = buffer[i].sensor;
219 if (buffer[i].type == SENSOR_TYPE_META_DATA) {
220 ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
221 buffer[i].meta_data.sensor);
222 // Setting sensor_handle to the correct sensor to ensure the sensor events per
223 // connection are filtered correctly. buffer[i].sensor is zero for meta_data
224 // events.
225 sensor_handle = buffer[i].meta_data.sensor;
226 }
227
228 ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
229 // Check if this connection has registered for this sensor. If not continue to the
230 // next sensor_event.
231 if (index < 0) {
232 ++i;
233 continue;
234 }
235
236 FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
237 // Check if there is a pending flush_complete event for this sensor on this connection.
238 if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
Peng Xuded526e2016-08-12 16:39:44 -0700239 mapFlushEventsToConnections[i] == this) {
Peng Xueb4d6282015-12-10 18:02:41 -0800240 flushInfo.mFirstFlushPending = false;
241 ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
242 buffer[i].meta_data.sensor);
243 ++i;
244 continue;
245 }
246
247 // If there is a pending flush complete event for this sensor on this connection,
248 // ignore the event and proceed to the next.
249 if (flushInfo.mFirstFlushPending) {
250 ++i;
251 continue;
252 }
253
254 do {
255 // Keep copying events into the scratch buffer as long as they are regular
256 // sensor_events are from the same sensor_handle OR they are flush_complete_events
257 // from the same sensor_handle AND the current connection is mapped to the
258 // corresponding flush_complete_event.
259 if (buffer[i].type == SENSOR_TYPE_META_DATA) {
Peng Xuded526e2016-08-12 16:39:44 -0700260 if (mapFlushEventsToConnections[i] == this) {
Peng Xueb4d6282015-12-10 18:02:41 -0800261 scratch[count++] = buffer[i];
262 }
263 ++i;
264 } else {
265 // Regular sensor event, just copy it to the scratch buffer.
266 scratch[count++] = buffer[i++];
267 }
268 } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
269 buffer[i].type != SENSOR_TYPE_META_DATA) ||
270 (buffer[i].type == SENSOR_TYPE_META_DATA &&
271 buffer[i].meta_data.sensor == sensor_handle)));
272 }
273 } else {
274 scratch = const_cast<sensors_event_t *>(buffer);
275 count = numEvents;
276 }
277
278 sendPendingFlushEventsLocked();
279 // Early return if there are no events for this connection.
280 if (count == 0) {
281 return status_t(NO_ERROR);
282 }
283
284#if DEBUG_CONNECTIONS
285 mEventsReceived += count;
286#endif
287 if (mCacheSize != 0) {
288 // There are some events in the cache which need to be sent first. Copy this buffer to
289 // the end of cache.
290 if (mCacheSize + count <= mMaxCacheSize) {
291 memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
292 mCacheSize += count;
293 } else {
294 // Check if any new sensors have registered on this connection which may have increased
295 // the max cache size that is desired.
296 if (mCacheSize + count < computeMaxCacheSizeLocked()) {
297 reAllocateCacheLocked(scratch, count);
298 return status_t(NO_ERROR);
299 }
300 // Some events need to be dropped.
301 int remaningCacheSize = mMaxCacheSize - mCacheSize;
302 if (remaningCacheSize != 0) {
303 memcpy(&mEventCache[mCacheSize], scratch,
304 remaningCacheSize * sizeof(sensors_event_t));
305 }
306 int numEventsDropped = count - remaningCacheSize;
307 countFlushCompleteEventsLocked(mEventCache, numEventsDropped);
308 // Drop the first "numEventsDropped" in the cache.
309 memmove(mEventCache, &mEventCache[numEventsDropped],
310 (mCacheSize - numEventsDropped) * sizeof(sensors_event_t));
311
312 // Copy the remainingEvents in scratch buffer to the end of cache.
313 memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize,
314 numEventsDropped * sizeof(sensors_event_t));
315 }
316 return status_t(NO_ERROR);
317 }
318
319 int index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
320 if (index_wake_up_event >= 0) {
321 scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
322 ++mWakeLockRefCount;
323#if DEBUG_CONNECTIONS
324 ++mTotalAcksNeeded;
325#endif
326 }
327
328 // NOTE: ASensorEvent and sensors_event_t are the same type.
329 ssize_t size = SensorEventQueue::write(mChannel,
330 reinterpret_cast<ASensorEvent const*>(scratch), count);
331 if (size < 0) {
332 // Write error, copy events to local cache.
333 if (index_wake_up_event >= 0) {
334 // If there was a wake_up sensor_event, reset the flag.
335 scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
336 if (mWakeLockRefCount > 0) {
337 --mWakeLockRefCount;
338 }
339#if DEBUG_CONNECTIONS
340 --mTotalAcksNeeded;
341#endif
342 }
343 if (mEventCache == NULL) {
344 mMaxCacheSize = computeMaxCacheSizeLocked();
345 mEventCache = new sensors_event_t[mMaxCacheSize];
346 mCacheSize = 0;
347 }
348 memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
349 mCacheSize += count;
350
351 // Add this file descriptor to the looper to get a callback when this fd is available for
352 // writing.
353 updateLooperRegistrationLocked(mService->getLooper());
354 return size;
355 }
356
357#if DEBUG_CONNECTIONS
358 if (size > 0) {
359 mEventsSent += count;
360 }
361#endif
362
363 return size < 0 ? status_t(size) : status_t(NO_ERROR);
364}
365
366void SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch,
367 int count) {
368 sensors_event_t *eventCache_new;
369 const int new_cache_size = computeMaxCacheSizeLocked();
370 // Allocate new cache, copy over events from the old cache & scratch, free up memory.
371 eventCache_new = new sensors_event_t[new_cache_size];
372 memcpy(eventCache_new, mEventCache, mCacheSize * sizeof(sensors_event_t));
373 memcpy(&eventCache_new[mCacheSize], scratch, count * sizeof(sensors_event_t));
374
375 ALOGD_IF(DEBUG_CONNECTIONS, "reAllocateCacheLocked maxCacheSize=%d %d", mMaxCacheSize,
376 new_cache_size);
377
378 delete mEventCache;
379 mEventCache = eventCache_new;
380 mCacheSize += count;
381 mMaxCacheSize = new_cache_size;
382}
383
384void SensorService::SensorEventConnection::sendPendingFlushEventsLocked() {
385 ASensorEvent flushCompleteEvent;
386 memset(&flushCompleteEvent, 0, sizeof(flushCompleteEvent));
387 flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
388 // Loop through all the sensors for this connection and check if there are any pending
389 // flush complete events to be sent.
390 for (size_t i = 0; i < mSensorInfo.size(); ++i) {
Peng Xu755c4512016-04-07 23:15:14 -0700391 const int handle = mSensorInfo.keyAt(i);
392 sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
393 if (si == nullptr) {
394 continue;
395 }
396
Peng Xueb4d6282015-12-10 18:02:41 -0800397 FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
398 while (flushInfo.mPendingFlushEventsToSend > 0) {
Peng Xu755c4512016-04-07 23:15:14 -0700399 flushCompleteEvent.meta_data.sensor = handle;
400 bool wakeUpSensor = si->getSensor().isWakeUpSensor();
Peng Xueb4d6282015-12-10 18:02:41 -0800401 if (wakeUpSensor) {
402 ++mWakeLockRefCount;
403 flushCompleteEvent.flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
404 }
405 ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
406 if (size < 0) {
407 if (wakeUpSensor) --mWakeLockRefCount;
408 return;
409 }
410 ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
411 flushCompleteEvent.meta_data.sensor);
412 flushInfo.mPendingFlushEventsToSend--;
413 }
414 }
415}
416
417void SensorService::SensorEventConnection::writeToSocketFromCache() {
418 // At a time write at most half the size of the receiver buffer in SensorEventQueue OR
419 // half the size of the socket buffer allocated in BitTube whichever is smaller.
420 const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
421 int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
422 Mutex::Autolock _l(mConnectionLock);
423 // Send pending flush complete events (if any)
424 sendPendingFlushEventsLocked();
425 for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
426 const int numEventsToWrite = helpers::min(mCacheSize - numEventsSent, maxWriteSize);
427 int index_wake_up_event =
428 findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite);
429 if (index_wake_up_event >= 0) {
430 mEventCache[index_wake_up_event + numEventsSent].flags |=
431 WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
432 ++mWakeLockRefCount;
433#if DEBUG_CONNECTIONS
434 ++mTotalAcksNeeded;
435#endif
436 }
437
438 ssize_t size = SensorEventQueue::write(mChannel,
439 reinterpret_cast<ASensorEvent const*>(mEventCache + numEventsSent),
440 numEventsToWrite);
441 if (size < 0) {
442 if (index_wake_up_event >= 0) {
443 // If there was a wake_up sensor_event, reset the flag.
444 mEventCache[index_wake_up_event + numEventsSent].flags &=
445 ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
446 if (mWakeLockRefCount > 0) {
447 --mWakeLockRefCount;
448 }
449#if DEBUG_CONNECTIONS
450 --mTotalAcksNeeded;
451#endif
452 }
453 memmove(mEventCache, &mEventCache[numEventsSent],
454 (mCacheSize - numEventsSent) * sizeof(sensors_event_t));
455 ALOGD_IF(DEBUG_CONNECTIONS, "wrote %d events from cache size==%d ",
456 numEventsSent, mCacheSize);
457 mCacheSize -= numEventsSent;
458 return;
459 }
460 numEventsSent += numEventsToWrite;
461#if DEBUG_CONNECTIONS
462 mEventsSentFromCache += numEventsToWrite;
463#endif
464 }
465 ALOGD_IF(DEBUG_CONNECTIONS, "wrote all events from cache size=%d ", mCacheSize);
466 // All events from the cache have been sent. Reset cache size to zero.
467 mCacheSize = 0;
468 // There are no more events in the cache. We don't need to poll for write on the fd.
469 // Update Looper registration.
470 updateLooperRegistrationLocked(mService->getLooper());
471}
472
473void SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
474 sensors_event_t const* scratch, const int numEventsDropped) {
475 ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
476 // Count flushComplete events in the events that are about to the dropped. These will be sent
477 // separately before the next batch of events.
478 for (int j = 0; j < numEventsDropped; ++j) {
479 if (scratch[j].type == SENSOR_TYPE_META_DATA) {
480 FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
481 flushInfo.mPendingFlushEventsToSend++;
482 ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
483 flushInfo.mPendingFlushEventsToSend);
484 }
485 }
486 return;
487}
488
489int SensorService::SensorEventConnection::findWakeUpSensorEventLocked(
490 sensors_event_t const* scratch, const int count) {
491 for (int i = 0; i < count; ++i) {
492 if (mService->isWakeUpSensorEvent(scratch[i])) {
493 return i;
494 }
495 }
496 return -1;
497}
498
499sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
500{
501 return mChannel;
502}
503
504status_t SensorService::SensorEventConnection::enableDisable(
505 int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
506 int reservedFlags)
507{
508 status_t err;
509 if (enabled) {
510 err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
511 reservedFlags, mOpPackageName);
512
513 } else {
514 err = mService->disable(this, handle);
515 }
516 return err;
517}
518
519status_t SensorService::SensorEventConnection::setEventRate(
520 int handle, nsecs_t samplingPeriodNs)
521{
522 return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
523}
524
525status_t SensorService::SensorEventConnection::flush() {
526 return mService->flushSensor(this, mOpPackageName);
527}
528
Peng Xue36e3472016-11-03 11:57:10 -0700529int32_t SensorService::SensorEventConnection::configureChannel(int handle, int rateLevel) {
530 // SensorEventConnection does not support configureChannel, parameters not used
531 UNUSED(handle);
532 UNUSED(rateLevel);
533 return INVALID_OPERATION;
534}
535
Peng Xueb4d6282015-12-10 18:02:41 -0800536int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* /*data*/) {
537 if (events & ALOOPER_EVENT_HANGUP || events & ALOOPER_EVENT_ERROR) {
538 {
539 // If the Looper encounters some error, set the flag mDead, reset mWakeLockRefCount,
540 // and remove the fd from Looper. Call checkWakeLockState to know if SensorService
541 // can release the wake-lock.
542 ALOGD_IF(DEBUG_CONNECTIONS, "%p Looper error %d", this, fd);
543 Mutex::Autolock _l(mConnectionLock);
544 mDead = true;
545 mWakeLockRefCount = 0;
546 updateLooperRegistrationLocked(mService->getLooper());
547 }
548 mService->checkWakeLockState();
549 if (mDataInjectionMode) {
550 // If the Looper has encountered some error in data injection mode, reset SensorService
551 // back to normal mode.
552 mService->resetToNormalMode();
553 mDataInjectionMode = false;
554 }
555 return 1;
556 }
557
558 if (events & ALOOPER_EVENT_INPUT) {
559 unsigned char buf[sizeof(sensors_event_t)];
560 ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
561 {
Peng Xu755c4512016-04-07 23:15:14 -0700562 Mutex::Autolock _l(mConnectionLock);
563 if (numBytesRead == sizeof(sensors_event_t)) {
564 if (!mDataInjectionMode) {
565 ALOGE("Data injected in normal mode, dropping event"
566 "package=%s uid=%d", mPackageName.string(), mUid);
567 // Unregister call backs.
568 return 0;
569 }
570 sensors_event_t sensor_event;
571 memcpy(&sensor_event, buf, sizeof(sensors_event_t));
572 sp<SensorInterface> si =
573 mService->getSensorInterfaceFromHandle(sensor_event.sensor);
574 if (si == nullptr) {
575 return 1;
576 }
577
578 SensorDevice& dev(SensorDevice::getInstance());
579 sensor_event.type = si->getSensor().getType();
580 dev.injectSensorData(&sensor_event);
Peng Xueb4d6282015-12-10 18:02:41 -0800581#if DEBUG_CONNECTIONS
Peng Xu755c4512016-04-07 23:15:14 -0700582 ++mEventsReceived;
Peng Xueb4d6282015-12-10 18:02:41 -0800583#endif
Peng Xu755c4512016-04-07 23:15:14 -0700584 } else if (numBytesRead == sizeof(uint32_t)) {
585 uint32_t numAcks = 0;
586 memcpy(&numAcks, buf, numBytesRead);
587 // Sanity check to ensure there are no read errors in recv, numAcks is always
588 // within the range and not zero. If any of the above don't hold reset
589 // mWakeLockRefCount to zero.
590 if (numAcks > 0 && numAcks < mWakeLockRefCount) {
591 mWakeLockRefCount -= numAcks;
592 } else {
593 mWakeLockRefCount = 0;
594 }
Peng Xueb4d6282015-12-10 18:02:41 -0800595#if DEBUG_CONNECTIONS
Peng Xu755c4512016-04-07 23:15:14 -0700596 mTotalAcksReceived += numAcks;
Peng Xueb4d6282015-12-10 18:02:41 -0800597#endif
598 } else {
599 // Read error, reset wakelock refcount.
600 mWakeLockRefCount = 0;
601 }
602 }
603 // Check if wakelock can be released by sensorservice. mConnectionLock needs to be released
604 // here as checkWakeLockState() will need it.
605 if (mWakeLockRefCount == 0) {
606 mService->checkWakeLockState();
607 }
608 // continue getting callbacks.
609 return 1;
610 }
611
612 if (events & ALOOPER_EVENT_OUTPUT) {
613 // send sensor data that is stored in mEventCache for this connection.
614 mService->sendEventsFromCache(this);
615 }
616 return 1;
617}
618
619int SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const {
620 size_t fifoWakeUpSensors = 0;
621 size_t fifoNonWakeUpSensors = 0;
622 for (size_t i = 0; i < mSensorInfo.size(); ++i) {
Peng Xu755c4512016-04-07 23:15:14 -0700623 sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(mSensorInfo.keyAt(i));
624 if (si == nullptr) {
625 continue;
626 }
627 const Sensor& sensor = si->getSensor();
Peng Xueb4d6282015-12-10 18:02:41 -0800628 if (sensor.getFifoReservedEventCount() == sensor.getFifoMaxEventCount()) {
629 // Each sensor has a reserved fifo. Sum up the fifo sizes for all wake up sensors and
630 // non wake_up sensors.
631 if (sensor.isWakeUpSensor()) {
632 fifoWakeUpSensors += sensor.getFifoReservedEventCount();
633 } else {
634 fifoNonWakeUpSensors += sensor.getFifoReservedEventCount();
635 }
636 } else {
637 // Shared fifo. Compute the max of the fifo sizes for wake_up and non_wake up sensors.
638 if (sensor.isWakeUpSensor()) {
639 fifoWakeUpSensors = fifoWakeUpSensors > sensor.getFifoMaxEventCount() ?
640 fifoWakeUpSensors : sensor.getFifoMaxEventCount();
641
642 } else {
643 fifoNonWakeUpSensors = fifoNonWakeUpSensors > sensor.getFifoMaxEventCount() ?
644 fifoNonWakeUpSensors : sensor.getFifoMaxEventCount();
645
646 }
647 }
648 }
649 if (fifoWakeUpSensors + fifoNonWakeUpSensors == 0) {
650 // It is extremely unlikely that there is a write failure in non batch mode. Return a cache
651 // size that is equal to that of the batch mode.
652 // ALOGW("Write failure in non-batch mode");
653 return MAX_SOCKET_BUFFER_SIZE_BATCHED/sizeof(sensors_event_t);
654 }
655 return fifoWakeUpSensors + fifoNonWakeUpSensors;
656}
657
658} // namespace android
659