OLD | NEW |
---|---|
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/ScriptPromiseResolver.h" | 7 #include "bindings/core/v8/ScriptPromiseResolver.h" |
8 #include "bindings/core/v8/V8ArrayBuffer.h" | 8 #include "bindings/core/v8/V8ArrayBuffer.h" |
9 #include "bindings/core/v8/V8StringResource.h" | 9 #include "bindings/core/v8/V8StringResource.h" |
10 #include "core/dom/DOMArrayBuffer.h" | 10 #include "core/dom/DOMArrayBuffer.h" |
11 #include "core/dom/DOMException.h" | 11 #include "core/dom/DOMException.h" |
12 #include "core/dom/Document.h" | 12 #include "core/dom/Document.h" |
13 #include "core/dom/ExceptionCode.h" | 13 #include "core/dom/ExceptionCode.h" |
14 #include "core/frame/LocalDOMWindow.h" | 14 #include "core/frame/LocalDOMWindow.h" |
15 #include "modules/nfc/NFCError.h" | 15 #include "modules/nfc/NFCError.h" |
16 #include "modules/nfc/NFCMessage.h" | 16 #include "modules/nfc/NFCMessage.h" |
17 #include "modules/nfc/NFCPushOptions.h" | 17 #include "modules/nfc/NFCPushOptions.h" |
18 #include "modules/nfc/NFCWatchOptions.h" | |
18 #include "platform/mojo/MojoHelper.h" | 19 #include "platform/mojo/MojoHelper.h" |
19 #include "public/platform/InterfaceProvider.h" | 20 #include "public/platform/InterfaceProvider.h" |
20 #include "public/platform/Platform.h" | 21 #include "public/platform/Platform.h" |
21 | 22 |
22 namespace { | 23 namespace { |
23 const char kJsonMimePrefix[] = "application/"; | 24 const char kJsonMimePrefix[] = "application/"; |
24 const char kJsonMimeType[] = "application/json"; | 25 const char kJsonMimeType[] = "application/json"; |
25 const char kOpaqueMimeType[] = "application/octet-stream"; | 26 const char kOpaqueMimeType[] = "application/octet-stream"; |
26 const char kPlainTextMimeType[] = "text/plain"; | 27 const char kPlainTextMimeType[] = "text/plain"; |
27 const char kPlainTextMimePrefix[] = "text/"; | 28 const char kPlainTextMimePrefix[] = "text/"; |
28 const char kCharSetUTF8[] = ";charset=UTF-8"; | 29 const char kCharSetUTF8[] = ";charset=UTF-8"; |
29 } // anonymous namespace | 30 } // anonymous namespace |
30 | 31 |
31 // Mojo type converters | 32 // Mojo type converters |
32 namespace mojo { | 33 namespace mojo { |
33 | 34 |
34 using device::nfc::mojom::blink::NFCMessage; | 35 using device::nfc::mojom::blink::NFCMessage; |
35 using device::nfc::mojom::blink::NFCMessagePtr; | 36 using device::nfc::mojom::blink::NFCMessagePtr; |
36 using device::nfc::mojom::blink::NFCRecord; | 37 using device::nfc::mojom::blink::NFCRecord; |
37 using device::nfc::mojom::blink::NFCRecordPtr; | 38 using device::nfc::mojom::blink::NFCRecordPtr; |
38 using device::nfc::mojom::blink::NFCRecordType; | 39 using device::nfc::mojom::blink::NFCRecordType; |
40 using device::nfc::mojom::blink::NFCRecordTypeFilter; | |
39 using device::nfc::mojom::blink::NFCPushOptions; | 41 using device::nfc::mojom::blink::NFCPushOptions; |
40 using device::nfc::mojom::blink::NFCPushOptionsPtr; | 42 using device::nfc::mojom::blink::NFCPushOptionsPtr; |
41 using device::nfc::mojom::blink::NFCPushTarget; | 43 using device::nfc::mojom::blink::NFCPushTarget; |
44 using device::nfc::mojom::blink::NFCWatchMode; | |
45 using device::nfc::mojom::blink::NFCWatchOptions; | |
46 using device::nfc::mojom::blink::NFCWatchOptionsPtr; | |
42 | 47 |
43 NFCPushTarget toNFCPushTarget(const WTF::String& target) { | 48 NFCPushTarget toNFCPushTarget(const WTF::String& target) { |
44 if (target == "tag") | 49 if (target == "tag") |
45 return NFCPushTarget::TAG; | 50 return NFCPushTarget::TAG; |
46 | 51 |
47 if (target == "peer") | 52 if (target == "peer") |
48 return NFCPushTarget::PEER; | 53 return NFCPushTarget::PEER; |
49 | 54 |
50 return NFCPushTarget::ANY; | 55 return NFCPushTarget::ANY; |
51 } | 56 } |
(...skipping 11 matching lines...) Expand all Loading... | |
63 if (recordType == "json") | 68 if (recordType == "json") |
64 return NFCRecordType::JSON; | 69 return NFCRecordType::JSON; |
65 | 70 |
66 if (recordType == "opaque") | 71 if (recordType == "opaque") |
67 return NFCRecordType::OPAQUE_RECORD; | 72 return NFCRecordType::OPAQUE_RECORD; |
68 | 73 |
69 NOTREACHED(); | 74 NOTREACHED(); |
70 return NFCRecordType::EMPTY; | 75 return NFCRecordType::EMPTY; |
71 } | 76 } |
72 | 77 |
78 NFCWatchMode toNFCWatchMode(const WTF::String& watchMode) { | |
79 if (watchMode == "web-nfc-only") | |
80 return NFCWatchMode::WEBNFC_ONLY; | |
81 | |
82 if (watchMode == "any") | |
83 return NFCWatchMode::ANY; | |
84 | |
85 NOTREACHED(); | |
86 return NFCWatchMode::WEBNFC_ONLY; | |
87 } | |
88 | |
73 // https://w3c.github.io/web-nfc/#creating-web-nfc-message Step 2.1 | 89 // https://w3c.github.io/web-nfc/#creating-web-nfc-message Step 2.1 |
74 // If NFCRecord type is not provided, deduce NFCRecord type from JS data type: | 90 // If NFCRecord type is not provided, deduce NFCRecord type from JS data type: |
75 // String or Number => 'text' record | 91 // String or Number => 'text' record |
76 // ArrayBuffer => 'opaque' record | 92 // ArrayBuffer => 'opaque' record |
77 // JSON serializable Object => 'json' record | 93 // JSON serializable Object => 'json' record |
78 NFCRecordType deduceRecordTypeFromDataType(const blink::NFCRecord& record) { | 94 NFCRecordType deduceRecordTypeFromDataType(const blink::NFCRecord& record) { |
79 if (record.hasData()) { | 95 if (record.hasData()) { |
80 v8::Local<v8::Value> value = record.data().v8Value(); | 96 v8::Local<v8::Value> value = record.data().v8Value(); |
81 | 97 |
82 if (value->IsString() || | 98 if (value->IsString() || |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 | 311 |
296 if (pushOptions.hasIgnoreRead()) | 312 if (pushOptions.hasIgnoreRead()) |
297 pushOptionsPtr->ignore_read = pushOptions.ignoreRead(); | 313 pushOptionsPtr->ignore_read = pushOptions.ignoreRead(); |
298 else | 314 else |
299 pushOptionsPtr->ignore_read = true; | 315 pushOptionsPtr->ignore_read = true; |
300 | 316 |
301 return pushOptionsPtr; | 317 return pushOptionsPtr; |
302 } | 318 } |
303 }; | 319 }; |
304 | 320 |
321 template <> | |
322 struct TypeConverter<NFCWatchOptionsPtr, blink::NFCWatchOptions> { | |
323 static NFCWatchOptionsPtr Convert( | |
324 const blink::NFCWatchOptions& watchOptions) { | |
325 // https://w3c.github.io/web-nfc/#the-nfcwatchoptions-dictionary | |
326 // Default values for NFCWatchOptions dictionary are: | |
327 // url = "", recordType = null, mediaType = "", mode = "web-nfc-only" | |
328 NFCWatchOptionsPtr watchOptionsPtr = NFCWatchOptions::New(); | |
329 watchOptionsPtr->url = watchOptions.url(); | |
330 watchOptionsPtr->media_type = watchOptions.mediaType(); | |
331 | |
332 if (watchOptions.hasMode()) | |
333 watchOptionsPtr->mode = toNFCWatchMode(watchOptions.mode()); | |
334 else | |
335 watchOptionsPtr->mode = NFCWatchMode::WEBNFC_ONLY; | |
336 | |
337 if (watchOptions.hasRecordType()) { | |
338 watchOptionsPtr->record_filter = NFCRecordTypeFilter::New(); | |
339 watchOptionsPtr->record_filter->record_type = | |
340 toNFCRecordType(watchOptions.recordType()); | |
341 } | |
342 | |
343 return watchOptionsPtr; | |
344 } | |
345 }; | |
346 | |
305 } // namespace mojo | 347 } // namespace mojo |
306 | 348 |
307 namespace blink { | 349 namespace blink { |
308 namespace { | 350 namespace { |
309 | 351 |
310 bool isValidTextRecord(const NFCRecord& record) { | 352 bool isValidTextRecord(const NFCRecord& record) { |
311 v8::Local<v8::Value> value = record.data().v8Value(); | 353 v8::Local<v8::Value> value = record.data().v8Value(); |
312 if (!value->IsString() && | 354 if (!value->IsString() && |
313 !(value->IsNumber() && !std::isnan(value.As<v8::Number>()->Value()))) | 355 !(value->IsNumber() && !std::isnan(value.As<v8::Number>()->Value()))) |
314 return false; | 356 return false; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
419 KURL originURL(ParsedURLString, origin); | 461 KURL originURL(ParsedURLString, origin); |
420 | 462 |
421 if (!message->url.isEmpty() && originURL.canSetPathname()) { | 463 if (!message->url.isEmpty() && originURL.canSetPathname()) { |
422 originURL.setPath(message->url); | 464 originURL.setPath(message->url); |
423 } | 465 } |
424 | 466 |
425 message->url = originURL; | 467 message->url = originURL; |
426 return originURL.isValid(); | 468 return originURL.isValid(); |
427 } | 469 } |
428 | 470 |
471 String toNFCRecordType(const device::nfc::mojom::blink::NFCRecordType& type) { | |
472 switch (type) { | |
473 case device::nfc::mojom::blink::NFCRecordType::TEXT: | |
474 return "text"; | |
475 case device::nfc::mojom::blink::NFCRecordType::URL: | |
476 return "url"; | |
477 case device::nfc::mojom::blink::NFCRecordType::JSON: | |
478 return "json"; | |
479 case device::nfc::mojom::blink::NFCRecordType::OPAQUE_RECORD: | |
480 return "opaque"; | |
481 case device::nfc::mojom::blink::NFCRecordType::EMPTY: | |
482 return "empty"; | |
483 } | |
484 | |
485 NOTREACHED(); | |
486 return String(); | |
487 } | |
488 | |
489 v8::Local<v8::Value> toV8(const device::nfc::mojom::blink::NFCRecordPtr& record, | |
490 ScriptState* scriptState) { | |
haraken
2016/11/23 13:35:15
Move ScriptState to the first parameter.
shalamov
2016/11/23 14:58:38
Done.
| |
491 switch (record->record_type) { | |
492 case device::nfc::mojom::blink::NFCRecordType::TEXT: | |
493 case device::nfc::mojom::blink::NFCRecordType::URL: | |
494 case device::nfc::mojom::blink::NFCRecordType::JSON: { | |
495 String stringData; | |
496 if (!record->data.isEmpty()) { | |
497 stringData = String::fromUTF8WithLatin1Fallback( | |
498 static_cast<unsigned char*>(&record->data.first()), | |
499 record->data.size()); | |
500 } | |
501 | |
502 if (record->record_type == | |
503 device::nfc::mojom::blink::NFCRecordType::JSON) { | |
504 return v8::JSON::Parse(scriptState->isolate(), | |
505 v8String(scriptState->isolate(), stringData)) | |
506 .ToLocalChecked(); | |
haraken
2016/11/23 13:35:15
Is it guaranteed that the stringData has a valid J
shalamov
2016/11/23 14:58:38
Done.
| |
507 } | |
508 | |
509 return v8String(scriptState->isolate(), stringData); | |
510 } | |
511 | |
512 case device::nfc::mojom::blink::NFCRecordType::OPAQUE_RECORD: { | |
513 if (!record->data.isEmpty()) { | |
514 DOMArrayBuffer* buffer = DOMArrayBuffer::create( | |
515 static_cast<void*>(&record->data.first()), record->data.size()); | |
516 return toV8(buffer, scriptState->context()->Global(), | |
517 scriptState->isolate()); | |
518 } | |
519 | |
520 return v8::Null(scriptState->isolate()); | |
521 } | |
522 | |
523 case device::nfc::mojom::blink::NFCRecordType::EMPTY: | |
524 return v8::Null(scriptState->isolate()); | |
525 } | |
526 | |
527 NOTREACHED(); | |
528 return v8::Local<v8::Value>(); | |
529 } | |
530 | |
531 NFCRecord toNFCRecord(const device::nfc::mojom::blink::NFCRecordPtr& record, | |
532 ScriptState* scriptState) { | |
haraken
2016/11/23 13:35:15
Ditto.
shalamov
2016/11/23 14:58:38
Done.
| |
533 NFCRecord nfcRecord; | |
534 nfcRecord.setMediaType(record->media_type); | |
535 nfcRecord.setRecordType(toNFCRecordType(record->record_type)); | |
536 nfcRecord.setData(ScriptValue(scriptState, toV8(record, scriptState))); | |
537 return nfcRecord; | |
538 } | |
539 | |
540 NFCMessage toNFCMessage(const device::nfc::mojom::blink::NFCMessagePtr& message, | |
541 ScriptState* scriptState) { | |
haraken
2016/11/23 13:35:15
Ditto.
shalamov
2016/11/23 14:58:38
Done.
| |
542 NFCMessage nfcMessage; | |
543 nfcMessage.setURL(message->url); | |
544 blink::HeapVector<NFCRecord> records; | |
545 for (size_t i = 0; i < message->data.size(); ++i) | |
546 records.append(toNFCRecord(message->data[i], scriptState)); | |
547 nfcMessage.setData(records); | |
548 return nfcMessage; | |
549 } | |
550 | |
429 size_t getNFCMessageSize( | 551 size_t getNFCMessageSize( |
430 const device::nfc::mojom::blink::NFCMessagePtr& message) { | 552 const device::nfc::mojom::blink::NFCMessagePtr& message) { |
431 size_t messageSize = message->url.charactersSizeInBytes(); | 553 size_t messageSize = message->url.charactersSizeInBytes(); |
432 for (size_t i = 0; i < message->data.size(); ++i) { | 554 for (size_t i = 0; i < message->data.size(); ++i) { |
433 messageSize += message->data[i]->media_type.charactersSizeInBytes(); | 555 messageSize += message->data[i]->media_type.charactersSizeInBytes(); |
434 messageSize += message->data[i]->data.size(); | 556 messageSize += message->data[i]->data.size(); |
435 } | 557 } |
436 return messageSize; | 558 return messageSize; |
437 } | 559 } |
438 | 560 |
(...skipping 21 matching lines...) Expand all Loading... | |
460 DCHECK(m_requests.isEmpty()); | 582 DCHECK(m_requests.isEmpty()); |
461 } | 583 } |
462 | 584 |
463 void NFC::dispose() { | 585 void NFC::dispose() { |
464 m_client.Close(); | 586 m_client.Close(); |
465 } | 587 } |
466 | 588 |
467 void NFC::contextDestroyed() { | 589 void NFC::contextDestroyed() { |
468 m_nfc.reset(); | 590 m_nfc.reset(); |
469 m_requests.clear(); | 591 m_requests.clear(); |
592 m_callbacks.clear(); | |
470 } | 593 } |
471 | 594 |
472 // https://w3c.github.io/web-nfc/#writing-or-pushing-content | 595 // https://w3c.github.io/web-nfc/#writing-or-pushing-content |
596 // https://w3c.github.io/web-nfc/#dom-nfc-push | |
473 ScriptPromise NFC::push(ScriptState* scriptState, | 597 ScriptPromise NFC::push(ScriptState* scriptState, |
474 const NFCPushMessage& pushMessage, | 598 const NFCPushMessage& pushMessage, |
475 const NFCPushOptions& options) { | 599 const NFCPushOptions& options) { |
476 String errorMessage; | 600 ScriptPromise promise = rejectIfNotSupported(scriptState); |
477 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) | 601 if (!promise.isEmpty()) |
478 return ScriptPromise::rejectWithDOMException( | 602 return promise; |
479 scriptState, DOMException::create(SecurityError, errorMessage)); | |
480 | 603 |
481 DOMException* exception = isValidNFCPushMessage(pushMessage); | 604 DOMException* exception = isValidNFCPushMessage(pushMessage); |
482 if (exception) | 605 if (exception) |
483 return ScriptPromise::rejectWithDOMException(scriptState, exception); | 606 return ScriptPromise::rejectWithDOMException(scriptState, exception); |
484 | 607 |
485 if (!m_nfc) | |
486 return ScriptPromise::rejectWithDOMException( | |
487 scriptState, DOMException::create(NotSupportedError)); | |
488 | |
489 device::nfc::mojom::blink::NFCMessagePtr message = | 608 device::nfc::mojom::blink::NFCMessagePtr message = |
490 device::nfc::mojom::blink::NFCMessage::From(pushMessage); | 609 device::nfc::mojom::blink::NFCMessage::From(pushMessage); |
491 if (!message) | 610 if (!message) |
492 return ScriptPromise::rejectWithDOMException( | 611 return ScriptPromise::rejectWithDOMException( |
493 scriptState, DOMException::create(SyntaxError)); | 612 scriptState, DOMException::create(SyntaxError)); |
494 | 613 |
495 if (!setURL( | 614 if (!setURL( |
496 scriptState->getExecutionContext()->getSecurityOrigin()->toString(), | 615 scriptState->getExecutionContext()->getSecurityOrigin()->toString(), |
497 message)) | 616 message)) |
498 return ScriptPromise::rejectWithDOMException( | 617 return ScriptPromise::rejectWithDOMException( |
(...skipping 10 matching lines...) Expand all Loading... | |
509 auto callback = convertToBaseCallback(WTF::bind(&NFC::OnRequestCompleted, | 628 auto callback = convertToBaseCallback(WTF::bind(&NFC::OnRequestCompleted, |
510 wrapPersistent(this), | 629 wrapPersistent(this), |
511 wrapPersistent(resolver))); | 630 wrapPersistent(resolver))); |
512 m_nfc->Push(std::move(message), | 631 m_nfc->Push(std::move(message), |
513 device::nfc::mojom::blink::NFCPushOptions::From(options), | 632 device::nfc::mojom::blink::NFCPushOptions::From(options), |
514 callback); | 633 callback); |
515 | 634 |
516 return resolver->promise(); | 635 return resolver->promise(); |
517 } | 636 } |
518 | 637 |
638 // https://w3c.github.io/web-nfc/#dom-nfc-cancelpush | |
519 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target) { | 639 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target) { |
520 String errorMessage; | 640 ScriptPromise promise = rejectIfNotSupported(scriptState); |
521 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) | 641 if (!promise.isEmpty()) |
522 return ScriptPromise::rejectWithDOMException( | 642 return promise; |
523 scriptState, DOMException::create(SecurityError, errorMessage)); | |
524 | |
525 if (!m_nfc) | |
526 return ScriptPromise::rejectWithDOMException( | |
527 scriptState, DOMException::create(NotSupportedError)); | |
528 | 643 |
529 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 644 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
530 m_requests.add(resolver); | 645 m_requests.add(resolver); |
531 auto callback = convertToBaseCallback(WTF::bind(&NFC::OnRequestCompleted, | 646 auto callback = convertToBaseCallback(WTF::bind(&NFC::OnRequestCompleted, |
532 wrapPersistent(this), | 647 wrapPersistent(this), |
533 wrapPersistent(resolver))); | 648 wrapPersistent(resolver))); |
534 m_nfc->CancelPush(mojo::toNFCPushTarget(target), callback); | 649 m_nfc->CancelPush(mojo::toNFCPushTarget(target), callback); |
535 | 650 |
536 return resolver->promise(); | 651 return resolver->promise(); |
537 } | 652 } |
538 | 653 |
654 // https://w3c.github.io/web-nfc/#watching-for-content | |
655 // https://w3c.github.io/web-nfc/#dom-nfc-watch | |
539 ScriptPromise NFC::watch(ScriptState* scriptState, | 656 ScriptPromise NFC::watch(ScriptState* scriptState, |
540 MessageCallback* callback, | 657 MessageCallback* callback, |
541 const NFCWatchOptions& options) { | 658 const NFCWatchOptions& options) { |
542 // TODO(shalamov): To be implemented. | 659 ScriptPromise promise = rejectIfNotSupported(scriptState); |
543 return ScriptPromise::rejectWithDOMException( | 660 if (!promise.isEmpty()) |
544 scriptState, DOMException::create(NotSupportedError)); | 661 return promise; |
662 | |
663 callback->setScriptState(scriptState); | |
664 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | |
665 m_requests.add(resolver); | |
666 auto watchCallback = convertToBaseCallback( | |
667 WTF::bind(&NFC::OnWatchRegistered, wrapPersistent(this), | |
668 wrapPersistent(callback), wrapPersistent(resolver))); | |
669 m_nfc->Watch(device::nfc::mojom::blink::NFCWatchOptions::From(options), | |
670 watchCallback); | |
671 return resolver->promise(); | |
545 } | 672 } |
546 | 673 |
674 // https://w3c.github.io/web-nfc/#dom-nfc-cancelwatch | |
547 ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id) { | 675 ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id) { |
548 // TODO(shalamov): To be implemented. | 676 ScriptPromise promise = rejectIfNotSupported(scriptState); |
549 return ScriptPromise::rejectWithDOMException( | 677 if (!promise.isEmpty()) |
550 scriptState, DOMException::create(NotSupportedError)); | 678 return promise; |
679 | |
680 if (id) { | |
681 m_callbacks.remove(id); | |
682 } else { | |
683 return ScriptPromise::rejectWithDOMException( | |
684 scriptState, DOMException::create(NotFoundError)); | |
685 } | |
686 | |
687 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | |
688 m_requests.add(resolver); | |
689 m_nfc->CancelWatch(id, convertToBaseCallback(WTF::bind( | |
690 &NFC::OnRequestCompleted, wrapPersistent(this), | |
691 wrapPersistent(resolver)))); | |
692 return resolver->promise(); | |
551 } | 693 } |
552 | 694 |
695 // https://w3c.github.io/web-nfc/#dom-nfc-cancelwatch | |
696 // If watchId is not provided to nfc.cancelWatch, cancel all watch operations. | |
553 ScriptPromise NFC::cancelWatch(ScriptState* scriptState) { | 697 ScriptPromise NFC::cancelWatch(ScriptState* scriptState) { |
554 // TODO(shalamov): To be implemented. | 698 ScriptPromise promise = rejectIfNotSupported(scriptState); |
555 return ScriptPromise::rejectWithDOMException( | 699 if (!promise.isEmpty()) |
556 scriptState, DOMException::create(NotSupportedError)); | 700 return promise; |
701 | |
702 m_callbacks.clear(); | |
703 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | |
704 m_requests.add(resolver); | |
705 m_nfc->CancelAllWatches(convertToBaseCallback( | |
706 WTF::bind(&NFC::OnRequestCompleted, wrapPersistent(this), | |
707 wrapPersistent(resolver)))); | |
708 return resolver->promise(); | |
557 } | 709 } |
558 | 710 |
559 void NFC::pageVisibilityChanged() { | 711 void NFC::pageVisibilityChanged() { |
560 // If service is not initialized, there cannot be any pending NFC activities | 712 // If service is not initialized, there cannot be any pending NFC activities |
561 if (!m_nfc) | 713 if (!m_nfc) |
562 return; | 714 return; |
563 | 715 |
564 // NFC operations should be suspended. | 716 // NFC operations should be suspended. |
565 // https://w3c.github.io/web-nfc/#nfc-suspended | 717 // https://w3c.github.io/web-nfc/#nfc-suspended |
566 if (page()->visibilityState() == PageVisibilityStateVisible) | 718 if (page()->visibilityState() == PageVisibilityStateVisible) |
(...skipping 14 matching lines...) Expand all Loading... | |
581 resolver->reject(NFCError::take(resolver, error->error_type)); | 733 resolver->reject(NFCError::take(resolver, error->error_type)); |
582 } | 734 } |
583 | 735 |
584 void NFC::OnConnectionError() { | 736 void NFC::OnConnectionError() { |
585 if (!Platform::current()) { | 737 if (!Platform::current()) { |
586 // TODO(rockot): Clean this up once renderer shutdown sequence is fixed. | 738 // TODO(rockot): Clean this up once renderer shutdown sequence is fixed. |
587 return; | 739 return; |
588 } | 740 } |
589 | 741 |
590 m_nfc.reset(); | 742 m_nfc.reset(); |
743 m_callbacks.clear(); | |
591 | 744 |
592 // If NFCService is not available or disappears when NFC hardware is | 745 // If NFCService is not available or disappears when NFC hardware is |
593 // disabled, reject promise with NotSupportedError exception. | 746 // disabled, reject promise with NotSupportedError exception. |
594 for (ScriptPromiseResolver* resolver : m_requests) { | 747 for (ScriptPromiseResolver* resolver : m_requests) |
595 resolver->reject(NFCError::take( | 748 resolver->reject(NFCError::take( |
596 resolver, device::nfc::mojom::blink::NFCErrorType::NOT_SUPPORTED)); | 749 resolver, device::nfc::mojom::blink::NFCErrorType::NOT_SUPPORTED)); |
597 } | |
598 | 750 |
599 m_requests.clear(); | 751 m_requests.clear(); |
600 } | 752 } |
601 | 753 |
602 void NFC::OnWatch(const WTF::Vector<uint32_t>& ids, | 754 void NFC::OnWatch(const WTF::Vector<uint32_t>& ids, |
603 device::nfc::mojom::blink::NFCMessagePtr) { | 755 device::nfc::mojom::blink::NFCMessagePtr message) { |
604 // TODO(shalamov): Not implemented. | 756 for (const auto& id : ids) { |
757 auto it = m_callbacks.find(id); | |
758 if (it != m_callbacks.end()) { | |
759 MessageCallback* callback = it->value; | |
760 ScriptState* scriptState = callback->getScriptState(); | |
761 if (!scriptState || !scriptState->contextIsValid()) | |
haraken
2016/11/23 13:35:15
DCHECK(!scriptState). scriptState should not be nu
shalamov
2016/11/23 14:58:38
Done.
| |
762 continue; | |
763 | |
764 ScriptState::Scope scope(scriptState); | |
765 NFCMessage nfcMessage = toNFCMessage(message, scriptState); | |
766 callback->handleMessage(nfcMessage); | |
767 } | |
768 } | |
769 } | |
770 | |
771 ScriptPromise NFC::rejectIfNotSupported(ScriptState* scriptState) { | |
772 String errorMessage; | |
773 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { | |
774 return ScriptPromise::rejectWithDOMException( | |
775 scriptState, DOMException::create(SecurityError, errorMessage)); | |
776 } | |
777 | |
778 if (!m_nfc) { | |
779 return ScriptPromise::rejectWithDOMException( | |
780 scriptState, DOMException::create(NotSupportedError)); | |
781 } | |
782 | |
783 return ScriptPromise(); | |
784 } | |
785 | |
786 void NFC::OnWatchRegistered(MessageCallback* callback, | |
787 ScriptPromiseResolver* resolver, | |
788 uint32_t id, | |
789 device::nfc::mojom::blink::NFCErrorPtr error) { | |
790 m_requests.remove(resolver); | |
791 | |
792 // Invalid id was returned. | |
793 // https://w3c.github.io/web-nfc/#dom-nfc-watch | |
794 // 8. If the request fails, reject promise with "NotSupportedError" | |
795 // and abort these steps. | |
796 if (!id) { | |
797 resolver->reject(NFCError::take( | |
798 resolver, device::nfc::mojom::blink::NFCErrorType::NOT_SUPPORTED)); | |
799 return; | |
800 } | |
801 | |
802 if (error.is_null()) { | |
803 m_callbacks.add(id, callback); | |
804 resolver->resolve(id); | |
805 } else { | |
806 resolver->reject(NFCError::take(resolver, error->error_type)); | |
807 } | |
605 } | 808 } |
606 | 809 |
607 DEFINE_TRACE(NFC) { | 810 DEFINE_TRACE(NFC) { |
608 PageVisibilityObserver::trace(visitor); | 811 PageVisibilityObserver::trace(visitor); |
609 ContextLifecycleObserver::trace(visitor); | 812 ContextLifecycleObserver::trace(visitor); |
610 visitor->trace(m_requests); | 813 visitor->trace(m_requests); |
814 visitor->trace(m_callbacks); | |
611 } | 815 } |
612 | 816 |
613 } // namespace blink | 817 } // namespace blink |
OLD | NEW |