зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1105666 - [BrowserAPI] Add an API to indicate this iframe could receive NFC event. r=smaug, kanru, yoshi
This commit is contained in:
Родитель
8e3173a869
Коммит
a09be7bb0a
|
@ -834,6 +834,35 @@ BrowserElementParent.prototype = {
|
|||
{isActive: isActive});
|
||||
},
|
||||
|
||||
setNFCFocus: function(isFocus) {
|
||||
if (!this._isAlive()) {
|
||||
throw Components.Exception("Dead content process",
|
||||
Cr.NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
}
|
||||
|
||||
// For now, we use tab id as an identifier to let NFC module know
|
||||
// which app is in foreground. But this approach will not work in
|
||||
// in-process mode because tab id doesn't exist. Fix bug 1116449
|
||||
// if we are going to support in-process mode.
|
||||
try {
|
||||
var tabId = this._frameLoader.QueryInterface(Ci.nsIFrameLoader)
|
||||
.tabParent
|
||||
.tabId;
|
||||
} catch(e) {
|
||||
debug("SetNFCFocus for in-process mode is not yet supported");
|
||||
throw Components.Exception("SetNFCFocus for in-process mode is not yet supported",
|
||||
Cr.NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
try {
|
||||
let nfcContentHelper =
|
||||
Cc["@mozilla.org/nfc/content-helper;1"].getService(Ci.nsINfcBrowserAPI);
|
||||
nfcContentHelper.setFocusApp(tabId, isFocus);
|
||||
} catch(e) {
|
||||
// Not all platforms support NFC
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the visibility of the window which owns this iframe changes.
|
||||
*/
|
||||
|
|
|
@ -26,7 +26,7 @@ interface nsIBrowserElementNextPaintListener : nsISupports
|
|||
* Interface to the BrowserElementParent implementation. All methods
|
||||
* but setFrameLoader throw when the remote process is dead.
|
||||
*/
|
||||
[scriptable, uuid(abae4fb1-7d6f-4e3f-b435-6501f1d4c659)]
|
||||
[scriptable, uuid(3811446f-90bb-42c1-b2b6-aae3603b61e1)]
|
||||
interface nsIBrowserElementAPI : nsISupports
|
||||
{
|
||||
void setFrameLoader(in nsIFrameLoader frameLoader);
|
||||
|
@ -71,4 +71,6 @@ interface nsIBrowserElementAPI : nsISupports
|
|||
void removeNextPaintListener(in nsIBrowserElementNextPaintListener listener);
|
||||
|
||||
nsIDOMDOMRequest setInputMethodActive(in boolean isActive);
|
||||
|
||||
void setNFCFocus(in boolean isFocus);
|
||||
};
|
||||
|
|
|
@ -542,4 +542,36 @@ nsBrowserElement::SetInputMethodActive(bool aIsActive,
|
|||
return req.forget().downcast<DOMRequest>();
|
||||
}
|
||||
|
||||
void
|
||||
nsBrowserElement::SetNFCFocus(bool aIsFocus,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
NS_ENSURE_TRUE_VOID(IsBrowserElementOrThrow(aRv));
|
||||
|
||||
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
||||
if (!frameLoader) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMElement> ownerElement;
|
||||
nsresult rv = frameLoader->GetOwnerElement(getter_AddRefs(ownerElement));
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(ownerElement);
|
||||
nsCOMPtr<nsIPrincipal> principal = node->NodePrincipal();
|
||||
if (!nsContentUtils::IsExactSitePermAllow(principal, "nfc-manager")) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
rv = mBrowserElementAPI->SetNFCFocus(aIsFocus);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -89,6 +89,9 @@ public:
|
|||
already_AddRefed<dom::DOMRequest> SetInputMethodActive(bool isActive,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void SetNFCFocus(bool isFocus,
|
||||
ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
NS_IMETHOD_(already_AddRefed<nsFrameLoader>) GetFrameLoader() = 0;
|
||||
nsCOMPtr<nsIBrowserElementAPI> mBrowserElementAPI;
|
||||
|
|
|
@ -10,7 +10,7 @@ interface nsIWebBrowserChrome3;
|
|||
native CommandsArray(nsTArray<nsCString>);
|
||||
[ref] native CommandsArrayRef(nsTArray<nsCString>);
|
||||
|
||||
[scriptable, uuid(7227bac4-b6fe-4090-aeb4-bc288b790925)]
|
||||
[scriptable, uuid(1fb79c27-e760-4088-b19c-1ce3673ec24e)]
|
||||
interface nsITabChild : nsISupports
|
||||
{
|
||||
readonly attribute nsIContentFrameMessageManager messageManager;
|
||||
|
@ -22,5 +22,7 @@ interface nsITabChild : nsISupports
|
|||
[noscript, notxpcom] void enableDisableCommands(in AString action,
|
||||
in CommandsArrayRef enabledCommands,
|
||||
in CommandsArrayRef disabledCommands);
|
||||
|
||||
readonly attribute uint64_t tabId;
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(33e8571d-5e5d-4000-81cf-e01f5f85d424)]
|
||||
[scriptable, uuid(30361a5b-a3b8-4dbc-b464-e08761abb123)]
|
||||
interface nsITabParent : nsISupports
|
||||
{
|
||||
void injectTouchEvent(in AString aType,
|
||||
|
@ -22,4 +22,6 @@ interface nsITabParent : nsISupports
|
|||
readonly attribute boolean useAsyncPanZoom;
|
||||
|
||||
void setIsDocShellActive(in bool aIsActive);
|
||||
|
||||
readonly attribute uint64_t tabId;
|
||||
};
|
||||
|
|
|
@ -3372,6 +3372,14 @@ TabChild::EnableDisableCommands(const nsAString& aAction,
|
|||
aEnabledCommands, aDisabledCommands);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::GetTabId(uint64_t* aId)
|
||||
{
|
||||
*aId = GetTabId();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
|
|
|
@ -2490,6 +2490,13 @@ TabParent::SetIsDocShellActive(bool isActive)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabParent::GetTabId(uint64_t* aId)
|
||||
{
|
||||
*aId = GetTabId();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvRemotePaintIsReady()
|
||||
{
|
||||
|
|
|
@ -79,18 +79,21 @@ NfcContentHelper.prototype = {
|
|||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINfcContentHelper,
|
||||
Ci.nsINfcBrowserAPI,
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsIObserver]),
|
||||
classID: NFCCONTENTHELPER_CID,
|
||||
classInfo: XPCOMUtils.generateCI({
|
||||
classID: NFCCONTENTHELPER_CID,
|
||||
classDescription: "NfcContentHelper",
|
||||
interfaces: [Ci.nsINfcContentHelper]
|
||||
interfaces: [Ci.nsINfcContentHelper,
|
||||
Ci.nsINfcBrowserAPI]
|
||||
}),
|
||||
|
||||
_window: null,
|
||||
_requestMap: null,
|
||||
_rfState: null,
|
||||
_tabId: null,
|
||||
eventListener: null,
|
||||
|
||||
init: function init(aWindow) {
|
||||
|
@ -112,6 +115,31 @@ NfcContentHelper.prototype = {
|
|||
|
||||
let info = cpmm.sendSyncMessage("NFC:QueryInfo")[0];
|
||||
this._rfState = info.rfState;
|
||||
|
||||
// For now, we assume app will run in oop mode so we can get
|
||||
// tab id for each app. Fix bug 1116449 if we are going to
|
||||
// support in-process mode.
|
||||
let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
try {
|
||||
this._tabId = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsITabChild)
|
||||
.tabId;
|
||||
} catch(e) {
|
||||
// Only parent process does not have tab id, so in this case
|
||||
// NfcContentHelper is used by system app. Use -1(tabId) to
|
||||
// indicate its system app.
|
||||
let inParent = Cc["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Ci.nsIXULRuntime)
|
||||
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
if (inParent) {
|
||||
this._tabId = -1;
|
||||
} else {
|
||||
throw Components.Exception("Can't get tab id in child process",
|
||||
Cr.NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
queryRFState: function queryRFState() {
|
||||
|
@ -132,6 +160,13 @@ NfcContentHelper.prototype = {
|
|||
return encodedRecords;
|
||||
},
|
||||
|
||||
setFocusApp: function setFocusApp(tabId, isFocus) {
|
||||
cpmm.sendAsyncMessage("NFC:SetFocusApp", {
|
||||
tabId: tabId,
|
||||
isFocus: isFocus
|
||||
});
|
||||
},
|
||||
|
||||
// NFCTag interface
|
||||
readNDEF: function readNDEF(sessionToken, callback) {
|
||||
let requestId = callback.getCallbackId();
|
||||
|
@ -207,7 +242,7 @@ NfcContentHelper.prototype = {
|
|||
|
||||
addEventListener: function addEventListener(listener) {
|
||||
this.eventListener = listener;
|
||||
cpmm.sendAsyncMessage("NFC:AddEventListener");
|
||||
cpmm.sendAsyncMessage("NFC:AddEventListener", { tabId: this._tabId });
|
||||
},
|
||||
|
||||
registerTargetForPeerReady: function registerTargetForPeerReady(appId) {
|
||||
|
|
|
@ -75,7 +75,8 @@ const NFC_IPC_MSG_ENTRIES = [
|
|||
messages: ["NFC:CheckP2PRegistration",
|
||||
"NFC:NotifyUserAcceptedP2P",
|
||||
"NFC:NotifySendFileStatus",
|
||||
"NFC:ChangeRFState"] }
|
||||
"NFC:ChangeRFState",
|
||||
"NFC:SetFocusApp"] }
|
||||
];
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||
|
@ -97,7 +98,9 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
|||
// Manage registered Peer Targets
|
||||
peerTargets: {},
|
||||
|
||||
eventListeners: [],
|
||||
eventListeners: {},
|
||||
|
||||
focusApp: null,
|
||||
|
||||
init: function init(nfc) {
|
||||
this.nfc = nfc;
|
||||
|
@ -172,18 +175,30 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
|||
target.sendAsyncMessage("NFC:DOMEvent", options);
|
||||
},
|
||||
|
||||
addEventListener: function addEventListener(target) {
|
||||
if (this.eventListeners.indexOf(target) != -1) {
|
||||
setFocusApp: function setFocusApp(id, isFocus) {
|
||||
if (isFocus) {
|
||||
// Now we only support one focus app.
|
||||
this.focusApp = id;
|
||||
} else if (this.focusApp == id){
|
||||
// Set focusApp to null means currently there is no foreground app.
|
||||
this.focusApp = null;
|
||||
}
|
||||
},
|
||||
|
||||
addEventListener: function addEventListener(target, id) {
|
||||
if (this.eventListeners[id] !== undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.eventListeners.push(target);
|
||||
this.eventListeners[id] = target;
|
||||
},
|
||||
|
||||
removeEventListener: function removeEventListener(target) {
|
||||
let index = this.eventListeners.indexOf(target);
|
||||
if (index !== -1) {
|
||||
this.eventListeners.splice(index, 1);
|
||||
for (let id in this.eventListeners) {
|
||||
if (target == this.eventListeners[id]) {
|
||||
delete this.eventListeners[id];
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -214,30 +229,33 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
|||
|
||||
onTagFound: function onTagFound(message) {
|
||||
message.event = NFC.TAG_EVENT_FOUND;
|
||||
for (let target of this.eventListeners) {
|
||||
this.notifyDOMEvent(target, message);
|
||||
for (let id in this.eventListeners) {
|
||||
this.notifyDOMEvent(this.eventListeners[id], message);
|
||||
}
|
||||
delete message.event;
|
||||
},
|
||||
|
||||
onTagLost: function onTagLost(sessionToken) {
|
||||
for (let target of this.eventListeners) {
|
||||
this.notifyDOMEvent(target, {event: NFC.TAG_EVENT_LOST,
|
||||
sessionToken: sessionToken});
|
||||
for (let id in this.eventListeners) {
|
||||
this.notifyDOMEvent(this.eventListeners[id],
|
||||
{ event: NFC.TAG_EVENT_LOST,
|
||||
sessionToken: sessionToken });
|
||||
}
|
||||
},
|
||||
|
||||
onPeerEvent: function onPeerEvent(eventType, sessionToken) {
|
||||
for (let target of this.eventListeners) {
|
||||
this.notifyDOMEvent(target, { event: eventType,
|
||||
sessionToken: sessionToken });
|
||||
for (let id in this.eventListeners) {
|
||||
this.notifyDOMEvent(this.eventListeners[id],
|
||||
{ event: eventType,
|
||||
sessionToken: sessionToken });
|
||||
}
|
||||
},
|
||||
|
||||
onRFStateChange: function onRFStateChange(rfState) {
|
||||
for (let target of this.eventListeners) {
|
||||
this.notifyDOMEvent(target, { event: NFC.RF_EVENT_STATE_CHANGE,
|
||||
rfState: rfState});
|
||||
for (let id in this.eventListeners) {
|
||||
this.notifyDOMEvent(this.eventListeners[id],
|
||||
{ event: NFC.RF_EVENT_STATE_CHANGE,
|
||||
rfState: rfState });
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -268,8 +286,11 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
|||
}
|
||||
|
||||
switch (message.name) {
|
||||
case "NFC:SetFocusApp":
|
||||
this.setFocusApp(message.data.tabId, message.data.isFocus);
|
||||
return null;
|
||||
case "NFC:AddEventListener":
|
||||
this.addEventListener(message.target);
|
||||
this.addEventListener(message.target, message.data.tabId);
|
||||
return null;
|
||||
case "NFC:RegisterPeerReadyTarget":
|
||||
this.registerPeerReadyTarget(message.target, message.data.appId);
|
||||
|
|
|
@ -102,6 +102,13 @@ interface nsINfcRequestCallback : nsISupports
|
|||
void notifyError(in DOMString errorMsg);
|
||||
};
|
||||
|
||||
[scriptable, uuid(7ae46728-bc42-44bd-8093-bc7563abf52d)]
|
||||
interface nsINfcBrowserAPI : nsISupports
|
||||
{
|
||||
void setFocusApp(in uint64_t tabId,
|
||||
in boolean isFocus);
|
||||
};
|
||||
|
||||
[scriptable, uuid(b5194ae8-d5d5-482f-a73f-dd0d755a1972)]
|
||||
interface nsINfcContentHelper : nsISupports
|
||||
{
|
||||
|
|
|
@ -331,7 +331,6 @@ function MozNFCImpl() {
|
|||
|
||||
this.eventService = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(Ci.nsIEventListenerService);
|
||||
this._nfcContentHelper.addEventListener(this);
|
||||
}
|
||||
MozNFCImpl.prototype = {
|
||||
_nfcContentHelper: null,
|
||||
|
@ -353,6 +352,7 @@ MozNFCImpl.prototype = {
|
|||
|
||||
if (this._nfcContentHelper) {
|
||||
this._nfcContentHelper.init(aWindow);
|
||||
this._nfcContentHelper.addEventListener(this);
|
||||
this._rfState = this._nfcContentHelper.queryRFState();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -139,4 +139,10 @@ interface BrowserElementPrivileged {
|
|||
Pref="dom.mozBrowserFramesEnabled",
|
||||
CheckPermissions="browser"]
|
||||
DOMRequest setInputMethodActive(boolean isActive);
|
||||
|
||||
// Additional |nfc-manager| permission is required for setNFCFocus API
|
||||
[Throws,
|
||||
Pref="dom.mozBrowserFramesEnabled",
|
||||
CheckPermissions="browser"]
|
||||
void setNFCFocus(boolean isFocus);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче