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 #define LOG_TAG "goog_sensor_motion"
18 
19 #include "goog_sensor_motion.h"
20 
21 #include <cinttypes>
22 
23 #include "utils/Errors.h"
24 #include "utils/Log.h"
25 #include "utils/Mutex.h"
26 #include "utils/RefBase.h"
27 #include "utils/String16.h"
28 
29 namespace android {
30 namespace camera_sensor_listener {
31 namespace {
32 
33 using ::android::frameworks::sensorservice::V1_0::ISensorManager;
34 using ::android::frameworks::sensorservice::V1_0::Result;
35 using ::android::hardware::sensors::V1_0::SensorInfo;
36 using ::android::hardware::sensors::V1_0::SensorType;
37 
GetHalSensorType(MotionSensorType sensor_type)38 SensorType GetHalSensorType(MotionSensorType sensor_type) {
39   switch (sensor_type) {
40     case MotionSensorType::ACCELEROMETER:
41       return SensorType::ACCELEROMETER;
42     case MotionSensorType::GRAVITY:
43       return SensorType::GRAVITY;
44     case MotionSensorType::GYROSCOPE:
45       return SensorType::GYROSCOPE;
46     case MotionSensorType::LINEAR_ACCELERATION:
47       return SensorType::LINEAR_ACCELERATION;
48     case MotionSensorType::MAGNETIC_FIELD:
49       return SensorType::MAGNETIC_FIELD;
50     default:
51       LOG_FATAL("Unknown sensor type %d", static_cast<int>(sensor_type));
52       return SensorType::ACCELEROMETER;
53   }
54 }
55 
56 }  // namespace
57 
GoogSensorMotion(MotionSensorType motion_sensor_type,int64_t sampling_period_us,size_t event_queue_size)58 GoogSensorMotion::GoogSensorMotion(MotionSensorType motion_sensor_type,
59                                    int64_t sampling_period_us,
60                                    size_t event_queue_size)
61     : GoogSensorWrapper(event_queue_size, sampling_period_us),
62       motion_sensor_type_(motion_sensor_type) {
63   ALOGD("%s %d create sensor %s", __func__, __LINE__,
64         GetSensorName(motion_sensor_type));
65 }
66 
~GoogSensorMotion()67 GoogSensorMotion::~GoogSensorMotion() {
68   Disable();
69   ALOGD("%s %d destroy sensor %s", __func__, __LINE__, GetSensorName());
70 }
71 
Create(MotionSensorType motion_sensor_type,int64_t sampling_period_us,size_t event_queue_size)72 sp<GoogSensorMotion> GoogSensorMotion::Create(MotionSensorType motion_sensor_type,
73                                               int64_t sampling_period_us,
74                                               size_t event_queue_size) {
75   // Check sensor_type validity.
76   int motion_sensor_type_index = static_cast<int>(motion_sensor_type);
77   if (motion_sensor_type_index >= static_cast<int>(MotionSensorType::TOTAL_NUM)) {
78     ALOGE("%s %d unsupported motion sensor type %d", __func__, __LINE__,
79           motion_sensor_type_index);
80     return nullptr;
81   }
82   // Check sampling period validity.
83   if (sampling_period_us < kMinSamplingPeriodUs) {
84     ALOGE("%s %d sampling period %" PRId64 "us is too small %s", __func__,
85           __LINE__, sampling_period_us,
86           "supported smallest sampling period is 2500us");
87     return nullptr;
88   }
89 
90   // Create sensor.
91   sp<GoogSensorMotion> sensor_ptr = new GoogSensorMotion(
92       motion_sensor_type, sampling_period_us, event_queue_size);
93   if (sensor_ptr == nullptr) {
94     ALOGE("%s %d failed to create GoogSensorMotion for %s", __func__, __LINE__,
95           GetSensorName(motion_sensor_type));
96   } else {
97     // Enable sensor.
98     status_t result = sensor_ptr->Enable();
99     if (result != 0) {
100       ALOGE("%s %d failed to enable GoogSensorMotion for %s", __func__,
101             __LINE__, sensor_ptr->GetSensorName());
102     } else {
103       ALOGD("%s %d successfully enabled GoogSensorMotion for %s", __func__,
104             __LINE__, sensor_ptr->GetSensorName());
105     }
106   }
107   return sensor_ptr;
108 }
109 
GetLatestNSensorEvents(int num_sample,std::vector<int64_t> * event_timestamps,std::vector<float> * motion_vector_x,std::vector<float> * motion_vector_y,std::vector<float> * motion_vector_z,std::vector<int64_t> * event_arrival_timestamps) const110 void GoogSensorMotion::GetLatestNSensorEvents(
111     int num_sample, std::vector<int64_t>* event_timestamps,
112     std::vector<float>* motion_vector_x, std::vector<float>* motion_vector_y,
113     std::vector<float>* motion_vector_z,
114     std::vector<int64_t>* event_arrival_timestamps) const {
115   event_timestamps->clear();
116   motion_vector_x->clear();
117   motion_vector_y->clear();
118   motion_vector_z->clear();
119   event_arrival_timestamps->clear();
120 
121   if (num_sample < 0) {
122     return;
123   }
124   std::lock_guard<std::mutex> l(event_buffer_lock_);
125   int start_index =
126       std::max(0, static_cast<int>(event_buffer_.size()) - num_sample);
127   auto event = event_buffer_.begin();
128   std::advance(event, start_index);
129   for (; event != event_buffer_.end(); ++event) {
130     event_timestamps->push_back(event->sensor_event.timestamp);
131     motion_vector_x->push_back(event->sensor_event.u.vec3.x);
132     motion_vector_y->push_back(event->sensor_event.u.vec3.y);
133     motion_vector_z->push_back(event->sensor_event.u.vec3.z);
134     event_arrival_timestamps->push_back(event->event_arrival_time_ns);
135   }
136 }
137 
QuerySensorEventsBetweenTimestamps(int64_t start_time,int64_t end_time,std::vector<int64_t> * event_timestamps,std::vector<float> * motion_vector_x,std::vector<float> * motion_vector_y,std::vector<float> * motion_vector_z,std::vector<int64_t> * event_arrival_timestamps) const138 void GoogSensorMotion::QuerySensorEventsBetweenTimestamps(
139     int64_t start_time, int64_t end_time,
140     std::vector<int64_t>* event_timestamps, std::vector<float>* motion_vector_x,
141     std::vector<float>* motion_vector_y, std::vector<float>* motion_vector_z,
142     std::vector<int64_t>* event_arrival_timestamps) const {
143   event_timestamps->clear();
144   motion_vector_x->clear();
145   motion_vector_y->clear();
146   motion_vector_z->clear();
147   event_arrival_timestamps->clear();
148 
149   std::lock_guard<std::mutex> l(event_buffer_lock_);
150   for (const auto& event : event_buffer_) {
151     int64_t event_time = event.sensor_event.timestamp;
152     if (event_time <= start_time || event_time > end_time) {
153       continue;
154     }
155     event_timestamps->push_back(event_time);
156     motion_vector_x->push_back(event.sensor_event.u.vec3.x);
157     motion_vector_y->push_back(event.sensor_event.u.vec3.y);
158     motion_vector_z->push_back(event.sensor_event.u.vec3.z);
159     event_arrival_timestamps->push_back(event.event_arrival_time_ns);
160   }
161 }
162 
GetSensorHandle()163 int32_t GoogSensorMotion::GetSensorHandle() {
164   sp<ISensorManager> manager = ISensorManager::getService();
165   if (manager == nullptr) {
166     ALOGE("%s %d Cannot get ISensorManager for sensor %s", __func__, __LINE__,
167           GetSensorName());
168     return -1;
169   }
170   bool found = false;
171   SensorInfo sensor;
172   manager->getDefaultSensor(GetHalSensorType(motion_sensor_type_),
173                             [&sensor, &found](const auto& info, auto result) {
174                               if (result != Result::OK) {
175                                 ALOGE("%s %d Cannot find default sensor",
176                                       __func__, __LINE__);
177                                 return;
178                               }
179                               sensor = info;
180                               found = true;
181                             });
182 
183   if (found) {
184     ALOGD("%s %d handle for %s is found.", __func__, __LINE__, GetSensorName());
185   } else {
186     ALOGE("%s %d handle for %s is not found!", __func__, __LINE__,
187           GetSensorName());
188   }
189   return found ? sensor.sensorHandle : -1;
190 }
191 
GetSensorName(MotionSensorType sensor_type)192 const char* GoogSensorMotion::GetSensorName(MotionSensorType sensor_type) {
193   static constexpr const char* kSensorNames[] = {
194       "accelerometer", "gravity", "gyroscope", "linear_acceleration",
195       "magnetic_field"};
196   return kSensorNames[static_cast<int>(sensor_type)];
197 }
198 
199 }  // namespace camera_sensor_listener
200 }  // namespace android