blob: 3dee40a2cd2a8cfb8a85315444ec4b7dff9b3bd9 [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
Shunkai Yao51379452022-08-30 03:14:50 +000021#include <algorithm>
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070022#include <future>
Shunkai Yao51379452022-08-30 03:14:50 +000023#include <inttypes.h>
24#include <limits>
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070025#include <map>
26#include <thread>
27
Shunkai Yao5a251df2022-07-22 18:42:27 +000028#include <android-base/stringprintf.h>
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -070029#include <android-base/thread_annotations.h>
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070030#include <log/log_main.h>
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070031#include <sensor/SensorEventQueue.h>
32#include <sensor/SensorManager.h>
33#include <utils/Looper.h>
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070034
Ytai Ben-Tsvi54f07582021-09-13 12:09:42 -070035#include "QuaternionUtil.h"
36
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070037namespace android {
38namespace media {
39namespace {
40
Shunkai Yao5a251df2022-07-22 18:42:27 +000041using android::base::StringAppendF;
42
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070043// Identifier to use for our event queue on the loop.
44// The number 19 is arbitrary, only useful if using multiple objects on the same looper.
45constexpr int kIdent = 19;
46
47static inline Looper* ALooper_to_Looper(ALooper* alooper) {
48 return reinterpret_cast<Looper*>(alooper);
49}
50
51static inline ALooper* Looper_to_ALooper(Looper* looper) {
52 return reinterpret_cast<ALooper*>(looper);
53}
54
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070055/**
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070056 * RAII-wrapper around SensorEventQueue, which unregisters it on destruction.
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070057 */
58class EventQueueGuard {
59 public:
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070060 EventQueueGuard(const sp<SensorEventQueue>& queue, Looper* looper) : mQueue(queue) {
61 mQueue->looper = Looper_to_ALooper(looper);
62 mQueue->requestAdditionalInfo = false;
63 looper->addFd(mQueue->getFd(), kIdent, ALOOPER_EVENT_INPUT, nullptr, nullptr);
64 }
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070065
66 ~EventQueueGuard() {
67 if (mQueue) {
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070068 ALooper_to_Looper(mQueue->looper)->removeFd(mQueue->getFd());
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070069 }
70 }
71
72 EventQueueGuard(const EventQueueGuard&) = delete;
73 EventQueueGuard& operator=(const EventQueueGuard&) = delete;
74
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070075 [[nodiscard]] SensorEventQueue* get() const { return mQueue.get(); }
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070076
77 private:
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070078 sp<SensorEventQueue> mQueue;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070079};
80
81/**
82 * RAII-wrapper around an enabled sensor, which disables it upon destruction.
83 */
84class SensorEnableGuard {
85 public:
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070086 SensorEnableGuard(const sp<SensorEventQueue>& queue, int32_t sensor)
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070087 : mQueue(queue), mSensor(sensor) {}
88
89 ~SensorEnableGuard() {
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -070090 if (mSensor != SensorPoseProvider::INVALID_HANDLE) {
91 int ret = mQueue->disableSensor(mSensor);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070092 if (ret) {
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -070093 ALOGE("Failed to disable sensor: %s", strerror(ret));
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -070094 }
95 }
96 }
97
98 SensorEnableGuard(const SensorEnableGuard&) = delete;
99 SensorEnableGuard& operator=(const SensorEnableGuard&) = delete;
100
101 // Enable moving.
102 SensorEnableGuard(SensorEnableGuard&& other) : mQueue(other.mQueue), mSensor(other.mSensor) {
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700103 other.mSensor = SensorPoseProvider::INVALID_HANDLE;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700104 }
105
106 private:
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700107 sp<SensorEventQueue> const mQueue;
108 int32_t mSensor;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700109};
110
111/**
112 * Streams the required events to a PoseListener, based on events originating from the Sensor stack.
113 */
114class SensorPoseProviderImpl : public SensorPoseProvider {
115 public:
116 static std::unique_ptr<SensorPoseProvider> create(const char* packageName, Listener* listener) {
117 std::unique_ptr<SensorPoseProviderImpl> result(
118 new SensorPoseProviderImpl(packageName, listener));
119 return result->waitInitFinished() ? std::move(result) : nullptr;
120 }
121
122 ~SensorPoseProviderImpl() override {
Ytai Ben-Tsvic29bad62021-09-09 10:22:52 -0700123 // Disable all active sensors.
124 mEnabledSensors.clear();
Andy Hungf1073882022-11-04 21:00:49 -0700125 mQuit = true;
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700126 mLooper->wake();
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700127 mThread.join();
128 }
129
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700130 bool startSensor(int32_t sensor, std::chrono::microseconds samplingPeriod) override {
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700131 // Figure out the sensor's data format.
132 DataFormat format = getSensorFormat(sensor);
133 if (format == DataFormat::kUnknown) {
134 ALOGE("Unknown format for sensor %" PRId32, sensor);
135 return false;
136 }
137
138 {
139 std::lock_guard lock(mMutex);
Shunkai Yao51379452022-08-30 03:14:50 +0000140 mEnabledSensorsExtra.emplace(
141 sensor,
142 SensorExtra{.format = format,
143 .samplingPeriod = static_cast<int32_t>(samplingPeriod.count())});
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700144 }
145
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700146 // Enable the sensor.
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700147 if (mQueue->enableSensor(sensor, samplingPeriod.count(), 0, 0)) {
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700148 ALOGE("Failed to enable sensor");
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700149 std::lock_guard lock(mMutex);
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800150 mEnabledSensorsExtra.erase(sensor);
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700151 return false;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700152 }
153
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700154 mEnabledSensors.emplace(sensor, SensorEnableGuard(mQueue.get(), sensor));
155 return true;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700156 }
157
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700158 void stopSensor(int handle) override {
159 mEnabledSensors.erase(handle);
160 std::lock_guard lock(mMutex);
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800161 mEnabledSensorsExtra.erase(handle);
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700162 }
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700163
Shunkai Yao5a251df2022-07-22 18:42:27 +0000164 std::string toString(unsigned level) override {
165 std::string prefixSpace(level, ' ');
166 std::string ss = prefixSpace + "SensorPoseProvider:\n";
167 bool needUnlock = false;
168
169 prefixSpace += " ";
170 auto now = std::chrono::steady_clock::now();
171 if (!mMutex.try_lock_until(now + media::kSpatializerDumpSysTimeOutInSecond)) {
172 ss.append(prefixSpace).append("try_lock failed, dumpsys below maybe INACCURATE!\n");
173 } else {
174 needUnlock = true;
175 }
176
177 // Enabled sensor information
178 StringAppendF(&ss, "%sSensors total number %zu:\n", prefixSpace.c_str(),
179 mEnabledSensorsExtra.size());
180 for (auto sensor : mEnabledSensorsExtra) {
Shunkai Yao51379452022-08-30 03:14:50 +0000181 StringAppendF(&ss,
182 "%s[Handle: 0x%08x, Format %s Period (set %d max %0.4f min %0.4f) ms",
183 prefixSpace.c_str(), sensor.first, toString(sensor.second.format).c_str(),
184 sensor.second.samplingPeriod, media::nsToFloatMs(sensor.second.maxPeriod),
185 media::nsToFloatMs(sensor.second.minPeriod));
Shunkai Yao5a251df2022-07-22 18:42:27 +0000186 if (sensor.second.discontinuityCount.has_value()) {
187 StringAppendF(&ss, ", DiscontinuityCount: %d",
188 sensor.second.discontinuityCount.value());
189 }
190 ss += "]\n";
191 }
192
193 if (needUnlock) {
194 mMutex.unlock();
195 }
196 return ss;
197 }
198
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700199 private:
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700200 enum DataFormat {
201 kUnknown,
202 kQuaternion,
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800203 kRotationVectorsAndDiscontinuityCount,
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700204 };
205
206 struct PoseEvent {
207 Pose3f pose;
208 std::optional<Twist3f> twist;
209 bool isNewReference;
210 };
211
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800212 struct SensorExtra {
Shunkai Yao51379452022-08-30 03:14:50 +0000213 DataFormat format = DataFormat::kUnknown;
214 int32_t samplingPeriod = 0;
215 int64_t latestTimestamp = 0;
216 int64_t maxPeriod = 0;
217 int64_t minPeriod = std::numeric_limits<int64_t>::max();
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800218 std::optional<int32_t> discontinuityCount;
219 };
220
Andy Hungf1073882022-11-04 21:00:49 -0700221 bool mQuit = false;
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700222 sp<Looper> mLooper;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700223 Listener* const mListener;
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700224 SensorManager* const mSensorManager;
Shunkai Yao5a251df2022-07-22 18:42:27 +0000225 std::timed_mutex mMutex;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700226 std::map<int32_t, SensorEnableGuard> mEnabledSensors;
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800227 std::map<int32_t, SensorExtra> mEnabledSensorsExtra GUARDED_BY(mMutex);
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700228 sp<SensorEventQueue> mQueue;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700229
230 // We must do some of the initialization operations on the worker thread, because the API relies
231 // on the thread-local looper. In addition, as a matter of convenience, we store some of the
232 // state on the stack.
233 // For that reason, we use a two-step initialization approach, where the ctor mostly just starts
234 // the worker thread and that thread would notify, via the promise below whenever initialization
235 // is finished, and whether it was successful.
236 std::promise<bool> mInitPromise;
Keith Mok674f7352022-06-06 21:40:11 +0000237 std::thread mThread;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700238
239 SensorPoseProviderImpl(const char* packageName, Listener* listener)
240 : mListener(listener),
Keith Mok674f7352022-06-06 21:40:11 +0000241 mSensorManager(&SensorManager::getInstanceForPackage(String16(packageName))) {
242 mThread = std::thread([this] { threadFunc(); });
243 }
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700244 void initFinished(bool success) { mInitPromise.set_value(success); }
245
246 bool waitInitFinished() { return mInitPromise.get_future().get(); }
247
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700248 void threadFunc() {
Ytai Ben-Tsvid9125692021-08-24 08:53:38 -0700249 // Obtain looper.
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700250 mLooper = Looper::prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700251
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700252 // Create event queue.
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700253 mQueue = mSensorManager->createEventQueue();
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700254
Ytai Ben-Tsvic29bad62021-09-09 10:22:52 -0700255 if (mQueue == nullptr) {
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700256 ALOGE("Failed to create a sensor event queue");
257 initFinished(false);
258 return;
259 }
260
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700261 EventQueueGuard eventQueueGuard(mQueue, mLooper.get());
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700262
263 initFinished(true);
264
Andy Hungf1073882022-11-04 21:00:49 -0700265 while (!mQuit) {
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700266 int ret = mLooper->pollOnce(-1 /* no timeout */, nullptr, nullptr, nullptr);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700267
268 switch (ret) {
269 case ALOOPER_POLL_WAKE:
Andy Hungf1073882022-11-04 21:00:49 -0700270 // Continue to see if mQuit flag is set.
271 // This can be spurious (due to bugreport being taken).
272 continue;
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700273
274 case kIdent:
275 // Possible events on our queue.
276 break;
277
278 default:
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700279 ALOGE("Unexpected status out of Looper::pollOnce: %d", ret);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700280 }
281
282 // Process an event.
283 ASensorEvent event;
Ytai Ben-Tsvi9f12f172021-09-23 16:47:25 -0700284 ssize_t actual = mQueue->read(&event, 1);
285 if (actual > 0) {
286 mQueue->sendAck(&event, actual);
287 }
288 ssize_t size = mQueue->filterEvents(&event, actual);
289
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700290 if (size < 0 || size > 1) {
Andy Hungf1073882022-11-04 21:00:49 -0700291 ALOGE("%s: Unexpected return value from SensorEventQueue::filterEvents: %zd",
292 __func__, size);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700293 break;
294 }
295 if (size == 0) {
296 // No events.
297 continue;
298 }
299
300 handleEvent(event);
301 }
Andy Hungf1073882022-11-04 21:00:49 -0700302 ALOGD("%s: Exiting sensor event loop", __func__);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700303 }
304
305 void handleEvent(const ASensorEvent& event) {
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800306 PoseEvent value;
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700307 {
308 std::lock_guard lock(mMutex);
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800309 auto iter = mEnabledSensorsExtra.find(event.sensor);
310 if (iter == mEnabledSensorsExtra.end()) {
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700311 // This can happen if we have any pending events shortly after stopping.
312 return;
313 }
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800314 value = parseEvent(event, iter->second.format, &iter->second.discontinuityCount);
Shunkai Yao51379452022-08-30 03:14:50 +0000315 updateEventTimestamp(event, iter->second);
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700316 }
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700317 mListener->onPose(event.timestamp, event.sensor, value.pose, value.twist,
318 value.isNewReference);
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700319 }
320
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700321 DataFormat getSensorFormat(int32_t handle) {
322 std::optional<const Sensor> sensor = getSensorByHandle(handle);
323 if (!sensor) {
324 ALOGE("Sensor not found: %d", handle);
325 return DataFormat::kUnknown;
326 }
327 if (sensor->getType() == ASENSOR_TYPE_ROTATION_VECTOR ||
328 sensor->getType() == ASENSOR_TYPE_GAME_ROTATION_VECTOR) {
329 return DataFormat::kQuaternion;
330 }
331
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800332 if (sensor->getType() == ASENSOR_TYPE_HEAD_TRACKER) {
333 return DataFormat::kRotationVectorsAndDiscontinuityCount;
334 }
335
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700336 return DataFormat::kUnknown;
337 }
338
Andy Hunga461a002022-05-17 10:36:02 -0700339 std::optional<const Sensor> getSensorByHandle(int32_t handle) override {
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700340 const Sensor* const* list;
341 ssize_t size;
342
343 // Search static sensor list.
344 size = mSensorManager->getSensorList(&list);
345 if (size < 0) {
346 ALOGE("getSensorList failed with error code %zd", size);
347 return std::nullopt;
348 }
349 for (size_t i = 0; i < size; ++i) {
350 if (list[i]->getHandle() == handle) {
351 return *list[i];
352 }
353 }
354
355 // Search dynamic sensor list.
356 Vector<Sensor> dynList;
357 size = mSensorManager->getDynamicSensorList(dynList);
358 if (size < 0) {
359 ALOGE("getDynamicSensorList failed with error code %zd", size);
360 return std::nullopt;
361 }
362 for (size_t i = 0; i < size; ++i) {
363 if (dynList[i].getHandle() == handle) {
364 return dynList[i];
365 }
366 }
367
368 return std::nullopt;
369 }
370
Shunkai Yao51379452022-08-30 03:14:50 +0000371 void updateEventTimestamp(const ASensorEvent& event, SensorExtra& extra) {
372 if (extra.latestTimestamp != 0) {
373 int64_t gap = event.timestamp - extra.latestTimestamp;
374 extra.maxPeriod = std::max(gap, extra.maxPeriod);
375 extra.minPeriod = std::min(gap, extra.minPeriod);
376 }
377 extra.latestTimestamp = event.timestamp;
378 }
379
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800380 static PoseEvent parseEvent(const ASensorEvent& event, DataFormat format,
381 std::optional<int32_t>* discontinutyCount) {
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700382 switch (format) {
383 case DataFormat::kQuaternion: {
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700384 Eigen::Quaternionf quat(event.data[3], event.data[0], event.data[1], event.data[2]);
Ytai Ben-Tsvi54f07582021-09-13 12:09:42 -0700385 // Adapt to different frame convention.
386 quat *= rotateX(-M_PI_2);
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700387 return PoseEvent{Pose3f(quat), std::optional<Twist3f>(), false};
388 }
389
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800390 case DataFormat::kRotationVectorsAndDiscontinuityCount: {
391 Eigen::Vector3f rotation = {event.head_tracker.rx, event.head_tracker.ry,
392 event.head_tracker.rz};
393 Eigen::Vector3f twist = {event.head_tracker.vx, event.head_tracker.vy,
Ytai Ben-Tsvi27bbea32022-01-28 18:01:06 -0800394 event.head_tracker.vz};
Ytai Ben-Tsvi87b06212022-01-20 16:52:03 -0800395 Eigen::Quaternionf quat = rotationVectorToQuaternion(rotation);
396 bool isNewReference =
397 !discontinutyCount->has_value() ||
398 discontinutyCount->value() != event.head_tracker.discontinuity_count;
399 *discontinutyCount = event.head_tracker.discontinuity_count;
400
401 return PoseEvent{Pose3f(quat), Twist3f(Eigen::Vector3f::Zero(), twist),
402 isNewReference};
403 }
404
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700405 default:
Ytai Ben-Tsvi2c694be2021-10-06 17:12:49 -0700406 LOG_ALWAYS_FATAL("Unexpected sensor type: %d", static_cast<int>(format));
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700407 }
408 }
Shunkai Yao5a251df2022-07-22 18:42:27 +0000409
Shunkai Yao51379452022-08-30 03:14:50 +0000410 const static std::string toString(DataFormat format) {
Shunkai Yao5a251df2022-07-22 18:42:27 +0000411 switch (format) {
412 case DataFormat::kUnknown:
413 return "kUnknown";
414 case DataFormat::kQuaternion:
415 return "kQuaternion";
416 case DataFormat::kRotationVectorsAndDiscontinuityCount:
417 return "kRotationVectorsAndDiscontinuityCount";
418 default:
419 return "NotImplemented";
420 }
421 }
Ytai Ben-Tsvi779d1ee2021-07-27 05:56:22 -0700422};
423
424} // namespace
425
426std::unique_ptr<SensorPoseProvider> SensorPoseProvider::create(const char* packageName,
427 Listener* listener) {
428 return SensorPoseProviderImpl::create(packageName, listener);
429}
430
431} // namespace media
432} // namespace android