Bug 976457 - B2G NFC: API for supporting NFC_A tags. r=yoshi r=smaug

This commit is contained in:
Thomas Nguyen 2015-11-13 02:01:00 +01:00
parent 0d325be5c6
commit 5645d7e0d3
12 changed files with 259 additions and 23 deletions

View File

@ -5,8 +5,11 @@
* 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 {
@ -35,7 +38,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MozIsoDepTech)
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>
@ -50,14 +53,7 @@ MozIsoDepTech::Constructor(const GlobalObject& aGlobal,
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;
}
@ -80,16 +76,7 @@ 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*

View File

@ -44,7 +44,7 @@ private:
RefPtr<nsPIDOMWindow> mWindow;
RefPtr<MozNFCTag> mTag;
static const NFCTechType mTechnology;
static const NFCTechType sTechnology;
};
} // namespace dom

88
dom/nfc/MozNfcATech.cpp Normal file
View File

@ -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

53
dom/nfc/MozNfcATech.h Normal file
View File

@ -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__

46
dom/nfc/TagUtils.cpp Normal file
View File

@ -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

43
dom/nfc/TagUtils.h Normal file
View File

@ -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__

View File

@ -14,10 +14,14 @@ if CONFIG['MOZ_NFC']:
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',

View File

@ -155,7 +155,8 @@ MozNFCTagImpl.prototype = {
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:

View File

@ -6,7 +6,7 @@
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);

View File

@ -36,7 +36,7 @@ enum NFCTagType {
"MIFARE-Classic"
};
typedef MozIsoDepTech MozTagTech;
typedef (MozIsoDepTech or MozNfcATech) MozTagTech;
[JSImplementation="@mozilla.org/nfc/tag;1", AvailableIn="PrivilegedApps"]
interface MozNFCTag {

View File

@ -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);
};

View File

@ -729,6 +729,7 @@ if CONFIG['MOZ_NFC']:
'MozIsoDepTech.webidl',
'MozNDEFRecord.webidl',
'MozNFC.webidl',
'MozNfcATech.webidl',
'MozNFCPeer.webidl',
'MozNFCTag.webidl',
'NfcOptions.webidl',