1 /*
2 * Copyright (C) 2017 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 "ASensorEventQueue.h"
18
19 #include "ALooper.h"
20
21 #define LOG_TAG "libsensorndkbridge"
22 #include <android-base/logging.h>
23
24 using android::sp;
25 using android::frameworks::sensorservice::V1_0::Result;
26 using android::hardware::sensors::V1_0::SensorInfo;
27 using android::OK;
28 using android::BAD_VALUE;
29 using android::Mutex;
30 using android::hardware::Return;
31
ASensorEventQueue(ALooper * looper,ALooper_callbackFunc callback,void * data)32 ASensorEventQueue::ASensorEventQueue(ALooper* looper, ALooper_callbackFunc callback, void* data)
33 : mLooper(looper), mCallback(callback), mData(data), mRequestAdditionalInfo(false) {}
34
setImpl(const sp<IEventQueue> & queueImpl)35 void ASensorEventQueue::setImpl(const sp<IEventQueue> &queueImpl) {
36 mQueueImpl = queueImpl;
37 }
38
registerSensor(ASensorRef sensor,int32_t samplingPeriodUs,int64_t maxBatchReportLatencyUs)39 int ASensorEventQueue::registerSensor(
40 ASensorRef sensor,
41 int32_t samplingPeriodUs,
42 int64_t maxBatchReportLatencyUs) {
43 Return<Result> ret = mQueueImpl->enableSensor(
44 reinterpret_cast<const SensorInfo *>(sensor)->sensorHandle,
45 samplingPeriodUs,
46 maxBatchReportLatencyUs);
47
48 if (!ret.isOk()) {
49 return BAD_VALUE;
50 }
51
52 return OK;
53 }
54
enableSensor(ASensorRef sensor)55 int ASensorEventQueue::enableSensor(ASensorRef sensor) {
56 static constexpr int32_t SENSOR_DELAY_NORMAL = 200000;
57
58 return registerSensor(
59 sensor, SENSOR_DELAY_NORMAL, 0 /* maxBatchReportLatencyUs */);
60 }
61
setEventRate(ASensorRef sensor,int32_t samplingPeriodUs)62 int ASensorEventQueue::setEventRate(
63 ASensorRef sensor, int32_t samplingPeriodUs) {
64 // Technically this is not supposed to enable the sensor but using this
65 // API without enabling the sensor first is a no-op, so...
66 return registerSensor(
67 sensor, samplingPeriodUs, 0 /* maxBatchReportLatencyUs */);
68 }
69
requestAdditionalInfoEvents(bool enable)70 int ASensorEventQueue::requestAdditionalInfoEvents(bool enable) {
71 mRequestAdditionalInfo = enable;
72 return OK;
73 }
74
disableSensor(ASensorRef sensor)75 int ASensorEventQueue::disableSensor(ASensorRef sensor) {
76 Return<Result> ret = mQueueImpl->disableSensor(
77 reinterpret_cast<const SensorInfo *>(sensor)->sensorHandle);
78
79 return ret.isOk() ? OK : BAD_VALUE;
80 }
81
getEvents(ASensorEvent * events,size_t count)82 ssize_t ASensorEventQueue::getEvents(ASensorEvent *events, size_t count) {
83 // XXX Should this block if there aren't any events in the queue?
84
85 Mutex::Autolock autoLock(mLock);
86
87 static_assert(
88 sizeof(ASensorEvent) == sizeof(sensors_event_t), "mismatched size");
89
90 size_t copy = std::min(count, mQueue.size());
91 for (size_t i = 0; i < copy; ++i) {
92 reinterpret_cast<sensors_event_t *>(events)[i] = mQueue[i];
93 }
94 mQueue.erase(mQueue.begin(), mQueue.begin() + copy);
95
96 LOG(VERBOSE) << "ASensorEventQueue::getEvents() returned " << copy << " events.";
97
98 return copy;
99 }
100
hasEvents() const101 int ASensorEventQueue::hasEvents() const {
102 return !mQueue.empty();
103 }
104
onEvent(const Event & event)105 Return<void> ASensorEventQueue::onEvent(const Event &event) {
106 LOG(VERBOSE) << "ASensorEventQueue::onEvent";
107
108 if (static_cast<int32_t>(event.sensorType) != ASENSOR_TYPE_ADDITIONAL_INFO ||
109 mRequestAdditionalInfo.load()) {
110 {
111 Mutex::Autolock autoLock(mLock);
112
113 mQueue.emplace_back();
114 sensors_event_t* sensorEvent = &mQueue[mQueue.size() - 1];
115 android::hardware::sensors::V1_0::implementation::convertToSensorEvent(event,
116 sensorEvent);
117 }
118
119 mLooper->signalSensorEvents(this);
120 }
121
122 return android::hardware::Void();
123 }
124
dispatchCallback()125 void ASensorEventQueue::dispatchCallback() {
126 if (mCallback != NULL) {
127 int res = (*mCallback)(-1 /* fd */, ALOOPER_EVENT_INPUT, mData);
128
129 if (res == 0) {
130 mCallback = NULL;
131 mData = NULL;
132 }
133 }
134 }
135
invalidate()136 void ASensorEventQueue::invalidate() {
137 mLooper->invalidateSensorQueue(this);
138 setImpl(nullptr);
139 }
140
141