Chromium Code Reviews| Index: device/vr/android/gvr/gvr_gamepad_data_fetcher.cc | 
| diff --git a/device/vr/android/gvr/gvr_gamepad_data_fetcher.cc b/device/vr/android/gvr/gvr_gamepad_data_fetcher.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..6dade1afeda7d0b6d1163291d3d780c4bb538af8 | 
| --- /dev/null | 
| +++ b/device/vr/android/gvr/gvr_gamepad_data_fetcher.cc | 
| @@ -0,0 +1,140 @@ | 
| +// Copyright 2016 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "device/vr/android/gvr/gvr_gamepad_data_fetcher.h" | 
| + | 
| +#include "base/strings/utf_string_conversions.h" | 
| + | 
| +#include "device/vr/android/gvr/gvr_delegate.h" | 
| +#include "third_party/WebKit/public/platform/WebGamepads.h" | 
| + | 
| +namespace device { | 
| + | 
| +namespace { | 
| + | 
| +void CopyToWebUString(unsigned short* dest, | 
| + size_t dest_length, | 
| + base::string16 src) { | 
| + const size_t str_to_copy = std::min(src.size(), dest_length - 1); | 
| + memcpy(dest, src.data(), str_to_copy * sizeof(base::string16::value_type)); | 
| 
 
bshe
2016/09/20 15:35:03
If dest_length - 1 < src.size and sizeof(base::str
 
 | 
| + dest[str_to_copy] = 0; | 
| +} | 
| + | 
| +} // namespace | 
| + | 
| +using namespace blink; | 
| + | 
| +GvrGamepadDataFetcher::Factory::Factory(GvrDelegate* delegate) | 
| + : delegate_(delegate) {} | 
| + | 
| +GvrGamepadDataFetcher::Factory::~Factory() {} | 
| + | 
| +std::unique_ptr<GamepadDataFetcher> | 
| +GvrGamepadDataFetcher::Factory::CreateDataFetcher() { | 
| + return std::unique_ptr<GamepadDataFetcher>( | 
| + new GvrGamepadDataFetcher(delegate_)); | 
| +} | 
| + | 
| +GamepadSource GvrGamepadDataFetcher::Factory::source() { | 
| + return GAMEPAD_SOURCE_GVR; | 
| +} | 
| + | 
| +GvrGamepadDataFetcher::GvrGamepadDataFetcher(GvrDelegate* delegate) { | 
| + gvr::GvrApi* gvr_api = delegate->gvr_api(); | 
| + controller_api_.reset(new gvr::ControllerApi()); | 
| + int32_t options = gvr::ControllerApi::DefaultOptions(); | 
| + options |= GVR_CONTROLLER_ENABLE_GYRO; | 
| + bool success = controller_api_->Init(options, gvr_api->GetContext()); | 
| + if (!success) | 
| + controller_api_.reset(nullptr); | 
| +} | 
| + | 
| +GvrGamepadDataFetcher::~GvrGamepadDataFetcher() {} | 
| + | 
| +GamepadSource GvrGamepadDataFetcher::source() { | 
| + return GAMEPAD_SOURCE_GVR; | 
| +} | 
| + | 
| +void GvrGamepadDataFetcher::OnAddedToProvider() { | 
| + PauseHint(false); | 
| +} | 
| + | 
| +void GvrGamepadDataFetcher::GetGamepadData(bool devices_changed_hint) { | 
| + if (!controller_api_) | 
| + return; | 
| + | 
| + PadState* state = GetPadState(0); | 
| + if (!state) | 
| + return; | 
| + | 
| + WebGamepad& pad = state->data; | 
| + if (state->active_state == GAMEPAD_NEWLY_ACTIVE) { | 
| + // This is the first time we've seen this device, so do some one-time | 
| + // initialization | 
| + pad.connected = true; | 
| + CopyToWebUString(pad.id, WebGamepad::idLengthCap - 1, | 
| 
 
mthiesse
2016/09/20 16:02:06
I don't think this is the right fix, I think this
 
 | 
| + base::UTF8ToUTF16("Daydream Controller")); | 
| + CopyToWebUString(pad.mapping, WebGamepad::mappingLengthCap - 1, | 
| + base::UTF8ToUTF16("")); | 
| + pad.buttonsLength = 1; | 
| + pad.axesLength = 2; | 
| + } | 
| + | 
| + controller_state_.Update(*controller_api_); | 
| + | 
| + pad.timestamp = controller_state_.GetLastOrientationTimestamp(); | 
| + | 
| + // TODO: Query from API if avaialable. | 
| + pad.hand = GamepadHandRight; | 
| + | 
| + if (controller_state_.IsTouching()) { | 
| + gvr_vec2f touch_position = controller_state_.GetTouchPos(); | 
| + pad.axes[0] = (touch_position.x * 2.0f) - 1.0f; | 
| + pad.axes[1] = (touch_position.y * 2.0f) - 1.0f; | 
| + } else { | 
| + pad.axes[0] = 0.0f; | 
| + pad.axes[1] = 0.0f; | 
| + } | 
| + | 
| + pad.buttons[0].touched = controller_state_.IsTouching(); | 
| + pad.buttons[0].pressed = | 
| + controller_state_.GetButtonState(GVR_CONTROLLER_BUTTON_CLICK); | 
| + pad.buttons[0].value = pad.buttons[0].pressed ? 1.0f : 0.0f; | 
| + | 
| + pad.pose.notNull = true; | 
| + pad.pose.hasOrientation = true; | 
| + pad.pose.hasPosition = false; | 
| + | 
| + gvr_quatf orientation = controller_state_.GetOrientation(); | 
| + pad.pose.orientation.notNull = true; | 
| + pad.pose.orientation.x = orientation.qx; | 
| + pad.pose.orientation.y = orientation.qy; | 
| + pad.pose.orientation.z = orientation.qz; | 
| + pad.pose.orientation.w = orientation.qw; | 
| + | 
| + gvr_vec3f accel = controller_state_.GetAccel(); | 
| + pad.pose.linearAcceleration.notNull = true; | 
| + pad.pose.linearAcceleration.x = accel.x; | 
| + pad.pose.linearAcceleration.y = accel.y; | 
| + pad.pose.linearAcceleration.z = accel.z; | 
| + | 
| + gvr_vec3f gyro = controller_state_.GetGyro(); | 
| + pad.pose.angularVelocity.notNull = true; | 
| + pad.pose.angularVelocity.x = gyro.x; | 
| + pad.pose.angularVelocity.y = gyro.y; | 
| + pad.pose.angularVelocity.z = gyro.z; | 
| +} | 
| + | 
| +void GvrGamepadDataFetcher::PauseHint(bool paused) { | 
| + if (!controller_api_) | 
| + return; | 
| + | 
| + if (paused) { | 
| + controller_api_->Pause(); | 
| + } else { | 
| + controller_api_->Resume(); | 
| + } | 
| +} | 
| + | 
| +} // namespace device |