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 294334 44aec780d0d5984970228a5089295af25020d688
parent 294333 543ec76d428e696521580d375b7c8ee5ede01f95
child 294335 11cc5726cc2d47157c1fa230a244bad3596a50a8
push id8824
push userraliiev@mozilla.com
push dateMon, 14 Dec 2015 20:18:56 +0000
treeherdermozilla-aurora@e2031358e2a6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyoshi, smaug
bugs976457
milestone45.0a1
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',