Backed out changeset 8cf341d4ccbd (bug 836654)
authorEd Morley <emorley@mozilla.com>
Thu, 14 Feb 2013 10:02:24 +0000
changeset 131748 20af8035e0f2081e570ec004acf6cc1b64c04d21
parent 131747 4f05e3bc58ce3286af782d254794c3d648e41219
child 131749 bbfd203a9019fe868a3559687985dfce7cdae262
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs836654
milestone21.0a1
backs out8cf341d4ccbd5490371d2930a178ddd478c58b0d
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 8cf341d4ccbd (bug 836654)
dom/alarm/AlarmService.jsm
--- a/dom/alarm/AlarmService.jsm
+++ b/dom/alarm/AlarmService.jsm
@@ -42,31 +42,34 @@ this.AlarmService = {
 
     let alarmHalService = this._alarmHalService = Cc["@mozilla.org/alarmHalService;1"].getService(Ci.nsIAlarmHalService);
     alarmHalService.setAlarmFiredCb(this._onAlarmFired.bind(this));
     alarmHalService.setTimezoneChangedCb(this._onTimezoneChanged.bind(this));
 
     // add the messages to be listened
     const messages = ["AlarmsManager:GetAll",
                       "AlarmsManager:Add",
-                      "AlarmsManager:Remove"];
+                      "AlarmsManager:Remove",
+                      "SystemMessageManager:HandleMessageDone"];
     messages.forEach(function addMessage(msgName) {
         ppmm.addMessageListener(msgName, this);
     }.bind(this));
 
     // set the indexeddb database
     let idbManager = Cc["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
     idbManager.initWindowless(myGlobal);
     this._db = new AlarmDB(myGlobal);
     this._db.init(myGlobal);
 
     // variable to save alarms waiting to be set
     this._alarmQueue = [];
 
     this._restoreAlarmsFromDb();
+
+    this._cpuWakeLocks = {};
   },
 
   // getter/setter to access the current alarm set in system
   _alarm: null,
   get _currentAlarm() {
     return this._alarm;
   },
   set _currentAlarm(aAlarm) {
@@ -208,16 +211,24 @@ this.AlarmService = {
 
             // no alarm waiting to be set in the queue
             this._currentAlarm = null;
             this._debugCurrentAlarm();
           }.bind(this)
         );
         break;
 
+      case "SystemMessageManager:HandleMessageDone":
+        if (json.type != "alarm") {
+          return;
+        }
+        debug("Unlock the CPU wake lock after the alarm is handled for sure.");
+        this._unlockCpuWakeLock(json.message.id);
+        break;
+
       default:
         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
         break;
     }
   },
 
   _sendAsyncMessage: function _sendAsyncMessage(aMessageManager, aMessageName, aSuccess, aRequestId, aData) {
     debug("_sendAsyncMessage()");
@@ -269,29 +280,54 @@ this.AlarmService = {
         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
       }
     );
   },
 
   _fireSystemMessage: function _fireSystemMessage(aAlarm) {
     debug("Fire system message: " + JSON.stringify(aAlarm));
 
+    // We have to ensure the CPU doesn't sleep during the process of
+    // handling alarm message, so that it can be handled on time.
+    this._cpuWakeLocks[aAlarm.id] = {
+      wakeLock: powerManagerService.newWakeLock("cpu"),
+      timer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer)
+    };
+
+    // Set a watchdog to avoid locking the CPU wake lock too long,
+    // because it'd exhaust the battery quickly which is very bad.
+    // This could probably happen if the app failed to launch or
+    // handle the alarm message due to any unexpected reasons.
+    this._cpuWakeLocks[aAlarm.id].timer.initWithCallback(function timerCb() {
+      debug("Unlock the CPU wake lock if the alarm isn't properly handled.");
+      this._unlockCpuWakeLock(aAlarm.id);
+    }.bind(this), 30000, Ci.nsITimer.TYPE_ONE_SHOT);
+
     let manifestURI = Services.io.newURI(aAlarm.manifestURL, null, null);
     let pageURI = Services.io.newURI(aAlarm.pageURL, null, null);
 
     // We don't need to expose everything to the web content.
     let alarm = { "id":              aAlarm.id,
                   "date":            aAlarm.date,
                   "respectTimezone": aAlarm.ignoreTimezone ?
                                        "ignoreTimezone" : "honorTimezone", 
                   "data":            aAlarm.data };
 
     messenger.sendMessage("alarm", alarm, pageURI, manifestURI);
   },
 
+  _unlockCpuWakeLock: function _unlockCpuWakeLock(aAlarmId) {
+    let cpuWakeLock = this._cpuWakeLocks[aAlarmId];
+    if (cpuWakeLock) {
+      cpuWakeLock.wakeLock.unlock();
+      cpuWakeLock.timer.cancel();
+      delete this._cpuWakeLocks[aAlarmId];
+    }
+  },
+
   _onAlarmFired: function _onAlarmFired() {
     debug("_onAlarmFired()");
 
     if (this._currentAlarm) {
       this._fireSystemMessage(this._currentAlarm);
       this._removeAlarmFromDb(this._currentAlarm.id, null);
       this._currentAlarm = null;
     }