| Index: third_party/WebKit/Source/modules/vr/VRController.cpp
|
| diff --git a/third_party/WebKit/Source/modules/vr/VRController.cpp b/third_party/WebKit/Source/modules/vr/VRController.cpp
|
| index 36aa47c5b8dcc414b32a940ddd4bdb11a5a0442e..210bd92349b3eec63c100e160596498d5b4858c2 100644
|
| --- a/third_party/WebKit/Source/modules/vr/VRController.cpp
|
| +++ b/third_party/WebKit/Source/modules/vr/VRController.cpp
|
| @@ -5,19 +5,23 @@
|
| #include "modules/vr/VRController.h"
|
|
|
| #include "core/frame/LocalFrame.h"
|
| +#include "modules/vr/VRTypeConverters.h"
|
| +#include "platform/MojoHelper.h"
|
| #include "platform/RuntimeEnabledFeatures.h"
|
| +#include "public/platform/ServiceRegistry.h"
|
|
|
| namespace blink {
|
|
|
| VRController::~VRController()
|
| {
|
| + m_pendingDeviceRequests.clear();
|
| }
|
|
|
| -void VRController::provideTo(LocalFrame& frame, WebVRClient* client)
|
| +void VRController::provideTo(LocalFrame& frame, ServiceRegistry* registry)
|
| {
|
| ASSERT(RuntimeEnabledFeatures::webVREnabled());
|
|
|
| - VRController* controller = new VRController(frame, client);
|
| + VRController* controller = new VRController(frame, registry);
|
| Supplement<LocalFrame>::provideTo(frame, supplementName(), controller);
|
| }
|
|
|
| @@ -26,10 +30,12 @@ VRController* VRController::from(LocalFrame& frame)
|
| return static_cast<VRController*>(Supplement<LocalFrame>::from(frame, supplementName()));
|
| }
|
|
|
| -VRController::VRController(LocalFrame& frame, WebVRClient* client)
|
| +VRController::VRController(LocalFrame& frame, ServiceRegistry* registry)
|
| : LocalFrameLifecycleObserver(&frame)
|
| - , m_client(client)
|
| + , m_registry(registry)
|
| {
|
| + DCHECK(!m_service.is_bound());
|
| + DCHECK(registry);
|
| }
|
|
|
| const char* VRController::supplementName()
|
| @@ -39,36 +45,89 @@ const char* VRController::supplementName()
|
|
|
| void VRController::getDevices(WebVRGetDevicesCallback* callback)
|
| {
|
| - // When detached, the client is no longer valid.
|
| - if (!m_client) {
|
| + // When detached, the service is no longer valid.
|
| + if (!service()) {
|
| callback->onError();
|
| delete callback;
|
| return;
|
| }
|
|
|
| - // Client is expected to take ownership of the callback
|
| - m_client->getDevices(callback);
|
| + bool requestPending = m_pendingDeviceRequests.size() > 0;
|
| +
|
| + // VRController takes ownership of the callback
|
| + m_pendingDeviceRequests.append(adoptPtr(callback));
|
| +
|
| + // We don't need to fire off another request if the previous one hasn't
|
| + // returned yet. Just add the callback to the pending request list in
|
| + // this case.
|
| + if (!requestPending)
|
| + service()->GetDevices(sameThreadBindForMojo(&VRController::OnGetDevices, this));
|
| }
|
|
|
| -void VRController::getSensorState(unsigned index, WebHMDSensorState& into)
|
| +void VRController::getSensorState(unsigned index, WebHMDSensorState* into)
|
| {
|
| - // When detached, the client is no longer valid.
|
| - if (!m_client)
|
| + // When detached, the service is no longer valid.
|
| + if (!service())
|
| return;
|
| - m_client->getSensorState(index, into);
|
| +
|
| + // Should never have overlapping getSensorState requests
|
| + DCHECK(!m_pendingState);
|
| +
|
| + m_pendingState = into;
|
| +
|
| + service()->GetSensorState(index, sameThreadBindForMojo(&VRController::OnGetSensorState, this));
|
| +
|
| + // This call needs to return results synchronously in order to be useful and
|
| + // provide the lowest latency results possible.
|
| + service().WaitForIncomingResponse();
|
| }
|
|
|
| void VRController::resetSensor(unsigned index)
|
| {
|
| - // When detached, the client is no longer valid.
|
| - if (!m_client)
|
| + // When detached, the service is no longer valid.
|
| + if (!service())
|
| return;
|
| - m_client->resetSensor(index);
|
| + service()->ResetSensor(index);
|
| +}
|
| +
|
| +void VRController::OnGetDevices(const mojo::WTFArray<mojom::wtf::VRDeviceInfoPtr>& devices)
|
| +{
|
| + WebVector<WebVRDevice> webDevices(devices.size());
|
| +
|
| + if (m_pendingDeviceRequests.size()) {
|
| + for (size_t i = 0; i < devices.size(); ++i) {
|
| + webDevices[i] = devices[i].To<WebVRDevice>();
|
| + }
|
| +
|
| + for (size_t i = 0; i < m_pendingDeviceRequests.size(); ++i) {
|
| + WebVRGetDevicesCallback* callback = m_pendingDeviceRequests[i].get();
|
| + callback->onSuccess(webDevices);
|
| + }
|
| +
|
| + m_pendingDeviceRequests.clear();
|
| + }
|
| +}
|
| +
|
| +void VRController::OnGetSensorState(const mojom::wtf::VRSensorStatePtr& mojoState)
|
| +{
|
| + if (m_pendingState) {
|
| + *m_pendingState = mojoState.To<WebHMDSensorState>();
|
| + m_pendingState = nullptr;
|
| + }
|
| }
|
|
|
| void VRController::willDetachFrameHost()
|
| {
|
| - m_client = nullptr;
|
| + m_registry = nullptr;
|
| + m_service = nullptr;
|
| +}
|
| +
|
| +mojom::wtf::VRServicePtr& VRController::service()
|
| +{
|
| + // Lazily initialize the VRService the first time it's used.
|
| + if (!m_service && m_registry)
|
| + m_registry->connectToRemoteService(mojo::GetProxy(&m_service));
|
| + return m_service;
|
| }
|
|
|
| DEFINE_TRACE(VRController)
|
|
|