Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: third_party/WebKit/Source/modules/vr/NavigatorVR.cpp

Issue 2703283003: Gracefully handle navigator.getVRDisplays() in detached contexts. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/LayoutTests/vr/getVRDisplays_detached.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "modules/vr/NavigatorVR.h" 5 #include "modules/vr/NavigatorVR.h"
6 6
7 #include "bindings/core/v8/ScriptPromiseResolver.h" 7 #include "bindings/core/v8/ScriptPromiseResolver.h"
8 #include "core/dom/DOMException.h" 8 #include "core/dom/DOMException.h"
9 #include "core/dom/Document.h" 9 #include "core/dom/Document.h"
10 #include "core/dom/DocumentUserGestureToken.h" 10 #include "core/dom/DocumentUserGestureToken.h"
11 #include "core/dom/ExceptionCode.h" 11 #include "core/dom/ExceptionCode.h"
12 #include "core/dom/Fullscreen.h" 12 #include "core/dom/Fullscreen.h"
13 #include "core/frame/LocalDOMWindow.h" 13 #include "core/frame/LocalDOMWindow.h"
14 #include "core/frame/LocalFrame.h" 14 #include "core/frame/LocalFrame.h"
15 #include "core/frame/Navigator.h" 15 #include "core/frame/Navigator.h"
16 #include "core/frame/UseCounter.h" 16 #include "core/frame/UseCounter.h"
17 #include "core/page/Page.h" 17 #include "core/page/Page.h"
18 #include "modules/vr/VRController.h" 18 #include "modules/vr/VRController.h"
19 #include "modules/vr/VRDisplay.h" 19 #include "modules/vr/VRDisplay.h"
20 #include "modules/vr/VRGetDevicesCallback.h" 20 #include "modules/vr/VRGetDevicesCallback.h"
21 #include "modules/vr/VRPose.h" 21 #include "modules/vr/VRPose.h"
22 #include "platform/UserGestureIndicator.h" 22 #include "platform/UserGestureIndicator.h"
23 #include "public/platform/Platform.h" 23 #include "public/platform/Platform.h"
24 #include "wtf/PtrUtil.h" 24 #include "wtf/PtrUtil.h"
25 25
26 namespace blink { 26 namespace blink {
27 27
28 namespace {
29
30 void rejectNavigatorDetached(ScriptPromiseResolver* resolver) {
31 DOMException* exception = DOMException::create(
32 InvalidStateError, "The object is no longer associated with a document.");
33 resolver->reject(exception);
34 }
35
36 } // namespace
37
28 NavigatorVR* NavigatorVR::from(Document& document) { 38 NavigatorVR* NavigatorVR::from(Document& document) {
29 if (!document.frame() || !document.frame()->domWindow()) 39 if (!document.frame() || !document.frame()->domWindow())
30 return 0; 40 return nullptr;
31 Navigator& navigator = *document.frame()->domWindow()->navigator(); 41 Navigator& navigator = *document.frame()->domWindow()->navigator();
32 return &from(navigator); 42 return &from(navigator);
33 } 43 }
34 44
35 NavigatorVR& NavigatorVR::from(Navigator& navigator) { 45 NavigatorVR& NavigatorVR::from(Navigator& navigator) {
36 NavigatorVR* supplement = static_cast<NavigatorVR*>( 46 NavigatorVR* supplement = static_cast<NavigatorVR*>(
37 Supplement<Navigator>::from(navigator, supplementName())); 47 Supplement<Navigator>::from(navigator, supplementName()));
38 if (!supplement) { 48 if (!supplement) {
39 supplement = new NavigatorVR(navigator); 49 supplement = new NavigatorVR(navigator);
40 provideTo(navigator, supplementName(), supplement); 50 provideTo(navigator, supplementName(), supplement);
41 } 51 }
42 return *supplement; 52 return *supplement;
43 } 53 }
44 54
45 ScriptPromise NavigatorVR::getVRDisplays(ScriptState* scriptState, 55 ScriptPromise NavigatorVR::getVRDisplays(ScriptState* scriptState,
46 Navigator& navigator) { 56 Navigator& navigator) {
57 if (!navigator.frame()) {
58 ScriptPromiseResolver* resolver =
59 ScriptPromiseResolver::create(scriptState);
60 ScriptPromise promise = resolver->promise();
mthiesse 2017/02/21 15:19:27 nit: Why not remove this line, and return resolver
sof 2017/02/21 15:29:12 You have to call promise() before rejecting/resolv
61 rejectNavigatorDetached(resolver);
62 return promise;
63 }
47 return NavigatorVR::from(navigator).getVRDisplays(scriptState); 64 return NavigatorVR::from(navigator).getVRDisplays(scriptState);
48 } 65 }
49 66
50 ScriptPromise NavigatorVR::getVRDisplays(ScriptState* scriptState) { 67 ScriptPromise NavigatorVR::getVRDisplays(ScriptState* scriptState) {
51 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 68 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
52 ScriptPromise promise = resolver->promise(); 69 ScriptPromise promise = resolver->promise();
53 70
54 if (!document()) { 71 if (!document()) {
55 DOMException* exception = DOMException::create( 72 rejectNavigatorDetached(resolver);
56 InvalidStateError, "The object is no longer associated to a document.");
57 resolver->reject(exception);
58 return promise; 73 return promise;
59 } 74 }
60 75
61 UseCounter::count(*document(), UseCounter::VRGetDisplays); 76 UseCounter::count(*document(), UseCounter::VRGetDisplays);
62 ExecutionContext* executionContext = scriptState->getExecutionContext(); 77 ExecutionContext* executionContext = scriptState->getExecutionContext();
63 if (!executionContext->isSecureContext()) 78 if (!executionContext->isSecureContext())
64 UseCounter::count(*document(), UseCounter::VRGetDisplaysInsecureOrigin); 79 UseCounter::count(*document(), UseCounter::VRGetDisplaysInsecureOrigin);
65 80
66 Platform::current()->recordRapporURL("VR.WebVR.GetDisplays", 81 Platform::current()->recordRapporURL("VR.WebVR.GetDisplays",
67 document()->url()); 82 document()->url());
68 83
69 controller()->getDisplays(resolver); 84 controller()->getDisplays(resolver);
70 85
71 return promise; 86 return promise;
72 } 87 }
73 88
74 VRController* NavigatorVR::controller() { 89 VRController* NavigatorVR::controller() {
75 if (!supplementable()->frame()) 90 if (!supplementable()->frame())
76 return 0; 91 return nullptr;
77 92
78 if (!m_controller) { 93 if (!m_controller) {
79 m_controller = new VRController(this); 94 m_controller = new VRController(this);
80 m_controller->setListeningForActivate(m_focused && m_listeningForActivate); 95 m_controller->setListeningForActivate(m_focused && m_listeningForActivate);
81 m_controller->focusChanged(); 96 m_controller->focusChanged();
82 } 97 }
83 98
84 return m_controller; 99 return m_controller;
85 } 100 }
86 101
87 Document* NavigatorVR::document() { 102 Document* NavigatorVR::document() {
88 return supplementable()->frame() ? supplementable()->frame()->document() 103 if (!supplementable()->frame())
89 : nullptr; 104 return nullptr;
105
106 return supplementable()->frame()->document();
90 } 107 }
91 108
92 DEFINE_TRACE(NavigatorVR) { 109 DEFINE_TRACE(NavigatorVR) {
93 visitor->trace(m_controller); 110 visitor->trace(m_controller);
94 Supplement<Navigator>::trace(visitor); 111 Supplement<Navigator>::trace(visitor);
95 } 112 }
96 113
97 NavigatorVR::NavigatorVR(Navigator& navigator) 114 NavigatorVR::NavigatorVR(Navigator& navigator)
98 : Supplement<Navigator>(navigator), 115 : Supplement<Navigator>(navigator),
99 FocusChangedObserver(navigator.frame()->page()) { 116 FocusChangedObserver(navigator.frame()->page()) {
100 navigator.frame()->domWindow()->registerEventListenerObserver(this); 117 navigator.frame()->domWindow()->registerEventListenerObserver(this);
101 focusedFrameChanged(); 118 focusedFrameChanged();
102 } 119 }
103 120
104 NavigatorVR::~NavigatorVR() {} 121 NavigatorVR::~NavigatorVR() {}
105 122
106 const char* NavigatorVR::supplementName() { 123 const char* NavigatorVR::supplementName() {
107 return "NavigatorVR"; 124 return "NavigatorVR";
108 } 125 }
109 126
110 void NavigatorVR::enqueueVREvent(VRDisplayEvent* event) { 127 void NavigatorVR::enqueueVREvent(VRDisplayEvent* event) {
111 if (supplementable()->frame()) { 128 if (!supplementable()->frame())
112 supplementable()->frame()->domWindow()->enqueueWindowEvent(event); 129 return;
113 } 130
131 supplementable()->frame()->domWindow()->enqueueWindowEvent(event);
114 } 132 }
115 133
116 void NavigatorVR::dispatchVRGestureEvent(VRDisplayEvent* event) { 134 void NavigatorVR::dispatchVRGestureEvent(VRDisplayEvent* event) {
117 if (!(supplementable()->frame())) 135 if (!(supplementable()->frame()))
118 return; 136 return;
137
119 UserGestureIndicator gestureIndicator( 138 UserGestureIndicator gestureIndicator(
120 DocumentUserGestureToken::create(document())); 139 DocumentUserGestureToken::create(document()));
121 LocalDOMWindow* window = supplementable()->frame()->domWindow(); 140 LocalDOMWindow* window = supplementable()->frame()->domWindow();
122 DCHECK(window); 141 DCHECK(window);
123 event->setTarget(window); 142 event->setTarget(window);
124 window->dispatchEvent(event); 143 window->dispatchEvent(event);
125 } 144 }
126 145
127 void NavigatorVR::focusedFrameChanged() { 146 void NavigatorVR::focusedFrameChanged() {
128 bool focused = isFrameFocused(supplementable()->frame()); 147 bool focused = isFrameFocused(supplementable()->frame());
(...skipping 25 matching lines...) Expand all
154 void NavigatorVR::didRemoveEventListener(LocalDOMWindow* window, 173 void NavigatorVR::didRemoveEventListener(LocalDOMWindow* window,
155 const AtomicString& eventType) { 174 const AtomicString& eventType) {
156 if (eventType == EventTypeNames::vrdisplayactivate && 175 if (eventType == EventTypeNames::vrdisplayactivate &&
157 !window->hasEventListeners(EventTypeNames::vrdisplayactivate)) { 176 !window->hasEventListeners(EventTypeNames::vrdisplayactivate)) {
158 m_listeningForActivate = false; 177 m_listeningForActivate = false;
159 controller()->setListeningForActivate(false); 178 controller()->setListeningForActivate(false);
160 } 179 }
161 } 180 }
162 181
163 void NavigatorVR::didRemoveAllEventListeners(LocalDOMWindow* window) { 182 void NavigatorVR::didRemoveAllEventListeners(LocalDOMWindow* window) {
164 if (m_controller) { 183 if (!m_controller)
165 m_controller->setListeningForActivate(false); 184 return;
166 m_listeningForActivate = false; 185
167 } 186 m_controller->setListeningForActivate(false);
187 m_listeningForActivate = false;
168 } 188 }
169 189
170 } // namespace blink 190 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/vr/getVRDisplays_detached.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698