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