gecko/mobile/android/modules/Notifications.jsm

219 lines
5.9 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"
let Cc = Components.classes;
let Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/Services.jsm");
this.EXPORTED_SYMBOLS = ["Notifications"];
function log(msg) {
// Services.console.logStringMessage(msg);
}
var _notificationsMap = {};
function Notification(aId, aOptions) {
this._id = aId;
this._when = (new Date).getTime();
this.fillWithOptions(aOptions);
}
Notification.prototype = {
fillWithOptions: function(aOptions) {
if ("icon" in aOptions && aOptions.icon != null)
this._icon = aOptions.icon;
else
throw "Notification icon is mandatory";
if ("title" in aOptions && aOptions.title != null)
this._title = aOptions.title;
else
throw "Notification title is mandatory";
if ("message" in aOptions && aOptions.message != null)
this._message = aOptions.message;
else
this._message = null;
if ("priority" in aOptions && aOptions.priority != null)
this._priority = aOptions.priority;
if ("buttons" in aOptions && aOptions.buttons != null) {
if (aOptions.buttons.length > 3)
throw "Too many buttons provided. The max number is 3";
this._buttons = {};
for (let i = 0; i < aOptions.buttons.length; i++) {
let button_id = aOptions.buttons[i].buttonId;
this._buttons[button_id] = aOptions.buttons[i];
}
} else {
this._buttons = null;
}
if ("ongoing" in aOptions && aOptions.ongoing != null)
this._ongoing = aOptions.ongoing;
else
this._ongoing = false;
if ("progress" in aOptions && aOptions.progress != null)
this._progress = aOptions.progress;
else
this._progress = null;
if ("onCancel" in aOptions && aOptions.onCancel != null)
this._onCancel = aOptions.onCancel;
else
this._onCancel = null;
if ("onClick" in aOptions && aOptions.onClick != null)
this._onClick = aOptions.onClick;
else
this._onClick = null;
if ("cookie" in aOptions && aOptions.cookie != null)
this._cookie = aOptions.cookie;
else
this._cookie = null;
if ("persistent" in aOptions && aOptions.persistent != null)
this._persistent = aOptions.persistent;
else
this._persistent = false;
},
show: function() {
let msg = {
type: "Notification:Show",
id: this._id,
title: this._title,
smallIcon: this._icon,
ongoing: this._ongoing,
when: this._when,
persistent: this._persistent
};
if (this._message)
msg.text = this._message;
if (this._progress) {
msg.progress_value = this._progress;
msg.progress_max = 100;
}
if (this._priority)
msg.priority = this._priority;
if (this._buttons) {
msg.actions = [];
let buttonName;
for (buttonName in this._buttons) {
let button = this._buttons[buttonName];
let obj = {
buttonId: button.buttonId,
title : button.title,
icon : button.icon
};
msg.actions.push(obj);
}
}
if (this._light)
msg.light = this._light;
Services.androidBridge.handleGeckoMessage(JSON.stringify(msg));
return this;
},
cancel: function() {
let msg = {
type: "Notification:Hide",
id: this._id
};
Services.androidBridge.handleGeckoMessage(JSON.stringify(msg));
}
}
var Notifications = {
_initObserver: function() {
if (!this._observerAdded) {
Services.obs.addObserver(this, "Notification:Event", true);
this._observerAdded = true;
}
},
get idService() {
delete this.idService;
return this.idService = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
},
create: function notif_notify(aOptions) {
this._initObserver();
let id = this.idService.generateUUID().toString();
let notification = new Notification(id, aOptions);
_notificationsMap[id] = notification;
notification.show();
return id;
},
update: function notif_update(aId, aOptions) {
let notification = _notificationsMap[aId];
if (!notification)
throw "Unknown notification id";
notification.fillWithOptions(aOptions);
notification.show();
},
cancel: function notif_cancel(aId) {
let notification = _notificationsMap[aId];
if (notification)
notification.cancel();
},
observe: function notif_observe(aSubject, aTopic, aData) {
let data = JSON.parse(aData);
let id = data.id;
let notification = _notificationsMap[id];
if (!notification) {
Services.console.logStringMessage("Notifications.jsm observe: received unknown event id " + id);
return;
}
switch (data.eventType) {
case "notification-clicked":
if (notification._onClick)
notification._onClick(id, notification._cookie);
break;
case "notification-button-clicked": {
if (!notification._buttons) {
Services.console.logStringMessage("Notifications.jsm: received button clicked event but no buttons are available");
break;
}
let button = notification._buttons[data.buttonId];
if (button)
button.onClicked(id, notification._cookie);
}
break;
case "notification-cleared":
case "notification-closed":
if (notification._onCancel)
notification._onCancel(id, notification._cookie);
delete _notificationsMap[id]; // since the notification was dismissed, we no longer need to hold a reference.
break;
}
},
QueryInterface: function (aIID) {
if (!aIID.equals(Ci.nsISupports) &&
!aIID.equals(Ci.nsIObserver) &&
!aIID.equals(Ci.nsISupportsWeakReference))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
}