| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "device/vr/android/gvr/gvr_gamepad_data_fetcher.h" | 5 #include "device/vr/android/gvr/gvr_gamepad_data_fetcher.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 | 9 |
| 10 #include "device/vr/android/gvr/gvr_delegate.h" | 10 #include "device/vr/android/gvr/gvr_gamepad_data_provider.h" |
| 11 #include "third_party/WebKit/public/platform/WebGamepads.h" | 11 #include "third_party/WebKit/public/platform/WebGamepads.h" |
| 12 #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/
gvr.h" | |
| 13 | 12 |
| 14 namespace device { | 13 namespace device { |
| 15 | 14 |
| 16 namespace { | 15 namespace { |
| 17 | 16 |
| 18 void CopyToWebUString(blink::WebUChar* dest, | 17 void CopyToWebUString(blink::WebUChar* dest, |
| 19 size_t dest_length, | 18 size_t dest_length, |
| 20 base::string16 src) { | 19 base::string16 src) { |
| 21 static_assert(sizeof(base::string16::value_type) == sizeof(blink::WebUChar), | 20 static_assert(sizeof(base::string16::value_type) == sizeof(blink::WebUChar), |
| 22 "Mismatched string16/WebUChar size."); | 21 "Mismatched string16/WebUChar size."); |
| 23 | 22 |
| 24 const size_t str_to_copy = std::min(src.size(), dest_length - 1); | 23 const size_t str_to_copy = std::min(src.size(), dest_length - 1); |
| 25 memcpy(dest, src.data(), str_to_copy * sizeof(base::string16::value_type)); | 24 memcpy(dest, src.data(), str_to_copy * sizeof(base::string16::value_type)); |
| 26 dest[str_to_copy] = 0; | 25 dest[str_to_copy] = 0; |
| 27 } | 26 } |
| 28 | 27 |
| 29 } // namespace | 28 } // namespace |
| 30 | 29 |
| 31 using namespace blink; | 30 using namespace blink; |
| 32 | 31 |
| 33 GvrGamepadDataFetcher::Factory::Factory(gvr_context* context, | 32 GvrGamepadDataFetcher::Factory::Factory(GvrGamepadDataProvider* data_provider, |
| 34 unsigned int display_id) | 33 unsigned int display_id) |
| 35 : context_(context), display_id_(display_id) {} | 34 : data_provider_(data_provider), display_id_(display_id) { |
| 35 DVLOG(1) << __FUNCTION__ << "=" << this; |
| 36 } |
| 36 | 37 |
| 37 GvrGamepadDataFetcher::Factory::~Factory() {} | 38 GvrGamepadDataFetcher::Factory::~Factory() { |
| 39 DVLOG(1) << __FUNCTION__ << "=" << this; |
| 40 } |
| 38 | 41 |
| 39 std::unique_ptr<GamepadDataFetcher> | 42 std::unique_ptr<GamepadDataFetcher> |
| 40 GvrGamepadDataFetcher::Factory::CreateDataFetcher() { | 43 GvrGamepadDataFetcher::Factory::CreateDataFetcher() { |
| 41 return base::MakeUnique<GvrGamepadDataFetcher>(context_, display_id_); | 44 return base::MakeUnique<GvrGamepadDataFetcher>(data_provider_, display_id_); |
| 42 } | 45 } |
| 43 | 46 |
| 44 GamepadSource GvrGamepadDataFetcher::Factory::source() { | 47 GamepadSource GvrGamepadDataFetcher::Factory::source() { |
| 45 return GAMEPAD_SOURCE_GVR; | 48 return GAMEPAD_SOURCE_GVR; |
| 46 } | 49 } |
| 47 | 50 |
| 48 GvrGamepadDataFetcher::GvrGamepadDataFetcher(gvr_context* context, | 51 GvrGamepadDataFetcher::GvrGamepadDataFetcher( |
| 49 unsigned int display_id) | 52 GvrGamepadDataProvider* data_provider, |
| 53 unsigned int display_id) |
| 50 : display_id_(display_id) { | 54 : display_id_(display_id) { |
| 51 controller_api_.reset(new gvr::ControllerApi()); | 55 // Called on UI thread. |
| 52 int32_t options = gvr::ControllerApi::DefaultOptions(); | 56 DVLOG(1) << __FUNCTION__ << "=" << this; |
| 53 options |= GVR_CONTROLLER_ENABLE_GYRO; | 57 data_provider->RegisterGamepadDataFetcher(this); |
| 54 | |
| 55 // TODO(mthiesse): Use of the gvr_context on multiple threads isn't guaranteed | |
| 56 // to be threadsafe. All gvr context usage should be moved to VR Shell's GL | |
| 57 // thread. crbug.com/674594 | |
| 58 std::unique_ptr<gvr::GvrApi> gvr = gvr::GvrApi::WrapNonOwned(context); | |
| 59 // TODO(bajones): Monitor changes to the controller handedness. | |
| 60 handedness_ = gvr->GetUserPrefs().GetControllerHandedness(); | |
| 61 | |
| 62 bool success = controller_api_->Init(options, context); | |
| 63 if (!success) | |
| 64 controller_api_.reset(nullptr); | |
| 65 } | 58 } |
| 66 | 59 |
| 67 GvrGamepadDataFetcher::~GvrGamepadDataFetcher() {} | 60 GvrGamepadDataFetcher::~GvrGamepadDataFetcher() { |
| 61 DVLOG(1) << __FUNCTION__ << "=" << this; |
| 62 } |
| 68 | 63 |
| 69 GamepadSource GvrGamepadDataFetcher::source() { | 64 GamepadSource GvrGamepadDataFetcher::source() { |
| 70 return GAMEPAD_SOURCE_GVR; | 65 return GAMEPAD_SOURCE_GVR; |
| 71 } | 66 } |
| 72 | 67 |
| 73 void GvrGamepadDataFetcher::OnAddedToProvider() { | 68 void GvrGamepadDataFetcher::OnAddedToProvider() { |
| 74 PauseHint(false); | 69 PauseHint(false); |
| 75 } | 70 } |
| 76 | 71 |
| 72 void GvrGamepadDataFetcher::SetGamepadData(GvrGamepadData data) { |
| 73 // Called from UI thread. |
| 74 gamepad_data_ = data; |
| 75 } |
| 76 |
| 77 void GvrGamepadDataFetcher::GetGamepadData(bool devices_changed_hint) { | 77 void GvrGamepadDataFetcher::GetGamepadData(bool devices_changed_hint) { |
| 78 if (!controller_api_) | 78 // Called from gamepad polling thread. |
| 79 return; | |
| 80 | 79 |
| 81 PadState* state = GetPadState(0); | 80 PadState* state = GetPadState(0); |
| 82 if (!state) | 81 if (!state) |
| 83 return; | 82 return; |
| 84 | 83 |
| 84 // Take a snapshot of the asynchronously updated gamepad data. |
| 85 // TODO(bajones): ensure consistency? |
| 86 GvrGamepadData provided_data = gamepad_data_; |
| 87 |
| 85 WebGamepad& pad = state->data; | 88 WebGamepad& pad = state->data; |
| 86 if (state->active_state == GAMEPAD_NEWLY_ACTIVE) { | 89 if (state->active_state == GAMEPAD_NEWLY_ACTIVE) { |
| 87 // This is the first time we've seen this device, so do some one-time | 90 // This is the first time we've seen this device, so do some one-time |
| 88 // initialization | 91 // initialization |
| 89 pad.connected = true; | 92 pad.connected = true; |
| 90 CopyToWebUString(pad.id, WebGamepad::idLengthCap, | 93 CopyToWebUString(pad.id, WebGamepad::idLengthCap, |
| 91 base::UTF8ToUTF16("Daydream Controller")); | 94 base::UTF8ToUTF16("Daydream Controller")); |
| 92 CopyToWebUString(pad.mapping, WebGamepad::mappingLengthCap, | 95 CopyToWebUString(pad.mapping, WebGamepad::mappingLengthCap, |
| 93 base::UTF8ToUTF16("")); | 96 base::UTF8ToUTF16("")); |
| 94 pad.buttonsLength = 1; | 97 pad.buttonsLength = 1; |
| 95 pad.axesLength = 2; | 98 pad.axesLength = 2; |
| 96 | 99 |
| 97 pad.displayId = display_id_; | 100 pad.displayId = display_id_; |
| 98 | 101 |
| 99 pad.hand = (handedness_ == GVR_CONTROLLER_RIGHT_HANDED) ? GamepadHandRight | 102 pad.hand = provided_data.right_handed ? GamepadHandRight : GamepadHandLeft; |
| 100 : GamepadHandLeft; | |
| 101 } | 103 } |
| 102 | 104 |
| 103 controller_state_.Update(*controller_api_); | 105 pad.timestamp = provided_data.timestamp; |
| 104 | 106 |
| 105 pad.timestamp = controller_state_.GetLastOrientationTimestamp(); | 107 if (provided_data.is_touching) { |
| 106 | 108 gvr_vec2f touch_position = provided_data.touch_pos; |
| 107 if (controller_state_.IsTouching()) { | |
| 108 gvr_vec2f touch_position = controller_state_.GetTouchPos(); | |
| 109 pad.axes[0] = (touch_position.x * 2.0f) - 1.0f; | 109 pad.axes[0] = (touch_position.x * 2.0f) - 1.0f; |
| 110 pad.axes[1] = (touch_position.y * 2.0f) - 1.0f; | 110 pad.axes[1] = (touch_position.y * 2.0f) - 1.0f; |
| 111 } else { | 111 } else { |
| 112 pad.axes[0] = 0.0f; | 112 pad.axes[0] = 0.0f; |
| 113 pad.axes[1] = 0.0f; | 113 pad.axes[1] = 0.0f; |
| 114 } | 114 } |
| 115 | 115 |
| 116 pad.buttons[0].touched = controller_state_.IsTouching(); | 116 pad.buttons[0].touched = provided_data.is_touching; |
| 117 pad.buttons[0].pressed = | 117 pad.buttons[0].pressed = provided_data.controller_button_pressed; |
| 118 controller_state_.GetButtonState(GVR_CONTROLLER_BUTTON_CLICK); | |
| 119 pad.buttons[0].value = pad.buttons[0].pressed ? 1.0f : 0.0f; | 118 pad.buttons[0].value = pad.buttons[0].pressed ? 1.0f : 0.0f; |
| 120 | 119 |
| 121 pad.pose.notNull = true; | 120 pad.pose.notNull = true; |
| 122 pad.pose.hasOrientation = true; | 121 pad.pose.hasOrientation = true; |
| 123 pad.pose.hasPosition = false; | 122 pad.pose.hasPosition = false; |
| 124 | 123 |
| 125 gvr_quatf orientation = controller_state_.GetOrientation(); | 124 gvr_quatf orientation = provided_data.orientation; |
| 126 pad.pose.orientation.notNull = true; | 125 pad.pose.orientation.notNull = true; |
| 127 pad.pose.orientation.x = orientation.qx; | 126 pad.pose.orientation.x = orientation.qx; |
| 128 pad.pose.orientation.y = orientation.qy; | 127 pad.pose.orientation.y = orientation.qy; |
| 129 pad.pose.orientation.z = orientation.qz; | 128 pad.pose.orientation.z = orientation.qz; |
| 130 pad.pose.orientation.w = orientation.qw; | 129 pad.pose.orientation.w = orientation.qw; |
| 131 | 130 |
| 132 gvr_vec3f accel = controller_state_.GetAccel(); | 131 gvr_vec3f accel = provided_data.accel; |
| 133 pad.pose.linearAcceleration.notNull = true; | 132 pad.pose.linearAcceleration.notNull = true; |
| 134 pad.pose.linearAcceleration.x = accel.x; | 133 pad.pose.linearAcceleration.x = accel.x; |
| 135 pad.pose.linearAcceleration.y = accel.y; | 134 pad.pose.linearAcceleration.y = accel.y; |
| 136 pad.pose.linearAcceleration.z = accel.z; | 135 pad.pose.linearAcceleration.z = accel.z; |
| 137 | 136 |
| 138 gvr_vec3f gyro = controller_state_.GetGyro(); | 137 gvr_vec3f gyro = provided_data.gyro; |
| 139 pad.pose.angularVelocity.notNull = true; | 138 pad.pose.angularVelocity.notNull = true; |
| 140 pad.pose.angularVelocity.x = gyro.x; | 139 pad.pose.angularVelocity.x = gyro.x; |
| 141 pad.pose.angularVelocity.y = gyro.y; | 140 pad.pose.angularVelocity.y = gyro.y; |
| 142 pad.pose.angularVelocity.z = gyro.z; | 141 pad.pose.angularVelocity.z = gyro.z; |
| 143 } | 142 } |
| 144 | 143 |
| 145 void GvrGamepadDataFetcher::PauseHint(bool paused) { | 144 void GvrGamepadDataFetcher::PauseHint(bool paused) {} |
| 146 if (!controller_api_) | |
| 147 return; | |
| 148 | |
| 149 if (paused) { | |
| 150 controller_api_->Pause(); | |
| 151 } else { | |
| 152 controller_api_->Resume(); | |
| 153 } | |
| 154 } | |
| 155 | 145 |
| 156 } // namespace device | 146 } // namespace device |
| OLD | NEW |