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_sync"
18 
19 #include "goog_sensor_sync.h"
20 
21 #include <inttypes.h>
22 #include <stdint.h>
23 #include <string.h>
24 
25 #include <algorithm>
26 #include <cmath>
27 #include <deque>
28 
29 #include "utils/Errors.h"
30 #include "utils/Log.h"
31 #include "utils/RefBase.h"
32 #include "utils/String16.h"
33 
34 namespace android {
35 namespace camera_sensor_listener {
36 
37 using ::android::frameworks::sensorservice::V1_0::ISensorManager;
38 using ::android::frameworks::sensorservice::V1_0::Result;
39 using ::android::hardware::sensors::V1_0::SensorInfo;
40 
GoogSensorSync(uint8_t cam_id,size_t event_queue_size)41 GoogSensorSync::GoogSensorSync(uint8_t cam_id, size_t event_queue_size)
42     : GoogSensorWrapper(event_queue_size), cam_id_(cam_id) {
43   ALOGI("%s %d Sensor sync camera ID: %d", __func__, __LINE__,
44         static_cast<int>(cam_id_));
45 }
46 
~GoogSensorSync()47 GoogSensorSync::~GoogSensorSync() {
48   Disable();
49   if (sync_cnt_ != 0) {
50     ALOGI("%s %d Total failure/sync for camera %d: %d/%d", __func__, __LINE__,
51           static_cast<int>(cam_id_), sync_failure_cnt_, sync_cnt_);
52   }
53   if (match_cnt_ != 0) {
54     ALOGI("%s %d Total failure/match for camera %d: %d/%d", __func__, __LINE__,
55           static_cast<int>(cam_id_), match_failure_cnt_, match_cnt_);
56   }
57 }
58 
Create(uint8_t cam_id,size_t event_queue_size)59 sp<GoogSensorSync> GoogSensorSync::Create(uint8_t cam_id,
60                                           size_t event_queue_size) {
61   sp<GoogSensorSync> sensor_sync_ptr =
62       new GoogSensorSync(cam_id, event_queue_size);
63   if (sensor_sync_ptr == nullptr) {
64     ALOGE("%s %d failed to create GoogSensorSync.", __func__, __LINE__);
65   } else {
66     status_t result = sensor_sync_ptr->Enable();
67     if (result != 0) {
68       ALOGE("%s %d failed to enable GoogSensorSync.", __func__, __LINE__);
69     } else {
70       ALOGI("%s %d successfully enabled GoogSensorSync.", __func__, __LINE__);
71     }
72   }
73   return sensor_sync_ptr;
74 }
75 
ExtractFrameIdAndBoottimeTimestamp(const ExtendedSensorEvent & event,int64_t * frame_id,int64_t * timestamp_boottime) const76 void GoogSensorSync::ExtractFrameIdAndBoottimeTimestamp(
77     const ExtendedSensorEvent& event, int64_t* frame_id,
78     int64_t* timestamp_boottime) const {
79   // Cast away const-ness.
80   float* data = const_cast<float*>(&event.sensor_event.u.data[0]);
81   // Reinterpret_cast to uint64_t pointer, since sensor hal concatenates
82   // two 32-bit floating point to pass 1 64-bit uint64_t data.
83   uint64_t* vsync_data = reinterpret_cast<uint64_t*>(data);
84   // Static_cast from uint64_t to int64_t to align with vsync timestamp format.
85   *frame_id = static_cast<int64_t>(vsync_data[1]);
86   *timestamp_boottime = static_cast<int64_t>(vsync_data[2]);
87 }
88 
ExtractAocEventCounter(const ExtendedSensorEvent & event)89 uint64_t GoogSensorSync::ExtractAocEventCounter(const ExtendedSensorEvent& event) {
90   // AoC sensor Event is one uint64_t data. It can be accessed with stepCount
91   // from the data union.
92   return event.sensor_event.u.stepCount;
93 }
94 
GetLatestNSamples(int num_sample,std::vector<int64_t> * latest_n_vsync_timestamps,std::vector<int64_t> * latest_n_frame_ids,std::vector<int64_t> * latest_n_boottime_timestamps,std::vector<int64_t> * latest_n_arrival_timestamps) const95 void GoogSensorSync::GetLatestNSamples(
96     int num_sample, std::vector<int64_t>* latest_n_vsync_timestamps,
97     std::vector<int64_t>* latest_n_frame_ids,
98     std::vector<int64_t>* latest_n_boottime_timestamps,
99     std::vector<int64_t>* latest_n_arrival_timestamps) const {
100   if (latest_n_vsync_timestamps == nullptr || latest_n_frame_ids == nullptr ||
101       latest_n_boottime_timestamps == nullptr ||
102       latest_n_arrival_timestamps == nullptr) {
103     return;
104   }
105   latest_n_vsync_timestamps->clear();
106   latest_n_frame_ids->clear();
107   latest_n_boottime_timestamps->clear();
108   latest_n_arrival_timestamps->clear();
109 
110   if (num_sample < 0) {
111     return;
112   }
113   std::lock_guard<std::mutex> el(event_buffer_lock_);
114   int start_index =
115       std::max(0, static_cast<int>(event_buffer_.size()) - num_sample);
116   auto event = event_buffer_.begin();
117   std::advance(event, start_index);
118   for (; event != event_buffer_.end(); ++event) {
119     latest_n_vsync_timestamps->push_back(event->sensor_event.timestamp);
120     latest_n_arrival_timestamps->push_back(event->event_arrival_time_ns);
121     int64_t frame_id, boottime_timestamp;
122     ExtractFrameIdAndBoottimeTimestamp(*event, &frame_id, &boottime_timestamp);
123     latest_n_frame_ids->push_back(frame_id);
124     latest_n_boottime_timestamps->push_back(boottime_timestamp);
125   }
126 }
127 
GetSensorHandle()128 int32_t GoogSensorSync::GetSensorHandle() {
129   sp<ISensorManager> manager = ISensorManager::getService();
130   if (manager == nullptr) {
131     ALOGE("%s %d Cannot get ISensorManager", __func__, __LINE__);
132     return -1;
133   }
134   SensorInfo info;
135   bool find = false;
136   static constexpr size_t kMaxVsyncNameSize = 16;
137   char sensor_for_camera[kMaxVsyncNameSize];
138   snprintf(sensor_for_camera, sizeof(sensor_for_camera), "camera v-sync %d",
139            cam_id_);
140 
141   manager->getSensorList(
142       [&info, &find, &sensor_for_camera](const auto& list, auto result) {
143         if (result != Result::OK) {
144           return;
145         }
146         for (const SensorInfo& item : list) {
147           if (item.typeAsString == "com.google.sensor.camera_vsync") {
148             ALOGV("%s %d Enumerating sensor %s %s %zu %zu", __func__, __LINE__,
149                   item.name.c_str(), sensor_for_camera,
150                   strlen(item.name.c_str()), strlen(sensor_for_camera));
151             if (!strncasecmp(item.name.c_str(), sensor_for_camera,
152                              strlen(sensor_for_camera))) {
153               info = item;
154               find = true;
155               break;
156             }
157           }
158         }
159       });
160 
161   if (find) {
162     ALOGI("%s %d handle for %d is found. Sensor name %s", __func__, __LINE__,
163           static_cast<int>(cam_id_), info.name.c_str());
164   } else {
165     ALOGE("%s %d handle for %d is not found!", __func__, __LINE__,
166           static_cast<int>(cam_id_));
167   }
168   return find ? info.sensorHandle : -1;
169 }
170 
SyncTimestamp(int64_t timestamp)171 int64_t GoogSensorSync::SyncTimestamp(int64_t timestamp) {
172   status_t ret;
173 
174   if (!IsEnabled()) {
175     ALOGE("%s %d sensor_sync sensor is not enabled", __func__, __LINE__);
176     return timestamp;
177   }
178 
179   std::lock_guard<std::mutex> el(event_buffer_lock_);
180   int64_t min_delta = kMaxTimeDriftNs;
181   int64_t nearest_sync = timestamp;
182   for (auto event : event_buffer_) {
183     if (llabs(event.sensor_event.timestamp - timestamp) < min_delta) {
184       min_delta = llabs(event.sensor_event.timestamp - timestamp);
185       nearest_sync = event.sensor_event.timestamp;
186     }
187   }
188 
189   sync_cnt_++;
190   if (min_delta == kMaxTimeDriftNs) {
191     struct timespec res;
192     clock_gettime(CLOCK_BOOTTIME, &res);
193     int64_t curr_time = (int64_t)res.tv_sec * 1000000000LL + res.tv_nsec;
194 
195     ALOGV("%s %d Cannot sync timestamp for input timestamp %" PRId64
196           "at CPU time %" PRId64,
197           __func__, __LINE__, timestamp, curr_time);
198     sync_failure_cnt_++;
199     if (sync_failure_cnt_ >= kFailureThreshold) {
200       ALOGW("%s %d Camera %d: out of %d camera timestamps, %d failed to sync",
201             __func__, __LINE__, static_cast<int>(cam_id_), sync_cnt_,
202             sync_failure_cnt_);
203       sync_cnt_ = 0;
204       sync_failure_cnt_ = 0;
205     }
206   }
207 
208   return nearest_sync;
209 }
210 
FindNearestEvent(int64_t timestamp)211 std::optional<ExtendedSensorEvent> GoogSensorSync::FindNearestEvent(
212     int64_t timestamp) {
213   if (!IsEnabled()) {
214     ALOGE("%s %d sensor_sync sensor is not enabled", __func__, __LINE__);
215     return std::nullopt;
216   }
217   std::lock_guard<std::mutex> el(event_buffer_lock_);
218   int64_t min_delta = kMaxTimeDriftNs;
219   std::optional<ExtendedSensorEvent> nearest_event;
220   for (auto event : event_buffer_) {
221     int64_t delta = llabs(event.sensor_event.timestamp - timestamp);
222     if (delta < min_delta) {
223       min_delta = delta;
224       nearest_event = event;
225     }
226   }
227   return nearest_event;
228 }
229 
MatchTimestamp(int64_t timestamp,int64_t frame_id)230 int64_t GoogSensorSync::MatchTimestamp(int64_t timestamp, int64_t frame_id) {
231   if (!IsEnabled()) {
232     ALOGE("%s %d sensor_sync sensor is not enabled", __func__, __LINE__);
233     return timestamp;
234   }
235 
236   std::lock_guard<std::mutex> el(event_buffer_lock_);
237   for (auto event : event_buffer_) {
238     int64_t event_frame_id, event_timestamp;
239     ExtractFrameIdAndBoottimeTimestamp(event, &event_frame_id, &event_timestamp);
240     if (frame_id == event_frame_id && timestamp == event_timestamp) {
241       match_cnt_++;
242       return event.sensor_event.timestamp;
243     }
244   }
245   match_cnt_++;
246   match_failure_cnt_++;
247   if (match_failure_cnt_ >= kFailureThreshold) {
248     ALOGW("%s %d Camera %d: out of %d camera timestamps, %d failed to match",
249           __func__, __LINE__, static_cast<int>(cam_id_), match_cnt_,
250           match_failure_cnt_);
251     match_cnt_ = 0;
252     match_failure_cnt_ = 0;
253   }
254   return timestamp;
255 }
256 
257 }  // namespace camera_sensor_listener
258 }  // namespace android
259