For Developers‎ > ‎Design Documents‎ > ‎

Web NFC

W3C Web NFC API implementation in Chromium

                         

                         Rijubrata Bhaumik <rijubrata.bhaumik@intel.com>

                         Leon Han <leon.han@intel.com>

                         Donna Wu <donna.wu@intel.com>

                        
                      Former: Alexander Shalamov <alexander.shalamov@intel.com>


Last updated: 8 Jan 2020

Objective

This document explains how W3C Web NFC API is implemented in Chromium on both renderer and browser process sides. Future work and implementation challenges are described in “Future work” section of this document.


ED Spec (27 Dec 2019):

W3C Web NFC API https://w3c.github.io/web-nfc/

Background

The Web NFC API enables wireless communication in close proximity between active and passive NFC devices. The means of communication are based on NDEF message exchange specification. The API provides simple, yet powerful interfaces to create, read (receive) or write (send) NDEF compliant messages. The NDEF format was chosen to hide low level complexity and laborious handling of various NFC technology types. The NFC APIs are available on Android, Windows (UWP), iOS, Chrome OS and Linux platforms.

High level overview

The implementation of Web NFC in Chromium consists of two main parts:

The NFC module in Blink located at third_party/blink/renderer/modules/nfc/ which contains Blink JS bindings for Web NFC, and the browser side platform level adaptation that is located at services/device/nfc. The Blink NFC module communicates with the browser adaptation through NFC mojo interface defined in nfc.mojom file and implemented by the services/device/nfc module. At the time of writing, only Android platform is supported behind WebNFC feature flag. Other platforms provide NFC interfaces and can be supported in the future.


NDEFWriter and NDEFReader are the two primary interfaces of the Web NFC APIs.


The NDEFWriter interface has the push method for writing data to NFC devices such as tags. This method will return a promise, which will be resolved when the message is successfully written to some target or be rejected when errors happened or the process is aborted by setting the AbortSignal in the NDEFPushOptions.


The NDEFReader interface has the scan method to try to read data from any NFC device that comes within proximity. Once there is some data found to be matching the filtering criteria provided by web developers in NDEFScanOptions, an NDEFReadingEvent carrying the data will be dispatched to the NDEFReader.

Detailed design

Blink module


Details:

  • NFCProxy will be the mojo interface proxy for NDEFWriter(s) and NDEFReader(s)

    • There will be one NFCProxy instance per Document, and its lifecycle is bound with the document which will align with the Spec’s description “per ExecutionContext”

  • NDEFReader:

    • NFCProxy will have a <reader, watch_id> map to keep all active readers.

    • NDEFReader::scan() will call NFCProxy::StartReading(reader), which will assign a |watch_id| for the |reader| and add it into NFCProxy’s active reader list then call device::mojom::blink::NFC::Watch() to make a request to DeviceService..

    • The promise returned by scan() being resolved means DeviceService has already started the scanning process.

    • The scanning can be aborted anytime by setting the corresponding AbortSignal in NDEFScanOptions, NDEFReader will call NFCProxy::StopReading(reader) to remove itself from NFCProxy’s active reader list and make a request to DeviceService to cancel.

    • Stop itself when document is destroyed or it is destroyed itself.

    • This will be an EventTarget and an ActiveScriptWrappable. If the reader is in the middle of scanning and there are event listeners registered, then it should remain alive until all pending activities get done.

  • NDEFWriter

    • It will implement ContextClient for a valid Document to get NFCProxy and pass the request to the NFCProxy for push() method.

    • A NDEFWriter without any reference could still be kept alive if it has a pending push(), as we bind a persistent reference to it on the Push() Mojo call.

    • The push() can be aborted anytime by setting the corresponding AbortSignal.

Android adaptation




The most important classes for Android adaptation are NfcImpl, NfcTagHandler and NdefMessageUtils.


NfcImpl class implements mojo NFC interface and uses Android platform NFC APIs to access NFC functionality. NfcTagHandler wraps android.nfc.Tag object and provides unified interface for reading / writing NDEF messages. NdefMessageUtils has few static methods for conversion between android.nfc.NdefMessage and mojom.NdefMessage objects.


At runtime, NFC.push operations are stored in PendingPushOperation object and as soon as the NFC tag appears within close proximity, write operation is performed. Same pattern is applicable for NFC.watch operations, the only difference is that NFCImpl will store watch filter criteria together with id, as soon as the tag is within close proximity and contains matching data, NFCImpl will notify its client through mojom.NfcClient interface.

Runtime view

NDEFWriter#push()


NDEFWriter::push() will resolve the promise if there is no error occurred and the message is written to a matched target successfully. In other cases, any errors, or the AbortSignal is set during the process, it will reject the promise.


NDEFReader#scan()


NDEFReader#scan() may trigger NDEFReader#{onreading,onerror}() events during the whole process. NDEFReader::scan() can be called multiple times on the same reader object but there is maximum only one active at any time point.

Future work

  • Support for NFC P2P. At the moment of writing, communication with passive NFC devices (tags) is supported in Chromium browser. In order to add support for active NFC devices (NFC P2P communication), without interfering with default Chromium behavior, intent handling system has to be modified.

  • Support for ISO-DEP. The ISO-DEP (ISO 14443-4) protocol provides low level I/O operations on a NFC tag. This functionality might be required by developers who would like to communicate with smart cards or implement custom communication mechanisms.

  • Support for HCE. Host-based Card Emulation (HCE) would allow web developers to emulate secure element component. This feature would enable ticketing, payments, and other complex use-cases.

  • Bootstrapping WebVR. HMD enclosure can have NFC tag that contains information about lens configuration (dual / single element), FOV, magnet button, URL to be opened and other features.

  • Support for: Chrome OS, Linux and Windows (UWP) platforms.

  • Support for: NFC assisted WebBluetooth handover / pairing.

  • Research whether iOS Core NFC can be used to implement Web NFC support in Chromium on iOS platform.

Security and Privacy

Please see the UX design for detailed information about the permission model.



Web NFC API can be only accessed by top-level secure browsing contexts and user permission is required to access NFC functionality. Web NFC API specification addresses security and privacy topics in chapter 7. Security and Privacy.

Glossary

[Web NFC] W3C Web NFC API https://w3c.github.io/web-nfc/

[active] Active NFC device (phones, NFC readers, powered devices)

[passive] Passive NFC device (tags, smart cards, etc)

[NDEF] NFC Data Exchange Format NDEF definition


ą
Rijubrata Bhaumik,
Jan 8, 2020, 4:24 AM
ą
Rijubrata Bhaumik,
Jan 8, 2020, 4:24 AM
ą
Rijubrata Bhaumik,
Jan 8, 2020, 4:24 AM
Comments