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

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

Issue 1759373003: [webnfc] Implement nfc.watch in blink nfc module. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@implement_nfc_push_in_android
Patch Set: Rebased. Created 4 years, 8 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/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/ExceptionCode.h" 12 #include "core/dom/ExceptionCode.h"
13 #include "core/frame/LocalDOMWindow.h" 13 #include "core/frame/LocalDOMWindow.h"
14 #include "modules/nfc/NFCError.h" 14 #include "modules/nfc/NFCError.h"
15 #include "modules/nfc/NFCMessage.h" 15 #include "modules/nfc/NFCMessage.h"
16 #include "modules/nfc/NFCPushOptions.h" 16 #include "modules/nfc/NFCPushOptions.h"
17 #include "modules/nfc/NFCWatchOptions.h"
17 #include "platform/mojo/MojoHelper.h" 18 #include "platform/mojo/MojoHelper.h"
18 #include "public/platform/ServiceRegistry.h" 19 #include "public/platform/ServiceRegistry.h"
19 20
20 namespace { 21 namespace {
21 const char kJsonMimePrefix[] = "application/"; 22 const char kJsonMimePrefix[] = "application/";
22 const char kJsonMimeType[] = "application/json"; 23 const char kJsonMimeType[] = "application/json";
23 const char kOpaqueMimeType[] = "application/octet-stream"; 24 const char kOpaqueMimeType[] = "application/octet-stream";
24 const char kPlainTextMimeType[] = "text/plain"; 25 const char kPlainTextMimeType[] = "text/plain";
25 const char kPlainTextMimePrefix[] = "text/"; 26 const char kPlainTextMimePrefix[] = "text/";
26 const char kCharSetUTF8[] = ";charset=UTF-8"; 27 const char kCharSetUTF8[] = ";charset=UTF-8";
27 } // anonymous namespace 28 } // anonymous namespace
28 29
29 // Mojo type converters 30 // Mojo type converters
30 namespace mojo { 31 namespace mojo {
31 32
32 using device::wtf::NFCMessage; 33 using device::wtf::NFCMessage;
33 using device::wtf::NFCMessagePtr; 34 using device::wtf::NFCMessagePtr;
34 using device::wtf::NFCRecord; 35 using device::wtf::NFCRecord;
35 using device::wtf::NFCRecordPtr; 36 using device::wtf::NFCRecordPtr;
36 using device::wtf::NFCRecordType; 37 using device::wtf::NFCRecordType;
38 using device::wtf::NFCRecordTypeFilter;
39 using device::wtf::NFCRecordTypeFilterPtr;
37 using device::wtf::NFCPushOptions; 40 using device::wtf::NFCPushOptions;
38 using device::wtf::NFCPushOptionsPtr; 41 using device::wtf::NFCPushOptionsPtr;
39 using device::wtf::NFCPushTarget; 42 using device::wtf::NFCPushTarget;
43 using device::wtf::NFCWatchMode;
44 using device::wtf::NFCWatchOptions;
45 using device::wtf::NFCWatchOptionsPtr;
40 46
41 NFCPushTarget toNFCPushTarget(const WTF::String& target) 47 NFCPushTarget toNFCPushTarget(const WTF::String& target)
42 { 48 {
43 if (target == "tag") 49 if (target == "tag")
44 return NFCPushTarget::TAG; 50 return NFCPushTarget::TAG;
45 51
46 if (target == "peer") 52 if (target == "peer")
47 return NFCPushTarget::PEER; 53 return NFCPushTarget::PEER;
48 54
49 return NFCPushTarget::ANY; 55 return NFCPushTarget::ANY;
(...skipping 13 matching lines...) Expand all
63 if (recordType == "json") 69 if (recordType == "json")
64 return NFCRecordType::JSON; 70 return NFCRecordType::JSON;
65 71
66 if (recordType == "opaque") 72 if (recordType == "opaque")
67 return NFCRecordType::OPAQUE_RECORD; 73 return NFCRecordType::OPAQUE_RECORD;
68 74
69 ASSERT_NOT_REACHED(); 75 ASSERT_NOT_REACHED();
70 return NFCRecordType::EMPTY; 76 return NFCRecordType::EMPTY;
71 } 77 }
72 78
79 NFCWatchMode toNFCWatchMode(const WTF::String& watchMode)
80 {
81 if (watchMode == "web-nfc-only")
82 return NFCWatchMode::WEBNFC_ONLY;
83
84 if (watchMode == "any")
85 return NFCWatchMode::ANY;
86
87 ASSERT_NOT_REACHED();
88 return NFCWatchMode::WEBNFC_ONLY;
89 }
90
73 // https://w3c.github.io/web-nfc/#creating-web-nfc-message Step 2.1 91 // 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: 92 // If NFCRecord type is not provided, deduct NFCRecord type from JS data type:
75 // String or Number => 'text' record 93 // String or Number => 'text' record
76 // ArrayBuffer => 'opaque' record 94 // ArrayBuffer => 'opaque' record
77 // JSON serializable Object => 'json' record 95 // JSON serializable Object => 'json' record
78 NFCRecordType deductRecordTypeFromDataType(const blink::NFCRecord& record) 96 NFCRecordType deductRecordTypeFromDataType(const blink::NFCRecord& record)
79 { 97 {
80 if (record.hasData()) { 98 if (record.hasData()) {
81 v8::Local<v8::Value> value = record.data().v8Value(); 99 v8::Local<v8::Value> value = record.data().v8Value();
82 100
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 319
302 if (pushOptions.hasIgnoreRead()) 320 if (pushOptions.hasIgnoreRead())
303 pushOptionsPtr->ignoreRead = pushOptions.ignoreRead(); 321 pushOptionsPtr->ignoreRead = pushOptions.ignoreRead();
304 else 322 else
305 pushOptionsPtr->ignoreRead = true; 323 pushOptionsPtr->ignoreRead = true;
306 324
307 return pushOptionsPtr; 325 return pushOptionsPtr;
308 } 326 }
309 }; 327 };
310 328
329 template <>
330 struct TypeConverter<NFCWatchOptionsPtr, blink::NFCWatchOptions> {
331 static NFCWatchOptionsPtr Convert(const blink::NFCWatchOptions& watchOptions )
332 {
333 // https://w3c.github.io/web-nfc/#the-nfcwatchoptions-dictionary
334 // Default values for NFCWatchOptions dictionary are:
335 // url = "", recordType = null, mediaType = "", mode = "web-nfc-only"
336 NFCWatchOptionsPtr watchOptionsPtr = NFCWatchOptions::New();
337 watchOptionsPtr->url = watchOptions.url();
338 watchOptionsPtr->mediaType = watchOptions.mediaType();
339
340 if (watchOptions.hasMode())
341 watchOptionsPtr->mode = toNFCWatchMode(watchOptions.mode());
342 else
343 watchOptionsPtr->mode = NFCWatchMode::WEBNFC_ONLY;
344
345 if (watchOptions.hasRecordType()) {
346 watchOptionsPtr->recordFilter = NFCRecordTypeFilter::New();
347 watchOptionsPtr->recordFilter->recordType = toNFCRecordType(watchOpt ions.recordType());
348 }
349
350 return watchOptionsPtr;
351 }
352 };
353
311 } // namespace mojo 354 } // namespace mojo
312 355
313 namespace blink { 356 namespace blink {
314 357
315 358
316 namespace { 359 namespace {
317 360
318 bool isValidTextRecord(const NFCRecord& record) 361 bool isValidTextRecord(const NFCRecord& record)
319 { 362 {
320 v8::Local<v8::Value> value = record.data().v8Value(); 363 v8::Local<v8::Value> value = record.data().v8Value();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 KURL originURL(ParsedURLString, origin); 466 KURL originURL(ParsedURLString, origin);
424 467
425 if (!message->url.isEmpty() && originURL.canSetPathname()) { 468 if (!message->url.isEmpty() && originURL.canSetPathname()) {
426 originURL.setPath(message->url); 469 originURL.setPath(message->url);
427 } 470 }
428 471
429 message->url = originURL; 472 message->url = originURL;
430 return originURL.isValid(); 473 return originURL.isValid();
431 } 474 }
432 475
476 String toNFCRecordType(const device::wtf::NFCRecordType& type)
477 {
478 switch (type) {
479 case device::wtf::NFCRecordType::TEXT:
480 return "text";
481 case device::wtf::NFCRecordType::URL:
482 return "url";
483 case device::wtf::NFCRecordType::JSON:
484 return "json";
485 case device::wtf::NFCRecordType::OPAQUE_RECORD:
486 return "opaque";
487 case device::wtf::NFCRecordType::EMPTY:
488 return "empty";
489 }
490
491 ASSERT_NOT_REACHED();
492 return String();
493 }
494
495 v8::Local<v8::Value> toV8(const device::wtf::NFCRecordPtr& record, ScriptState* scriptState)
496 {
497 switch (record->recordType) {
498 case device::wtf::NFCRecordType::TEXT:
499 case device::wtf::NFCRecordType::URL:
500 case device::wtf::NFCRecordType::JSON: {
501 String stringData;
502 if (!record->data.empty())
503 stringData = String::fromUTF8WithLatin1Fallback(static_cast<unsigned char*>(&record->data.front()), record->data.size());
504
505 if (record->recordType == device::wtf::NFCRecordType::JSON)
506 return v8::JSON::Parse(scriptState->isolate(), v8String(scriptState- >isolate(), stringData)).ToLocalChecked();
507 return v8String(scriptState->isolate(), stringData);
508 }
509
510 case device::wtf::NFCRecordType::OPAQUE_RECORD: {
511 if (!record->data.empty()) {
512 DOMArrayBuffer* buffer = DOMArrayBuffer::create(static_cast<void*>(& record->data.front()), record->data.size());
513 return toV8(buffer, scriptState->context()->Global(), scriptState->i solate());
514 }
515
516 return v8::Null(scriptState->isolate());
517 }
518
519 case device::wtf::NFCRecordType::EMPTY:
520 return v8::Null(scriptState->isolate());
521 }
522
523 ASSERT_NOT_REACHED();
524 return v8::Local<v8::Value>();
525 }
526
527 NFCRecord toNFCRecord(const device::wtf::NFCRecordPtr& record, ScriptState* scri ptState)
528 {
529 NFCRecord nfcRecord;
530 nfcRecord.setMediaType(record->mediaType);
531 nfcRecord.setRecordType(toNFCRecordType(record->recordType));
532 nfcRecord.setData(ScriptValue(scriptState, toV8(record, scriptState)));
533 return nfcRecord;
534 }
535
536 NFCMessage toNFCMessage(const device::wtf::NFCMessagePtr& message, ScriptState* scriptState)
537 {
538 NFCMessage nfcMessage;
539 nfcMessage.setURL(message->url);
540 blink::HeapVector<NFCRecord> records;
541 for (size_t i = 0; i < message->data.size(); ++i)
542 records.append(toNFCRecord(message->data[i], scriptState));
543 nfcMessage.setData(records);
544 return nfcMessage;
545 }
546
433 } // anonymous namespace 547 } // anonymous namespace
434 548
549 template <typename T>
550 class NFCCallbackBase {
551 public:
552 explicit NFCCallbackBase(ScriptPromiseResolver* resolver)
553 : m_promiseAdapter(adoptPtr(new T(resolver))) { }
554
555 // If NFCService is not available or disappears when NFC HW is disabled,
556 // mojo service will invalidate proxy and destroy all pending callbacks.
557 // Promise will be rejected with NotSupportedError exception.
558 virtual ~NFCCallbackBase()
559 {
560 m_promiseAdapter->onError(device::wtf::NFCErrorType::NOT_SUPPORTED);
561 }
562
563 protected:
564 OwnPtr<T> m_promiseAdapter;
565 };
566
435 using NFCMojoCallback = mojo::Callback<void(device::wtf::NFCErrorPtr)>; 567 using NFCMojoCallback = mojo::Callback<void(device::wtf::NFCErrorPtr)>;
436 class NFCCallback final : public NFCMojoCallback::Runnable { 568 using NFCCallbackPromiseAdapter = CallbackPromiseAdapter<void, NFCError>;
569
570 class NFCCallback final : public NFCMojoCallback::Runnable,
571 public NFCCallbackBase<NFCCallbackPromiseAdapter> {
437 WTF_MAKE_NONCOPYABLE(NFCCallback); 572 WTF_MAKE_NONCOPYABLE(NFCCallback);
438 public: 573 public:
439 using NFCCallbackPromiseAdapter = CallbackPromiseAdapter<void, NFCError>;
440 explicit NFCCallback(ScriptPromiseResolver* resolver) 574 explicit NFCCallback(ScriptPromiseResolver* resolver)
441 : m_promiseAdapter(adoptPtr(new NFCCallbackPromiseAdapter(resolver))) { } 575 : NFCCallbackBase<NFCCallbackPromiseAdapter>(resolver) { }
442
443 ~NFCCallback() override
444 {
445 // If NFCService is not available or disappears when NFC HW is disabled,
446 // reject promise with NotSupportedError exception.
447 m_promiseAdapter->onError(device::wtf::NFCErrorType::NOT_SUPPORTED);
448 }
449 576
450 void Run(device::wtf::NFCErrorPtr error) override 577 void Run(device::wtf::NFCErrorPtr error) override
451 { 578 {
452 if (error.is_null()) 579 if (error.is_null())
453 m_promiseAdapter->onSuccess(); 580 m_promiseAdapter->onSuccess();
454 else 581 else
455 m_promiseAdapter->onError(error->error_type); 582 m_promiseAdapter->onError(error->error_type);
456 } 583 }
584 };
585
586 using NFCWatchMojoCallback = mojo::Callback<void(uint32_t, device::wtf::NFCError Ptr)>;
587 using NFCWatchCallbackPromiseAdapter = CallbackPromiseAdapter<uint32_t, NFCError >;
588
589 class NFCWatchCallback final : public NFCWatchMojoCallback::Runnable,
590 public NFCCallbackBase<NFCWatchCallbackPromiseAdapter> {
591 WTF_MAKE_NONCOPYABLE(NFCWatchCallback);
592 public:
593 NFCWatchCallback(ScriptPromiseResolver* resolver, NFC* nfc, MessageCallback* callback)
594 : NFCCallbackBase<NFCWatchCallbackPromiseAdapter>(resolver)
595 , m_nfc(nfc)
596 , m_callback(callback) { }
597
598 void Run(uint32_t watchId, device::wtf::NFCErrorPtr error) override
599 {
600 if (error.is_null()) {
601 m_nfc->OnWatchRegistered(watchId, m_callback);
602 m_promiseAdapter->onSuccess(watchId);
603 } else {
604 m_promiseAdapter->onError(error->error_type);
605 }
606 }
457 607
458 private: 608 private:
459 OwnPtr<NFCCallbackPromiseAdapter> m_promiseAdapter; 609 Persistent<NFC> m_nfc;
610 Persistent<MessageCallback> m_callback;
460 }; 611 };
461 612
462 NFC::NFC(LocalFrame* frame) 613 NFC::NFC(LocalFrame* frame)
463 : PageLifecycleObserver(frame ? frame->page() : 0), 614 : PageLifecycleObserver(frame ? frame->page() : 0),
464 m_client(this) 615 m_client(this)
465 { 616 {
466 } 617 }
467 618
468 NFC* NFC::create(LocalFrame* frame) 619 NFC* NFC::create(LocalFrame* frame)
469 { 620 {
470 NFC* nfc = new NFC(frame); 621 NFC* nfc = new NFC(frame);
471 return nfc; 622 return nfc;
472 } 623 }
473 624
474 NFC::~NFC() = default; 625 NFC::~NFC() = default;
475 626
476 // https://w3c.github.io/web-nfc/#writing-or-pushing-content 627 // https://w3c.github.io/web-nfc/#writing-or-pushing-content
628 // https://w3c.github.io/web-nfc/#dom-nfc-push
477 ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& pushMess age, const NFCPushOptions& options) 629 ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& pushMess age, const NFCPushOptions& options)
478 { 630 {
479 String errorMessage; 631 ScriptPromise promise = RejectIfNotSupported(scriptState);
480 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { 632 if (!promise.isEmpty())
481 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage)); 633 return promise;
482 }
483 634
484 DOMException* exception = isValidNFCPushMessage(pushMessage); 635 DOMException* exception = isValidNFCPushMessage(pushMessage);
485 if (exception) 636 if (exception)
486 return ScriptPromise::rejectWithDOMException(scriptState, exception); 637 return ScriptPromise::rejectWithDOMException(scriptState, exception);
487 638
488 if (!Initialize(scriptState->domWindow()->frame()->serviceRegistry()))
489 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError));
490
491 device::wtf::NFCMessagePtr message = device::wtf::NFCMessage::From(pushMessa ge); 639 device::wtf::NFCMessagePtr message = device::wtf::NFCMessage::From(pushMessa ge);
492 if (!message) 640 if (!message)
493 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError)); 641 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError));
494 642
495 if (!setURL(scriptState->getExecutionContext()->getSecurityOrigin()->toStrin g(), message)) 643 if (!setURL(scriptState->getExecutionContext()->getSecurityOrigin()->toStrin g(), message))
496 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError)); 644 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError));
497 645
498 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 646 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
499 m_nfc->Push(std::move(message), device::wtf::NFCPushOptions::From(options), device::wtf::NFC::PushCallback(new NFCCallback(resolver))); 647 m_nfc->Push(std::move(message), device::wtf::NFCPushOptions::From(options), device::wtf::NFC::PushCallback(new NFCCallback(resolver)));
500 648
501 return resolver->promise(); 649 return resolver->promise();
502 } 650 }
503 651
652 // https://w3c.github.io/web-nfc/#dom-nfc-cancelpush
504 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target) 653 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target)
505 { 654 {
506 String errorMessage; 655 ScriptPromise promise = RejectIfNotSupported(scriptState);
507 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { 656 if (!promise.isEmpty())
508 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage)); 657 return promise;
509 }
510
511 if (!Initialize(scriptState->domWindow()->frame()->serviceRegistry()))
512 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError));
513 658
514 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 659 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
515 m_nfc->CancelPush(mojo::toNFCPushTarget(target), device::wtf::NFC::CancelPus hCallback(new NFCCallback(resolver))); 660 m_nfc->CancelPush(mojo::toNFCPushTarget(target), device::wtf::NFC::CancelPus hCallback(new NFCCallback(resolver)));
516 661
517 return resolver->promise(); 662 return resolver->promise();
518 } 663 }
519 664
665 // https://w3c.github.io/web-nfc/#watching-for-content
666 // https://w3c.github.io/web-nfc/#dom-nfc-watch
520 ScriptPromise NFC::watch(ScriptState* scriptState, MessageCallback* callback, co nst NFCWatchOptions& options) 667 ScriptPromise NFC::watch(ScriptState* scriptState, MessageCallback* callback, co nst NFCWatchOptions& options)
521 { 668 {
522 // TODO(shalamov): To be implemented. 669 ScriptPromise promise = RejectIfNotSupported(scriptState);
523 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 670 if (!promise.isEmpty())
671 return promise;
672
673 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
674 device::wtf::NFC::WatchCallback watchCallback(new NFCWatchCallback(resolver, this, callback));
675 m_nfc->Watch(device::wtf::NFCWatchOptions::From(options), watchCallback);
676 return resolver->promise();
524 } 677 }
525 678
679 // https://w3c.github.io/web-nfc/#dom-nfc-cancelwatch
526 ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id) 680 ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id)
527 { 681 {
528 // TODO(shalamov): To be implemented. 682 ScriptPromise promise = RejectIfNotSupported(scriptState);
529 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 683 if (!promise.isEmpty())
684 return promise;
685
686 if (id)
687 m_callbacks.remove(id);
688 else
689 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotFoundError));
690
691 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
692 m_nfc->CancelWatch(id, device::wtf::NFC::CancelWatchCallback(new NFCCallback (resolver)));
693 return resolver->promise();
530 } 694 }
531 695
696 // https://w3c.github.io/web-nfc/#dom-nfc-cancelwatch
697 // If watchId is not provided to nfc.cancelWatch, cancel all watch operations.
532 ScriptPromise NFC::cancelWatch(ScriptState* scriptState) 698 ScriptPromise NFC::cancelWatch(ScriptState* scriptState)
533 { 699 {
534 // TODO(shalamov): To be implemented. 700 ScriptPromise promise = RejectIfNotSupported(scriptState);
535 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 701 if (!promise.isEmpty())
702 return promise;
703
704 m_callbacks.clear();
705 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
706 m_nfc->CancelAllWatches(device::wtf::NFC::CancelAllWatchesCallback(new NFCCa llback(resolver)));
707 return resolver->promise();
536 } 708 }
537 709
538 void NFC::pageVisibilityChanged() 710 void NFC::pageVisibilityChanged()
539 { 711 {
540 // 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
541 if (!m_nfc) 713 if (!m_nfc)
542 return; 714 return;
543 715
544 // NFC operations should be suspended. 716 // NFC operations should be suspended.
545 // https://w3c.github.io/web-nfc/#nfc-suspended 717 // https://w3c.github.io/web-nfc/#nfc-suspended
546 if (page()->visibilityState() == PageVisibilityStateVisible) 718 if (page()->visibilityState() == PageVisibilityStateVisible)
547 m_nfc->ResumeNFCOperations(); 719 m_nfc->ResumeNFCOperations();
548 else 720 else
549 m_nfc->SuspendNFCOperations(); 721 m_nfc->SuspendNFCOperations();
550 } 722 }
551 723
552 void NFC::OnWatch(uint32_t id, device::wtf::NFCMessagePtr message) 724 void NFC::OnWatch(uint32_t id, device::wtf::NFCMessagePtr message)
553 { 725 {
726 WatchCallbacksMap::iterator it = m_callbacks.find(id);
727 if (it != m_callbacks.end()) {
728 ScriptState* scriptState = ScriptState::forMainWorld(toLocalFrame(page() ->mainFrame()));
729 ScriptState::Scope scope(scriptState);
730 it->value->handleMessage(toNFCMessage(message, scriptState));
731 }
554 } 732 }
555 733
556 bool NFC::Initialize(ServiceRegistry* registry) 734 bool NFC::Initialize(ServiceRegistry* registry)
557 { 735 {
558 DCHECK(registry); 736 DCHECK(registry);
559 737
560 if (m_nfc) 738 if (m_nfc)
561 return true; 739 return true;
562 740
563 registry->connectToRemoteService(mojo::GetProxy(&m_nfc)); 741 registry->connectToRemoteService(mojo::GetProxy(&m_nfc));
564 742
565 if (m_nfc) { 743 if (m_nfc) {
566 m_nfc.set_connection_error_handler(sameThreadBindForMojo(&NFC::OnError, this)); 744 m_nfc.set_connection_error_handler(sameThreadBindForMojo(&NFC::OnError, this));
567 m_nfc->SetClient(m_client.CreateInterfacePtrAndBind()); 745 m_nfc->SetClient(m_client.CreateInterfacePtrAndBind());
568 } 746 }
569 747
570 return m_nfc; 748 return m_nfc;
571 } 749 }
572 750
751 ScriptPromise NFC::RejectIfNotSupported(ScriptState* scriptState)
752 {
753 String errorMessage;
754 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) {
755 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage));
756 }
757
758 if (!Initialize(scriptState->domWindow()->frame()->serviceRegistry()))
759 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError));
760
761 return ScriptPromise();
762 }
763
573 void NFC::OnError() 764 void NFC::OnError()
574 { 765 {
575 // todo(shalamov): clear map that contains nfc watch callbacks 766 m_callbacks.clear();
576 if (m_client.is_bound()) 767 if (m_client.is_bound())
577 m_client.Close(); 768 m_client.Close();
578 m_nfc.reset(); 769 m_nfc.reset();
579 } 770 }
580 771
772 void NFC::OnWatchRegistered(uint32_t id, MessageCallback* callback)
773 {
774 if (id)
775 m_callbacks.add(id, callback);
776 }
777
581 DEFINE_TRACE(NFC) 778 DEFINE_TRACE(NFC)
582 { 779 {
583 PageLifecycleObserver::trace(visitor); 780 PageLifecycleObserver::trace(visitor);
781 visitor->trace(m_callbacks);
584 } 782 }
585 783
586 } // namespace blink 784 } // namespace blink
OLDNEW
« third_party/WebKit/LayoutTests/nfc/watch.html ('K') | « third_party/WebKit/Source/modules/nfc/NFC.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698