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

Side by Side Diff: Source/modules/webmidi/MIDIAccess.cpp

Issue 77773003: Make WebMIDI use blink Promise. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 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 | « Source/modules/webmidi/MIDIAccess.h ('k') | Source/modules/webmidi/MIDIAccessPromise.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 13 matching lines...) Expand all
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "modules/webmidi/MIDIAccess.h" 32 #include "modules/webmidi/MIDIAccess.h"
33 33
34 #include "bindings/v8/DOMRequestState.h"
35 #include "bindings/v8/DOMWrapperWorld.h"
36 #include "bindings/v8/ScriptPromise.h"
37 #include "bindings/v8/ScriptPromiseResolver.h"
38 #include "bindings/v8/V8Binding.h"
34 #include "core/dom/DOMError.h" 39 #include "core/dom/DOMError.h"
35 #include "core/dom/Document.h" 40 #include "core/dom/Document.h"
36 #include "core/loader/DocumentLoadTiming.h" 41 #include "core/loader/DocumentLoadTiming.h"
37 #include "core/loader/DocumentLoader.h" 42 #include "core/loader/DocumentLoader.h"
38 #include "modules/webmidi/MIDIAccessPromise.h"
39 #include "modules/webmidi/MIDIConnectionEvent.h" 43 #include "modules/webmidi/MIDIConnectionEvent.h"
40 #include "modules/webmidi/MIDIController.h" 44 #include "modules/webmidi/MIDIController.h"
45 #include "modules/webmidi/MIDIOptions.h"
41 #include "modules/webmidi/MIDIPort.h" 46 #include "modules/webmidi/MIDIPort.h"
47 #include "modules/webmidi/NavigatorWebMIDI.h"
42 48
43 namespace WebCore { 49 namespace WebCore {
44 50
45 DEFINE_GC_INFO(MIDIAccess); 51 DEFINE_GC_INFO(MIDIAccess);
46 52
47 PassRefPtrWillBeRawPtr<MIDIAccess> MIDIAccess::create(ExecutionContext* context, MIDIAccessPromise* promise) 53 PassRefPtrWillBeRawPtr<MIDIAccess> MIDIAccess::create(const MIDIOptions& options , ExecutionContext* context)
48 { 54 {
49 RefPtrWillBeRawPtr<MIDIAccess> midiAccess(adoptRefCountedWillBeRefCountedGar bageCollected(new MIDIAccess(context, promise))); 55 RefPtrWillBeRawPtr<MIDIAccess> midiAccess(adoptRefCountedWillBeRefCountedGar bageCollected(new MIDIAccess(options, context)));
50 midiAccess->suspendIfNeeded(); 56 midiAccess->suspendIfNeeded();
51 midiAccess->startRequest();
52 return midiAccess.release(); 57 return midiAccess.release();
53 } 58 }
54 59
55 MIDIAccess::~MIDIAccess() 60 MIDIAccess::~MIDIAccess()
56 { 61 {
57 stop(); 62 ASSERT(!m_requesting);
58 } 63 }
59 64
60 MIDIAccess::MIDIAccess(ExecutionContext* context, MIDIAccessPromise* promise) 65 MIDIAccess::MIDIAccess(const MIDIOptions& options, ExecutionContext* context)
61 : ActiveDOMObject(context) 66 : ActiveDOMObject(context)
62 , m_promise(promise) 67 , m_options(options)
63 , m_hasAccess(false) 68 , m_hasAccess(false)
64 , m_sysExEnabled(false) 69 , m_sysExEnabled(false)
65 , m_requesting(false) 70 , m_requesting(false)
66 { 71 {
67 ScriptWrappable::init(this); 72 ScriptWrappable::init(this);
68 m_accessor = MIDIAccessor::create(this); 73 m_accessor = MIDIAccessor::create(this);
69 } 74 }
70 75
71 void MIDIAccess::setSysExEnabled(bool enable) 76 void MIDIAccess::setSysExEnabled(bool enable)
72 { 77 {
73 m_requesting = false; 78 RefPtr<MIDIAccess> protect(this);
74 m_sysExEnabled = enable; 79 m_sysExEnabled = enable;
75 if (enable) 80 if (enable)
76 m_accessor->startSession(); 81 m_accessor->startSession();
77 else 82 else
78 permissionDenied(); 83 reject(DOMError::create("SecurityError"));
79 } 84 }
80 85
81 void MIDIAccess::didAddInputPort(const String& id, const String& manufacturer, c onst String& name, const String& version) 86 void MIDIAccess::didAddInputPort(const String& id, const String& manufacturer, c onst String& name, const String& version)
82 { 87 {
83 ASSERT(isMainThread()); 88 ASSERT(isMainThread());
84 89
85 m_inputs.append(MIDIInput::create(this, id, manufacturer, name, version)); 90 m_inputs.append(MIDIInput::create(this, id, manufacturer, name, version));
86 } 91 }
87 92
88 void MIDIAccess::didAddOutputPort(const String& id, const String& manufacturer, const String& name, const String& version) 93 void MIDIAccess::didAddOutputPort(const String& id, const String& manufacturer, const String& name, const String& version)
89 { 94 {
90 ASSERT(isMainThread()); 95 ASSERT(isMainThread());
91 96
92 unsigned portIndex = m_outputs.size(); 97 unsigned portIndex = m_outputs.size();
93 m_outputs.append(MIDIOutput::create(this, portIndex, id, manufacturer, name, version)); 98 m_outputs.append(MIDIOutput::create(this, portIndex, id, manufacturer, name, version));
94 } 99 }
95 100
96 void MIDIAccess::didStartSession(bool success) 101 void MIDIAccess::didStartSession(bool success)
97 { 102 {
103 RefPtr<MIDIAccess> protect(this);
98 ASSERT(isMainThread()); 104 ASSERT(isMainThread());
99 105 if (!m_requesting)
100 m_hasAccess = success; 106 return;
101 if (success) 107 if (success)
102 m_promise->fulfill(); 108 resolve();
103 else 109 else
104 m_promise->reject(DOMError::create("InvalidStateError")); 110 reject(DOMError::create("InvalidStateError"));
105 } 111 }
106 112
107 void MIDIAccess::didReceiveMIDIData(unsigned portIndex, const unsigned char* dat a, size_t length, double timeStamp) 113 void MIDIAccess::didReceiveMIDIData(unsigned portIndex, const unsigned char* dat a, size_t length, double timeStamp)
108 { 114 {
109 ASSERT(isMainThread()); 115 ASSERT(isMainThread());
110 116
111 if (m_hasAccess && portIndex < m_inputs.size()) { 117 if (m_hasAccess && portIndex < m_inputs.size()) {
112 // Convert from time in seconds which is based on the time coordinate sy stem of monotonicallyIncreasingTime() 118 // Convert from time in seconds which is based on the time coordinate sy stem of monotonicallyIncreasingTime()
113 // into time in milliseconds (a DOMHighResTimeStamp) according to the sa me time coordinate system as performance.now(). 119 // into time in milliseconds (a DOMHighResTimeStamp) according to the sa me time coordinate system as performance.now().
114 // This is how timestamps are defined in the Web MIDI spec. 120 // This is how timestamps are defined in the Web MIDI spec.
(...skipping 23 matching lines...) Expand all
138 double documentStartTime = document->loader()->timing()->referenceMo notonicTime(); 144 double documentStartTime = document->loader()->timing()->referenceMo notonicTime();
139 timeStamp = documentStartTime + 0.001 * timeStampInMilliseconds; 145 timeStamp = documentStartTime + 0.001 * timeStampInMilliseconds;
140 } 146 }
141 147
142 m_accessor->sendMIDIData(portIndex, data, length, timeStamp); 148 m_accessor->sendMIDIData(portIndex, data, length, timeStamp);
143 } 149 }
144 } 150 }
145 151
146 void MIDIAccess::stop() 152 void MIDIAccess::stop()
147 { 153 {
154 RefPtr<MIDIAccess> protect(this);
148 m_hasAccess = false; 155 m_hasAccess = false;
149 if (!m_requesting) 156 if (!m_requesting)
150 return; 157 return;
151 m_requesting = false;
152 Document* document = toDocument(executionContext()); 158 Document* document = toDocument(executionContext());
153 ASSERT(document); 159 ASSERT(document);
154 MIDIController* controller = MIDIController::from(document->page()); 160 MIDIController* controller = MIDIController::from(document->page());
155 ASSERT(controller); 161 ASSERT(controller);
156 controller->cancelSysExPermissionRequest(this); 162 controller->cancelSysExPermissionRequest(this);
163
164 m_accessor.clear();
165 reject(DOMError::create("AbortError"));
157 } 166 }
158 167
159 void MIDIAccess::startRequest() 168 void MIDIAccess::permissionDenied()
160 { 169 {
161 if (!m_promise->options()->sysex) { 170 RefPtr<MIDIAccess> protect(this);
171 ASSERT(isMainThread());
172 reject(DOMError::create("SecurityError"));
173 }
174
175 ScriptPromise MIDIAccess::startRequest()
176 {
177 ASSERT(!m_requesting);
178 RefPtr<MIDIAccess> protect(this);
haraken 2014/02/21 11:11:40 Why do you need protection? Is this "just in case"
yhirano 2014/02/21 13:52:35 I think they were introduced by your suggestion. h
yhirano 2014/02/26 09:18:08 I deleted many of protect(this).
179 ScriptPromise promise = ScriptPromise::createPending();
180 m_resolver = ScriptPromiseResolver::create(promise, executionContext());
181 m_world = RefPtr<DOMWrapperWorld>(DOMWrapperWorld::current(toIsolate(executi onContext())));
182 m_requesting = true;
183 setPendingActivity(this);
haraken 2014/02/21 11:11:40 m_requesting and setPendingActivity should be sync
yhirano 2014/02/21 13:52:35 Done.
184 if (!m_options.sysex) {
162 m_accessor->startSession(); 185 m_accessor->startSession();
163 return; 186 return promise;
164 } 187 }
165 Document* document = toDocument(executionContext()); 188 Document* document = toDocument(executionContext());
166 ASSERT(document); 189 ASSERT(document);
167 MIDIController* controller = MIDIController::from(document->page()); 190 MIDIController* controller = MIDIController::from(document->page());
168 if (controller) { 191 if (controller)
169 m_requesting = true;
170 controller->requestSysExPermission(this); 192 controller->requestSysExPermission(this);
171 } else { 193 else
172 permissionDenied(); 194 reject(DOMError::create("SecurityError"));
173 } 195 return promise;
174 } 196 }
175 197
176 void MIDIAccess::permissionDenied() 198 void MIDIAccess::resolve()
177 { 199 {
178 ASSERT(isMainThread()); 200 RefPtr<MIDIAccess> protect(this);
201 if (!m_requesting)
202 return;
203 ASSERT(m_world.get());
204 DOMRequestState state(executionContext(), m_world);
205 DOMRequestState::Scope scope(state);
haraken 2014/02/21 11:11:40 I don't understand why you need DOMRequestState he
yhirano 2014/02/21 13:52:35 I introduced MIDIAccessResolver.
206 m_world.clear();
207 m_hasAccess = true;
haraken 2014/02/21 11:11:40 What is m_hasAccess for?
yhirano 2014/02/21 13:52:35 m_hasAccess is used in didReceiveMIDIData and send
208 m_requesting = false;
209 unsetPendingActivity(this);
210 // FIXME: Care about suspend / stop.
haraken 2014/02/21 11:11:40 I think you need to fix this in this CL.
yhirano 2014/02/21 13:52:35 Done.
211 m_resolver->resolve(this, executionContext());
212 }
179 213
214 void MIDIAccess::reject(PassRefPtr<DOMError> error)
215 {
216 RefPtr<MIDIAccess> protect(this);
217 if (!m_requesting)
218 return;
219 ASSERT(m_world.get());
220 DOMRequestState state(executionContext(), m_world);
221 DOMRequestState::Scope scope(state);
222 m_world.clear();
180 m_hasAccess = false; 223 m_hasAccess = false;
181 m_promise->reject(DOMError::create("SecurityError")); 224 m_requesting = false;
225 unsetPendingActivity(this);
226 // FIXME: Care about suspend / stop.
227 m_resolver->reject(error, executionContext());
182 } 228 }
183 229
184 void MIDIAccess::trace(Visitor* visitor) 230 void MIDIAccess::trace(Visitor* visitor)
185 { 231 {
186 visitor->trace(m_inputs); 232 visitor->trace(m_inputs);
187 visitor->trace(m_outputs); 233 visitor->trace(m_outputs);
188 visitor->trace(m_promise);
189 } 234 }
190 235
191 } // namespace WebCore 236 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/modules/webmidi/MIDIAccess.h ('k') | Source/modules/webmidi/MIDIAccessPromise.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698