blob: 6c0a96dbd7d12eddfd4dd3b86aaf09a033eaa146 [file] [log] [blame]
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -07001/*
2 * Copyright (C) 2021 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 <media/SensorPoseProvider.h>
18
19#define LOG_TAG "SensorPoseProvider"
20
21#include <inttypes.h>
22
23#include <future>
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070024#include <map>
25#include <thread>
26
Shunkai Yao5a251df2022-07-22 18:42:27 +000027#include <android-base/stringprintf.h>
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -070028#include <android-base/thread_annotations.h>
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070029#include <log/log_main.h>
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070030#include <sensor/SensorEventQueue.h>
31#include <sensor/SensorManager.h>
32#include <utils/Looper.h>
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070033
Ytai Ben-Tsvi54f07582021-09-13 12:09:42 -070034#include "QuaternionUtil.h"
35
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070036namespace android {
37namespace media {
38namespace {
39
Shunkai Yao5a251df2022-07-22 18:42:27 +000040using android::base::StringAppendF;
41
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070042// Identifier to use for our event queue on the loop.
43// The number 19 is arbitrary, only useful if using multiple objects on the same looper.
44constexpr int kIdent = 19;
45
46static inline Looper* ALooper_to_Looper(ALooper* alooper) {
47 return reinterpret_cast<Looper*>(alooper);
48}
49
50static inline ALooper* Looper_to_ALooper(Looper* looper) {
51 return reinterpret_cast<ALooper*>(looper);
52}
53
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070054/**
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070055 * RAII-wrapper around SensorEventQueue, which unregisters it on destruction.
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070056 */
57class EventQueueGuard {
58 public:
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070059 EventQueueGuard(const sp<SensorEventQueue>& queue, Looper* looper) : mQueue(queue) {
60 mQueue->looper = Looper_to_ALooper(looper);
61 mQueue->requestAdditionalInfo = false;
62 looper->addFd(mQueue->getFd(), kIdent, ALOOPER_EVENT_INPUT, nullptr, nullptr);
63 }
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070064
65 ~EventQueueGuard() {
66 if (mQueue) {
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070067 ALooper_to_Looper(mQueue->looper)->removeFd(mQueue->getFd());
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070068 }
69 }
70
71 EventQueueGuard(const EventQueueGuard&) = delete;
72 EventQueueGuard& operator=(const EventQueueGuard&) = delete;
73
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070074 [[nodiscard]] SensorEventQueue* get() const { return mQueue.get(); }
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070075
76 private:
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070077 sp<SensorEventQueue> mQueue;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070078};
79
80/**
81 * RAII-wrapper around an enabled sensor, which disables it upon destruction.
82 */
83class SensorEnableGuard {
84 public:
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070085 SensorEnableGuard(const sp<SensorEventQueue>& queue, int32_t sensor)
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070086 : mQueue(queue), mSensor(sensor) {}
87
88 ~SensorEnableGuard() {
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070089 if (mSensor != SensorPoseProvider::INVALID_HANDLE) {
90 int ret = mQueue->disableSensor(mSensor);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070091 if (ret) {
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -070092 ALOGE("Failed to disable sensor: %s", strerror(ret));
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070093 }
94 }
95 }
96
97 SensorEnableGuard(const SensorEnableGuard&) = delete;
98 SensorEnableGuard& operator=(const SensorEnableGuard&) = delete;
99
100 // Enable moving.
101 SensorEnableGuard(SensorEnableGuard&& other) : mQueue(other.mQueue), mSensor(other.mSensor) {
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700102 other.mSensor = SensorPoseProvider::INVALID_HANDLE;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700103 }
104
105 private:
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700106 sp<SensorEventQueue> const mQueue;
107 int32_t mSensor;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700108};
109
110/**
111 * Streams the required events to a PoseListener, based on events originating from the Sensor stack.
112 */
113class SensorPoseProviderImpl : public SensorPoseProvider {
114 public:
115 static std::unique_ptr<SensorPoseProvider> create(const char* packageName, Listener* listener) {
116 std::unique_ptr<SensorPoseProviderImpl> result(
117 new SensorPoseProviderImpl(packageName, listener));
118 return result->waitInitFinished() ? std::move(result) : nullptr;
119 }
120
121 ~SensorPoseProviderImpl() override {
Ytai Ben-Tsvic29bad62021-09-09 10:22:52 -0700122 // Disable all active sensors.
123 mEnabledSensors.clear();
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700124 mLooper->wake();
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700125 mThread.join();
126 }
127
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700128 bool startSensor(int32_t sensor, std::chrono::microseconds samplingPeriod) override {
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700129 // Figure out the sensor's data format.
130 DataFormat format = getSensorFormat(sensor);
131 if (format == DataFormat::kUnknown) {
132 ALOGE("Unknown format for sensor %" PRId32, sensor);
133 return false;
134 }
135
136 {
137 std::lock_guard lock(mMutex);
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800138 mEnabledSensorsExtra.emplace(sensor, SensorExtra{ .format = format });
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700139 }
140
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700141 // Enable the sensor.
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700142 if (mQueue->enableSensor(sensor, samplingPeriod.count(), 0, 0)) {
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700143 ALOGE("Failed to enable sensor");
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700144 std::lock_guard lock(mMutex);
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800145 mEnabledSensorsExtra.erase(sensor);
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700146 return false;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700147 }
148
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700149 mEnabledSensors.emplace(sensor, SensorEnableGuard(mQueue.get(), sensor));
150 return true;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700151 }
152
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700153 void stopSensor(int handle) override {
154 mEnabledSensors.erase(handle);
155 std::lock_guard lock(mMutex);
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800156 mEnabledSensorsExtra.erase(handle);
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700157 }
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700158
Shunkai Yao5a251df2022-07-22 18:42:27 +0000159 std::string toString(unsigned level) override {
160 std::string prefixSpace(level, ' ');
161 std::string ss = prefixSpace + "SensorPoseProvider:\n";
162 bool needUnlock = false;
163
164 prefixSpace += " ";
165 auto now = std::chrono::steady_clock::now();
166 if (!mMutex.try_lock_until(now + media::kSpatializerDumpSysTimeOutInSecond)) {
167 ss.append(prefixSpace).append("try_lock failed, dumpsys below maybe INACCURATE!\n");
168 } else {
169 needUnlock = true;
170 }
171
172 // Enabled sensor information
173 StringAppendF(&ss, "%sSensors total number %zu:\n", prefixSpace.c_str(),
174 mEnabledSensorsExtra.size());
175 for (auto sensor : mEnabledSensorsExtra) {
176 StringAppendF(&ss, "%s[Handle: 0x%08x, Format %s", prefixSpace.c_str(), sensor.first,
177 toString(sensor.second.format).c_str());
178 if (sensor.second.discontinuityCount.has_value()) {
179 StringAppendF(&ss, ", DiscontinuityCount: %d",
180 sensor.second.discontinuityCount.value());
181 }
182 ss += "]\n";
183 }
184
185 if (needUnlock) {
186 mMutex.unlock();
187 }
188 return ss;
189 }
190
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700191 private:
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700192 enum DataFormat {
193 kUnknown,
194 kQuaternion,
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800195 kRotationVectorsAndDiscontinuityCount,
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700196 };
197
198 struct PoseEvent {
199 Pose3f pose;
200 std::optional<Twist3f> twist;
201 bool isNewReference;
202 };
203
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800204 struct SensorExtra {
205 DataFormat format;
206 std::optional<int32_t> discontinuityCount;
207 };
208
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700209 sp<Looper> mLooper;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700210 Listener* const mListener;
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700211 SensorManager* const mSensorManager;
Shunkai Yao5a251df2022-07-22 18:42:27 +0000212 std::timed_mutex mMutex;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700213 std::map<int32_t, SensorEnableGuard> mEnabledSensors;
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800214 std::map<int32_t, SensorExtra> mEnabledSensorsExtra GUARDED_BY(mMutex);
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700215 sp<SensorEventQueue> mQueue;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700216
217 // We must do some of the initialization operations on the worker thread, because the API relies
218 // on the thread-local looper. In addition, as a matter of convenience, we store some of the
219 // state on the stack.
220 // For that reason, we use a two-step initialization approach, where the ctor mostly just starts
221 // the worker thread and that thread would notify, via the promise below whenever initialization
222 // is finished, and whether it was successful.
223 std::promise<bool> mInitPromise;
Keith Mok674f7352022-06-06 21:40:11 +0000224 std::thread mThread;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700225
226 SensorPoseProviderImpl(const char* packageName, Listener* listener)
227 : mListener(listener),
Keith Mok674f7352022-06-06 21:40:11 +0000228 mSensorManager(&SensorManager::getInstanceForPackage(String16(packageName))) {
229 mThread = std::thread([this] { threadFunc(); });
230 }
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700231 void initFinished(bool success) { mInitPromise.set_value(success); }
232
233 bool waitInitFinished() { return mInitPromise.get_future().get(); }
234
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700235 void threadFunc() {
Ytai Ben-Tsvid9125692021-08-24 08:53:38 -0700236 // Obtain looper.
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700237 mLooper = Looper::prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700238
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700239 // Create event queue.
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700240 mQueue = mSensorManager->createEventQueue();
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700241
Ytai Ben-Tsvic29bad62021-09-09 10:22:52 -0700242 if (mQueue == nullptr) {
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700243 ALOGE("Failed to create a sensor event queue");
244 initFinished(false);
245 return;
246 }
247
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700248 EventQueueGuard eventQueueGuard(mQueue, mLooper.get());
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700249
250 initFinished(true);
251
252 while (true) {
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700253 int ret = mLooper->pollOnce(-1 /* no timeout */, nullptr, nullptr, nullptr);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700254
255 switch (ret) {
256 case ALOOPER_POLL_WAKE:
257 // Normal way to exit.
258 return;
259
260 case kIdent:
261 // Possible events on our queue.
262 break;
263
264 default:
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700265 ALOGE("Unexpected status out of Looper::pollOnce: %d", ret);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700266 }
267
268 // Process an event.
269 ASensorEvent event;
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700270 ssize_t actual = mQueue->read(&event, 1);
271 if (actual > 0) {
272 mQueue->sendAck(&event, actual);
273 }
274 ssize_t size = mQueue->filterEvents(&event, actual);
275
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700276 if (size < 0 || size > 1) {
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700277 ALOGE("Unexpected return value from SensorEventQueue::filterEvents: %zd", size);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700278 break;
279 }
280 if (size == 0) {
281 // No events.
282 continue;
283 }
284
285 handleEvent(event);
286 }
287 }
288
289 void handleEvent(const ASensorEvent& event) {
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800290 PoseEvent value;
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700291 {
292 std::lock_guard lock(mMutex);
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800293 auto iter = mEnabledSensorsExtra.find(event.sensor);
294 if (iter == mEnabledSensorsExtra.end()) {
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700295 // This can happen if we have any pending events shortly after stopping.
296 return;
297 }
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800298 value = parseEvent(event, iter->second.format, &iter->second.discontinuityCount);
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700299 }
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700300 mListener->onPose(event.timestamp, event.sensor, value.pose, value.twist,
301 value.isNewReference);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700302 }
303
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700304 DataFormat getSensorFormat(int32_t handle) {
305 std::optional<const Sensor> sensor = getSensorByHandle(handle);
306 if (!sensor) {
307 ALOGE("Sensor not found: %d", handle);
308 return DataFormat::kUnknown;
309 }
310 if (sensor->getType() == ASENSOR_TYPE_ROTATION_VECTOR ||
311 sensor->getType() == ASENSOR_TYPE_GAME_ROTATION_VECTOR) {
312 return DataFormat::kQuaternion;
313 }
314
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800315 if (sensor->getType() == ASENSOR_TYPE_HEAD_TRACKER) {
316 return DataFormat::kRotationVectorsAndDiscontinuityCount;
317 }
318
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700319 return DataFormat::kUnknown;
320 }
321
Andy Hunga461a002022-05-17 10:36:02 -0700322 std::optional<const Sensor> getSensorByHandle(int32_t handle) override {
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700323 const Sensor* const* list;
324 ssize_t size;
325
326 // Search static sensor list.
327 size = mSensorManager->getSensorList(&list);
328 if (size < 0) {
329 ALOGE("getSensorList failed with error code %zd", size);
330 return std::nullopt;
331 }
332 for (size_t i = 0; i < size; ++i) {
333 if (list[i]->getHandle() == handle) {
334 return *list[i];
335 }
336 }
337
338 // Search dynamic sensor list.
339 Vector<Sensor> dynList;
340 size = mSensorManager->getDynamicSensorList(dynList);
341 if (size < 0) {
342 ALOGE("getDynamicSensorList failed with error code %zd", size);
343 return std::nullopt;
344 }
345 for (size_t i = 0; i < size; ++i) {
346 if (dynList[i].getHandle() == handle) {
347 return dynList[i];
348 }
349 }
350
351 return std::nullopt;
352 }
353
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800354 static PoseEvent parseEvent(const ASensorEvent& event, DataFormat format,
355 std::optional<int32_t>* discontinutyCount) {
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700356 switch (format) {
357 case DataFormat::kQuaternion: {
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700358 Eigen::Quaternionf quat(event.data[3], event.data[0], event.data[1], event.data[2]);
Ytai Ben-Tsvi54f07582021-09-13 12:09:42 -0700359 // Adapt to different frame convention.
360 quat *= rotateX(-M_PI_2);
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700361 return PoseEvent{Pose3f(quat), std::optional<Twist3f>(), false};
362 }
363
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800364 case DataFormat::kRotationVectorsAndDiscontinuityCount: {
365 Eigen::Vector3f rotation = {event.head_tracker.rx, event.head_tracker.ry,
366 event.head_tracker.rz};
367 Eigen::Vector3f twist = {event.head_tracker.vx, event.head_tracker.vy,
Ytai Ben-Tsvi27bbea32022-01-28 18:01:06 -0800368 event.head_tracker.vz};
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800369 Eigen::Quaternionf quat = rotationVectorToQuaternion(rotation);
370 bool isNewReference =
371 !discontinutyCount->has_value() ||
372 discontinutyCount->value() != event.head_tracker.discontinuity_count;
373 *discontinutyCount = event.head_tracker.discontinuity_count;
374
375 return PoseEvent{Pose3f(quat), Twist3f(Eigen::Vector3f::Zero(), twist),
376 isNewReference};
377 }
378
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700379 default:
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700380 LOG_ALWAYS_FATAL("Unexpected sensor type: %d", static_cast<int>(format));
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700381 }
382 }
Shunkai Yao5a251df2022-07-22 18:42:27 +0000383
384 const std::string toString(DataFormat format) {
385 switch (format) {
386 case DataFormat::kUnknown:
387 return "kUnknown";
388 case DataFormat::kQuaternion:
389 return "kQuaternion";
390 case DataFormat::kRotationVectorsAndDiscontinuityCount:
391 return "kRotationVectorsAndDiscontinuityCount";
392 default:
393 return "NotImplemented";
394 }
395 }
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700396};
397
398} // namespace
399
400std::unique_ptr<SensorPoseProvider> SensorPoseProvider::create(const char* packageName,
401 Listener* listener) {
402 return SensorPoseProviderImpl::create(packageName, listener);
403}
404
405} // namespace media
406} // namespace android