Bug 976457 - B2G NFC: API for supporting NFC_A tags. r=yoshi r=smaug
authorThomas Nguyen <tnguyen@mozilla.com>
Fri, 13 Nov 2015 02:01:00 +0100
changeset 272683 44aec780d0d5984970228a5089295af25020d688
parent 272682 543ec76d428e696521580d375b7c8ee5ede01f95
child 272684 11cc5726cc2d47157c1fa230a244bad3596a50a8
push id29681
push userkwierso@gmail.com
push dateMon, 16 Nov 2015 23:39:08 +0000
treeherdermozilla-central@ffe020f91452 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyoshi, smaug
bugs976457
milestone45.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 976457 - B2G NFC: API for supporting NFC_A tags. r=yoshi r=smaug
dom/nfc/MozIsoDepTech.cpp
dom/nfc/MozIsoDepTech.h
dom/nfc/MozNfcATech.cpp
dom/nfc/MozNfcATech.h
dom/nfc/TagUtils.cpp
dom/nfc/TagUtils.h
dom/nfc/moz.build
dom/nfc/nsNfc.js
dom/webidl/MozIsoDepTech.webidl
dom/webidl/MozNFCTag.webidl
dom/webidl/MozNfcATech.webidl
dom/webidl/moz.build
--- a/dom/nfc/MozIsoDepTech.cpp
+++ b/dom/nfc/MozIsoDepTech.cpp
@@ -1,17 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MozIsoDepTech.h"
+#include "TagUtils.h"
 #include "mozilla/dom/Promise.h"
 
+using namespace mozilla::dom::nfc;
+
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(MozIsoDepTech)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(MozIsoDepTech)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
@@ -30,39 +33,32 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(MozIsoDepTech)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(MozIsoDepTech)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MozIsoDepTech)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-const NFCTechType MozIsoDepTech::mTechnology = NFCTechType::ISO_DEP;
+const NFCTechType MozIsoDepTech::sTechnology = NFCTechType::ISO_DEP;
 
 /* static */
 already_AddRefed<MozIsoDepTech>
 MozIsoDepTech::Constructor(const GlobalObject& aGlobal,
                            MozNFCTag& aNFCTag,
                            ErrorResult& aRv)
 {
   ErrorResult rv;
   nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aGlobal.GetAsSupports());
   if (!win) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  Nullable<nsTArray<NFCTechType>> techList;
-  aNFCTag.GetTechList(techList, rv);
-  if (rv.Failed()) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  if (techList.IsNull() || !(techList.Value().Contains(mTechnology))) {
+  if (!TagUtils::IsTechSupported(aNFCTag, sTechnology)) {
     aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return nullptr;
   }
 
   RefPtr<MozIsoDepTech> isoDep = new MozIsoDepTech(win, aNFCTag);
 
   return isoDep.forget();
 }
@@ -75,26 +71,17 @@ MozIsoDepTech::MozIsoDepTech(nsPIDOMWind
 
 MozIsoDepTech::~MozIsoDepTech()
 {
 }
 
 already_AddRefed<Promise>
 MozIsoDepTech::Transceive(const Uint8Array& aCommand, ErrorResult& aRv)
 {
-  ErrorResult rv;
-
-  aCommand.ComputeLengthAndData();
-  RefPtr<Promise> promise = mTag->Transceive(mTechnology, aCommand, rv);
-  if (rv.Failed()) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  return promise.forget();
+  return TagUtils::Transceive(mTag, sTechnology, aCommand, aRv);
 }
 
 JSObject*
 MozIsoDepTech::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return MozIsoDepTechBinding::Wrap(aCx, this, aGivenProto);
 }
 
--- a/dom/nfc/MozIsoDepTech.h
+++ b/dom/nfc/MozIsoDepTech.h
@@ -39,15 +39,15 @@ public:
 
 private:
   MozIsoDepTech(nsPIDOMWindow* aWindow, MozNFCTag& aNFCTag);
   virtual ~MozIsoDepTech();
 
   RefPtr<nsPIDOMWindow> mWindow;
   RefPtr<MozNFCTag> mTag;
 
-  static const NFCTechType mTechnology;
+  static const NFCTechType sTechnology;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif  // mozilla_dom_nfc_MozIsoDepTech_h__
new file mode 100644
--- /dev/null
+++ b/dom/nfc/MozNfcATech.cpp
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "MozNfcATech.h"
+#include "TagUtils.h"
+#include "mozilla/dom/Promise.h"
+
+using namespace mozilla::dom::nfc;
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(MozNfcATech)
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(MozNfcATech)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MozNfcATech)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTag)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MozNfcATech)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTag)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(MozNfcATech)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(MozNfcATech)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MozNfcATech)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+const NFCTechType MozNfcATech::sTechnology = NFCTechType::NFC_A;
+
+/* static */
+already_AddRefed<MozNfcATech>
+MozNfcATech::Constructor(const GlobalObject& aGlobal,
+                         MozNFCTag& aNFCTag,
+                         ErrorResult& aRv)
+{
+  ErrorResult rv;
+  nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aGlobal.GetAsSupports());
+  if (!win) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  if (!TagUtils::IsTechSupported(aNFCTag, sTechnology)) {
+    aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return nullptr;
+  }
+
+  RefPtr<MozNfcATech> nfcA = new MozNfcATech(win, aNFCTag);
+  return nfcA.forget();
+}
+
+MozNfcATech::MozNfcATech(nsPIDOMWindow* aWindow, MozNFCTag& aNFCTag)
+ : mWindow(aWindow)
+ , mTag(&aNFCTag)
+{
+}
+
+MozNfcATech::~MozNfcATech()
+{
+}
+
+already_AddRefed<Promise>
+MozNfcATech::Transceive(const Uint8Array& aCommand, ErrorResult& aRv)
+{
+  return TagUtils::Transceive(mTag, sTechnology, aCommand, aRv);
+}
+
+JSObject*
+MozNfcATech::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return MozNfcATechBinding::Wrap(aCx, this, aGivenProto);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/nfc/MozNfcATech.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_nfc_MozNfcATech_h__
+#define mozilla_dom_nfc_MozNfcATech_h__
+
+#include "mozilla/dom/MozNFCTagBinding.h"
+#include "mozilla/dom/MozNfcATechBinding.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
+#include "nsISupportsImpl.h"
+#include "nsPIDOMWindow.h"
+
+namespace mozilla {
+namespace dom {
+
+class Promise;
+
+class MozNfcATech : public nsISupports,
+                    public nsWrapperCache
+{
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MozNfcATech)
+
+  already_AddRefed<Promise> Transceive(const Uint8Array& aCommand,
+                                       ErrorResult& aRv);
+
+  nsPIDOMWindow* GetParentObject() const { return mWindow; }
+
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+
+  static already_AddRefed<MozNfcATech>
+  Constructor(const GlobalObject& aGlobal, MozNFCTag& aNFCTag,
+              ErrorResult& aRv);
+
+private:
+  MozNfcATech(nsPIDOMWindow* aWindow, MozNFCTag& aNFCTag);
+  virtual ~MozNfcATech();
+
+  RefPtr<nsPIDOMWindow> mWindow;
+  RefPtr<MozNFCTag> mTag;
+
+  static const NFCTechType sTechnology;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif  // mozilla_dom_nfc_MozNfcATech_h__
new file mode 100644
--- /dev/null
+++ b/dom/nfc/TagUtils.cpp
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "TagUtils.h"
+#include "mozilla/dom/Promise.h"
+
+namespace mozilla {
+namespace dom {
+namespace nfc {
+
+bool
+TagUtils::IsTechSupported(const MozNFCTag& aTag,
+                          const NFCTechType& aTechnology)
+{
+  ErrorResult rv;
+
+  Nullable<nsTArray<NFCTechType>> techList;
+  aTag.GetTechList(techList, rv);
+  ENSURE_SUCCESS(rv, false);
+  return !techList.IsNull() && techList.Value().Contains(aTechnology);
+}
+
+already_AddRefed<Promise>
+TagUtils::Transceive(MozNFCTag* aTag,
+                     const NFCTechType& aTechnology,
+                     const Uint8Array& aCommand,
+                     ErrorResult& aRv)
+{
+  ErrorResult rv;
+
+  aCommand.ComputeLengthAndData();
+  RefPtr<Promise> promise = aTag->Transceive(aTechnology, aCommand, rv);
+  if (rv.Failed()) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  return promise.forget();
+}
+
+} // namespace nfc
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/nfc/TagUtils.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_nfc_TagUtils_h__
+#define mozilla_dom_nfc_TagUtils_h__
+
+#include "mozilla/dom/MozNFCTagBinding.h"
+
+namespace mozilla {
+namespace dom {
+namespace nfc {
+
+/**
+ * Class of static helper functions for nfc tag.
+ */
+class TagUtils
+{
+public:
+  /**
+   * Check if specified technogy is supported in this tag.
+   */
+  static bool
+  IsTechSupported(const MozNFCTag& aNFCTag,
+                  const NFCTechType& aTechnology);
+
+  /**
+   * Send raw command to tag and receive the response.
+   */
+  static already_AddRefed<Promise>
+  Transceive(MozNFCTag* aTag,
+             const NFCTechType& aTechnology,
+             const Uint8Array& aCommand,
+             ErrorResult& aRv);
+};
+
+} // namespace nfc
+} // namespace dom
+} // namespace mozilla
+
+#endif  // mozilla_dom_nfc_TagUtils_h__
--- a/dom/nfc/moz.build
+++ b/dom/nfc/moz.build
@@ -9,20 +9,24 @@ XPIDL_MODULE = 'dom_nfc'
 
 if CONFIG['MOZ_NFC']:
     XPIDL_SOURCES += [
         'nsINfcContentHelper.idl',
     ]
     EXPORTS.mozilla.dom += [
         'MozIsoDepTech.h',
         'MozNDEFRecord.h',
+        'MozNfcATech.h',
+        'TagUtils.h',
     ]
     UNIFIED_SOURCES += [
         'MozIsoDepTech.cpp',
         'MozNDEFRecord.cpp',
+        'MozNfcATech.cpp',
+        'TagUtils.cpp',
     ]
     EXTRA_COMPONENTS += [
         'NfcContentHelper.js',
         'NfcContentHelper.manifest',
         'nsNfc.js',
         'nsNfc.manifest',
     ]
 
--- a/dom/nfc/nsNfc.js
+++ b/dom/nfc/nsNfc.js
@@ -150,17 +150,18 @@ MozNFCTagImpl.prototype = {
   id: null,
   type: null,
   maxNDEFSize: null,
   isReadOnly: null,
   isFormatable: null,
   canBeMadeReadOnly: null,
   isLost: false,
 
-  createTech: { "ISO-DEP": (win, tag) => { return new win.MozIsoDepTech(tag); }
+  createTech: { "ISO-DEP": (win, tag) => { return new win.MozIsoDepTech(tag); },
+                "NFC-A"  : (win, tag) => { return new win.MozNfcATech(tag);   },
               },
 
   // NFCTag interface:
   readNDEF: function readNDEF() {
     if (this.isLost) {
       throw new this._window.Error("NFCTag object is invalid");
     }
 
--- a/dom/webidl/MozIsoDepTech.webidl
+++ b/dom/webidl/MozIsoDepTech.webidl
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 [Func="Navigator::HasNFCSupport", AvailableIn="PrivilegedApps",
  ChromeConstructor(MozNFCTag tag)]
 interface MozIsoDepTech {
   /**
-   * Send raw command to tag and receive the response.
+   * Send raw ISO-DEP command to tag and receive the response.
    */
   [Throws]
   Promise<Uint8Array> transceive(Uint8Array command);
 };
--- a/dom/webidl/MozNFCTag.webidl
+++ b/dom/webidl/MozNFCTag.webidl
@@ -31,17 +31,17 @@ enum NFCTechType {
 enum NFCTagType {
   "Type1",
   "Type2",
   "Type3",
   "Type4",
   "MIFARE-Classic"
 };
 
-typedef MozIsoDepTech MozTagTech;
+typedef (MozIsoDepTech or MozNfcATech) MozTagTech;
 
 [JSImplementation="@mozilla.org/nfc/tag;1", AvailableIn="PrivilegedApps"]
 interface MozNFCTag {
   /**
    * The supported technologies of this tag, null if unknown.
    */
   [Cached, Pure] readonly attribute sequence<NFCTechType>? techList;
 
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MozNfcATech.webidl
@@ -0,0 +1,13 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+[Func="Navigator::HasNFCSupport", AvailableIn="PrivilegedApps",
+ ChromeConstructor(MozNFCTag tag)]
+interface MozNfcATech {
+  /**
+   * Send raw NFC-A command to tag and receive the response.
+   */
+  [Throws]
+  Promise<Uint8Array> transceive(Uint8Array command);
+};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -724,16 +724,17 @@ else:
         'PushSubscription.webidl',
     ]
 
 if CONFIG['MOZ_NFC']:
     WEBIDL_FILES += [
          'MozIsoDepTech.webidl',
          'MozNDEFRecord.webidl',
          'MozNFC.webidl',
+         'MozNfcATech.webidl',
          'MozNFCPeer.webidl',
          'MozNFCTag.webidl',
          'NfcOptions.webidl',
     ]
 
 if CONFIG['MOZ_SECUREELEMENT']:
     WEBIDL_FILES += [
          'SecureElement.webidl',