• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,int ident,ALooper_callbackFunc callback,void * data)32 ASensorEventQueue::ASensorEventQueue(
33         ALooper *looper, int ident, ALooper_callbackFunc callback, void *data)
34     : mLooper(looper),
35       mIdent(ident),
36       mCallback(callback),
37       mData(data) {
38 }
39 
setImpl(const sp<IEventQueue> & queueImpl)40 void ASensorEventQueue::setImpl(const sp<IEventQueue> &queueImpl) {
41     mQueueImpl = queueImpl;
42 }
43 
registerSensor(ASensorRef sensor,int32_t samplingPeriodUs,int64_t maxBatchReportLatencyUs)44 int ASensorEventQueue::registerSensor(
45         ASensorRef sensor,
46         int32_t samplingPeriodUs,
47         int64_t maxBatchReportLatencyUs) {
48     Return<Result> ret = mQueueImpl->enableSensor(
49             reinterpret_cast<const SensorInfo *>(sensor)->sensorHandle,
50             samplingPeriodUs,
51             maxBatchReportLatencyUs);
52 
53     if (!ret.isOk()) {
54         return BAD_VALUE;
55     }
56 
57     return OK;
58 }
59 
enableSensor(ASensorRef sensor)60 int ASensorEventQueue::enableSensor(ASensorRef sensor) {
61     static constexpr int32_t SENSOR_DELAY_NORMAL = 200000;
62 
63     return registerSensor(
64             sensor, SENSOR_DELAY_NORMAL, 0 /* maxBatchReportLatencyUs */);
65 }
66 
setEventRate(ASensorRef sensor,int32_t samplingPeriodUs)67 int ASensorEventQueue::setEventRate(
68         ASensorRef sensor, int32_t samplingPeriodUs) {
69     // Technically this is not supposed to enable the sensor but using this
70     // API without enabling the sensor first is a no-op, so...
71     return registerSensor(
72             sensor, samplingPeriodUs, 0 /* maxBatchReportLatencyUs */);
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     {
109         Mutex::Autolock autoLock(mLock);
110 
111         mQueue.emplace_back();
112         sensors_event_t *sensorEvent = &mQueue[mQueue.size() - 1];
113         android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
114                 event, sensorEvent);
115     }
116 
117     mLooper->signalSensorEvents(this);
118 
119     return android::hardware::Void();
120 }
121 
dispatchCallback()122 void ASensorEventQueue::dispatchCallback() {
123     if (mCallback != NULL) {
124         int res = (*mCallback)(-1 /* fd */, ALOOPER_EVENT_INPUT, mData);
125 
126         if (res == 0) {
127             mCallback = NULL;
128             mData = NULL;
129         }
130     }
131 }
132 
invalidate()133 void ASensorEventQueue::invalidate() {
134     mLooper->invalidateSensorQueue(this);
135     setImpl(nullptr);
136 }
137 
138