mobile/android/modules/Notifications.jsm

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/modules/Notifications.jsm	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,223 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +"use strict"
     1.8 +
     1.9 +let Cc = Components.classes;
    1.10 +let Ci = Components.interfaces;
    1.11 +
    1.12 +Components.utils.import("resource://gre/modules/Services.jsm");
    1.13 +
    1.14 +this.EXPORTED_SYMBOLS = ["Notifications"];
    1.15 +
    1.16 +function log(msg) {
    1.17 +  // Services.console.logStringMessage(msg);
    1.18 +}
    1.19 +
    1.20 +var _notificationsMap = {};
    1.21 +
    1.22 +function Notification(aId, aOptions) {
    1.23 +  this._id = aId;
    1.24 +  this._when = (new Date).getTime();
    1.25 +  this.fillWithOptions(aOptions);
    1.26 +}
    1.27 +
    1.28 +Notification.prototype = {
    1.29 +  fillWithOptions: function(aOptions) {
    1.30 +    if ("icon" in aOptions && aOptions.icon != null)
    1.31 +      this._icon = aOptions.icon;
    1.32 +    else
    1.33 +      throw "Notification icon is mandatory";
    1.34 +
    1.35 +    if ("title" in aOptions && aOptions.title != null)
    1.36 +      this._title = aOptions.title;
    1.37 +    else
    1.38 +      throw "Notification title is mandatory";
    1.39 +
    1.40 +    if ("message" in aOptions && aOptions.message != null)
    1.41 +      this._message = aOptions.message;
    1.42 +    else
    1.43 +      this._message = null;
    1.44 +
    1.45 +    if ("priority" in aOptions && aOptions.priority != null)
    1.46 +      this._priority = aOptions.priority;
    1.47 +
    1.48 +    if ("buttons" in aOptions && aOptions.buttons != null) {
    1.49 +      if (aOptions.buttons.length > 3)
    1.50 +        throw "Too many buttons provided. The max number is 3";
    1.51 +
    1.52 +      this._buttons = {};
    1.53 +      for (let i = 0; i < aOptions.buttons.length; i++) {
    1.54 +        let button_id = aOptions.buttons[i].buttonId;
    1.55 +        this._buttons[button_id] = aOptions.buttons[i];
    1.56 +      }
    1.57 +    } else {
    1.58 +      this._buttons = null;
    1.59 +    }
    1.60 +
    1.61 +    if ("ongoing" in aOptions && aOptions.ongoing != null)
    1.62 +      this._ongoing = aOptions.ongoing;
    1.63 +    else
    1.64 +      this._ongoing = false;
    1.65 +
    1.66 +    if ("progress" in aOptions && aOptions.progress != null)
    1.67 +      this._progress = aOptions.progress;
    1.68 +    else
    1.69 +      this._progress = null;
    1.70 +
    1.71 +    if ("onCancel" in aOptions && aOptions.onCancel != null)
    1.72 +      this._onCancel = aOptions.onCancel;
    1.73 +    else
    1.74 +      this._onCancel = null;
    1.75 +
    1.76 +    if ("onClick" in aOptions && aOptions.onClick != null)
    1.77 +      this._onClick = aOptions.onClick;
    1.78 +    else
    1.79 +      this._onClick = null;
    1.80 +
    1.81 +    if ("cookie" in aOptions && aOptions.cookie != null)
    1.82 +      this._cookie = aOptions.cookie;
    1.83 +    else
    1.84 +      this._cookie = null;
    1.85 +
    1.86 +    if ("persistent" in aOptions && aOptions.persistent != null)
    1.87 +      this._persistent = aOptions.persistent;
    1.88 +    else
    1.89 +      this._persistent = false;
    1.90 +  },
    1.91 +
    1.92 +  show: function() {
    1.93 +    let msg = {
    1.94 +        type: "Notification:Show",
    1.95 +        id: this._id,
    1.96 +        title: this._title,
    1.97 +        smallIcon: this._icon,
    1.98 +        ongoing: this._ongoing,
    1.99 +        when: this._when,
   1.100 +        persistent: this._persistent
   1.101 +    };
   1.102 +
   1.103 +    if (this._message)
   1.104 +      msg.text = this._message;
   1.105 +
   1.106 +    if (this._progress) {
   1.107 +      msg.progress_value = this._progress;
   1.108 +      msg.progress_max = 100;
   1.109 +      msg.progress_indeterminate = false;
   1.110 +    } else if (Number.isNaN(this._progress)) {
   1.111 +      msg.progress_value = 0;
   1.112 +      msg.progress_max = 0;
   1.113 +      msg.progress_indeterminate = true;
   1.114 +    }
   1.115 +
   1.116 +    if (this._priority)
   1.117 +      msg.priority = this._priority;
   1.118 +
   1.119 +    if (this._buttons) {
   1.120 +      msg.actions = [];
   1.121 +      let buttonName;
   1.122 +      for (buttonName in this._buttons) {
   1.123 +        let button = this._buttons[buttonName];
   1.124 +        let obj = {
   1.125 +          buttonId: button.buttonId,
   1.126 +          title : button.title,
   1.127 +          icon : button.icon
   1.128 +        };
   1.129 +        msg.actions.push(obj);
   1.130 +      }
   1.131 +    }
   1.132 +
   1.133 +    if (this._light)
   1.134 +      msg.light = this._light;
   1.135 +
   1.136 +    Services.androidBridge.handleGeckoMessage(msg);
   1.137 +    return this;
   1.138 +  },
   1.139 +
   1.140 +  cancel: function() {
   1.141 +    let msg = {
   1.142 +        type: "Notification:Hide",
   1.143 +        id: this._id
   1.144 +    };
   1.145 +    Services.androidBridge.handleGeckoMessage(msg);
   1.146 +  }
   1.147 +}
   1.148 +
   1.149 +var Notifications = {
   1.150 +  _initObserver: function() {
   1.151 +    if (!this._observerAdded) {
   1.152 +      Services.obs.addObserver(this, "Notification:Event", true);
   1.153 +      this._observerAdded = true;
   1.154 +    }
   1.155 +  },
   1.156 +
   1.157 +  get idService() {
   1.158 +    delete this.idService;
   1.159 +    return this.idService = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
   1.160 +  },
   1.161 +
   1.162 +  create: function notif_notify(aOptions) {
   1.163 +    this._initObserver();
   1.164 +    let id = this.idService.generateUUID().toString();
   1.165 +    let notification = new Notification(id, aOptions);
   1.166 +    _notificationsMap[id] = notification;
   1.167 +    notification.show();
   1.168 +    return id;
   1.169 +  },
   1.170 +
   1.171 +  update: function notif_update(aId, aOptions) {
   1.172 +    let notification = _notificationsMap[aId];
   1.173 +    if (!notification)
   1.174 +      throw "Unknown notification id";
   1.175 +    notification.fillWithOptions(aOptions);
   1.176 +    notification.show();
   1.177 +  },
   1.178 +
   1.179 +  cancel: function notif_cancel(aId) {
   1.180 +    let notification = _notificationsMap[aId];
   1.181 +    if (notification)
   1.182 +      notification.cancel();
   1.183 +  },
   1.184 +
   1.185 +  observe: function notif_observe(aSubject, aTopic, aData) {
   1.186 +    let data = JSON.parse(aData);
   1.187 +    let id = data.id;
   1.188 +    let notification = _notificationsMap[id];
   1.189 +    if (!notification) {
   1.190 +      Services.console.logStringMessage("Notifications.jsm observe: received unknown event id " + id);
   1.191 +      return;
   1.192 +    }
   1.193 +
   1.194 +    switch (data.eventType) {
   1.195 +      case "notification-clicked":
   1.196 +        if (notification._onClick)
   1.197 +          notification._onClick(id, notification._cookie);
   1.198 +        break;
   1.199 +      case "notification-button-clicked": {
   1.200 +        if (!notification._buttons) {
   1.201 +          Services.console.logStringMessage("Notifications.jsm: received button clicked event but no buttons are available");
   1.202 +          break;
   1.203 +        }
   1.204 +
   1.205 +        let button = notification._buttons[data.buttonId];
   1.206 +        if (button)
   1.207 +          button.onClicked(id, notification._cookie);
   1.208 +        }
   1.209 +        break;
   1.210 +      case "notification-cleared":
   1.211 +      case "notification-closed":
   1.212 +        if (notification._onCancel)
   1.213 +          notification._onCancel(id, notification._cookie);
   1.214 +        delete _notificationsMap[id]; // since the notification was dismissed, we no longer need to hold a reference.
   1.215 +        break;
   1.216 +    }
   1.217 +  },
   1.218 +
   1.219 +  QueryInterface: function (aIID) {
   1.220 +    if (!aIID.equals(Ci.nsISupports) &&
   1.221 +        !aIID.equals(Ci.nsIObserver) &&
   1.222 +        !aIID.equals(Ci.nsISupportsWeakReference))
   1.223 +      throw Components.results.NS_ERROR_NO_INTERFACE;
   1.224 +    return this;
   1.225 +  }
   1.226 +}

mercurial