Bug 991970 - Part 2: implement ontagfound/lost. r=smaug, dimi

This commit is contained in:
Yoshi Huang 2014-10-20 17:53:39 +08:00
parent 3ed92b1d34
commit 9598a835f6
9 changed files with 245 additions and 94 deletions

View File

@ -297,6 +297,10 @@ const kEventConstructors = {
return new MozNFCPeerEvent(aName, aProps);
},
},
MozNFCTagEvent: { create: function (aName, aProps) {
return new MozNFCTagEvent(aName, aProps);
},
},
MozOtaStatusEvent: { create: function (aName, aProps) {
return new MozOtaStatusEvent(aName, aProps);
},

View File

@ -408,12 +408,19 @@ NfcContentHelper.prototype = {
break;
case "NFC:DOMEvent":
switch (result.event) {
case NFC.NFC_PEER_EVENT_READY:
case NFC.PEER_EVENT_READY:
this.eventTarget.notifyPeerReady(result.sessionToken);
break;
case NFC.NFC_PEER_EVENT_LOST:
case NFC.PEER_EVENT_LOST:
this.eventTarget.notifyPeerLost(result.sessionToken);
break;
case NFC.TAG_EVENT_FOUND:
let event = new NfcTagEvent(result.techList);
this.eventTarget.notifyTagFound(result.sessionToken, event, result.records);
break;
case NFC.TAG_EVENT_LOST:
this.eventTarget.notifyTagLost(result.sessionToken);
break;
}
break;
}
@ -462,6 +469,15 @@ NfcContentHelper.prototype = {
},
};
function NfcTagEvent(techList) {
this.techList = techList;
}
NfcTagEvent.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsINfcTagEvent]),
techList: null
};
if (NFC_ENABLED) {
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NfcContentHelper]);
}

View File

@ -247,10 +247,25 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
// Remember the target that receives onpeerready.
this.currentPeer = target;
this.notifyDOMEvent(target, {event: NFC.NFC_PEER_EVENT_READY,
this.notifyDOMEvent(target, {event: NFC.PEER_EVENT_READY,
sessionToken: sessionToken});
},
onTagFound: function onTagFound(message) {
message.event = NFC.TAG_EVENT_FOUND;
for (let target of this.eventTargets) {
this.notifyDOMEvent(target, message);
}
delete message.event;
},
onTagLost: function onTagLost(sessionToken) {
for (let target of this.eventTargets) {
this.notifyDOMEvent(target, {event: NFC.TAG_EVENT_LOST,
sessionToken: sessionToken});
}
},
onPeerLost: function onPeerLost(sessionToken) {
if (!this.currentPeer) {
// The target is already killed.
@ -259,7 +274,7 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
// For peerlost, the message is delievered to the target which
// onpeerready has been called before.
this.notifyDOMEvent(this.currentPeer, {event: NFC.NFC_PEER_EVENT_LOST,
this.notifyDOMEvent(this.currentPeer, {event: NFC.PEER_EVENT_LOST,
sessionToken: sessionToken});
this.currentPeer = null;
},
@ -526,8 +541,13 @@ Nfc.prototype = {
SessionHelper.registerSession(message.sessionId, message.techList);
// Do not expose the actual session to the content
let sessionId = message.sessionId;
delete message.sessionId;
if (!SessionHelper.isP2PSession(sessionId)) {
gMessageManager.onTagFound(message);
}
gSystemMessenger.broadcastMessage("nfc-manager-tech-discovered", message);
break;
case "TechLostNotification":
@ -537,6 +557,8 @@ Nfc.prototype = {
message.sessionToken = SessionHelper.getToken(message.sessionId);
if (SessionHelper.isP2PSession(message.sessionId)) {
gMessageManager.onPeerLost(message.sessionToken);
} else {
gMessageManager.onTagLost(message.sessionToken);
}
SessionHelper.unregisterSession(message.sessionId);

View File

@ -86,8 +86,10 @@ this.TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
this.SETTING_NFC_DEBUG = "nfc.debugging.enabled";
this.NFC_PEER_EVENT_READY = 0x01;
this.NFC_PEER_EVENT_LOST = 0x02;
this.PEER_EVENT_READY = 0x01;
this.PEER_EVENT_LOST = 0x02;
this.TAG_EVENT_FOUND = 0x03;
this.TAG_EVENT_LOST = 0x04;
// Allow this file to be imported via Components.utils.import().
this.EXPORTED_SYMBOLS = Object.keys(this);

View File

@ -7,24 +7,52 @@
interface nsIVariant;
[scriptable, uuid(e81cc1ac-6f0b-4581-a9fb-7ee47ed0158e)]
[scriptable, uuid(44eb02f4-6eba-4c12-8ed1-c142513776c9)]
interface nsINfcTagEvent : nsISupports
{
readonly attribute nsIVariant techList;
};
[scriptable, uuid(8d77d653-f76a-4a21-ae3f-c4cc6074d8ec)]
interface nsINfcDOMEventTarget : nsISupports
{
/**
* Callback function used to notify tagfound.
*
* @param sessionToken
* SessionToken received from parent process
* @param event
* nsINfcTagFoundEvent received from parent process.
* @param ndefRecords
* NDEF records pre-read during tag-discovered.
*/
void notifyTagFound(in DOMString sessionToken,
in nsINfcTagEvent event,
in nsIVariant ndefRecords);
/**
* Callback function used to notify taglost.
*
* @param sessionToken
* SessionToken received from parent process
*/
void notifyTagLost(in DOMString sessionToken);
/**
* Callback function used to notify peerready.
*
* @param sessionToken
* SessionToken received from Chrome process
* SessionToken received from parent process
*/
void notifyPeerReady(in DOMString sessionToken);
void notifyPeerReady(in DOMString sessionToken);
/**
* Callback function used to notify peerlost.
*
* @param sessionToken
* SessionToken received from Chrome process
* SessionToken received from parent process
*/
void notifyPeerLost(in DOMString sessionToken);
void notifyPeerLost(in DOMString sessionToken);
};
[scriptable, uuid(cb9c934d-a7fa-422b-bcc1-4ac39741e6ec)]
@ -44,23 +72,23 @@ interface nsINfcContentHelper : nsISupports
nsIDOMDOMRequest connect(in nsIDOMWindow window, in unsigned long techType, in DOMString sessionToken);
nsIDOMDOMRequest close(in nsIDOMWindow window, in DOMString sessionToken);
/**
* Initiate Send file operation
*
* @param window
* Current window
*
* @param blob
* Raw data of the file to be sent. This object represents a file-like
* (nsIDOMFile) object of immutable, raw data. The blob data needs
* to be 'object wrapped' before calling this interface.
*
* @param sessionToken
* Current token
*
* Returns DOMRequest, if initiation of send file operation is successful
* then 'onsuccess' is called else 'onerror'
*/
/**
* Initiate send file operation.
*
* @param window
* Current window
*
* @param blob
* Raw data of the file to be sent. This object represents a file-like
* (nsIDOMFile) object of immutable, raw data. The blob data needs
* to be 'object wrapped' before calling this interface.
*
* @param sessionToken
* Current token
*
* Returns DOMRequest, if initiation of send file operation is successful
* then 'onsuccess' is called else 'onerror'
*/
nsIDOMDOMRequest sendFile(in nsIDOMWindow window,
in jsval blob,
in DOMString sessionToken);
@ -72,66 +100,66 @@ interface nsINfcContentHelper : nsISupports
*/
void registerEventTarget(in nsINfcDOMEventTarget target);
/**
* Register the given application id with Chrome process
*
* @param window
* Current window
*
* @param appId
* Application ID to be registered
*/
/**
* Register the given application id with parent process
*
* @param window
* Current window
*
* @param appId
* Application ID to be registered
*/
void registerTargetForPeerReady(in nsIDOMWindow window,
in unsigned long appId);
/**
* Unregister the given application id with Chrome process
*
* @param window
* Current window
*
* @param appId
* Application ID to be registered
*/
/**
* Unregister the given application id with parent process
*
* @param window
* Current window
*
* @param appId
* Application ID to be registered
*/
void unregisterTargetForPeerReady(in nsIDOMWindow window,
in unsigned long appId);
/**
* Checks if the given application's id is a registered peer target (with the Chrome process)
*
* @param window
* Current window
*
* @param appId
* Application ID to be updated with Chrome process
*
* Returns DOMRequest, if appId is registered then 'onsuccess' is called else 'onerror'
*/
/**
* Checks if the given application's id is a registered peer target (with the parent process)
*
* @param window
* Current window
*
* @param appId
* Application ID to be updated with parent process
*
* Returns DOMRequest, if appId is registered then 'onsuccess' is called else 'onerror'
*/
nsIDOMDOMRequest checkP2PRegistration(in nsIDOMWindow window, in unsigned long appId);
/**
* Notify the Chrome process that user has accepted to share nfc message on P2P UI
*
* @param window
* Current window
*
* @param appId
* Application ID that is capable of handling NFC_EVENT_PEER_READY event
*/
/**
* Notify the parent process that user has accepted to share nfc message on P2P UI
*
* @param window
* Current window
*
* @param appId
* Application ID that is capable of handling NFC_EVENT_PEER_READY event
*/
void notifyUserAcceptedP2P(in nsIDOMWindow window, in unsigned long appId);
/**
* Notify the status of sendFile operation to Chrome process
*
* @param window
* Current window
*
* @param status
* Status of sendFile operation
*
* @param requestId
* Request ID of SendFile DOM Request
*/
/**
* Notify the status of sendFile operation to parent process
*
* @param window
* Current window
*
* @param status
* Status of sendFile operation
*
* @param requestId
* Request ID of SendFile DOM Request
*/
void notifySendFileStatus(in nsIDOMWindow window,
in octet status,
in DOMString requestId);

View File

@ -125,6 +125,11 @@ mozNfc.prototype = {
init: function init(aWindow) {
debug("mozNfc init called");
this._window = aWindow;
this.defineEventHandlerGetterSetter("ontagfound");
this.defineEventHandlerGetterSetter("ontaglost");
this.defineEventHandlerGetterSetter("onpeerready");
this.defineEventHandlerGetterSetter("onpeerlost");
if (this._nfcContentHelper) {
this._nfcContentHelper.init(aWindow);
}
@ -184,22 +189,15 @@ mozNfc.prototype = {
return this.nfcObject.contentObject;
},
// get/set onpeerready
get onpeerready() {
return this.__DOM_IMPL__.getEventHandler("onpeerready");
},
set onpeerready(handler) {
this.__DOM_IMPL__.setEventHandler("onpeerready", handler);
},
// get/set onpeerlost
get onpeerlost() {
return this.__DOM_IMPL__.getEventHandler("onpeerlost");
},
set onpeerlost(handler) {
this.__DOM_IMPL__.setEventHandler("onpeerlost", handler);
defineEventHandlerGetterSetter: function defineEventHandlerGetterSetter(name) {
Object.defineProperty(this, name, {
get: function get() {
return this.__DOM_IMPL__.getEventHandler(name);
},
set: function set(handler) {
this.__DOM_IMPL__.setEventHandler(name, handler);
}
});
},
eventListenerWasAdded: function(eventType) {
@ -220,6 +218,46 @@ mozNfc.prototype = {
this._nfcContentHelper.unregisterTargetForPeerReady(this._window, appId);
},
notifyTagFound: function notifyTagFound(sessionToken, event, records) {
if (this.hasDeadWrapper()) {
dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
return;
}
let tag = new MozNFCTag(this._window, sessionToken);
let tagContentObj = this._window.MozNFCTag._create(this._window, tag);
let length = records ? records.length : 0;
let ndefRecords = records ? [] : null;
for (let i = 0; i < length; i++) {
let record = records[i];
ndefRecords.push(new this._window.MozNDEFRecord({tnf: record.tnf,
type: record.type,
id: record.id,
payload: record.payload}));
}
let eventData = {
"tag": tagContentObj,
"ndefRecords": ndefRecords
};
debug("fire ontagfound " + sessionToken);
let tagEvent = new this._window.MozNFCTagEvent("tagfound", eventData);
this.__DOM_IMPL__.dispatchEvent(tagEvent);
},
notifyTagLost: function notifyTagLost(sessionToken) {
if (this.hasDeadWrapper()) {
dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
return;
}
debug("fire ontaglost " + sessionToken);
let event = new this._window.Event("taglost");
this.__DOM_IMPL__.dispatchEvent(event);
},
notifyPeerReady: function notifyPeerReady(sessionToken) {
if (this.hasDeadWrapper()) {
dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");

View File

@ -72,6 +72,17 @@ interface MozNFC : EventTarget {
attribute EventHandler onpeerready;
[CheckPermissions="nfc-write"]
attribute EventHandler onpeerlost;
/**
* Ths event will be fired when a NFCTag is detected.
*/
[CheckPermissions="nfc-read nfc-write"]
attribute EventHandler ontagfound;
/**
* This event will be fired if the tag detected in ontagfound has been removed.
*/
attribute EventHandler ontaglost;
};
// Mozilla Only

View File

@ -0,0 +1,29 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*/
[Constructor(DOMString type, optional MozNFCTagEventInit eventInitDict),
Func="Navigator::HasNFCSupport", CheckPermissions="nfc-read nfc-write",
AvailableIn="CertifiedApps"]
interface MozNFCTagEvent : Event
{
/**
* The detected NFCTag.
*/
readonly attribute MozNFCTag? tag;
/**
* The MozNDEFRecords pre-read during tag-discovered.
*/
[Cached, Pure]
readonly attribute sequence<MozNDEFRecord>? ndefRecords;
};
dictionary MozNFCTagEventInit : EventInit
{
MozNFCTag? tag = null;
sequence<MozNDEFRecord>? ndefRecords = [];
};

View File

@ -763,6 +763,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
if CONFIG['MOZ_NFC']:
GENERATED_EVENTS_WEBIDL_FILES += [
'MozNFCPeerEvent.webidl',
'MozNFCTagEvent.webidl',
]
if CONFIG['MOZ_BUILD_APP'] in ['browser', 'xulrunner']: