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

Side by Side Diff: third_party/WebKit/Source/modules/nfc/NFC.cpp

Issue 1708543002: [webnfc] Implement push() method in blink nfc module. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@onionsoup_webnfc
Patch Set: Use new createBaseCallback helper instead of custom callback class. Created 4 years, 7 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
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/nfc/NFC.h" 5 #include "modules/nfc/NFC.h"
6 6
7 #include "bindings/core/v8/JSONValuesForV8.h"
7 #include "bindings/core/v8/ScriptPromiseResolver.h" 8 #include "bindings/core/v8/ScriptPromiseResolver.h"
9 #include "bindings/core/v8/V8ArrayBuffer.h"
10 #include "core/dom/DOMArrayBuffer.h"
8 #include "core/dom/DOMException.h" 11 #include "core/dom/DOMException.h"
9 #include "core/dom/ExceptionCode.h" 12 #include "core/dom/ExceptionCode.h"
13 #include "core/frame/LocalDOMWindow.h"
14 #include "modules/nfc/NFCError.h"
10 #include "modules/nfc/NFCMessage.h" 15 #include "modules/nfc/NFCMessage.h"
11 #include "modules/nfc/NFCPushOptions.h" 16 #include "modules/nfc/NFCPushOptions.h"
17 #include "platform/mojo/MojoHelper.h"
18 #include "public/platform/ServiceRegistry.h"
19
20 namespace {
21 const char kJsonMimePrefix[] = "application/";
22 const char kJsonMimeType[] = "application/json";
23 const char kOpaqueMimeType[] = "application/octet-stream";
24 const char kPlainTextMimeType[] = "text/plain";
25 const char kPlainTextMimePrefix[] = "text/";
26 const char kCharSetUTF8[] = ";charset=UTF-8";
27 } // anonymous namespace
28
29 // Mojo type converters
30 namespace mojo {
31
32 using device::wtf::NFCMessage;
33 using device::wtf::NFCMessagePtr;
34 using device::wtf::NFCRecord;
35 using device::wtf::NFCRecordPtr;
36 using device::wtf::NFCRecordType;
37 using device::wtf::NFCPushOptions;
38 using device::wtf::NFCPushOptionsPtr;
39 using device::wtf::NFCPushTarget;
40
41 NFCPushTarget toNFCPushTarget(const WTF::String& target)
42 {
43 if (target == "tag")
44 return NFCPushTarget::TAG;
45
46 if (target == "peer")
47 return NFCPushTarget::PEER;
48
49 return NFCPushTarget::ANY;
50 }
51
52 NFCRecordType toNFCRecordType(const WTF::String& recordType)
53 {
54 if (recordType == "empty")
55 return NFCRecordType::EMPTY;
56
57 if (recordType == "text")
58 return NFCRecordType::TEXT;
59
60 if (recordType == "url")
61 return NFCRecordType::URL;
62
63 if (recordType == "json")
64 return NFCRecordType::JSON;
65
66 if (recordType == "opaque")
67 return NFCRecordType::OPAQUE_RECORD;
68
69 ASSERT_NOT_REACHED();
70 return NFCRecordType::EMPTY;
71 }
72
73 // https://w3c.github.io/web-nfc/#creating-web-nfc-message Step 2.1
74 // If NFCRecord type is not provided, deduct NFCRecord type from JS data type:
75 // String or Number => 'text' record
76 // ArrayBuffer => 'opaque' record
77 // JSON serializable Object => 'json' record
78 NFCRecordType deductRecordTypeFromDataType(const blink::NFCRecord& record)
79 {
80 if (record.hasData()) {
81 v8::Local<v8::Value> value = record.data().v8Value();
82
83 if (value->IsString()
84 || (value->IsNumber() && !std::isnan(value.As<v8::Number>()->Value() ))) {
85 return NFCRecordType::TEXT;
86 }
87
88 if (value->IsObject() && !value->IsArrayBuffer()) {
89 return NFCRecordType::JSON;
90 }
91
92 if (value->IsArrayBuffer()) {
93 return NFCRecordType::OPAQUE_RECORD;
94 }
95 }
96
97 return NFCRecordType::EMPTY;
98 }
99
100 void setMediaType(NFCRecordPtr& recordPtr, const WTF::String& recordMediaType, const WTF::String& defaultMediaType)
101 {
102 recordPtr->mediaType = recordMediaType.isEmpty() ? defaultMediaType : record MediaType;
103 }
104
105 template <>
106 struct TypeConverter<mojo::WTFArray<uint8_t>, WTF::String> {
107 static mojo::WTFArray<uint8_t> Convert(const WTF::String& string)
108 {
109 WTF::CString utf8String = string.utf8();
110 mojo::WTFArray<uint8_t> array(utf8String.length());
111 memcpy(&array.front(), utf8String.data(), utf8String.length());
112 return array;
Reilly Grant (use Gerrit) 2016/04/27 23:32:53 We try to avoid calling memcpy. Instead declare ar
shalamov 2016/04/28 14:16:14 Done.
113 }
114 };
115
116 template <>
117 struct TypeConverter<mojo::WTFArray<uint8_t>, blink::DOMArrayBuffer*> {
118 static mojo::WTFArray<uint8_t> Convert(blink::DOMArrayBuffer* buffer)
119 {
120 mojo::WTFArray<uint8_t> array(buffer->byteLength());
121 memcpy(&array.front(), buffer->data(), buffer->byteLength());
122 return array;
Reilly Grant (use Gerrit) 2016/04/27 23:32:53 Same here.
shalamov 2016/04/28 14:16:14 Done.
123 }
124 };
125
126 template <>
127 struct TypeConverter<NFCRecordPtr, WTF::String> {
128 static NFCRecordPtr Convert(const WTF::String& string)
129 {
130 NFCRecordPtr record = NFCRecord::New();
131 record->recordType = NFCRecordType::TEXT;
132 record->mediaType = kPlainTextMimeType;
133 record->mediaType.append(kCharSetUTF8);
134 record->data = mojo::WTFArray<uint8_t>::From(string);
135 return record;
136 }
137 };
138
139 template <>
140 struct TypeConverter<NFCRecordPtr, blink::DOMArrayBuffer*> {
141 static NFCRecordPtr Convert(blink::DOMArrayBuffer* buffer)
142 {
143 NFCRecordPtr record = NFCRecord::New();
144 record->recordType = NFCRecordType::OPAQUE_RECORD;
145 record->mediaType = kOpaqueMimeType;
146 record->data = mojo::WTFArray<uint8_t>::From(buffer);
147 return record;
148 }
149 };
150
151 template <>
152 struct TypeConverter<NFCMessagePtr, WTF::String> {
153 static NFCMessagePtr Convert(const WTF::String& string)
154 {
155 NFCMessagePtr message = NFCMessage::New();
156 message->data = mojo::WTFArray<NFCRecordPtr>::New(1);
157 message->data[0] = NFCRecord::From(string);
158 return message;
159 }
160 };
161
162 template <>
163 struct TypeConverter<mojo::WTFArray<uint8_t>, blink::ScriptValue> {
164 static mojo::WTFArray<uint8_t> Convert(const blink::ScriptValue& scriptValue )
165 {
166 v8::Local<v8::Value> value = scriptValue.v8Value();
167
168 if (value->IsNumber())
169 return mojo::WTFArray<uint8_t>::From(WTF::String::number(value.As<v8 ::Number>()->Value()));
170
171 if (value->IsString()) {
172 blink::V8StringResource<> stringResource = value;
173 if (stringResource.prepare())
174 return mojo::WTFArray<uint8_t>::From<WTF::String>(stringResource );
175 }
176
177 if (value->IsObject() && !value->IsArrayBuffer()) {
178 RefPtr<blink::JSONValue> jsonResult = blink::toJSONValue(scriptValue .context(), value);
179 if (jsonResult && (jsonResult->getType() == blink::JSONValue::TypeOb ject))
180 return mojo::WTFArray<uint8_t>::From(jsonResult->toJSONString()) ;
181 }
182
183 if (value->IsArrayBuffer())
184 return mojo::WTFArray<uint8_t>::From(blink::V8ArrayBuffer::toImpl(va lue.As<v8::Object>()));
185
186 return nullptr;
187 }
188 };
189
190 template <>
191 struct TypeConverter<NFCRecordPtr, blink::NFCRecord> {
192 static NFCRecordPtr Convert(const blink::NFCRecord& record)
193 {
194 NFCRecordPtr recordPtr = NFCRecord::New();
195
196 if (record.hasRecordType())
197 recordPtr->recordType = toNFCRecordType(record.recordType());
198 else
199 recordPtr->recordType = deductRecordTypeFromDataType(record);
200
201 // If record type is "empty", no need to set media type or data.
202 // https://w3c.github.io/web-nfc/#creating-web-nfc-message
203 if (recordPtr->recordType == NFCRecordType::EMPTY)
204 return recordPtr;
205
206 switch (recordPtr->recordType) {
207 case NFCRecordType::TEXT:
208 case NFCRecordType::URL:
209 setMediaType(recordPtr, record.mediaType(), kPlainTextMimeType);
210 recordPtr->mediaType.append(kCharSetUTF8);
211 break;
212 case NFCRecordType::JSON:
213 setMediaType(recordPtr, record.mediaType(), kJsonMimeType);
214 break;
215 case NFCRecordType::OPAQUE_RECORD:
216 setMediaType(recordPtr, record.mediaType(), kOpaqueMimeType);
217 break;
218 default:
219 ASSERT_NOT_REACHED();
220 break;
221 }
222
223 recordPtr->data = mojo::WTFArray<uint8_t>::From(record.data());
224
225 // If JS object cannot be converted to uint8_t array, return null,
226 // interrupt NFCMessage conversion algorithm and reject promise with
227 // SyntaxError exception.
228 if (recordPtr->data.is_null())
229 return nullptr;
230
231 return recordPtr;
232 }
233 };
234
235 template <>
236 struct TypeConverter<NFCMessagePtr, blink::NFCMessage> {
237 static NFCMessagePtr Convert(const blink::NFCMessage& message)
238 {
239 NFCMessagePtr messagePtr = NFCMessage::New();
240 messagePtr->url = message.url();
241 messagePtr->data.resize(message.data().size());
242 for (size_t i = 0; i < message.data().size(); ++i) {
243 NFCRecordPtr record = NFCRecord::From(message.data()[i]);
244 if (record.is_null())
245 return nullptr;
246
247 messagePtr->data[i] = std::move(record);
248 }
249 messagePtr->data = mojo::WTFArray<NFCRecordPtr>::From(message.data());
250 return messagePtr;
251 }
252 };
253
254 template <>
255 struct TypeConverter<NFCMessagePtr, blink::DOMArrayBuffer*> {
256 static NFCMessagePtr Convert(blink::DOMArrayBuffer* buffer)
257 {
258 NFCMessagePtr message = NFCMessage::New();
259 message->data = mojo::WTFArray<NFCRecordPtr>::New(1);
260 message->data[0] = NFCRecord::From(buffer);
261 return message;
262 }
263 };
264
265 template <>
266 struct TypeConverter<NFCMessagePtr, blink::NFCPushMessage> {
267 static NFCMessagePtr Convert(const blink::NFCPushMessage& message)
268 {
269 if (message.isString())
270 return NFCMessage::From(message.getAsString());
271
272 if (message.isNFCMessage())
273 return NFCMessage::From(message.getAsNFCMessage());
274
275 if (message.isArrayBuffer())
276 return NFCMessage::From(message.getAsArrayBuffer());
277
278 ASSERT_NOT_REACHED();
279 return nullptr;
280 }
281 };
282
283 template <>
284 struct TypeConverter<NFCPushOptionsPtr, blink::NFCPushOptions> {
285 static NFCPushOptionsPtr Convert(const blink::NFCPushOptions& pushOptions)
286 {
287 // https://w3c.github.io/web-nfc/#the-nfcpushoptions-dictionary
288 // Default values for NFCPushOptions dictionary are:
289 // target = 'any', timeout = Infinity, ignoreRead = true
290 NFCPushOptionsPtr pushOptionsPtr = NFCPushOptions::New();
291
292 if (pushOptions.hasTarget())
293 pushOptionsPtr->target = toNFCPushTarget(pushOptions.target());
294 else
295 pushOptionsPtr->target = NFCPushTarget::ANY;
296
297 if (pushOptions.hasTimeout())
298 pushOptionsPtr->timeout = pushOptions.timeout();
299 else
300 pushOptionsPtr->timeout = std::numeric_limits<double>::infinity();
301
302 if (pushOptions.hasIgnoreRead())
303 pushOptionsPtr->ignoreRead = pushOptions.ignoreRead();
304 else
305 pushOptionsPtr->ignoreRead = true;
306
307 return pushOptionsPtr;
308 }
309 };
310
311 } // namespace mojo
12 312
13 namespace blink { 313 namespace blink {
14 314
315
316 namespace {
317
318 bool isValidTextRecord(const NFCRecord& record)
319 {
320 v8::Local<v8::Value> value = record.data().v8Value();
321 if (!value->IsString() && !(value->IsNumber() && !std::isnan(value.As<v8::Nu mber>()->Value())))
322 return false;
323
324 if (record.hasMediaType() && !record.mediaType().startsWith(kPlainTextMimePr efix, TextCaseInsensitive))
325 return false;
326
327 return true;
328 }
329
330 bool isValidURLRecord(const NFCRecord& record)
331 {
332 if (!record.data().v8Value()->IsString())
333 return false;
334
335 return isValidTextRecord(record);
336 }
337
338 bool isValidJSONRecord(const NFCRecord& record)
339 {
340 v8::Local<v8::Value> value = record.data().v8Value();
341 if (!value->IsObject() || value->IsArrayBuffer())
342 return false;
343
344 if (record.hasMediaType() && !record.mediaType().startsWith(kJsonMimePrefix, TextCaseInsensitive))
345 return false;
346
347 return true;
348 }
349
350 bool isValidOpaqueRecord(const NFCRecord& record)
351 {
352 return record.data().v8Value()->IsArrayBuffer();
353 }
354
355 bool isValidNFCRecord(const NFCRecord& record)
356 {
357 device::wtf::NFCRecordType type;
358 if (record.hasRecordType()) {
359 type = mojo::toNFCRecordType(record.recordType());
360 } else {
361 type = mojo::deductRecordTypeFromDataType(record);
362
363 // https://w3c.github.io/web-nfc/#creating-web-nfc-message
364 // If NFCRecord.recordType is not set and record type cannot be deducted
365 // from NFCRecord.data, reject promise with SyntaxError.
366 if (type == device::wtf::NFCRecordType::EMPTY)
367 return false;
368 }
369
370 // Non-empty records must have data.
371 if (!record.hasData() && (type != device::wtf::NFCRecordType::EMPTY))
372 return false;
373
374 switch (type) {
375 case device::wtf::NFCRecordType::TEXT:
376 return isValidTextRecord(record);
377 case device::wtf::NFCRecordType::URL:
378 return isValidURLRecord(record);
379 case device::wtf::NFCRecordType::JSON:
380 return isValidJSONRecord(record);
381 case device::wtf::NFCRecordType::OPAQUE_RECORD:
382 return isValidOpaqueRecord(record);
383 case device::wtf::NFCRecordType::EMPTY:
384 return !record.hasData() && record.mediaType().isEmpty();
385 }
386
387 ASSERT_NOT_REACHED();
388 return false;
389 }
390
391 DOMException* isValidNFCRecordArray(const HeapVector<NFCRecord>& records)
392 {
393 // https://w3c.github.io/web-nfc/#the-push-method
394 // If NFCMessage.data is empty, reject promise with SyntaxError
395 if (records.isEmpty())
396 return DOMException::create(SyntaxError);
397
398 for (const auto& record : records) {
399 if (!isValidNFCRecord(record))
400 return DOMException::create(SyntaxError);
401 }
402
403 return nullptr;
404 }
405
406 DOMException* isValidNFCPushMessage(const NFCPushMessage& message)
407 {
408 if (!message.isNFCMessage() && !message.isString() && !message.isArrayBuffer ())
Reilly Grant (use Gerrit) 2016/04/27 23:32:53 I recommend supporting ArrayBufferView in addition
shalamov 2016/04/28 14:16:14 I will talk to Kenneth and Zoltan who are spec aut
409 return DOMException::create(TypeMismatchError);
410
411 if (message.isNFCMessage()) {
412 if (!message.getAsNFCMessage().hasData())
413 return DOMException::create(TypeMismatchError);
414
415 return isValidNFCRecordArray(message.getAsNFCMessage().data());
416 }
417
418 return nullptr;
419 }
420
421 bool setURL(const String& origin, device::wtf::NFCMessagePtr& message)
422 {
423 KURL originURL(ParsedURLString, origin);
424
425 if (!message->url.isEmpty() && originURL.canSetPathname()) {
426 originURL.setPath(message->url);
427 }
428
429 message->url = originURL;
430 return originURL.isValid();
431 }
432
433 } // anonymous namespace
434
15 NFC::NFC(LocalFrame* frame) 435 NFC::NFC(LocalFrame* frame)
16 : LocalFrameLifecycleObserver(frame) 436 : PageLifecycleObserver(frame ? frame->page() : 0),
17 , PageLifecycleObserver(frame ? frame->page() : 0) 437 m_client(this)
18 { 438 {
19 } 439 }
20 440
21 NFC* NFC::create(LocalFrame* frame) 441 NFC* NFC::create(LocalFrame* frame)
22 { 442 {
23 NFC* nfc = new NFC(frame); 443 NFC* nfc = new NFC(frame);
24 return nfc; 444 return nfc;
25 } 445 }
26 446
27 ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& records, const NFCPushOptions& options) 447 NFC::~NFC() = default;
448
449 // https://w3c.github.io/web-nfc/#writing-or-pushing-content
450 ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& pushMess age, const NFCPushOptions& options)
28 { 451 {
29 // TODO(shalamov): To be implemented. 452 String errorMessage;
30 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 453 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) {
454 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage));
455 }
456
457 DOMException* exception = isValidNFCPushMessage(pushMessage);
458 if (exception)
459 return ScriptPromise::rejectWithDOMException(scriptState, exception);
460
461 if (!Initialize(scriptState->domWindow()->frame()->serviceRegistry()))
462 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError));
463
464 device::wtf::NFCMessagePtr message = device::wtf::NFCMessage::From(pushMessa ge);
465 if (!message)
466 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError));
467
468 if (!setURL(scriptState->getExecutionContext()->getSecurityOrigin()->toStrin g(), message))
469 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError));
470
471 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
472 m_requests.add(resolver);
473 auto callback = createBaseCallback(bind<device::wtf::NFCErrorPtr>(&NFC::OnRe questCompleted, this, resolver));
474 m_nfc->Push(std::move(message), device::wtf::NFCPushOptions::From(options), callback);
475
476 return resolver->promise();
31 } 477 }
32 478
33 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target) 479 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target)
34 { 480 {
35 // TODO(shalamov): To be implemented. 481 String errorMessage;
36 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 482 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) {
483 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage));
484 }
485
486 if (!Initialize(scriptState->domWindow()->frame()->serviceRegistry()))
487 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError));
488
489 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
490 m_requests.add(resolver);
491 auto callback = createBaseCallback(bind<device::wtf::NFCErrorPtr>(&NFC::OnRe questCompleted, this, resolver));
492 m_nfc->CancelPush(mojo::toNFCPushTarget(target), callback);
493
494 return resolver->promise();
37 } 495 }
38 496
39 ScriptPromise NFC::watch(ScriptState* scriptState, MessageCallback* callback, co nst NFCWatchOptions& options) 497 ScriptPromise NFC::watch(ScriptState* scriptState, MessageCallback* callback, co nst NFCWatchOptions& options)
40 { 498 {
41 // TODO(shalamov): To be implemented. 499 // TODO(shalamov): To be implemented.
42 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 500 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError));
43 } 501 }
44 502
45 ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id) 503 ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id)
46 { 504 {
47 // TODO(shalamov): To be implemented. 505 // TODO(shalamov): To be implemented.
48 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 506 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError));
49 } 507 }
50 508
51 ScriptPromise NFC::cancelWatch(ScriptState* scriptState) 509 ScriptPromise NFC::cancelWatch(ScriptState* scriptState)
52 { 510 {
53 // TODO(shalamov): To be implemented. 511 // TODO(shalamov): To be implemented.
54 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 512 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError));
55 } 513 }
56 514
57 void NFC::willDetachFrameHost()
58 {
59 // TODO(shalamov): To be implemented.
60 }
61
62 void NFC::pageVisibilityChanged() 515 void NFC::pageVisibilityChanged()
63 { 516 {
64 // TODO(shalamov): To be implemented. When visibility is lost, 517 // If service is not initialized, there cannot be any pending NFC activities
518 if (!m_nfc)
519 return;
520
65 // NFC operations should be suspended. 521 // NFC operations should be suspended.
66 // https://w3c.github.io/web-nfc/#nfc-suspended 522 // https://w3c.github.io/web-nfc/#nfc-suspended
523 if (page()->visibilityState() == PageVisibilityStateVisible)
524 m_nfc->ResumeNFCOperations();
525 else
526 m_nfc->SuspendNFCOperations();
527 }
528
529 void NFC::OnWatch(uint32_t id, device::wtf::NFCMessagePtr message)
530 {
531 }
532
533 bool NFC::Initialize(ServiceRegistry* registry)
534 {
535 DCHECK(registry);
536
537 if (m_nfc)
538 return true;
539
540 registry->connectToRemoteService(mojo::GetProxy(&m_nfc));
541
542 if (m_nfc) {
543 m_nfc.set_connection_error_handler([this]() {
Reilly Grant (use Gerrit) 2016/04/27 23:32:53 Instead of a C++ lambda use WTF::bind to bind to a
shalamov 2016/04/28 14:16:14 Done.
544 // todo(shalamov): clear map that contains nfc watch callbacks
545 if (m_client.is_bound())
546 m_client.Close();
547 m_nfc.reset();
548
549 // If NFCService is not available or disappears when NFC hardware is
550 // disabled, reject promise with NotSupportedError exception.
551 for (ScriptPromiseResolver* resolver : m_requests) {
552 resolver->reject(NFCError::take(resolver, device::wtf::NFCErrorT ype::NOT_SUPPORTED));
553 }
554 });
555 m_nfc->SetClient(m_client.CreateInterfacePtrAndBind());
556 }
557
558 return m_nfc;
559 }
560
561 void NFC::OnRequestCompleted(ScriptPromiseResolver* resolver, device::wtf::NFCEr rorPtr error)
562 {
563 m_requests.remove(resolver);
564 if (error.is_null())
565 resolver->resolve();
566 else
567 resolver->reject(NFCError::take(resolver, error->error_type));
67 } 568 }
68 569
69 DEFINE_TRACE(NFC) 570 DEFINE_TRACE(NFC)
70 { 571 {
71 LocalFrameLifecycleObserver::trace(visitor);
72 PageLifecycleObserver::trace(visitor); 572 PageLifecycleObserver::trace(visitor);
573 visitor->trace(m_requests);
73 } 574 }
74 575
75 } // namespace blink 576 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698