Chromium Code Reviews| 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 |