From 6864dbe08dad693cbc10782f59362c1f2b895eb8 Mon Sep 17 00:00:00 2001 From: Leon Han Date: Fri, 30 Aug 2019 03:02:48 -0700 Subject: [PATCH] [webnfc] Use AbortController for NFCReader This CL uses AbortController to replace the stop() method of NFCReader interface. The corresponding spec change is from: https://github.com/w3c/web-nfc/pull/300 BUG=520391 Change-Id: Ia28bfb283a7ad66fb9c4cb0fc744582671a62fa0 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1769245 Reviewed-by: Daniel Cheng Reviewed-by: Reilly Grant Reviewed-by: Rijubrata Bhaumik Commit-Queue: Leon Han Cr-Commit-Position: refs/heads/master@{#691988} --- web-nfc/NFCReader.https.html | 79 +++++++++++++------------ web-nfc/NFCReader_options.https.html | 88 ++++++++++++++-------------- web-nfc/resources/nfc-helpers.js | 32 +++++----- 3 files changed, 103 insertions(+), 96 deletions(-) diff --git a/web-nfc/NFCReader.https.html b/web-nfc/NFCReader.https.html index 4488097d6ebee4..6fcb9b161dd127 100644 --- a/web-nfc/NFCReader.https.html +++ b/web-nfc/NFCReader.https.html @@ -10,122 +10,125 @@ "use strict"; -function waitSyntaxErrorPromise(t, reader) { +function waitSyntaxErrorPromise(t, scan_options) { + const reader = new NFCReader(); const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); const promise = readerWatcher.wait_for("error").then(event => { assert_equals(event.error.name, 'SyntaxError'); }); - // NFCReader#start() asynchronously dispatches the syntax error event. - reader.start(); + // NFCReader#scan() asynchronously dispatches the syntax error event. + reader.scan(scan_options); return promise; } promise_test(async t => { - const reader = new NFCReader({url: "www.a.com"}); - await waitSyntaxErrorPromise(t, reader); -}, "Test that NFCReader.start fails if NFCReaderOptions.url is missing \ + await waitSyntaxErrorPromise(t, {url: "www.a.com"}); +}, "Test that NFCReader.scan fails if NFCScanOptions.url is missing \ components."); promise_test(async t => { - const reader = new NFCReader({url: "invalid"}); - await waitSyntaxErrorPromise(t, reader); -}, "Test that NFCReader.start fails if NFCReaderOptions.url is invalid."); + await waitSyntaxErrorPromise(t, {url: "invalid"}); +}, "Test that NFCReader.scan fails if NFCScanOptions.url is invalid."); promise_test(async t => { - const reader = new NFCReader({url: "http://a.com"}); - await waitSyntaxErrorPromise(t, reader); -}, "Test that NFCReader.start fails if NFCReaderOptions.url has wrong \ + await waitSyntaxErrorPromise(t, {url: "http://a.com"}); +}, "Test that NFCReader.scan fails if NFCScanOptions.url has wrong \ protocol."); nfc_test(async (t, mockNFC) => { const reader = new NFCReader(); const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); - reader.start(); + reader.scan(); mockNFC.setHWStatus(NFCHWStatus.DISABLED); const event = await readerWatcher.wait_for("error"); assert_equals(event.error.name, 'NotReadableError'); -}, "NFCReader.start should fail if NFC HW is disabled."); +}, "NFCReader.scan should fail if NFC HW is disabled."); nfc_test(async (t, mockNFC) => { const reader = new NFCReader(); const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); - reader.start(); + reader.scan(); mockNFC.setHWStatus(NFCHWStatus.NOT_SUPPORTED); const event = await readerWatcher.wait_for("error"); assert_equals(event.error.name, 'NotSupportedError'); -}, "NFCReader.start should fail if NFC HW is not supported."); +}, "NFCReader.scan should fail if NFC HW is not supported."); nfc_test(async (t, mockNFC) => { const reader = new NFCReader(); + const controller = new AbortController(); const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); mockNFC.setReadingMessage(createMessage([createTextRecord(test_text_data)])); const promise = readerWatcher.wait_for("reading").then(event => { assert_true(event instanceof NFCReadingEvent); - reader.stop(); + controller.abort(); }); - // NFCReader#start() asynchronously dispatches the reading event. - reader.start(); + // NFCReader#scan() asynchronously dispatches the reading event. + reader.scan({signal : controller.signal}); await promise; }, "Test that nfc watch success if NFC HW is enabled."); nfc_test(async (t, mockNFC) => { - const reader = new NFCReader({url: "https://a.com"}); + const reader = new NFCReader(); + const controller = new AbortController(); const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); mockNFC.setReadingMessage(createMessage([createTextRecord(test_text_data)])); const promise = readerWatcher.wait_for("reading").then(event => { assert_true(event instanceof NFCReadingEvent); - reader.stop(); + controller.abort(); }); - // NFCReader#start() asynchronously dispatches the reading event. - reader.start(); + // NFCReader#scan() asynchronously dispatches the reading event. + reader.scan({signal : controller.signal, url: "https://a.com"}); await promise; -}, "Test that NFCReader.start succeeds if NFCReaderOptions.url is valid URL."); +}, "Test that NFCReader.scan succeeds if NFCScanOptions.url is valid URL."); nfc_test(async (t, mockNFC) => { - const reader = new NFCReader({url: "https://a.com/*"}); + const reader = new NFCReader(); + const controller = new AbortController(); const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); mockNFC.setReadingMessage(createMessage([createTextRecord(test_text_data)])); const promise = readerWatcher.wait_for("reading").then(event => { assert_true(event instanceof NFCReadingEvent); - reader.stop(); + controller.abort(); }); - // NFCReader#start() asynchronously dispatches the reading event. - reader.start(); + // NFCReader#scan() asynchronously dispatches the reading event. + reader.scan({signal : controller.signal, url: "https://a.com/*"}); await promise; -}, "Test that NFCReader.start succeeds if NFCReaderOptions.url is valid URL \ +}, "Test that NFCReader.scan succeeds if NFCScanOptions.url is valid URL \ with '*' wildcard character in path."); nfc_test(async (t, mockNFC) => { - const reader = new NFCReader({url: "https://a.com/*/bar"}); + const reader = new NFCReader(); + const controller = new AbortController(); const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); mockNFC.setReadingMessage(createMessage([createTextRecord(test_text_data)])); const promise = readerWatcher.wait_for("reading").then(event => { assert_true(event instanceof NFCReadingEvent); - reader.stop(); + controller.abort(); }); - // NFCReader#start() asynchronously dispatches the reading event. - reader.start(); + // NFCReader#scan() asynchronously dispatches the reading event. + reader.scan({signal : controller.signal, url: "https://a.com/*/bar"}); await promise; -}, "Test that NFCReader.start succeeds if NFCReaderOptions.url is valid URL \ +}, "Test that NFCReader.scan succeeds if NFCScanOptions.url is valid URL \ with '*' wildcard character in the beginning of path component followed by \ subpath."); nfc_test(async (t, mockNFC) => { const reader = new NFCReader({url: ""}); + const controller = new AbortController(); const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); mockNFC.setReadingMessage(createMessage([createTextRecord(test_text_data)])); const promise = readerWatcher.wait_for("reading").then(event => { assert_true(event instanceof NFCReadingEvent); - reader.stop(); + controller.abort(); }); - // NFCReader#start() asynchronously dispatches the reading event. - reader.start(); + // NFCReader#scan() asynchronously dispatches the reading event. + reader.scan({signal : controller.signal, url: ""}); await promise; -}, "Test that NFCReader.start succeeds if NFCReaderOptions.url is empty."); +}, "Test that NFCReader.scan succeeds if NFCScanOptions.url is empty."); diff --git a/web-nfc/NFCReader_options.https.html b/web-nfc/NFCReader_options.https.html index ebda3859834c5b..7c77045afb3ee5 100644 --- a/web-nfc/NFCReader_options.https.html +++ b/web-nfc/NFCReader_options.https.html @@ -13,60 +13,60 @@ const NFCReaderOptionTests = [ { - desc: "Test that reading data succeed when NFCReaderOptions'" + + desc: "Test that reading data succeed when NFCScanOptions'" + " recordType is set to 'empty'.", - readOptions: {recordType: "empty"}, - unmatchedReadOptions: {recordType: "json"}, + scanOptions: {recordType: "empty"}, + unmatchedScanOptions: {recordType: "json"}, message: createMessage([createRecord('empty', '')]) }, { - desc: "Test that reading data succeed when NFCReaderOptions'" + + desc: "Test that reading data succeed when NFCScanOptions'" + " recordType is set to 'json'.", - readOptions: {recordType: "json"}, - unmatchedReadOptions: {recordType: "url"}, + scanOptions: {recordType: "json"}, + unmatchedScanOptions: {recordType: "url"}, message: createMessage([createJsonRecord(test_json_data)]) }, { - desc: "Test that reading data succeed when NFCReaderOptions'" + + desc: "Test that reading data succeed when NFCScanOptions'" + " recordType is set to 'opaque'.", - readOptions: {recordType: "opaque"}, - unmatchedReadOptions: {recordType: "json"}, + scanOptions: {recordType: "opaque"}, + unmatchedScanOptions: {recordType: "json"}, message: createMessage([createOpaqueRecord(test_buffer_data)]) }, { - desc: "Test that reading data succeed when NFCReaderOptions'" + + desc: "Test that reading data succeed when NFCScanOptions'" + " recordType is set to 'text'.", - readOptions: {recordType: "text"}, - unmatchedReadOptions: {recordType: "json"}, + scanOptions: {recordType: "text"}, + unmatchedScanOptions: {recordType: "json"}, message: createMessage([createTextRecord(test_text_data)]) }, { - desc: "Test that reading data succeed when NFCReaderOptions'" + + desc: "Test that reading data succeed when NFCScanOptions'" + " recordType is set to 'url'.", - readOptions: {recordType: "url"}, - unmatchedReadOptions: {recordType: "json"}, + scanOptions: {recordType: "url"}, + unmatchedScanOptions: {recordType: "json"}, message: createMessage([createUrlRecord(test_url_data)]) }, { - desc: "Test that the url of NFCReaderOptions filters relevant data" + + desc: "Test that the url of NFCScanOptions filters relevant data" + " sources correctly.", - readOptions: {url: `${location.origin}/custom/path`}, - unmatchedReadOptions: {url: `${location.origin}/custom/invalid`}, + scanOptions: {url: `${location.origin}/custom/path`}, + unmatchedScanOptions: {url: `${location.origin}/custom/invalid`}, message: {url: `${location.origin}/custom/path/update`, records: [createTextRecord(test_text_data)]} }, { - desc: "Test that the mediaType of NFCReaderOptions filters relevant data" + + desc: "Test that the mediaType of NFCScanOptions filters relevant data" + " sources correctly.", - readOptions: {mediaType: "application/octet-stream"}, - unmatchedReadOptions: {mediaType: "application/json"}, + scanOptions: {mediaType: "application/octet-stream"}, + unmatchedScanOptions: {mediaType: "application/json"}, message: createMessage([createOpaqueRecord(test_buffer_data)]) }, { - desc: "Test that the compatibility of NFCReaderOptions filters relevant data" + + desc: "Test that the compatibility of NFCScanOptions filters relevant data" + " sources correctly.", - readOptions: {compatibility: "vendor"}, - unmatchedReadOptions: {compatibility: "nfc-forum"}, + scanOptions: {compatibility: "vendor"}, + unmatchedScanOptions: {compatibility: "nfc-forum"}, message: createMessage([createTextRecord(test_text_data)]), } ]; @@ -75,43 +75,43 @@ [ { desc: "Test that filtering 'empty' record from different messages" + - " correctly with NFCReaderOptions' recordType is set to 'empty'.", - readOptions: {recordType: "empty"}, + " correctly with NFCScanOptions' recordType is set to 'empty'.", + scanOptions: {recordType: "empty"}, message: createMessage([createRecord('empty', '')]), unmatchedMessage: createMessage([createJsonRecord(test_json_data)]), }, { desc: "Test that filtering 'json' record from different messages" + - " correctly with NFCReaderOptions' recordType is set to 'json'.", - readOptions: {recordType: "json"}, + " correctly with NFCScanOptions' recordType is set to 'json'.", + scanOptions: {recordType: "json"}, message: createMessage([createJsonRecord(test_json_data)]), unmatchedMessage: createMessage([createUrlRecord(test_url_data)]) }, { desc: "Test that filtering 'opaque' record from different messages" + - " correctly with NFCReaderOptions' recordType is set to 'opaque'.", - readOptions: {recordType: "opaque"}, + " correctly with NFCScanOptions' recordType is set to 'opaque'.", + scanOptions: {recordType: "opaque"}, message: createMessage([createOpaqueRecord(test_buffer_data)]), unmatchedMessage: createMessage([createJsonRecord(test_json_data)]) }, { desc: "Test that filtering 'text' record from different messages" + - " correctly with NFCReaderOptions' recordType is set to 'text'.", - readOptions: {recordType: "text"}, + " correctly with NFCScanOptions' recordType is set to 'text'.", + scanOptions: {recordType: "text"}, message: createMessage([createTextRecord(test_text_data)]), unmatchedMessage: createMessage([createUrlRecord(test_url_data)]) }, { desc: "Test that filtering 'url' record from different messages" + - " correctly with NFCReaderOptions' recordType is set to 'url'.", - readOptions: {recordType: "url"}, + " correctly with NFCScanOptions' recordType is set to 'url'.", + scanOptions: {recordType: "url"}, message: createMessage([createUrlRecord(test_url_data)]), unmatchedMessage: createMessage([createTextRecord(test_text_data)]) }, { desc: "Test that filtering 'text' record from different messages" + - " correctly with NFCReaderOptions' url set.", - readOptions: {url: `${location.origin}/custom/path`}, + " correctly with NFCScanOptions' url set.", + scanOptions: {url: `${location.origin}/custom/path`}, message: {url: `${location.origin}/custom/path/update`, records: [createTextRecord(test_text_data)]}, unmatchedMessage: {url: `${location.origin}/custom/invalid`, @@ -119,15 +119,15 @@ }, { desc: "Test that filtering 'opaque' record from different messages" + - " correctly with NFCReaderOptions' mediaType set.", - readOptions: {mediaType: "application/octet-stream"}, + " correctly with NFCScanOptions' mediaType set.", + scanOptions: {mediaType: "application/octet-stream"}, message: createMessage([createOpaqueRecord(test_buffer_data)]), unmatchedMessage: createMessage([createJsonRecord(test_json_data)]) }, { desc: "Test that filtering 'text' record from different messages" + - " correctly with NFCReaderOptions' compatibility set.", - readOptions: {compatibility: "nfc-forum"}, + " correctly with NFCScanOptions' compatibility set.", + scanOptions: {compatibility: "nfc-forum"}, message: createMessage([createTextRecord(test_text_data)]), unmatchedMessage: createMessage([createJsonRecord(test_json_data)]), unmatchedCompatibility: "vendor" @@ -135,10 +135,10 @@ ]; for (let NFCReaderOptionTest of NFCReaderOptionTests) { - testNFCReaderOptions( + testNFCScanOptions( NFCReaderOptionTest.message, - NFCReaderOptionTest.readOptions, - NFCReaderOptionTest.unmatchedReadOptions, + NFCReaderOptionTest.scanOptions, + NFCReaderOptionTest.unmatchedScanOptions, NFCReaderOptionTest.desc ); } @@ -151,7 +151,7 @@ testReadingMultiMessages( readMultiMessagesTest.message, - readMultiMessagesTest.readOptions, + readMultiMessagesTest.scanOptions, readMultiMessagesTest.unmatchedMessage, unmatchedCompatibility, readMultiMessagesTest.desc diff --git a/web-nfc/resources/nfc-helpers.js b/web-nfc/resources/nfc-helpers.js index 02f348ddf275d5..f7ee7a4786eef3 100644 --- a/web-nfc/resources/nfc-helpers.js +++ b/web-nfc/resources/nfc-helpers.js @@ -172,42 +172,46 @@ function assertWebNDEFMessagesEqual(message, expectedMessage) { } } -function testNFCReaderOptions(message, readOptions, unmatchedReadOptions, desc) { +function testNFCScanOptions(message, scanOptions, unmatchedScanOptions, desc) { nfc_test(async (t, mockNFC) => { - const reader1 = new NFCReader(unmatchedReadOptions); - const reader2 = new NFCReader(readOptions); + const reader1 = new NFCReader(); + const reader2 = new NFCReader(); + const controller = new AbortController(); - mockNFC.setReadingMessage(message, readOptions.compatibility); + mockNFC.setReadingMessage(message, scanOptions.compatibility); // Reading from unmatched reader will not be triggered reader1.onreading = t.unreached_func("reading event should not be fired."); - reader1.start(); + unmatchedScanOptions.signal = controller.signal; + reader1.scan(unmatchedScanOptions); const readerWatcher = new EventWatcher(t, reader2, ["reading", "error"]); const promise = readerWatcher.wait_for("reading").then(event => { - reader1.stop(); - reader2.stop(); + controller.abort(); assertWebNDEFMessagesEqual(event.message, new NDEFMessage(message)); }); - // NFCReader#start() asynchronously dispatches the onreading event. - reader2.start(); + // NFCReader#scan() asynchronously dispatches the onreading event. + scanOptions.signal = controller.signal; + reader2.scan(scanOptions); await promise; }, desc); } -function testReadingMultiMessages(message, readOptions, unmatchedMessage, +function testReadingMultiMessages(message, scanOptions, unmatchedMessage, unmatchedCompatibility, desc) { nfc_test(async (t, mockNFC) => { - const reader = new NFCReader(readOptions); + const reader = new NFCReader(scanOptions); + const controller = new AbortController(); const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); const promise = readerWatcher.wait_for("reading").then(event => { - reader.stop(); + controller.abort(); assertWebNDEFMessagesEqual(event.message, new NDEFMessage(message)); }); - // NFCReader#start() asynchronously dispatches the onreading event. - reader.start(); + // NFCReader#scan() asynchronously dispatches the onreading event. + scanOptions.signal = controller.signal; + reader.scan(scanOptions); // Unmatched message will not be read mockNFC.setReadingMessage(unmatchedMessage, unmatchedCompatibility);