Commit 5b152f15 authored by Leon Han's avatar Leon Han Committed by Commit Bot

[webnfc] Introduce NDEFCompatibility to replace NFCWatchMode

This CL switches the existing enum NFCWatchMode to NDEFCompatibility
which is newly defined at
http://w3c.github.io/web-nfc/#dom-ndefcompatibility
and updated the behaviors implemented in Device Service accordingly.

Now we just use it for watch operations, in the future we'll be using it
for push operations as well.

BUG=520391

Change-Id: I82cf736d1a57044e9fd59a350b748b99548f9a82
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1628537
Commit-Queue: Leon Han <leon.han@intel.com>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#666621}
parent 7c7006f2
...@@ -23,6 +23,7 @@ import android.util.SparseArray; ...@@ -23,6 +23,7 @@ import android.util.SparseArray;
import org.chromium.base.Callback; import org.chromium.base.Callback;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.Log; import org.chromium.base.Log;
import org.chromium.device.mojom.NdefCompatibility;
import org.chromium.device.mojom.NdefMessage; import org.chromium.device.mojom.NdefMessage;
import org.chromium.device.mojom.Nfc; import org.chromium.device.mojom.Nfc;
import org.chromium.device.mojom.NfcClient; import org.chromium.device.mojom.NfcClient;
...@@ -30,7 +31,6 @@ import org.chromium.device.mojom.NfcError; ...@@ -30,7 +31,6 @@ import org.chromium.device.mojom.NfcError;
import org.chromium.device.mojom.NfcErrorType; import org.chromium.device.mojom.NfcErrorType;
import org.chromium.device.mojom.NfcPushOptions; import org.chromium.device.mojom.NfcPushOptions;
import org.chromium.device.mojom.NfcPushTarget; import org.chromium.device.mojom.NfcPushTarget;
import org.chromium.device.mojom.NfcWatchMode;
import org.chromium.device.mojom.NfcWatchOptions; import org.chromium.device.mojom.NfcWatchOptions;
import org.chromium.mojo.bindings.Callbacks; import org.chromium.mojo.bindings.Callbacks;
import org.chromium.mojo.system.MojoException; import org.chromium.mojo.system.MojoException;
...@@ -544,20 +544,21 @@ public class NfcImpl implements Nfc { ...@@ -544,20 +544,21 @@ public class NfcImpl implements Nfc {
Log.w(TAG, "Cannot read data from NFC tag. IO_ERROR."); Log.w(TAG, "Cannot read data from NFC tag. IO_ERROR.");
} }
if (message != null) notifyMatchingWatchers(message); if (message != null) notifyMatchingWatchers(message, mTagHandler.compatibility());
} }
/** /**
* Iterates through active watchers and if any of those match NfcWatchOptions criteria, * Iterates through active watchers and if any of those match NfcWatchOptions criteria,
* delivers NdefMessage to the client. * delivers NdefMessage to the client.
*/ */
private void notifyMatchingWatchers(android.nfc.NdefMessage message) { private void notifyMatchingWatchers(android.nfc.NdefMessage message, int compatibility) {
try { try {
NdefMessage ndefMessage = NfcTypeConverter.toNdefMessage(message); NdefMessage ndefMessage = NfcTypeConverter.toNdefMessage(message);
List<Integer> watchIds = new ArrayList<Integer>(); List<Integer> watchIds = new ArrayList<Integer>();
for (int i = 0; i < mWatchers.size(); i++) { for (int i = 0; i < mWatchers.size(); i++) {
NfcWatchOptions options = mWatchers.valueAt(i); NfcWatchOptions options = mWatchers.valueAt(i);
if (matchesWatchOptions(ndefMessage, options)) watchIds.add(mWatchers.keyAt(i)); if (matchesWatchOptions(ndefMessage, compatibility, options))
watchIds.add(mWatchers.keyAt(i));
} }
if (watchIds.size() != 0) { if (watchIds.size() != 0) {
...@@ -575,10 +576,12 @@ public class NfcImpl implements Nfc { ...@@ -575,10 +576,12 @@ public class NfcImpl implements Nfc {
/** /**
* Implements matching algorithm. * Implements matching algorithm.
*/ */
private boolean matchesWatchOptions(NdefMessage message, NfcWatchOptions options) { private boolean matchesWatchOptions(
// Valid WebNFC message must have non-empty url. NdefMessage message, int compatibility, NfcWatchOptions options) {
if (options.mode == NfcWatchMode.WEBNFC_ONLY // 'nfc-forum' option can only read messages from NFC standard devices and 'vendor' option
&& (message.url == null || message.url.isEmpty())) { // can only read from vendor specific ones.
if (options.compatibility != NdefCompatibility.ANY
&& options.compatibility != compatibility) {
return false; return false;
} }
......
...@@ -12,12 +12,15 @@ import android.nfc.tech.Ndef; ...@@ -12,12 +12,15 @@ import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable; import android.nfc.tech.NdefFormatable;
import android.nfc.tech.TagTechnology; import android.nfc.tech.TagTechnology;
import org.chromium.device.mojom.NdefCompatibility;
import java.io.IOException; import java.io.IOException;
/** /**
* Utility class that provides I/O operations for NFC tags. * Utility class that provides I/O operations for NFC tags.
*/ */
public class NfcTagHandler { public class NfcTagHandler {
private final int mCompatibility;
private final TagTechnology mTech; private final TagTechnology mTech;
private final TagTechnologyHandler mTechHandler; private final TagTechnologyHandler mTechHandler;
private boolean mWasConnected; private boolean mWasConnected;
...@@ -32,11 +35,20 @@ public class NfcTagHandler { ...@@ -32,11 +35,20 @@ public class NfcTagHandler {
if (tag == null) return null; if (tag == null) return null;
Ndef ndef = Ndef.get(tag); Ndef ndef = Ndef.get(tag);
if (ndef != null) return new NfcTagHandler(ndef, new NdefHandler(ndef)); if (ndef != null) {
int compatibility = NdefCompatibility.VENDOR;
String type = ndef.getType();
if (type.equals(Ndef.NFC_FORUM_TYPE_1) || type.equals(Ndef.NFC_FORUM_TYPE_2)
|| type.equals(Ndef.NFC_FORUM_TYPE_3) || type.equals(Ndef.NFC_FORUM_TYPE_4)) {
compatibility = NdefCompatibility.NFC_FORUM;
}
return new NfcTagHandler(compatibility, ndef, new NdefHandler(ndef));
}
NdefFormatable formattable = NdefFormatable.get(tag); NdefFormatable formattable = NdefFormatable.get(tag);
if (formattable != null) { if (formattable != null) {
return new NfcTagHandler(formattable, new NdefFormattableHandler(formattable)); return new NfcTagHandler(
NdefCompatibility.VENDOR, formattable, new NdefFormattableHandler(formattable));
} }
return null; return null;
...@@ -100,7 +112,8 @@ public class NfcTagHandler { ...@@ -100,7 +112,8 @@ public class NfcTagHandler {
} }
} }
protected NfcTagHandler(TagTechnology tech, TagTechnologyHandler handler) { protected NfcTagHandler(int compatibility, TagTechnology tech, TagTechnologyHandler handler) {
mCompatibility = compatibility;
mTech = tech; mTech = tech;
mTechHandler = handler; mTechHandler = handler;
} }
...@@ -154,4 +167,12 @@ public class NfcTagHandler { ...@@ -154,4 +167,12 @@ public class NfcTagHandler {
} }
return false; return false;
} }
/**
* Returns NdefCompatibility.NFC_FORUM if the tag has a NFC standard type, otherwise returns
* NdefCompatibility.VENDOR.
*/
public int compatibility() {
return mCompatibility;
}
} }
...@@ -33,12 +33,13 @@ enum NFCPushTarget { ...@@ -33,12 +33,13 @@ enum NFCPushTarget {
ANY ANY
}; };
enum NFCWatchMode { enum NDEFCompatibility {
// Restricts scope of the watch operation. Only Web NFC messages must be // Allows all active and passive NFC devices, supported by the NFC standard.
// used by matching algorithm. NFC_FORUM,
WEBNFC_ONLY, // Allows vendor specific NFC tags (passive device) that require specific
// Allows performing watch operation for all NFC messages. For example, NFC // reader chips.
// tags with valid NDEF messages. VENDOR,
// Allows all NDEF compatible devices that the reader chip can read.
ANY ANY
}; };
...@@ -96,8 +97,8 @@ struct NFCWatchOptions { ...@@ -96,8 +97,8 @@ struct NFCWatchOptions {
// Defines media type filtering constraint. // Defines media type filtering constraint.
string? media_type; string? media_type;
// Defines mode of watch operation. // Defines the accepted kind of NFC devices.
NFCWatchMode mode; NDEFCompatibility compatibility;
}; };
interface NFC { interface NFC {
......
...@@ -38,6 +38,7 @@ const char kCharSetUTF8[] = ";charset=UTF-8"; ...@@ -38,6 +38,7 @@ const char kCharSetUTF8[] = ";charset=UTF-8";
// Mojo type converters // Mojo type converters
namespace mojo { namespace mojo {
using device::mojom::blink::NDEFCompatibility;
using device::mojom::blink::NDEFMessage; using device::mojom::blink::NDEFMessage;
using device::mojom::blink::NDEFMessagePtr; using device::mojom::blink::NDEFMessagePtr;
using device::mojom::blink::NDEFRecord; using device::mojom::blink::NDEFRecord;
...@@ -47,11 +48,10 @@ using device::mojom::blink::NDEFRecordTypeFilter; ...@@ -47,11 +48,10 @@ using device::mojom::blink::NDEFRecordTypeFilter;
using device::mojom::blink::NFCPushOptions; using device::mojom::blink::NFCPushOptions;
using device::mojom::blink::NFCPushOptionsPtr; using device::mojom::blink::NFCPushOptionsPtr;
using device::mojom::blink::NFCPushTarget; using device::mojom::blink::NFCPushTarget;
using device::mojom::blink::NFCWatchMode;
using device::mojom::blink::NFCWatchOptions; using device::mojom::blink::NFCWatchOptions;
using device::mojom::blink::NFCWatchOptionsPtr; using device::mojom::blink::NFCWatchOptionsPtr;
NFCPushTarget toNFCPushTarget(const String& target) { NFCPushTarget ToNFCPushTarget(const String& target) {
if (target == "tag") if (target == "tag")
return NFCPushTarget::TAG; return NFCPushTarget::TAG;
...@@ -61,7 +61,7 @@ NFCPushTarget toNFCPushTarget(const String& target) { ...@@ -61,7 +61,7 @@ NFCPushTarget toNFCPushTarget(const String& target) {
return NFCPushTarget::ANY; return NFCPushTarget::ANY;
} }
NDEFRecordType toNDEFRecordType(const String& recordType) { NDEFRecordType ToNDEFRecordType(const String& recordType) {
if (recordType == "empty") if (recordType == "empty")
return NDEFRecordType::EMPTY; return NDEFRecordType::EMPTY;
...@@ -81,15 +81,18 @@ NDEFRecordType toNDEFRecordType(const String& recordType) { ...@@ -81,15 +81,18 @@ NDEFRecordType toNDEFRecordType(const String& recordType) {
return NDEFRecordType::EMPTY; return NDEFRecordType::EMPTY;
} }
NFCWatchMode toNFCWatchMode(const String& watchMode) { NDEFCompatibility ToNDEFCompatibility(const String& compatibility) {
if (watchMode == "web-nfc-only") if (compatibility == "nfc-forum")
return NFCWatchMode::WEBNFC_ONLY; return NDEFCompatibility::NFC_FORUM;
if (watchMode == "any") if (compatibility == "vendor")
return NFCWatchMode::ANY; return NDEFCompatibility::VENDOR;
if (compatibility == "any")
return NDEFCompatibility::ANY;
NOTREACHED(); NOTREACHED();
return NFCWatchMode::WEBNFC_ONLY; return NDEFCompatibility::NFC_FORUM;
} }
// https://w3c.github.io/web-nfc/#creating-web-nfc-message Step 2.1 // https://w3c.github.io/web-nfc/#creating-web-nfc-message Step 2.1
...@@ -221,7 +224,7 @@ struct TypeConverter<NDEFRecordPtr, blink::NDEFRecord*> { ...@@ -221,7 +224,7 @@ struct TypeConverter<NDEFRecordPtr, blink::NDEFRecord*> {
NDEFRecordPtr recordPtr = NDEFRecord::New(); NDEFRecordPtr recordPtr = NDEFRecord::New();
if (record->hasRecordType()) if (record->hasRecordType())
recordPtr->record_type = toNDEFRecordType(record->recordType()); recordPtr->record_type = ToNDEFRecordType(record->recordType());
else else
recordPtr->record_type = deduceRecordTypeFromDataType(record); recordPtr->record_type = deduceRecordTypeFromDataType(record);
...@@ -312,7 +315,7 @@ struct TypeConverter<NFCPushOptionsPtr, const blink::NFCPushOptions*> { ...@@ -312,7 +315,7 @@ struct TypeConverter<NFCPushOptionsPtr, const blink::NFCPushOptions*> {
NFCPushOptionsPtr pushOptionsPtr = NFCPushOptions::New(); NFCPushOptionsPtr pushOptionsPtr = NFCPushOptions::New();
if (pushOptions->hasTarget()) if (pushOptions->hasTarget())
pushOptionsPtr->target = toNFCPushTarget(pushOptions->target()); pushOptionsPtr->target = ToNFCPushTarget(pushOptions->target());
else else
pushOptionsPtr->target = NFCPushTarget::ANY; pushOptionsPtr->target = NFCPushTarget::ANY;
...@@ -336,20 +339,17 @@ struct TypeConverter<NFCWatchOptionsPtr, const blink::NFCWatchOptions*> { ...@@ -336,20 +339,17 @@ struct TypeConverter<NFCWatchOptionsPtr, const blink::NFCWatchOptions*> {
const blink::NFCWatchOptions* watchOptions) { const blink::NFCWatchOptions* watchOptions) {
// https://w3c.github.io/web-nfc/#the-nfcwatchoptions-dictionary // https://w3c.github.io/web-nfc/#the-nfcwatchoptions-dictionary
// Default values for NFCWatchOptions dictionary are: // Default values for NFCWatchOptions dictionary are:
// url = "", recordType = null, mediaType = "", mode = "web-nfc-only" // url = "", recordType = null, mediaType = "", compatibility = "nfc-forum"
NFCWatchOptionsPtr watchOptionsPtr = NFCWatchOptions::New(); NFCWatchOptionsPtr watchOptionsPtr = NFCWatchOptions::New();
watchOptionsPtr->url = watchOptions->url(); watchOptionsPtr->url = watchOptions->url();
watchOptionsPtr->media_type = watchOptions->mediaType(); watchOptionsPtr->media_type = watchOptions->mediaType();
watchOptionsPtr->compatibility =
if (watchOptions->hasMode()) ToNDEFCompatibility(watchOptions->compatibility());
watchOptionsPtr->mode = toNFCWatchMode(watchOptions->mode());
else
watchOptionsPtr->mode = NFCWatchMode::WEBNFC_ONLY;
if (watchOptions->hasRecordType()) { if (watchOptions->hasRecordType()) {
watchOptionsPtr->record_filter = NDEFRecordTypeFilter::New(); watchOptionsPtr->record_filter = NDEFRecordTypeFilter::New();
watchOptionsPtr->record_filter->record_type = watchOptionsPtr->record_filter->record_type =
toNDEFRecordType(watchOptions->recordType()); ToNDEFRecordType(watchOptions->recordType());
} }
return watchOptionsPtr; return watchOptionsPtr;
...@@ -446,7 +446,7 @@ ScriptPromise RejectIfInvalidNDEFRecord(ScriptState* script_state, ...@@ -446,7 +446,7 @@ ScriptPromise RejectIfInvalidNDEFRecord(ScriptState* script_state,
const NDEFRecord* record) { const NDEFRecord* record) {
device::mojom::blink::NDEFRecordType type; device::mojom::blink::NDEFRecordType type;
if (record->hasRecordType()) { if (record->hasRecordType()) {
type = mojo::toNDEFRecordType(record->recordType()); type = mojo::ToNDEFRecordType(record->recordType());
} else { } else {
type = mojo::deduceRecordTypeFromDataType(record); type = mojo::deduceRecordTypeFromDataType(record);
...@@ -751,7 +751,7 @@ ScriptPromise NFC::cancelPush(ScriptState* script_state, const String& target) { ...@@ -751,7 +751,7 @@ ScriptPromise NFC::cancelPush(ScriptState* script_state, const String& target) {
requests_.insert(resolver); requests_.insert(resolver);
auto callback = WTF::Bind(&NFC::OnRequestCompleted, WrapPersistent(this), auto callback = WTF::Bind(&NFC::OnRequestCompleted, WrapPersistent(this),
WrapPersistent(resolver)); WrapPersistent(resolver));
nfc_->CancelPush(mojo::toNFCPushTarget(target), std::move(callback)); nfc_->CancelPush(mojo::ToNFCPushTarget(target), std::move(callback));
return resolver->Promise(); return resolver->Promise();
} }
......
...@@ -2,13 +2,14 @@ ...@@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// https://w3c.github.io/web-nfc/#the-nfcwatchoptions-dictionary
enum NFCWatchMode { "web-nfc-only", "any" }; // http://w3c.github.io/web-nfc/#dom-ndefcompatibility
enum NDEFCompatibility { "nfc-forum", "vendor", "any" };
// https://w3c.github.io/web-nfc/#the-nfcwatchoptions-dictionary
dictionary NFCWatchOptions { dictionary NFCWatchOptions {
USVString url = ""; USVString url = "";
NDEFRecordType? recordType; NDEFRecordType? recordType;
USVString mediaType = ""; USVString mediaType = "";
NFCWatchMode mode = "web-nfc-only"; NDEFCompatibility compatibility = "nfc-forum";
}; };
...@@ -47,8 +47,8 @@ function createNFCPushOptions(target, timeout, ignoreRead) { ...@@ -47,8 +47,8 @@ function createNFCPushOptions(target, timeout, ignoreRead) {
return { target, timeout, ignoreRead }; return { target, timeout, ignoreRead };
} }
function createNFCWatchOptions(url, recordType, mediaType, mode) { function createNFCWatchOptions(url, recordType, mediaType, compatibility) {
return { url, recordType, mediaType, mode}; return { url, recordType, mediaType, compatibility };
} }
function createTextRecord(text) { function createTextRecord(text) {
...@@ -95,10 +95,12 @@ function toMojoNFCPushTarget(target) { ...@@ -95,10 +95,12 @@ function toMojoNFCPushTarget(target) {
return device.mojom.NFCPushTarget.ANY; return device.mojom.NFCPushTarget.ANY;
} }
function toMojoNFCWatchMode(mode) { function toMojoNDEFCompatibility(compatibility) {
if (mode === 'web-nfc-only') if (compatibility === 'nfc-forum')
return device.mojom.NFCWatchMode.WEBNFC_ONLY; return device.mojom.NDEFCompatibility.NFC_FORUM;
return device.mojom.NFCWatchMode.ANY; if (compatibility === 'vendor')
return device.mojom.NDEFCompatibility.VENDOR;
return device.mojom.NDEFCompatibility.ANY;
} }
// Converts between NDEFMessage https://w3c.github.io/web-nfc/#dom-ndefmessage // Converts between NDEFMessage https://w3c.github.io/web-nfc/#dom-ndefmessage
...@@ -233,10 +235,10 @@ function assertNFCWatchOptionsEqual(provided, received) { ...@@ -233,10 +235,10 @@ function assertNFCWatchOptionsEqual(provided, received) {
else else
assert_equals(received.mediaType, ''); assert_equals(received.mediaType, '');
if (provided.mode !== undefined) if (provided.compatibility !== undefined)
assert_equals(toMojoNFCWatchMode(provided.mode), received.mode); assert_equals(toMojoNDEFCompatibility(provided.compatibility), received.compatibility);
else else
assert_equals(received.mode, device.mojom.NFCWatchMode.WEBNFC_ONLY); assert_equals(received.compatibility, device.mojom.NDEFCompatibility.NFC_FORUM);
if (provided.recordType !== undefined) { if (provided.recordType !== undefined) {
assert_equals(!+received.record_filter, true); assert_equals(!+received.record_filter, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment