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/JSONValuesForV8.h" | 7 #include "bindings/core/v8/JSONValuesForV8.h" |
8 #include "bindings/core/v8/ScriptPromiseResolver.h" | 8 #include "bindings/core/v8/ScriptPromiseResolver.h" |
9 #include "bindings/core/v8/V8ArrayBuffer.h" | 9 #include "bindings/core/v8/V8ArrayBuffer.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 | 21 |
21 namespace nfc = device::nfc::blink; | 22 namespace nfc = device::nfc::blink; |
22 | 23 |
23 namespace { | 24 namespace { |
24 const char kJsonMimePrefix[] = "application/"; | 25 const char kJsonMimePrefix[] = "application/"; |
25 const char kJsonMimeType[] = "application/json"; | 26 const char kJsonMimeType[] = "application/json"; |
26 const char kOpaqueMimeType[] = "application/octet-stream"; | 27 const char kOpaqueMimeType[] = "application/octet-stream"; |
27 const char kPlainTextMimeType[] = "text/plain"; | 28 const char kPlainTextMimeType[] = "text/plain"; |
28 const char kPlainTextMimePrefix[] = "text/"; | 29 const char kPlainTextMimePrefix[] = "text/"; |
29 const char kCharSetUTF8[] = ";charset=UTF-8"; | 30 const char kCharSetUTF8[] = ";charset=UTF-8"; |
30 } // anonymous namespace | 31 } // anonymous namespace |
31 | 32 |
32 // Mojo type converters | 33 // Mojo type converters |
33 namespace mojo { | 34 namespace mojo { |
34 | 35 |
35 using nfc::NFCMessage; | 36 using nfc::NFCMessage; |
36 using nfc::NFCMessagePtr; | 37 using nfc::NFCMessagePtr; |
37 using nfc::NFCRecord; | 38 using nfc::NFCRecord; |
38 using nfc::NFCRecordPtr; | 39 using nfc::NFCRecordPtr; |
39 using nfc::NFCRecordType; | 40 using nfc::NFCRecordType; |
41 using nfc::NFCRecordTypeFilter; | |
42 using nfc::NFCRecordTypeFilterPtr; | |
40 using nfc::NFCPushOptions; | 43 using nfc::NFCPushOptions; |
41 using nfc::NFCPushOptionsPtr; | 44 using nfc::NFCPushOptionsPtr; |
42 using nfc::NFCPushTarget; | 45 using nfc::NFCPushTarget; |
46 using nfc::NFCWatchMode; | |
47 using nfc::NFCWatchOptions; | |
48 using nfc::NFCWatchOptionsPtr; | |
43 | 49 |
44 NFCPushTarget toNFCPushTarget(const WTF::String& target) | 50 NFCPushTarget toNFCPushTarget(const WTF::String& target) |
45 { | 51 { |
46 if (target == "tag") | 52 if (target == "tag") |
47 return NFCPushTarget::TAG; | 53 return NFCPushTarget::TAG; |
48 | 54 |
49 if (target == "peer") | 55 if (target == "peer") |
50 return NFCPushTarget::PEER; | 56 return NFCPushTarget::PEER; |
51 | 57 |
52 return NFCPushTarget::ANY; | 58 return NFCPushTarget::ANY; |
(...skipping 13 matching lines...) Expand all Loading... | |
66 if (recordType == "json") | 72 if (recordType == "json") |
67 return NFCRecordType::JSON; | 73 return NFCRecordType::JSON; |
68 | 74 |
69 if (recordType == "opaque") | 75 if (recordType == "opaque") |
70 return NFCRecordType::OPAQUE_RECORD; | 76 return NFCRecordType::OPAQUE_RECORD; |
71 | 77 |
72 NOTREACHED(); | 78 NOTREACHED(); |
73 return NFCRecordType::EMPTY; | 79 return NFCRecordType::EMPTY; |
74 } | 80 } |
75 | 81 |
82 NFCWatchMode toNFCWatchMode(const WTF::String& watchMode) | |
83 { | |
84 if (watchMode == "web-nfc-only") | |
85 return NFCWatchMode::WEBNFC_ONLY; | |
86 | |
87 if (watchMode == "any") | |
88 return NFCWatchMode::ANY; | |
89 | |
90 NOTREACHED(); | |
91 return NFCWatchMode::WEBNFC_ONLY; | |
92 } | |
93 | |
76 // https://w3c.github.io/web-nfc/#creating-web-nfc-message Step 2.1 | 94 // https://w3c.github.io/web-nfc/#creating-web-nfc-message Step 2.1 |
77 // If NFCRecord type is not provided, deduce NFCRecord type from JS data type: | 95 // If NFCRecord type is not provided, deduce NFCRecord type from JS data type: |
78 // String or Number => 'text' record | 96 // String or Number => 'text' record |
79 // ArrayBuffer => 'opaque' record | 97 // ArrayBuffer => 'opaque' record |
80 // JSON serializable Object => 'json' record | 98 // JSON serializable Object => 'json' record |
81 NFCRecordType deduceRecordTypeFromDataType(const blink::NFCRecord& record) | 99 NFCRecordType deduceRecordTypeFromDataType(const blink::NFCRecord& record) |
82 { | 100 { |
83 if (record.hasData()) { | 101 if (record.hasData()) { |
84 v8::Local<v8::Value> value = record.data().v8Value(); | 102 v8::Local<v8::Value> value = record.data().v8Value(); |
85 | 103 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
304 | 322 |
305 if (pushOptions.hasIgnoreRead()) | 323 if (pushOptions.hasIgnoreRead()) |
306 pushOptionsPtr->ignore_read = pushOptions.ignoreRead(); | 324 pushOptionsPtr->ignore_read = pushOptions.ignoreRead(); |
307 else | 325 else |
308 pushOptionsPtr->ignore_read = true; | 326 pushOptionsPtr->ignore_read = true; |
309 | 327 |
310 return pushOptionsPtr; | 328 return pushOptionsPtr; |
311 } | 329 } |
312 }; | 330 }; |
313 | 331 |
332 template <> | |
333 struct TypeConverter<NFCWatchOptionsPtr, blink::NFCWatchOptions> { | |
334 static NFCWatchOptionsPtr Convert(const blink::NFCWatchOptions& watchOptions ) | |
335 { | |
336 // https://w3c.github.io/web-nfc/#the-nfcwatchoptions-dictionary | |
337 // Default values for NFCWatchOptions dictionary are: | |
338 // url = "", recordType = null, mediaType = "", mode = "web-nfc-only" | |
339 NFCWatchOptionsPtr watchOptionsPtr = NFCWatchOptions::New(); | |
340 watchOptionsPtr->url = watchOptions.url(); | |
341 watchOptionsPtr->media_type = watchOptions.mediaType(); | |
342 | |
343 if (watchOptions.hasMode()) | |
344 watchOptionsPtr->mode = toNFCWatchMode(watchOptions.mode()); | |
345 else | |
346 watchOptionsPtr->mode = NFCWatchMode::WEBNFC_ONLY; | |
347 | |
348 if (watchOptions.hasRecordType()) { | |
349 watchOptionsPtr->record_filter = NFCRecordTypeFilter::New(); | |
350 watchOptionsPtr->record_filter->record_type = toNFCRecordType(watchO ptions.recordType()); | |
351 } | |
352 | |
353 return watchOptionsPtr; | |
dcheng
2016/09/08 04:42:38
Please use a typemap instead (see https://www.chro
shalamov
2016/09/22 13:53:22
I don't think blink generated bindings <=> mojo ty
| |
354 } | |
355 }; | |
356 | |
314 } // namespace mojo | 357 } // namespace mojo |
315 | 358 |
316 namespace blink { | 359 namespace blink { |
317 namespace { | 360 namespace { |
318 | 361 |
319 bool isValidTextRecord(const NFCRecord& record) | 362 bool isValidTextRecord(const NFCRecord& record) |
320 { | 363 { |
321 v8::Local<v8::Value> value = record.data().v8Value(); | 364 v8::Local<v8::Value> value = record.data().v8Value(); |
322 if (!value->IsString() && !(value->IsNumber() && !std::isnan(value.As<v8::Nu mber>()->Value()))) | 365 if (!value->IsString() && !(value->IsNumber() && !std::isnan(value.As<v8::Nu mber>()->Value()))) |
323 return false; | 366 return false; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
428 KURL originURL(ParsedURLString, origin); | 471 KURL originURL(ParsedURLString, origin); |
429 | 472 |
430 if (!message->url.isEmpty() && originURL.canSetPathname()) { | 473 if (!message->url.isEmpty() && originURL.canSetPathname()) { |
431 originURL.setPath(message->url); | 474 originURL.setPath(message->url); |
432 } | 475 } |
433 | 476 |
434 message->url = originURL; | 477 message->url = originURL; |
435 return originURL.isValid(); | 478 return originURL.isValid(); |
436 } | 479 } |
437 | 480 |
481 String toNFCRecordType(const nfc::NFCRecordType& type) | |
482 { | |
483 switch (type) { | |
484 case nfc::NFCRecordType::TEXT: | |
485 return "text"; | |
486 case nfc::NFCRecordType::URL: | |
487 return "url"; | |
488 case nfc::NFCRecordType::JSON: | |
489 return "json"; | |
490 case nfc::NFCRecordType::OPAQUE_RECORD: | |
491 return "opaque"; | |
492 case nfc::NFCRecordType::EMPTY: | |
493 return "empty"; | |
494 } | |
495 | |
496 NOTREACHED(); | |
497 return String(); | |
498 } | |
499 | |
500 v8::Local<v8::Value> toV8(const nfc::NFCRecordPtr& record, ScriptState* scriptSt ate) | |
dcheng
2016/09/08 04:42:38
Why do we need to do this manually? I would expect
shalamov
2016/09/22 13:53:22
NFCRecord is a kind of container Type,Mime,Data. V
| |
501 { | |
502 switch (record->record_type) { | |
503 case nfc::NFCRecordType::TEXT: | |
504 case nfc::NFCRecordType::URL: | |
505 case nfc::NFCRecordType::JSON: { | |
506 String stringData; | |
507 if (!record->data.empty()) | |
508 stringData = String::fromUTF8WithLatin1Fallback(static_cast<unsigned char*>(&record->data.front()), record->data.size()); | |
509 | |
510 if (record->record_type == nfc::NFCRecordType::JSON) | |
511 return v8::JSON::Parse(scriptState->isolate(), v8String(scriptState- >isolate(), stringData)).ToLocalChecked(); | |
512 return v8String(scriptState->isolate(), stringData); | |
513 } | |
514 | |
515 case nfc::NFCRecordType::OPAQUE_RECORD: { | |
516 if (!record->data.empty()) { | |
517 DOMArrayBuffer* buffer = DOMArrayBuffer::create(static_cast<void*>(& record->data.front()), record->data.size()); | |
518 return toV8(buffer, scriptState->context()->Global(), scriptState->i solate()); | |
519 } | |
520 | |
521 return v8::Null(scriptState->isolate()); | |
522 } | |
523 | |
524 case nfc::NFCRecordType::EMPTY: | |
525 return v8::Null(scriptState->isolate()); | |
526 } | |
527 | |
528 NOTREACHED(); | |
529 return v8::Local<v8::Value>(); | |
530 } | |
531 | |
532 NFCRecord toNFCRecord(const nfc::NFCRecordPtr& record, ScriptState* scriptState) | |
533 { | |
534 NFCRecord nfcRecord; | |
535 nfcRecord.setMediaType(record->media_type); | |
536 nfcRecord.setRecordType(toNFCRecordType(record->record_type)); | |
537 nfcRecord.setData(ScriptValue(scriptState, toV8(record, scriptState))); | |
538 return nfcRecord; | |
539 } | |
540 | |
541 NFCMessage toNFCMessage(const nfc::NFCMessagePtr& message, ScriptState* scriptSt ate) | |
542 { | |
543 NFCMessage nfcMessage; | |
544 nfcMessage.setURL(message->url); | |
545 blink::HeapVector<NFCRecord> records; | |
546 for (size_t i = 0; i < message->data.size(); ++i) | |
547 records.append(toNFCRecord(message->data[i], scriptState)); | |
548 nfcMessage.setData(records); | |
549 return nfcMessage; | |
550 } | |
551 | |
552 size_t getNFCMessageSize(const nfc::NFCMessagePtr& message) | |
553 { | |
554 size_t messageSize = message->url.charactersSizeInBytes(); | |
555 for (size_t i = 0; i < message->data.size(); ++i) { | |
556 messageSize += message->data[i]->media_type.charactersSizeInBytes(); | |
557 messageSize += message->data[i]->data.size(); | |
558 } | |
559 return messageSize; | |
560 } | |
561 | |
438 } // anonymous namespace | 562 } // anonymous namespace |
439 | 563 |
440 NFC::NFC(LocalFrame* frame) | 564 NFC::NFC(LocalFrame* frame) |
441 : PageVisibilityObserver(frame->page()) | 565 : PageVisibilityObserver(frame->page()) |
442 , ContextLifecycleObserver(frame->document()) | 566 , ContextLifecycleObserver(frame->document()) |
443 , m_client(this) | 567 , m_client(this) |
444 { | 568 { |
445 ThreadState::current()->registerPreFinalizer(this); | 569 ThreadState::current()->registerPreFinalizer(this); |
446 frame->interfaceProvider()->getInterface(mojo::GetProxy(&m_nfc)); | 570 frame->interfaceProvider()->getInterface(mojo::GetProxy(&m_nfc)); |
447 m_nfc.set_connection_error_handler(convertToBaseCallback(WTF::bind(&NFC::OnC onnectionError, wrapWeakPersistent(this)))); | 571 m_nfc.set_connection_error_handler(convertToBaseCallback(WTF::bind(&NFC::OnC onnectionError, wrapWeakPersistent(this)))); |
(...skipping 15 matching lines...) Expand all Loading... | |
463 | 587 |
464 void NFC::dispose() | 588 void NFC::dispose() |
465 { | 589 { |
466 m_client.Close(); | 590 m_client.Close(); |
467 } | 591 } |
468 | 592 |
469 void NFC::contextDestroyed() | 593 void NFC::contextDestroyed() |
470 { | 594 { |
471 m_nfc.reset(); | 595 m_nfc.reset(); |
472 m_requests.clear(); | 596 m_requests.clear(); |
597 m_callbacks.clear(); | |
473 } | 598 } |
474 | 599 |
475 // https://w3c.github.io/web-nfc/#writing-or-pushing-content | 600 // https://w3c.github.io/web-nfc/#writing-or-pushing-content |
601 // https://w3c.github.io/web-nfc/#dom-nfc-push | |
476 ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& pushMess age, const NFCPushOptions& options) | 602 ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& pushMess age, const NFCPushOptions& options) |
477 { | 603 { |
478 String errorMessage; | 604 ScriptPromise promise = RejectIfNotSupported(scriptState); |
479 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) | 605 if (!promise.isEmpty()) |
480 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage)); | 606 return promise; |
481 | 607 |
482 DOMException* exception = isValidNFCPushMessage(pushMessage); | 608 DOMException* exception = isValidNFCPushMessage(pushMessage); |
483 if (exception) | 609 if (exception) |
484 return ScriptPromise::rejectWithDOMException(scriptState, exception); | 610 return ScriptPromise::rejectWithDOMException(scriptState, exception); |
485 | 611 |
486 if (!m_nfc) | |
487 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError)); | |
488 | |
489 nfc::NFCMessagePtr message = nfc::NFCMessage::From(pushMessage); | 612 nfc::NFCMessagePtr message = nfc::NFCMessage::From(pushMessage); |
490 if (!message) | 613 if (!message) |
491 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError)); | 614 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError)); |
492 | 615 |
493 if (!setURL(scriptState->getExecutionContext()->getSecurityOrigin()->toStrin g(), message)) | 616 if (!setURL(scriptState->getExecutionContext()->getSecurityOrigin()->toStrin g(), message)) |
494 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError)); | 617 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError)); |
495 | 618 |
619 if (getNFCMessageSize(message) > nfc::NFCMessage::kMaxNFCMessageSize) | |
dcheng
2016/09/08 04:42:38
Do we have an equivalent check on the handling sid
shalamov
2016/09/22 13:53:22
We need two checks, one for push (write), one for
| |
620 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError)); | |
621 | |
496 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 622 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
497 m_requests.add(resolver); | 623 m_requests.add(resolver); |
498 auto callback = convertToBaseCallback(WTF::bind(&NFC::OnRequestCompleted, wr apPersistent(this), wrapPersistent(resolver))); | 624 auto callback = convertToBaseCallback(WTF::bind(&NFC::OnRequestCompleted, wr apPersistent(this), wrapPersistent(resolver))); |
499 m_nfc->Push(std::move(message), nfc::NFCPushOptions::From(options), callback ); | 625 m_nfc->Push(std::move(message), nfc::NFCPushOptions::From(options), callback ); |
500 | 626 |
501 return resolver->promise(); | 627 return resolver->promise(); |
502 } | 628 } |
503 | 629 |
630 // https://w3c.github.io/web-nfc/#dom-nfc-cancelpush | |
504 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target) | 631 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target) |
505 { | 632 { |
506 String errorMessage; | 633 ScriptPromise promise = RejectIfNotSupported(scriptState); |
507 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) | 634 if (!promise.isEmpty()) |
508 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage)); | 635 return promise; |
509 | |
510 if (!m_nfc) | |
511 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError)); | |
512 | 636 |
513 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 637 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
514 m_requests.add(resolver); | 638 m_requests.add(resolver); |
515 auto callback = convertToBaseCallback(WTF::bind(&NFC::OnRequestCompleted, wr apPersistent(this), wrapPersistent(resolver))); | 639 auto callback = convertToBaseCallback(WTF::bind(&NFC::OnRequestCompleted, wr apPersistent(this), wrapPersistent(resolver))); |
516 m_nfc->CancelPush(mojo::toNFCPushTarget(target), callback); | 640 m_nfc->CancelPush(mojo::toNFCPushTarget(target), callback); |
517 | 641 |
518 return resolver->promise(); | 642 return resolver->promise(); |
519 } | 643 } |
520 | 644 |
645 // https://w3c.github.io/web-nfc/#watching-for-content | |
646 // https://w3c.github.io/web-nfc/#dom-nfc-watch | |
521 ScriptPromise NFC::watch(ScriptState* scriptState, MessageCallback* callback, co nst NFCWatchOptions& options) | 647 ScriptPromise NFC::watch(ScriptState* scriptState, MessageCallback* callback, co nst NFCWatchOptions& options) |
522 { | 648 { |
523 // TODO(shalamov): To be implemented. | 649 ScriptPromise promise = RejectIfNotSupported(scriptState); |
524 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); | 650 if (!promise.isEmpty()) |
651 return promise; | |
652 | |
653 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | |
654 m_requests.add(resolver); | |
655 auto watchCallback = convertToBaseCallback(WTF::bind(&NFC::OnWatchRegistered , wrapPersistent(this), wrapPersistent(callback), wrapPersistent(resolver))); | |
656 m_nfc->Watch(nfc::NFCWatchOptions::From(options), watchCallback); | |
657 return resolver->promise(); | |
525 } | 658 } |
526 | 659 |
660 // https://w3c.github.io/web-nfc/#dom-nfc-cancelwatch | |
527 ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id) | 661 ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id) |
528 { | 662 { |
529 // TODO(shalamov): To be implemented. | 663 ScriptPromise promise = RejectIfNotSupported(scriptState); |
530 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); | 664 if (!promise.isEmpty()) |
665 return promise; | |
666 | |
667 if (id) | |
668 m_callbacks.remove(id); | |
669 else | |
670 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotFoundError)); | |
671 | |
672 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | |
673 m_requests.add(resolver); | |
674 m_nfc->CancelWatch(id, convertToBaseCallback(WTF::bind(&NFC::OnRequestComple ted, wrapPersistent(this), wrapPersistent(resolver)))); | |
675 return resolver->promise(); | |
531 } | 676 } |
532 | 677 |
678 // https://w3c.github.io/web-nfc/#dom-nfc-cancelwatch | |
679 // If watchId is not provided to nfc.cancelWatch, cancel all watch operations. | |
533 ScriptPromise NFC::cancelWatch(ScriptState* scriptState) | 680 ScriptPromise NFC::cancelWatch(ScriptState* scriptState) |
534 { | 681 { |
535 // TODO(shalamov): To be implemented. | 682 ScriptPromise promise = RejectIfNotSupported(scriptState); |
536 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); | 683 if (!promise.isEmpty()) |
684 return promise; | |
685 | |
686 m_callbacks.clear(); | |
687 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | |
688 m_requests.add(resolver); | |
689 m_nfc->CancelAllWatches(convertToBaseCallback(WTF::bind(&NFC::OnRequestCompl eted, wrapPersistent(this), wrapPersistent(resolver)))); | |
690 return resolver->promise(); | |
537 } | 691 } |
538 | 692 |
539 void NFC::pageVisibilityChanged() | 693 void NFC::pageVisibilityChanged() |
540 { | 694 { |
541 // If service is not initialized, there cannot be any pending NFC activities | 695 // If service is not initialized, there cannot be any pending NFC activities |
542 if (!m_nfc) | 696 if (!m_nfc) |
543 return; | 697 return; |
544 | 698 |
545 // NFC operations should be suspended. | 699 // NFC operations should be suspended. |
546 // https://w3c.github.io/web-nfc/#nfc-suspended | 700 // https://w3c.github.io/web-nfc/#nfc-suspended |
(...skipping 11 matching lines...) Expand all Loading... | |
558 m_requests.remove(resolver); | 712 m_requests.remove(resolver); |
559 if (error.is_null()) | 713 if (error.is_null()) |
560 resolver->resolve(); | 714 resolver->resolve(); |
561 else | 715 else |
562 resolver->reject(NFCError::take(resolver, error->error_type)); | 716 resolver->reject(NFCError::take(resolver, error->error_type)); |
563 } | 717 } |
564 | 718 |
565 void NFC::OnConnectionError() | 719 void NFC::OnConnectionError() |
566 { | 720 { |
567 m_nfc.reset(); | 721 m_nfc.reset(); |
722 m_callbacks.clear(); | |
568 | 723 |
569 // If NFCService is not available or disappears when NFC hardware is | 724 // If NFCService is not available or disappears when NFC hardware is |
570 // disabled, reject promise with NotSupportedError exception. | 725 // disabled, reject promise with NotSupportedError exception. |
571 for (ScriptPromiseResolver* resolver : m_requests) | 726 for (ScriptPromiseResolver* resolver : m_requests) |
572 resolver->reject(NFCError::take(resolver, nfc::NFCErrorType::NOT_SUPPORT ED)); | 727 resolver->reject(NFCError::take(resolver, nfc::NFCErrorType::NOT_SUPPORT ED)); |
573 | 728 |
574 m_requests.clear(); | 729 m_requests.clear(); |
575 } | 730 } |
576 | 731 |
577 void NFC::OnWatch(mojo::WTFArray<uint32_t> ids, nfc::NFCMessagePtr) | 732 void NFC::OnWatch(mojo::WTFArray<uint32_t> ids, nfc::NFCMessagePtr message) |
578 { | 733 { |
579 // TODO(shalamov): Not implemented. | 734 ScriptState* scriptState = ScriptState::forMainWorld(toLocalFrame(page()->ma inFrame())); |
dcheng
2016/09/08 04:42:38
Why does this always use the main frame? Can this
shalamov
2016/09/22 13:53:22
I added comment, according to the specification, a
| |
735 ScriptState::Scope scope(scriptState); | |
736 NFCMessage nfcMessage = toNFCMessage(message, scriptState); | |
737 | |
738 for (size_t i = 0; i < ids.size(); ++i) { | |
739 WatchCallbacksMap::iterator it = m_callbacks.find(ids[i]); | |
740 if (it != m_callbacks.end()) { | |
741 it->value->handleMessage(nfcMessage); | |
742 } | |
743 } | |
744 } | |
745 | |
746 ScriptPromise NFC::RejectIfNotSupported(ScriptState* scriptState) | |
747 { | |
748 String errorMessage; | |
749 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { | |
750 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage)); | |
751 } | |
752 | |
753 if (!m_nfc) | |
754 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError)); | |
755 | |
756 return ScriptPromise(); | |
757 } | |
758 | |
759 void NFC::OnWatchRegistered(MessageCallback* callback, ScriptPromiseResolver* re solver, uint32_t id, nfc::NFCErrorPtr error) | |
760 { | |
761 m_requests.remove(resolver); | |
762 | |
763 // Invalid id was returned. | |
764 // https://w3c.github.io/web-nfc/#dom-nfc-watch | |
765 // 8. If the request fails, reject promise with "NotSupportedError" | |
766 // and abort these steps. | |
767 if (!id) { | |
768 resolver->reject(NFCError::take(resolver, nfc::NFCErrorType::NOT_SUPPORT ED)); | |
769 return; | |
770 } | |
771 | |
772 if (error.is_null()) { | |
773 m_callbacks.add(id, callback); | |
774 resolver->resolve(id); | |
775 } else { | |
776 resolver->reject(NFCError::take(resolver, error->error_type)); | |
777 } | |
580 } | 778 } |
581 | 779 |
582 DEFINE_TRACE(NFC) | 780 DEFINE_TRACE(NFC) |
583 { | 781 { |
584 PageVisibilityObserver::trace(visitor); | 782 PageVisibilityObserver::trace(visitor); |
585 ContextLifecycleObserver::trace(visitor); | 783 ContextLifecycleObserver::trace(visitor); |
586 visitor->trace(m_requests); | 784 visitor->trace(m_requests); |
785 visitor->trace(m_callbacks); | |
587 } | 786 } |
588 | 787 |
589 } // namespace blink | 788 } // namespace blink |
OLD | NEW |