gecko/dom/push/Push.js
2015-08-11 12:53:14 -07:00

188 lines
5.6 KiB
JavaScript

/* 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/. */
"use strict";
// Don't modify this, instead set dom.push.debug.
let gDebuggingEnabled = false;
function debug(s) {
if (gDebuggingEnabled)
dump("-*- Push.js: " + s + "\n");
}
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
const PUSH_CID = Components.ID("{cde1d019-fad8-4044-b141-65fb4fb7a245}");
/**
* The Push component runs in the child process and exposes the SimplePush API
* to the web application. The PushService running in the parent process is the
* one actually performing all operations.
*/
function Push() {
debug("Push Constructor");
}
Push.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
contractID: "@mozilla.org/push/PushManager;1",
classID : PUSH_CID,
QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference,
Ci.nsIObserver]),
init: function(aWindow) {
// Set debug first so that all debugging actually works.
// NOTE: We don't add an observer here like in PushService. Flipping the
// pref will require a reload of the app/page, which seems acceptable.
gDebuggingEnabled = Services.prefs.getBoolPref("dom.push.debug");
debug("init()");
this._window = aWindow;
this.initDOMRequestHelper(aWindow);
this._principal = aWindow.document.nodePrincipal;
this._client = Cc["@mozilla.org/push/PushClient;1"].createInstance(Ci.nsIPushClient);
},
setScope: function(scope){
debug('setScope ' + scope);
this._scope = scope;
},
askPermission: function (aAllowCallback, aCancelCallback) {
debug("askPermission");
let principal = this._window.document.nodePrincipal;
let type = "push";
let permValue =
Services.perms.testExactPermissionFromPrincipal(principal, type);
if (permValue == Ci.nsIPermissionManager.ALLOW_ACTION) {
aAllowCallback();
return;
}
if (permValue == Ci.nsIPermissionManager.DENY_ACTION) {
aCancelCallback();
return;
}
// Create an array with a single nsIContentPermissionType element.
type = {
type: "push",
access: null,
options: [],
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionType])
};
let typeArray = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
typeArray.appendElement(type, false);
// create a nsIContentPermissionRequest
let request = {
types: typeArray,
principal: principal,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]),
allow: function() {
aAllowCallback();
},
cancel: function() {
aCancelCallback();
},
window: this._window
};
// Using askPermission from nsIDOMWindowUtils that takes care of the
// remoting if needed.
let windowUtils = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
windowUtils.askPermission(request);
},
getEndpointResponse: function(fn) {
debug("GetEndpointResponse " + fn.toSource());
let that = this;
let p = this.createPromise(function(resolve, reject) {
this.askPermission(
() => {
fn(that._scope, that._principal, {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPushEndpointCallback]),
onPushEndpoint: function(ok, endpoint) {
if (ok === Cr.NS_OK) {
if (endpoint) {
let sub = new that._window.PushSubscription(endpoint, that._scope);
sub.setPrincipal(that._principal);
resolve(sub);
} else {
resolve(null);
}
} else {
reject("AbortError");
}
}
});
},
() => {
reject("PermissionDeniedError");
}
);
}.bind(this));
return p;
},
subscribe: function() {
debug("subscribe()");
return this.getEndpointResponse(this._client.subscribe.bind(this._client));
},
getSubscription: function() {
debug("getSubscription()" + this._scope);
return this.getEndpointResponse(this._client.getSubscription.bind(this._client));
},
permissionState: function() {
debug("permissionState()" + this._scope);
let p = this.createPromise((resolve, reject) => {
let permission = Ci.nsIPermissionManager.DENY_ACTION;
try {
let permissionManager = Cc["@mozilla.org/permissionmanager;1"]
.getService(Ci.nsIPermissionManager);
permission =
permissionManager.testExactPermissionFromPrincipal(this._principal,
"push");
} catch(e) {
reject();
return;
}
let pushPermissionStatus = "prompt";
if (permission == Ci.nsIPermissionManager.ALLOW_ACTION) {
pushPermissionStatus = "granted";
} else if (permission == Ci.nsIPermissionManager.DENY_ACTION) {
pushPermissionStatus = "denied";
}
resolve(pushPermissionStatus);
});
return p;
},
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Push]);