зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1082443 - B2G NFC: event fallback to System app if the foreground app cannot handle it. r=smaug, dimi
This commit is contained in:
Родитель
accb13c8fc
Коммит
9f90a20a21
|
@ -147,6 +147,10 @@ NfcContentHelper.prototype = {
|
|||
},
|
||||
|
||||
encodeNDEFRecords: function encodeNDEFRecords(records) {
|
||||
if (!Array.isArray(records)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let encodedRecords = [];
|
||||
for (let i = 0; i < records.length; i++) {
|
||||
let record = records[i];
|
||||
|
@ -278,6 +282,16 @@ NfcContentHelper.prototype = {
|
|||
rfState: rfState});
|
||||
},
|
||||
|
||||
callDefaultFoundHandler: function callDefaultFoundHandler(sessionToken,
|
||||
isP2P,
|
||||
records) {
|
||||
let encodedRecords = this.encodeNDEFRecords(records);
|
||||
cpmm.sendAsyncMessage("NFC:CallDefaultFoundHandler",
|
||||
{sessionToken: sessionToken,
|
||||
isP2P: isP2P,
|
||||
records: encodedRecords});
|
||||
},
|
||||
|
||||
// nsIObserver
|
||||
observe: function observe(subject, topic, data) {
|
||||
if (topic == "xpcom-shutdown") {
|
||||
|
|
|
@ -57,7 +57,8 @@ const NFC_CID =
|
|||
const NFC_IPC_MSG_ENTRIES = [
|
||||
{ permission: null,
|
||||
messages: ["NFC:AddEventListener",
|
||||
"NFC:QueryInfo"] },
|
||||
"NFC:QueryInfo",
|
||||
"NFC:CallDefaultFoundHandler"] },
|
||||
|
||||
{ permission: "nfc",
|
||||
messages: ["NFC:ReadNDEF",
|
||||
|
@ -227,6 +228,13 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
|||
sessionToken: sessionToken});
|
||||
},
|
||||
|
||||
callDefaultFoundHandler: function callDefaultFoundHandler(message) {
|
||||
let sysMsg = new NfcTechDiscoveredSysMsg(message.sessionToken,
|
||||
message.isP2P,
|
||||
message.records || null);
|
||||
gSystemMessenger.broadcastMessage("nfc-manager-tech-discovered", sysMsg);
|
||||
},
|
||||
|
||||
onTagFound: function onTagFound(message) {
|
||||
let target = this.eventListeners[this.focusApp] ||
|
||||
this.eventListeners[NFC.SYSTEM_APP_ID];
|
||||
|
@ -317,6 +325,9 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
|||
}
|
||||
this.nfc.sendNfcResponse(message.data);
|
||||
return null;
|
||||
case "NFC:CallDefaultFoundHandler":
|
||||
this.callDefaultFoundHandler(message.data);
|
||||
return null;
|
||||
default:
|
||||
return this.nfc.receiveMessage(message);
|
||||
}
|
||||
|
@ -502,11 +513,6 @@ Nfc.prototype = {
|
|||
} else {
|
||||
gMessageManager.onTagFound(message);
|
||||
}
|
||||
|
||||
let sysMsg = new NfcTechDiscoveredSysMsg(message.sessionToken,
|
||||
message.isP2P,
|
||||
message.records || null);
|
||||
gSystemMessenger.broadcastMessage("nfc-manager-tech-discovered", sysMsg);
|
||||
break;
|
||||
case "TechLostNotification":
|
||||
message.type = "techLost";
|
||||
|
|
|
@ -111,7 +111,7 @@ interface nsINfcBrowserAPI : nsISupports
|
|||
in boolean isFocus);
|
||||
};
|
||||
|
||||
[scriptable, uuid(b5194ae8-d5d5-482f-a73f-dd0d755a1972)]
|
||||
[scriptable, uuid(b35f4bf5-e1b8-45f4-b5d3-2ae9b6d5871e)]
|
||||
interface nsINfcContentHelper : nsISupports
|
||||
{
|
||||
void init(in nsIDOMWindow window);
|
||||
|
@ -278,4 +278,19 @@ interface nsINfcContentHelper : nsISupports
|
|||
*/
|
||||
void changeRFState(in DOMString rfState,
|
||||
in nsINfcRequestCallback callback);
|
||||
|
||||
/**
|
||||
* Notify parent process to call the default tagfound or peerfound event
|
||||
* handler.
|
||||
*
|
||||
* @param sessionToken
|
||||
* Session token of this event.
|
||||
* @param isP2P
|
||||
* Is this a P2P Session.
|
||||
* @param records
|
||||
* NDEF Records.
|
||||
*/
|
||||
void callDefaultFoundHandler(in DOMString sessionToken,
|
||||
in boolean isP2P,
|
||||
in nsIVariant records);
|
||||
};
|
||||
|
|
|
@ -431,18 +431,29 @@ MozNFCImpl.prototype = {
|
|||
},
|
||||
|
||||
notifyTagFound: function notifyTagFound(sessionToken, tagInfo, ndefInfo, records) {
|
||||
if (!this.handleTagFound(sessionToken, tagInfo, ndefInfo, records)) {
|
||||
this._nfcContentHelper.callDefaultFoundHandler(sessionToken, false, records);
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles Tag Found event.
|
||||
*
|
||||
* returns true if the app could process this event, false otherwise.
|
||||
*/
|
||||
handleTagFound: function handleTagFound(sessionToken, tagInfo, ndefInfo, records) {
|
||||
if (this.hasDeadWrapper()) {
|
||||
dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.eventService.hasListenersFor(this.__DOM_IMPL__, "tagfound")) {
|
||||
debug("ontagfound is not registered.");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.checkPermissions(["nfc"])) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.eventService.addSystemEventListener(this._window, "visibilitychange",
|
||||
|
@ -465,6 +476,7 @@ MozNFCImpl.prototype = {
|
|||
}
|
||||
|
||||
let eventData = {
|
||||
"cancelable": true,
|
||||
"tag": tag,
|
||||
"ndefRecords": ndefRecords
|
||||
};
|
||||
|
@ -472,6 +484,15 @@ MozNFCImpl.prototype = {
|
|||
debug("fire ontagfound " + sessionToken);
|
||||
let tagEvent = new this._window.MozNFCTagEvent("tagfound", eventData);
|
||||
this.__DOM_IMPL__.dispatchEvent(tagEvent);
|
||||
|
||||
// If defaultPrevented is false, means we need to take the default action
|
||||
// for this event - redirect this event to System app. Before redirecting to
|
||||
// System app, we need revoke the tag object first.
|
||||
if (!tagEvent.defaultPrevented) {
|
||||
this.notifyTagLost(sessionToken);
|
||||
}
|
||||
|
||||
return tagEvent.defaultPrevented;
|
||||
},
|
||||
|
||||
notifyTagLost: function notifyTagLost(sessionToken) {
|
||||
|
@ -504,20 +525,31 @@ MozNFCImpl.prototype = {
|
|||
},
|
||||
|
||||
notifyPeerFound: function notifyPeerFound(sessionToken, isPeerReady) {
|
||||
if (!this.handlePeerFound(sessionToken, isPeerReady)) {
|
||||
this._nfcContentHelper.callDefaultFoundHandler(sessionToken, true, null);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles Peer Found/Peer Ready event.
|
||||
*
|
||||
* returns true if the app could process this event, false otherwise.
|
||||
*/
|
||||
handlePeerFound: function handlePeerFound(sessionToken, isPeerReady) {
|
||||
if (this.hasDeadWrapper()) {
|
||||
dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isPeerReady &&
|
||||
!this.eventService.hasListenersFor(this.__DOM_IMPL__, "peerfound")) {
|
||||
debug("onpeerfound is not registered.");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
let perm = isPeerReady ? ["nfc-share"] : ["nfc"];
|
||||
if (!this.checkPermissions(perm)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.eventService.addSystemEventListener(this._window, "visibilitychange",
|
||||
|
@ -525,12 +557,36 @@ MozNFCImpl.prototype = {
|
|||
|
||||
let peerImpl = new MozNFCPeerImpl(this._window, sessionToken);
|
||||
this.nfcPeer = this._window.MozNFCPeer._create(this._window, peerImpl);
|
||||
let eventData = { "peer": this.nfcPeer };
|
||||
let type = (isPeerReady) ? "peerready" : "peerfound";
|
||||
|
||||
debug("fire on" + type + " " + sessionToken);
|
||||
let event = new this._window.MozNFCPeerEvent(type, eventData);
|
||||
let eventType;
|
||||
let eventData = {
|
||||
"peer": this.nfcPeer
|
||||
};
|
||||
|
||||
if (isPeerReady) {
|
||||
eventType = "peerready";
|
||||
} else {
|
||||
eventData.cancelable = true;
|
||||
eventType = "peerfound";
|
||||
}
|
||||
|
||||
debug("fire on" + eventType + " " + sessionToken);
|
||||
let event = new this._window.MozNFCPeerEvent(eventType, eventData);
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
|
||||
// For peerready we don't take the default action.
|
||||
if (isPeerReady) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If defaultPrevented is false, means we need to take the default action
|
||||
// for this event - redirect this event to System app. Before redirecting to
|
||||
// System app, we need revoke the peer object first.
|
||||
if (!event.defaultPrevented) {
|
||||
this.notifyPeerLost(sessionToken);
|
||||
}
|
||||
|
||||
return event.defaultPrevented;
|
||||
},
|
||||
|
||||
notifyPeerLost: function notifyPeerLost(sessionToken) {
|
||||
|
|
|
@ -90,7 +90,13 @@ interface MozNFC : EventTarget {
|
|||
attribute EventHandler onpeerready;
|
||||
|
||||
/**
|
||||
* This event will be fired when a NFCPeer is detected.
|
||||
* This event will be fired when a NFCPeer is detected. The application has to
|
||||
* be running on the foreground (decided by System app) to receive this event.
|
||||
*
|
||||
* The default action of this event is to dispatch the event in System app
|
||||
* again, and System app will run the default UX behavior (like vibration).
|
||||
* So if the application would like to cancel the event, the application
|
||||
* should call event.preventDefault() or return false in this event handler.
|
||||
*/
|
||||
attribute EventHandler onpeerfound;
|
||||
|
||||
|
@ -101,7 +107,16 @@ interface MozNFC : EventTarget {
|
|||
attribute EventHandler onpeerlost;
|
||||
|
||||
/**
|
||||
* Ths event will be fired when a NFCTag is detected.
|
||||
* This event will be fired when a NFCTag is detected. The application has to
|
||||
* be running on the foreground (decided by System app) to receive this event.
|
||||
*
|
||||
* The default action of this event is to dispatch the event in System app
|
||||
* again, and System app will run the default UX behavior (like vibration) and
|
||||
* launch MozActivity to handle the content of the tag. (For example, System
|
||||
* app will launch Browser if the tag contains URL). So if the application
|
||||
* would like to cancel the event, i.e. in the above example, the application
|
||||
* would process the URL by itself without launching Browser, the application
|
||||
* should call event.preventDefault() or return false in this event handler.
|
||||
*/
|
||||
attribute EventHandler ontagfound;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче