mobile/android/modules/Notifications.jsm

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 "use strict"
     6 let Cc = Components.classes;
     7 let Ci = Components.interfaces;
     9 Components.utils.import("resource://gre/modules/Services.jsm");
    11 this.EXPORTED_SYMBOLS = ["Notifications"];
    13 function log(msg) {
    14   // Services.console.logStringMessage(msg);
    15 }
    17 var _notificationsMap = {};
    19 function Notification(aId, aOptions) {
    20   this._id = aId;
    21   this._when = (new Date).getTime();
    22   this.fillWithOptions(aOptions);
    23 }
    25 Notification.prototype = {
    26   fillWithOptions: function(aOptions) {
    27     if ("icon" in aOptions && aOptions.icon != null)
    28       this._icon = aOptions.icon;
    29     else
    30       throw "Notification icon is mandatory";
    32     if ("title" in aOptions && aOptions.title != null)
    33       this._title = aOptions.title;
    34     else
    35       throw "Notification title is mandatory";
    37     if ("message" in aOptions && aOptions.message != null)
    38       this._message = aOptions.message;
    39     else
    40       this._message = null;
    42     if ("priority" in aOptions && aOptions.priority != null)
    43       this._priority = aOptions.priority;
    45     if ("buttons" in aOptions && aOptions.buttons != null) {
    46       if (aOptions.buttons.length > 3)
    47         throw "Too many buttons provided. The max number is 3";
    49       this._buttons = {};
    50       for (let i = 0; i < aOptions.buttons.length; i++) {
    51         let button_id = aOptions.buttons[i].buttonId;
    52         this._buttons[button_id] = aOptions.buttons[i];
    53       }
    54     } else {
    55       this._buttons = null;
    56     }
    58     if ("ongoing" in aOptions && aOptions.ongoing != null)
    59       this._ongoing = aOptions.ongoing;
    60     else
    61       this._ongoing = false;
    63     if ("progress" in aOptions && aOptions.progress != null)
    64       this._progress = aOptions.progress;
    65     else
    66       this._progress = null;
    68     if ("onCancel" in aOptions && aOptions.onCancel != null)
    69       this._onCancel = aOptions.onCancel;
    70     else
    71       this._onCancel = null;
    73     if ("onClick" in aOptions && aOptions.onClick != null)
    74       this._onClick = aOptions.onClick;
    75     else
    76       this._onClick = null;
    78     if ("cookie" in aOptions && aOptions.cookie != null)
    79       this._cookie = aOptions.cookie;
    80     else
    81       this._cookie = null;
    83     if ("persistent" in aOptions && aOptions.persistent != null)
    84       this._persistent = aOptions.persistent;
    85     else
    86       this._persistent = false;
    87   },
    89   show: function() {
    90     let msg = {
    91         type: "Notification:Show",
    92         id: this._id,
    93         title: this._title,
    94         smallIcon: this._icon,
    95         ongoing: this._ongoing,
    96         when: this._when,
    97         persistent: this._persistent
    98     };
   100     if (this._message)
   101       msg.text = this._message;
   103     if (this._progress) {
   104       msg.progress_value = this._progress;
   105       msg.progress_max = 100;
   106       msg.progress_indeterminate = false;
   107     } else if (Number.isNaN(this._progress)) {
   108       msg.progress_value = 0;
   109       msg.progress_max = 0;
   110       msg.progress_indeterminate = true;
   111     }
   113     if (this._priority)
   114       msg.priority = this._priority;
   116     if (this._buttons) {
   117       msg.actions = [];
   118       let buttonName;
   119       for (buttonName in this._buttons) {
   120         let button = this._buttons[buttonName];
   121         let obj = {
   122           buttonId: button.buttonId,
   123           title : button.title,
   124           icon : button.icon
   125         };
   126         msg.actions.push(obj);
   127       }
   128     }
   130     if (this._light)
   131       msg.light = this._light;
   133     Services.androidBridge.handleGeckoMessage(msg);
   134     return this;
   135   },
   137   cancel: function() {
   138     let msg = {
   139         type: "Notification:Hide",
   140         id: this._id
   141     };
   142     Services.androidBridge.handleGeckoMessage(msg);
   143   }
   144 }
   146 var Notifications = {
   147   _initObserver: function() {
   148     if (!this._observerAdded) {
   149       Services.obs.addObserver(this, "Notification:Event", true);
   150       this._observerAdded = true;
   151     }
   152   },
   154   get idService() {
   155     delete this.idService;
   156     return this.idService = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
   157   },
   159   create: function notif_notify(aOptions) {
   160     this._initObserver();
   161     let id = this.idService.generateUUID().toString();
   162     let notification = new Notification(id, aOptions);
   163     _notificationsMap[id] = notification;
   164     notification.show();
   165     return id;
   166   },
   168   update: function notif_update(aId, aOptions) {
   169     let notification = _notificationsMap[aId];
   170     if (!notification)
   171       throw "Unknown notification id";
   172     notification.fillWithOptions(aOptions);
   173     notification.show();
   174   },
   176   cancel: function notif_cancel(aId) {
   177     let notification = _notificationsMap[aId];
   178     if (notification)
   179       notification.cancel();
   180   },
   182   observe: function notif_observe(aSubject, aTopic, aData) {
   183     let data = JSON.parse(aData);
   184     let id = data.id;
   185     let notification = _notificationsMap[id];
   186     if (!notification) {
   187       Services.console.logStringMessage("Notifications.jsm observe: received unknown event id " + id);
   188       return;
   189     }
   191     switch (data.eventType) {
   192       case "notification-clicked":
   193         if (notification._onClick)
   194           notification._onClick(id, notification._cookie);
   195         break;
   196       case "notification-button-clicked": {
   197         if (!notification._buttons) {
   198           Services.console.logStringMessage("Notifications.jsm: received button clicked event but no buttons are available");
   199           break;
   200         }
   202         let button = notification._buttons[data.buttonId];
   203         if (button)
   204           button.onClicked(id, notification._cookie);
   205         }
   206         break;
   207       case "notification-cleared":
   208       case "notification-closed":
   209         if (notification._onCancel)
   210           notification._onCancel(id, notification._cookie);
   211         delete _notificationsMap[id]; // since the notification was dismissed, we no longer need to hold a reference.
   212         break;
   213     }
   214   },
   216   QueryInterface: function (aIID) {
   217     if (!aIID.equals(Ci.nsISupports) &&
   218         !aIID.equals(Ci.nsIObserver) &&
   219         !aIID.equals(Ci.nsISupportsWeakReference))
   220       throw Components.results.NS_ERROR_NO_INTERFACE;
   221     return this;
   222   }
   223 }

mercurial