xref: /aosp_15_r20/frameworks/native/libs/sensor/SensorEventQueue.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
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 #define LOG_TAG "Sensors"
18 #define ATRACE_TAG ATRACE_TAG_SYSTEM_SERVER
19 
20 #include <android/sensor.h>
21 #include <com_android_hardware_libsensor_flags.h>
22 #include <cutils/trace.h>
23 #include <hardware/sensors-base.h>
24 #include <sensor/BitTube.h>
25 #include <sensor/ISensorEventConnection.h>
26 #include <sensor/Sensor.h>
27 #include <sensor/SensorEventQueue.h>
28 #include <sensor/SensorManager.h>
29 #include <sys/socket.h>
30 #include <utils/Looper.h>
31 #include <utils/RefBase.h>
32 
33 #include <algorithm>
34 #include <cinttypes>
35 #include <string>
36 
37 using std::min;
38 namespace libsensor_flags = com::android::hardware::libsensor::flags;
39 
40 // ----------------------------------------------------------------------------
41 namespace android {
42 // ----------------------------------------------------------------------------
43 
SensorEventQueue(const sp<ISensorEventConnection> & connection,SensorManager & sensorManager,String8 packageName)44 SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection,
45                                    SensorManager& sensorManager, String8 packageName)
46       : mSensorEventConnection(connection),
47         mRecBuffer(nullptr),
48         mSensorManager(sensorManager),
49         mPackageName(packageName),
50         mAvailable(0),
51         mConsumed(0),
52         mNumAcksToSend(0) {
53     mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];
54 }
55 
~SensorEventQueue()56 SensorEventQueue::~SensorEventQueue() {
57     delete [] mRecBuffer;
58 }
59 
onFirstRef()60 void SensorEventQueue::onFirstRef()
61 {
62     mSensorChannel = mSensorEventConnection->getSensorChannel();
63 }
64 
getFd() const65 int SensorEventQueue::getFd() const
66 {
67     return mSensorChannel->getFd();
68 }
69 
70 
write(const sp<BitTube> & tube,ASensorEvent const * events,size_t numEvents)71 ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
72         ASensorEvent const* events, size_t numEvents) {
73     return BitTube::sendObjects(tube, events, numEvents);
74 }
75 
read(ASensorEvent * events,size_t numEvents)76 ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
77     if (mAvailable == 0) {
78         ssize_t err =
79                 BitTube::recvObjects(mSensorChannel, mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
80         if (err < 0) {
81             return err;
82         }
83         mAvailable = static_cast<size_t>(err);
84         mConsumed = 0;
85     }
86     size_t count = min(numEvents, mAvailable);
87     memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
88 
89     if (CC_UNLIKELY(ATRACE_ENABLED()) &&
90         libsensor_flags::sensor_event_queue_report_sensor_usage_in_tracing()) {
91         for (size_t i = 0; i < count; i++) {
92             std::optional<std::string_view> sensorName =
93                     mSensorManager.getSensorNameByHandle(events->sensor);
94             if (sensorName.has_value()) {
95                 char buffer[UINT8_MAX];
96                 IPCThreadState* thread = IPCThreadState::self();
97                 pid_t pid = (thread != nullptr) ? thread->getCallingPid() : -1;
98                 std::snprintf(buffer, sizeof(buffer),
99                               "Sensor event from %s to %s PID: %d (%zu/%zu)",
100                               sensorName.value().data(), mPackageName.c_str(), pid, i, count);
101                 ATRACE_INSTANT_FOR_TRACK(LOG_TAG, buffer);
102             }
103         }
104     }
105     mAvailable -= count;
106     mConsumed += count;
107     return static_cast<ssize_t>(count);
108 }
109 
getLooper() const110 sp<Looper> SensorEventQueue::getLooper() const
111 {
112     Mutex::Autolock _l(mLock);
113     if (mLooper == nullptr) {
114         mLooper = new Looper(true);
115         mLooper->addFd(getFd(), getFd(), ALOOPER_EVENT_INPUT, nullptr, nullptr);
116     }
117     return mLooper;
118 }
119 
waitForEvent() const120 status_t SensorEventQueue::waitForEvent() const
121 {
122     const int fd = getFd();
123     sp<Looper> looper(getLooper());
124 
125     int events;
126     int32_t result;
127     do {
128         result = looper->pollOnce(-1, nullptr, &events, nullptr);
129         if (result == ALOOPER_POLL_ERROR) {
130             ALOGE("SensorEventQueue::waitForEvent error (errno=%d)", errno);
131             result = -EPIPE; // unknown error, so we make up one
132             break;
133         }
134         if (events & ALOOPER_EVENT_HANGUP) {
135             // the other-side has died
136             ALOGE("SensorEventQueue::waitForEvent error HANGUP");
137             result = -EPIPE; // unknown error, so we make up one
138             break;
139         }
140     } while (result != fd);
141 
142     return  (result == fd) ? status_t(NO_ERROR) : result;
143 }
144 
wake() const145 status_t SensorEventQueue::wake() const
146 {
147     sp<Looper> looper(getLooper());
148     looper->wake();
149     return NO_ERROR;
150 }
151 
enableSensor(Sensor const * sensor) const152 status_t SensorEventQueue::enableSensor(Sensor const* sensor) const {
153     return enableSensor(sensor, SENSOR_DELAY_NORMAL);
154 }
155 
enableSensor(Sensor const * sensor,int32_t samplingPeriodUs) const156 status_t SensorEventQueue::enableSensor(Sensor const* sensor, int32_t samplingPeriodUs) const {
157     return mSensorEventConnection->enableDisable(sensor->getHandle(), true,
158                                                  us2ns(samplingPeriodUs), 0, 0);
159 }
160 
disableSensor(Sensor const * sensor) const161 status_t SensorEventQueue::disableSensor(Sensor const* sensor) const {
162     return mSensorEventConnection->enableDisable(sensor->getHandle(), false, 0, 0, 0);
163 }
164 
enableSensor(int32_t handle,int32_t samplingPeriodUs,int64_t maxBatchReportLatencyUs,int reservedFlags) const165 status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,
166                                         int64_t maxBatchReportLatencyUs, int reservedFlags) const {
167     return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),
168                                                  us2ns(maxBatchReportLatencyUs), reservedFlags);
169 }
170 
flush() const171 status_t SensorEventQueue::flush() const {
172     return mSensorEventConnection->flush();
173 }
174 
disableSensor(int32_t handle) const175 status_t SensorEventQueue::disableSensor(int32_t handle) const {
176     return mSensorEventConnection->enableDisable(handle, false, 0, 0, false);
177 }
178 
setEventRate(Sensor const * sensor,nsecs_t ns) const179 status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const {
180     return mSensorEventConnection->setEventRate(sensor->getHandle(), ns);
181 }
182 
injectSensorEvent(const ASensorEvent & event)183 status_t SensorEventQueue::injectSensorEvent(const ASensorEvent& event) {
184     do {
185         // Blocking call.
186         ssize_t size = ::send(mSensorChannel->getFd(), &event, sizeof(event), MSG_NOSIGNAL);
187         if (size >= 0) {
188             return NO_ERROR;
189         } else if (size < 0 && errno == EAGAIN) {
190             // If send is returning a "Try again" error, sleep for 100ms and try again. In all
191             // other cases log a failure and exit.
192             usleep(100000);
193         } else {
194             ALOGE("injectSensorEvent failure %s %zd", strerror(errno), size);
195             return INVALID_OPERATION;
196         }
197     } while (true);
198 }
199 
sendAck(const ASensorEvent * events,int count)200 void SensorEventQueue::sendAck(const ASensorEvent* events, int count) {
201     for (int i = 0; i < count; ++i) {
202         if (events[i].flags & WAKE_UP_SENSOR_EVENT_NEEDS_ACK) {
203             ++mNumAcksToSend;
204         }
205     }
206     // Send mNumAcksToSend to acknowledge for the wake up sensor events received.
207     if (mNumAcksToSend > 0) {
208         ssize_t size = ::send(mSensorChannel->getFd(), &mNumAcksToSend, sizeof(mNumAcksToSend),
209                 MSG_DONTWAIT | MSG_NOSIGNAL);
210         if (size < 0) {
211             ALOGE("sendAck failure %zd %d", size, mNumAcksToSend);
212         } else {
213             mNumAcksToSend = 0;
214         }
215     }
216     return;
217 }
218 
filterEvents(ASensorEvent * events,size_t count) const219 ssize_t SensorEventQueue::filterEvents(ASensorEvent* events, size_t count) const {
220     // Check if this Sensor Event Queue is registered to receive each type of event. If it is not,
221     // then do not copy the event into the final buffer. Minimize the number of copy operations by
222     // finding consecutive sequences of events that the Sensor Event Queue should receive and only
223     // copying the events once an unregistered event type is reached.
224     bool intervalStartLocSet = false;
225     size_t intervalStartLoc = 0;
226     size_t eventsInInterval = 0;
227     ssize_t eventsCopied = 0;
228 
229     for (size_t i = 0; i < count; i++) {
230         bool includeEvent =
231                 (events[i].type != SENSOR_TYPE_ADDITIONAL_INFO || requestAdditionalInfo);
232 
233         if (includeEvent) {
234             // Do not copy events yet since there may be more consecutive events that should be
235             // copied together. Track the start location and number of events in the current
236             // sequence.
237             if (!intervalStartLocSet) {
238                 intervalStartLoc = i;
239                 intervalStartLocSet = true;
240                 eventsInInterval = 0;
241             }
242             eventsInInterval++;
243         }
244 
245         // Shift the events from the already processed interval once an event that should not be
246         // included is reached or if this is the final event to be processed.
247         if (!includeEvent || (i + 1 == count)) {
248             // Only shift the events if the interval did not start with the first event. If the
249             // interval started with the first event, the events are already in their correct
250             // location.
251             if (intervalStartLoc > 0) {
252                 memmove(&events[eventsCopied], &events[intervalStartLoc],
253                         eventsInInterval * sizeof(ASensorEvent));
254             }
255             eventsCopied += eventsInInterval;
256 
257             // Reset the interval information
258             eventsInInterval = 0;
259             intervalStartLocSet = false;
260         }
261     }
262     return eventsCopied;
263 }
264 
265 // ----------------------------------------------------------------------------
266 }; // namespace android
267 
268