Commit 9d9a5a39 authored by Leon Han's avatar Leon Han Committed by Commit Bot

[webnfc] Bypass android.nfc.NdefRecord.createMime()

This is in preparation for supporting writing NDEFRecord#id into a nfc
tag.

The plan is:
1. Introduces NDEFRecord{Init}#id and supports reading.
   Already done by crrev.com/c/1861574.

2. Supports writing.
   This CL is part of the effort of bypassing all helper functions
   android.nfc.NdefRecord.createXXX() to enable us to write the
   id when constructing android.nfc.NdefRecord.
   See discussions at https://github.com/w3c/web-nfc/issues/410.

3. Introduces NFCScanOptions#id and filters records by it when scanning.

4. Removes NDEFMessage{Init}#url and old impl of the author record.

The spec changes:
https://github.com/w3c/web-nfc/pull/338
https://github.com/w3c/web-nfc/pull/340

BUG=520391

Change-Id: If3c37f59249a6852d0960eac2c3e4319b82a4a11
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1910906Reviewed-by: default avatarFrançois Beaufort <beaufort.francois@gmail.com>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Commit-Queue: Leon Han <leon.han@intel.com>
Cr-Commit-Position: refs/heads/master@{#715193}
parent d7fa6156
......@@ -4,6 +4,7 @@
package org.chromium.device.nfc;
import android.content.Intent;
import android.net.Uri;
import android.nfc.FormatException;
......@@ -118,7 +119,7 @@ public final class NdefMessageUtils {
return new android.nfc.NdefRecord(android.nfc.NdefRecord.TNF_WELL_KNOWN,
android.nfc.NdefRecord.RTD_TEXT, null, payload);
case RECORD_TYPE_MIME:
return android.nfc.NdefRecord.createMime(record.mediaType, record.data);
return createPlatformMimeRecord(record.mediaType, record.id, record.data);
case RECORD_TYPE_UNKNOWN:
return new android.nfc.NdefRecord(
android.nfc.NdefRecord.TNF_UNKNOWN, null, null, record.data);
......@@ -300,6 +301,31 @@ public final class NdefMessageUtils {
return android.nfc.NdefRecord.createUri(new String(url, "UTF-8"));
}
/**
* Creates a TNF_MIME_MEDIA android.nfc.NdefRecord.
*/
public static android.nfc.NdefRecord createPlatformMimeRecord(
String mimeType, String id, byte[] payload) {
// Already verified by NdefMessageValidator.
assert mimeType != null && !mimeType.isEmpty();
// We only do basic MIME type validation: trying to follow the
// RFCs strictly only ends in tears, since there are lots of MIME
// types in common use that are not strictly valid as per RFC rules.
mimeType = Intent.normalizeMimeType(mimeType);
if (mimeType.length() == 0) throw new IllegalArgumentException("mimeType is empty");
int slashIndex = mimeType.indexOf('/');
if (slashIndex == 0) throw new IllegalArgumentException("mimeType must have major type");
if (slashIndex == mimeType.length() - 1) {
throw new IllegalArgumentException("mimeType must have minor type");
}
// missing '/' is allowed
return new android.nfc.NdefRecord(android.nfc.NdefRecord.TNF_MIME_MEDIA,
ApiCompatibilityUtils.getBytesUtf8(mimeType),
id == null ? null : ApiCompatibilityUtils.getBytesUtf8(id), payload);
}
/**
* Parses the input custom type to get its domain and type.
* e.g. returns a pair ('w3.org', 'xyz') for the input 'w3.org:xyz'.
......
......@@ -295,28 +295,28 @@ public class NFCTest {
// Test mime record conversion with "text/plain" mime type.
android.nfc.NdefMessage mimeNdefMessage =
new android.nfc.NdefMessage(android.nfc.NdefRecord.createMime(
TEXT_MIME, ApiCompatibilityUtils.getBytesUtf8(TEST_TEXT)));
new android.nfc.NdefMessage(NdefMessageUtils.createPlatformMimeRecord(
TEXT_MIME, DUMMY_RECORD_ID, ApiCompatibilityUtils.getBytesUtf8(TEST_TEXT)));
NdefMessage mimeMojoNdefMessage = NdefMessageUtils.toNdefMessage(mimeNdefMessage);
assertNull(mimeMojoNdefMessage.url);
assertEquals(1, mimeMojoNdefMessage.data.length);
assertEquals(NdefMessageUtils.RECORD_TYPE_MIME, mimeMojoNdefMessage.data[0].recordType);
assertEquals(TEXT_MIME, mimeMojoNdefMessage.data[0].mediaType);
assertEquals(true, mimeMojoNdefMessage.data[0].id.isEmpty());
assertEquals(DUMMY_RECORD_ID, mimeMojoNdefMessage.data[0].id);
assertNull(mimeMojoNdefMessage.data[0].encoding);
assertNull(mimeMojoNdefMessage.data[0].lang);
assertEquals(TEST_TEXT, new String(mimeMojoNdefMessage.data[0].data));
// Test mime record conversion with "application/json" mime type.
android.nfc.NdefMessage jsonNdefMessage =
new android.nfc.NdefMessage(android.nfc.NdefRecord.createMime(
JSON_MIME, ApiCompatibilityUtils.getBytesUtf8(TEST_JSON)));
new android.nfc.NdefMessage(NdefMessageUtils.createPlatformMimeRecord(
JSON_MIME, DUMMY_RECORD_ID, ApiCompatibilityUtils.getBytesUtf8(TEST_JSON)));
NdefMessage jsonMojoNdefMessage = NdefMessageUtils.toNdefMessage(jsonNdefMessage);
assertNull(jsonMojoNdefMessage.url);
assertEquals(1, jsonMojoNdefMessage.data.length);
assertEquals(NdefMessageUtils.RECORD_TYPE_MIME, jsonMojoNdefMessage.data[0].recordType);
assertEquals(JSON_MIME, jsonMojoNdefMessage.data[0].mediaType);
assertEquals(true, jsonMojoNdefMessage.data[0].id.isEmpty());
assertEquals(DUMMY_RECORD_ID, jsonMojoNdefMessage.data[0].id);
assertNull(jsonMojoNdefMessage.data[0].encoding);
assertNull(jsonMojoNdefMessage.data[0].lang);
assertEquals(TEST_JSON, new String(jsonMojoNdefMessage.data[0].data));
......@@ -373,8 +373,8 @@ public class NFCTest {
assertEquals(TEST_TEXT, new String(payloadMojoMessage.data[0].data));
// Test NdefMessage with an additional WebNFC author record.
android.nfc.NdefRecord jsonNdefRecord = android.nfc.NdefRecord.createMime(
JSON_MIME, ApiCompatibilityUtils.getBytesUtf8(TEST_JSON));
android.nfc.NdefRecord jsonNdefRecord = NdefMessageUtils.createPlatformMimeRecord(
JSON_MIME, DUMMY_RECORD_ID, ApiCompatibilityUtils.getBytesUtf8(TEST_JSON));
android.nfc.NdefRecord extNdefRecord =
android.nfc.NdefRecord.createExternal(AUTHOR_RECORD_DOMAIN, AUTHOR_RECORD_TYPE,
ApiCompatibilityUtils.getBytesUtf8(TEST_URL));
......@@ -384,6 +384,7 @@ public class NFCTest {
assertEquals(TEST_URL, webMojoNdefMessage.url);
assertEquals(1, webMojoNdefMessage.data.length);
assertEquals(NdefMessageUtils.RECORD_TYPE_MIME, webMojoNdefMessage.data[0].recordType);
assertEquals(DUMMY_RECORD_ID, webMojoNdefMessage.data[0].id);
assertEquals(JSON_MIME, webMojoNdefMessage.data[0].mediaType);
assertNull(webMojoNdefMessage.data[0].encoding);
assertNull(webMojoNdefMessage.data[0].lang);
......@@ -490,6 +491,7 @@ public class NFCTest {
NdefRecord mimeMojoNdefRecord = new NdefRecord();
mimeMojoNdefRecord.recordType = NdefMessageUtils.RECORD_TYPE_MIME;
mimeMojoNdefRecord.mediaType = TEXT_MIME;
mimeMojoNdefRecord.id = DUMMY_RECORD_ID;
mimeMojoNdefRecord.data = ApiCompatibilityUtils.getBytesUtf8(TEST_TEXT);
NdefMessage mimeMojoNdefMessage = createMojoNdefMessage(TEST_URL, mimeMojoNdefRecord);
android.nfc.NdefMessage mimeNdefMessage =
......@@ -498,6 +500,7 @@ public class NFCTest {
assertEquals(
android.nfc.NdefRecord.TNF_MIME_MEDIA, mimeNdefMessage.getRecords()[0].getTnf());
assertEquals(TEXT_MIME, mimeNdefMessage.getRecords()[0].toMimeType());
assertEquals(DUMMY_RECORD_ID, new String(mimeNdefMessage.getRecords()[0].getId()));
assertEquals(TEST_TEXT, new String(mimeNdefMessage.getRecords()[0].getPayload()));
assertEquals(
android.nfc.NdefRecord.TNF_EXTERNAL_TYPE, mimeNdefMessage.getRecords()[1].getTnf());
......@@ -506,6 +509,7 @@ public class NFCTest {
NdefRecord jsonMojoNdefRecord = new NdefRecord();
jsonMojoNdefRecord.recordType = NdefMessageUtils.RECORD_TYPE_MIME;
jsonMojoNdefRecord.mediaType = JSON_MIME;
jsonMojoNdefRecord.id = DUMMY_RECORD_ID;
jsonMojoNdefRecord.data = ApiCompatibilityUtils.getBytesUtf8(TEST_JSON);
NdefMessage jsonMojoNdefMessage = createMojoNdefMessage(TEST_URL, jsonMojoNdefRecord);
android.nfc.NdefMessage jsonNdefMessage =
......@@ -514,6 +518,7 @@ public class NFCTest {
assertEquals(
android.nfc.NdefRecord.TNF_MIME_MEDIA, jsonNdefMessage.getRecords()[0].getTnf());
assertEquals(JSON_MIME, jsonNdefMessage.getRecords()[0].toMimeType());
assertEquals(DUMMY_RECORD_ID, new String(jsonNdefMessage.getRecords()[0].getId()));
assertEquals(TEST_JSON, new String(jsonNdefMessage.getRecords()[0].getPayload()));
assertEquals(
android.nfc.NdefRecord.TNF_EXTERNAL_TYPE, jsonNdefMessage.getRecords()[1].getTnf());
......
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