1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define LOG_TAG "PoseClient" 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <dvr/pose_client.h> 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <stdint.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 64fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/client.h> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/default_transport/client_channel_factory.h> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/file_handle.h> 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/dvr/buffer_hub_client.h> 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/dvr/pose-ipc.h> 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/dvr/pose_client_internal.h> 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/dvr/sensor_constants.h> 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalHandle; 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalChannelHandle; 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Status; 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Transaction; 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 204fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#define arraysize(x) (static_cast<int32_t>(std::extent<decltype(x)>::value)) 214fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr { 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// PoseClient is a remote interface to the pose service in sensord. 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass PoseClient : public pdx::ClientBase<PoseClient> { 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ~PoseClient() override {} 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Casts C handle into an instance of this class. 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static PoseClient* FromC(DvrPose* client) { 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return reinterpret_cast<PoseClient*>(client); 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Polls the pose service for the current state and stores it in *state. 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Returns zero on success, a negative error code otherwise. 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Poll(DvrPoseState* state) { 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> status = 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko trans.Send<int>(DVR_POSE_POLL, nullptr, 0, state, sizeof(*state)); 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE_IF(!status, "Pose poll() failed because: %s\n", 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.GetErrorMessage().c_str()); 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(status); 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetPose(uint32_t vsync_count, DvrPoseAsync* out_pose) { 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!mapped_pose_buffer_) { 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ret = GetRingBuffer(nullptr); 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ret; 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *out_pose = 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko mapped_pose_buffer_->ring[vsync_count & kPoseAsyncBufferIndexMask]; 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint32_t GetVsyncCount() { 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!mapped_pose_buffer_) { 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ret = GetRingBuffer(nullptr); 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return mapped_pose_buffer_->vsync_count; 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetControllerPose(int32_t controller_id, uint32_t vsync_count, 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DvrPoseAsync* out_pose) { 684fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko if (controller_id < 0 || controller_id >= arraysize(controllers_)) { 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -EINVAL; 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!controllers_[controller_id].mapped_pose_buffer) { 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ret = GetControllerRingBuffer(controller_id); 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ret; 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *out_pose = 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko controllers_[controller_id] 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko .mapped_pose_buffer[vsync_count & kPoseAsyncBufferIndexMask]; 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int LogController(bool enable) { 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> status = trans.Send<int>(DVR_POSE_LOG_CONTROLLER, &enable, 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sizeof(enable), nullptr, 0); 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE_IF(!status, "Pose LogController() failed because: %s", 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.GetErrorMessage().c_str()); 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(status); 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Freezes the pose to the provided state. Future poll operations will return 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // this state until a different state is frozen or SetMode() is called with a 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // different mode. 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Returns zero on success, a negative error code otherwise. 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Freeze(const DvrPoseState& frozen_state) { 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> status = trans.Send<int>(DVR_POSE_FREEZE, &frozen_state, 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sizeof(frozen_state), nullptr, 0); 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE_IF(!status, "Pose Freeze() failed because: %s\n", 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.GetErrorMessage().c_str()); 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(status); 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Sets the data mode for the pose service. 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int SetMode(DvrPoseMode mode) { 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> status = 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko trans.Send<int>(DVR_POSE_SET_MODE, &mode, sizeof(mode), nullptr, 0); 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE_IF(!status, "Pose SetPoseMode() failed because: %s", 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.GetErrorMessage().c_str()); 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(status); 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Gets the data mode for the pose service. 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetMode(DvrPoseMode* out_mode) { 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int mode; 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> status = 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko trans.Send<int>(DVR_POSE_GET_MODE, nullptr, 0, &mode, sizeof(mode)); 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE_IF(!status, "Pose GetPoseMode() failed because: %s", 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.GetErrorMessage().c_str()); 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *out_mode = DvrPoseMode(mode); 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(status); 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetRingBuffer(DvrPoseRingBufferInfo* out_info) { 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (pose_buffer_.get()) { 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (out_info) { 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko GetPoseRingBufferInfo(out_info); 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> status = 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko trans.Send<LocalChannelHandle>(DVR_POSE_GET_RING_BUFFER); 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Pose GetRingBuffer() failed because: %s", 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.GetErrorMessage().c_str()); 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -status.error(); 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto buffer = BufferConsumer::Import(status.take()); 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!buffer) { 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Pose failed to import ring buffer"); 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -EIO; 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* addr = nullptr; 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ret = buffer->GetBlobReadOnlyPointer(sizeof(DvrPoseRingBuffer), &addr); 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0 || !addr) { 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Pose failed to map ring buffer: ret:%d, addr:%p", ret, addr); 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -EIO; 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pose_buffer_.swap(buffer); 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko mapped_pose_buffer_ = static_cast<const DvrPoseRingBuffer*>(addr); 1574fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko ALOGI("Mapped pose data translation %f,%f,%f quat %f,%f,%f,%f", 1584fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko mapped_pose_buffer_->ring[0].translation[0], 1594fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko mapped_pose_buffer_->ring[0].translation[1], 1604fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko mapped_pose_buffer_->ring[0].translation[2], 1614fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko mapped_pose_buffer_->ring[0].orientation[0], 1624fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko mapped_pose_buffer_->ring[0].orientation[1], 1634fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko mapped_pose_buffer_->ring[0].orientation[2], 1644fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko mapped_pose_buffer_->ring[0].orientation[3]); 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (out_info) { 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko GetPoseRingBufferInfo(out_info); 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetControllerRingBuffer(int32_t controller_id) { 1724fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko if (controller_id < 0 || controller_id >= arraysize(controllers_)) { 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -EINVAL; 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ControllerClientState& client_state = controllers_[controller_id]; 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (client_state.pose_buffer.get()) { 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<LocalChannelHandle> status = trans.Send<LocalChannelHandle>( 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DVR_POSE_GET_CONTROLLER_RING_BUFFER, &controller_id, 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sizeof(controller_id), nullptr, 0); 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -status.error(); 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto buffer = BufferConsumer::Import(status.take()); 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!buffer) { 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Pose failed to import ring buffer"); 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -EIO; 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko constexpr size_t size = kPoseAsyncBufferTotalCount * sizeof(DvrPoseAsync); 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* addr = nullptr; 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ret = buffer->GetBlobReadOnlyPointer(size, &addr); 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0 || !addr) { 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Pose failed to map ring buffer: ret:%d, addr:%p", ret, addr); 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -EIO; 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client_state.pose_buffer.swap(buffer); 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client_state.mapped_pose_buffer = static_cast<const DvrPoseAsync*>(addr); 2024fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko ALOGI( 2034fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko "Mapped controller %d pose data translation %f,%f,%f quat %f,%f,%f,%f", 2044fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko controller_id, client_state.mapped_pose_buffer[0].translation[0], 2054fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko client_state.mapped_pose_buffer[0].translation[1], 2064fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko client_state.mapped_pose_buffer[0].translation[2], 2074fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko client_state.mapped_pose_buffer[0].orientation[0], 2084fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko client_state.mapped_pose_buffer[0].orientation[1], 2094fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko client_state.mapped_pose_buffer[0].orientation[2], 2104fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko client_state.mapped_pose_buffer[0].orientation[3]); 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int NotifyVsync(uint32_t vsync_count, int64_t display_timestamp, 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t display_period_ns, 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t right_eye_photon_offset_ns) { 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const struct iovec data[] = { 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko {.iov_base = &vsync_count, .iov_len = sizeof(vsync_count)}, 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko {.iov_base = &display_timestamp, .iov_len = sizeof(display_timestamp)}, 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko {.iov_base = &display_period_ns, .iov_len = sizeof(display_period_ns)}, 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko {.iov_base = &right_eye_photon_offset_ns, 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko .iov_len = sizeof(right_eye_photon_offset_ns)}, 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko }; 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<int> status = 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko trans.SendVector<int>(DVR_POSE_NOTIFY_VSYNC, data, nullptr); 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE_IF(!status, "Pose NotifyVsync() failed because: %s\n", 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.GetErrorMessage().c_str()); 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(status); 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetRingBufferFd(LocalHandle* fd) { 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ret = GetRingBuffer(nullptr); 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ret; 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *fd = pose_buffer_->GetBlobFd(); 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend BASE; 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Set up a channel to the pose service. 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko PoseClient() 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BASE(pdx::default_transport::ClientChannelFactory::Create( 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DVR_POSE_SERVICE_CLIENT)) { 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // TODO(eieio): Cache the pose and make timeout 0 so that the API doesn't 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // block while waiting for the pose service to come back up. 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EnableAutoReconnect(kInfiniteTimeout); 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko PoseClient(const PoseClient&) = delete; 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko PoseClient& operator=(const PoseClient&) = delete; 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void GetPoseRingBufferInfo(DvrPoseRingBufferInfo* out_info) const { 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko out_info->min_future_count = kPoseAsyncBufferMinFutureCount; 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko out_info->total_count = kPoseAsyncBufferTotalCount; 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko out_info->buffer = mapped_pose_buffer_->ring; 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::unique_ptr<BufferConsumer> pose_buffer_; 262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const DvrPoseRingBuffer* mapped_pose_buffer_ = nullptr; 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko struct ControllerClientState { 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::unique_ptr<BufferConsumer> pose_buffer; 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const DvrPoseAsync* mapped_pose_buffer = nullptr; 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko }; 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ControllerClientState controllers_[2]; 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::dvr::PoseClient; 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct DvrPose {}; 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoextern "C" { 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoDvrPose* dvrPoseCreate() { 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko PoseClient* client = PoseClient::Create().release(); 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return reinterpret_cast<DvrPose*>(client); 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid dvrPoseDestroy(DvrPose* client) { delete PoseClient::FromC(client); } 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint dvrPoseGet(DvrPose* client, uint32_t vsync_count, DvrPoseAsync* out_pose) { 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->GetPose(vsync_count, out_pose); 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkouint32_t dvrPoseGetVsyncCount(DvrPose* client) { 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->GetVsyncCount(); 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint dvrPoseGetController(DvrPose* client, int32_t controller_id, 296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint32_t vsync_count, DvrPoseAsync* out_pose) { 297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->GetControllerPose(controller_id, 298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko vsync_count, out_pose); 299e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint dvrPoseLogController(DvrPose* client, bool enable) { 302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->LogController(enable); 303e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 304e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint dvrPosePoll(DvrPose* client, DvrPoseState* state) { 306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->Poll(state); 307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint dvrPoseFreeze(DvrPose* client, const DvrPoseState* frozen_state) { 310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->Freeze(*frozen_state); 311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint dvrPoseSetMode(DvrPose* client, DvrPoseMode mode) { 314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->SetMode(mode); 315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint dvrPoseGetMode(DvrPose* client, DvrPoseMode* mode) { 318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->GetMode(mode); 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint dvrPoseGetRingBuffer(DvrPose* client, DvrPoseRingBufferInfo* out_info) { 322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->GetRingBuffer(out_info); 323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint privateDvrPoseNotifyVsync(DvrPose* client, uint32_t vsync_count, 326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t display_timestamp, 327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t display_period_ns, 328e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t right_eye_photon_offset_ns) { 329e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->NotifyVsync(vsync_count, display_timestamp, 330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko display_period_ns, 331e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko right_eye_photon_offset_ns); 332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint privateDvrPoseGetRingBufferFd(DvrPose* client, LocalHandle* fd) { 335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return PoseClient::FromC(client)->GetRingBufferFd(fd); 336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 337e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // extern "C" 339