1 /*
2  * Copyright (C) 2018 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 "android-base/thread_annotations.h"
18 #define LOG_TAG "goog_sensor_wrapper"
19 
20 #include <assert.h>
21 #include <inttypes.h>
22 #include <stdint.h>
23 #include <sys/time.h>
24 #include <utils/Log.h>
25 #include <utils/String16.h>
26 #include <utils/SystemClock.h>
27 
28 #include <algorithm>
29 #include <cmath>
30 
31 #include "goog_sensor_wrapper.h"
32 
33 namespace android {
34 namespace camera_sensor_listener {
35 
36 using ::android::frameworks::sensorservice::V1_0::IEventQueue;
37 using ::android::frameworks::sensorservice::V1_0::IEventQueueCallback;
38 using ::android::frameworks::sensorservice::V1_0::ISensorManager;
39 using ::android::frameworks::sensorservice::V1_0::Result;
40 using ::android::hardware::Return;
41 using ::android::hardware::Void;
42 using ::android::hardware::sensors::V1_0::Event;
43 using ::android::hardware::sensors::V1_0::SensorType;
44 
45 // Derived IEventQueueCallbak class needed by sensor service.
46 class EventQueueCallback : public IEventQueueCallback {
47  public:
EventQueueCallback(wp<GoogSensorWrapper> master)48   EventQueueCallback(wp<GoogSensorWrapper> master) {
49     assert(master);
50     master_ = master;
51   }
52 
onEvent(const Event & e)53   Return<void> onEvent(const Event& e) {
54     sp<GoogSensorWrapper> master = master_.promote();
55     if (master != nullptr) {
56       master->EventCallback(e);
57     }
58     return Void();
59   }
60 
61  private:
62   wp<GoogSensorWrapper> master_;
63 };
64 
GoogSensorWrapper(size_t event_buffer_size,int64_t sensor_sampling_period_us)65 GoogSensorWrapper::GoogSensorWrapper(size_t event_buffer_size,
66                                      int64_t sensor_sampling_period_us)
67     : event_queue_(nullptr),
68       event_buffer_size_limit_(event_buffer_size),
69       sensor_sampling_period_us_(sensor_sampling_period_us),
70       handle_(-1),
71       enabled_(false) {
72   ALOGV("%s %d", __func__, __LINE__);
73 }
74 
~GoogSensorWrapper()75 GoogSensorWrapper::~GoogSensorWrapper() { ALOGV("%s %d", __func__, __LINE__); }
76 
SetEventProcessor(std::function<void (const ExtendedSensorEvent & event)> event_processor)77 status_t GoogSensorWrapper::SetEventProcessor(
78     std::function<void(const ExtendedSensorEvent& event)> event_processor) {
79   std::lock_guard<std::mutex> l(event_processor_lock_);
80   event_processor_ = std::move(event_processor);
81   return OK;
82 }
83 
Enable()84 status_t GoogSensorWrapper::Enable() {
85   status_t res = OK;
86   std::lock_guard<std::mutex> l(event_queue_lock_);
87 
88   if (event_queue_ == nullptr) {
89     res = InitializeEventQueueLocked();
90     if (res != OK) {
91       ALOGE("%s %d initializing event queue failed: %d(%s)", __func__, __LINE__,
92             res, strerror(-res));
93       return res;
94     }
95   }
96   Return<Result> result =
97       event_queue_->enableSensor(handle_, sensor_sampling_period_us_, 0);
98   if (!result.isOk()) {
99     ALOGE("%s %d enable sensor Hidl call failed: %s", __func__, __LINE__,
100           result.description().c_str());
101     return -1;
102   }
103   if (result != Result::OK) {
104     ALOGE("%s %d enable sensor %s failed.", __func__, __LINE__,
105           toString(result).c_str());
106     return -1;
107   }
108 
109   enabled_ = true;
110   return res;
111 }
112 
Disable()113 status_t GoogSensorWrapper::Disable() {
114   std::lock_guard<std::mutex> l(event_queue_lock_);
115 
116   if (enabled_) {
117     if (event_queue_ != nullptr) {
118       Return<Result> result = event_queue_->disableSensor(handle_);
119       if (!result.isOk()) {
120         ALOGE("%s %d disable sensor Hidl call failed: %s", __func__, __LINE__,
121               result.description().c_str());
122         return -1;
123       }
124       if (result != Result::OK) {
125         ALOGE("%s %d disable sensor %s failed.", __func__, __LINE__,
126               toString(result).c_str());
127         return -1;
128       }
129     }
130     enabled_ = false;
131   }
132   return OK;
133 }
134 
InitializeEventQueueLocked()135 status_t GoogSensorWrapper::InitializeEventQueueLocked() {
136   ALOGV("%s %d", __func__, __LINE__);
137 
138   handle_ = GetSensorHandle();
139   if (handle_ < 0) {
140     ALOGE("%s %d Getting sensor from Sensor Manager failed.", __func__,
141           __LINE__);
142     return INVALID_OPERATION;
143   }
144 
145   sp<ISensorManager> manager = ISensorManager::getService();
146   if (manager == nullptr) {
147     ALOGE("%s %d Cannot get ISensorManager", __func__, __LINE__);
148     return INVALID_OPERATION;
149   }
150 
151   manager->createEventQueue(
152       new EventQueueCallback(this), [this](const auto& q, auto result) {
153         // The lock will be held when this synchronous callback executes
154         base::ScopedLockAssertion assertion(event_queue_lock_);
155         if (result != Result::OK) {
156           ALOGE("%s %d Cannot create event queue", __func__, __LINE__);
157           return;
158         }
159         event_queue_ = q;
160       });
161 
162   if (event_queue_ == nullptr) {
163     return INVALID_OPERATION;
164   }
165 
166   return OK;
167 }
168 
EventCallback(const Event & e)169 int GoogSensorWrapper::EventCallback(const Event& e) {
170   ExtendedSensorEvent event;
171   memset(&event, 0, sizeof(event));
172   std::lock_guard<std::mutex> l(event_queue_lock_);
173   event.sensor_event = e;
174   if (event.sensor_event.sensorHandle == handle_ &&
175       event.sensor_event.sensorType != SensorType::ADDITIONAL_INFO) {
176     {
177       std::lock_guard<std::mutex> l(event_buffer_lock_);
178       if (event_buffer_.size() >= event_buffer_size_limit_) {
179         event_buffer_.pop_front();
180       }
181       event.event_arrival_time_ns = elapsedRealtimeNano();
182       event_buffer_.push_back(event);
183     }
184 
185     std::lock_guard<std::mutex> el(event_processor_lock_);
186     if (event_processor_ != nullptr) {
187       event_processor_(event);
188     }
189   }
190 
191   // Return 1 to continue receiving callbacks.
192   return 1;
193 }
194 
195 }  // namespace camera_sensor_listener
196 }  // namespace android
197