Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Bug 898666 - [clock] Clock refactor alarm object and add test
Browse files Browse the repository at this point in the history
1. An Alarm constructor is used to create new Alarms, instead of
   creating new object literals.
2. The AlarmsDB API is changed to pass error messages in the
   function(err, value) {...} style.
3. Asyncronous API calls are checked using callbacks. The async
   functions in Utils make this easy (although including async.js
   would be easier.
4. Testing is added for the Alarm object.
5. Added mock_alarmsDB and mock_mozAlarms for testing Alarms
6. Fixed alarm_edit tests. Moved to a new alarm_edit_test.js file.
7. Add tests for new utils methods (async and safeCpuLock)
8. Rename some variables. Remove "_name" naming scheme.
9. Removed in app alarm set indicator
10. Protect id, repeat, and enabled properties on the Alarm object.

r=jugglinmike
  • Loading branch information
Eric O'Connor authored and jugglinmike committed Aug 29, 2013
1 parent 29246db commit 3746b1c
Show file tree
Hide file tree
Showing 16 changed files with 1,896 additions and 866 deletions.
1 change: 1 addition & 0 deletions apps/clock/index.html
Expand Up @@ -30,6 +30,7 @@
<script defer src="shared/js/async_storage.js"></script>
<script defer src="js/constants.js"></script>
<script defer src="js/utils.js"></script>
<script defer src="js/alarm.js"></script>
<script defer src="js/active_alarm.js"></script>
<script defer src="js/alarmsdb.js"></script>
<script defer src="js/clock.js"></script>
Expand Down
149 changes: 63 additions & 86 deletions apps/clock/js/active_alarm.js
Expand Up @@ -12,113 +12,90 @@ var ActiveAlarm = {
* A snooze alarm should be turned off.
*/

_onFireAlarm: {},
_onFireChildWindow: null,
firedAlarm: null,
message: null,
childwindow: null,

init: function am_init() {
var self = this;
navigator.mozSetMessageHandler('alarm', function gotMessage(message) {
self.onAlarmFiredHandler(message);
});
navigator.mozSetMessageHandler('alarm', this.handler.bind(this));
AlarmManager.updateAlarmStatusBar();
},

onAlarmFiredHandler: function aac_onAlarmFiredHandler(message) {
// We have to ensure the CPU doesn't sleep during the process of
// handling alarm message, so that it can be handled on time.
var cpuWakeLock = navigator.requestWakeLock('cpu');

handler: function aac_handler(message) {
// 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.
var unlockCpuWakeLock = function unlockCpuWakeLock() {
if (cpuWakeLock) {
cpuWakeLock.unlock();
cpuWakeLock = null;
}
};
setTimeout(unlockCpuWakeLock, 30000);
Utils.safeCpuLock(30000, function(done) {
// receive and parse the alarm id from the message
var id = message.data.id;
var type = message.data.type;

// receive and parse the alarm id from the message
var id = message.data.id;
var type = message.data.type;
// clear the requested id of went off alarm to DB
var clearAlarmRequestId = function clearAlarmRequestId(alarm, callback) {
if (type === 'normal') {
alarm.normalAlarmId = '';
} else {
alarm.snoozeAlarmId = '';
}

AlarmManager.putAlarm(alarm, function aac_putAlarm(alarmFromDB) {
// Set the next repeat alarm when nornal alarm goes off.
if (type === 'normal' &&
!Utils.isEmptyRepeat(alarmFromDB.repeat) &&
callback) {
alarmFromDB.enabled = false;
callback(alarmFromDB);
} else {
// Except repeat alarm, the active alarm should be turned off.
if (!alarmFromDB.normalAlarmId)
AlarmList.toggleAlarmEnableState(false, alarmFromDB);
}
// Unlock the CPU when these functions have been called
var finalizer = Utils.async.namedParallel([
'onReschedule',
'onReceivedAlarm'
], function(err) {
AlarmList.refresh();
AlarmManager.updateAlarmStatusBar();
done();
});
};

// set the next repeat alarm
var setRepeatAlarm = function setRepeatAlarm(alarm) {
AlarmList.toggleAlarmEnableState(true, alarm);
};

// use the alarm id to query db
// find out which alarm is being fired.
var self = this;
AlarmManager.getAlarmById(id, function aac_gotAlarm(alarm) {
if (!alarm) {
unlockCpuWakeLock();
return;
}
// clear the requested id of went off alarm to DB
clearAlarmRequestId(alarm, setRepeatAlarm);

// If previous active alarm is showing,
// turn it off and stop its notification
if (self._onFireChildWindow !== null &&
typeof self._onFireChildWindow !== 'undefined' &&
!self._onFireChildWindow.closed) {
if (self._onFireChildWindow.RingView) {
self._onFireChildWindow.RingView.stopAlarmNotification();
}
if (this.childwindow !== null &&
typeof this.childwindow !== 'undefined' &&
!this.childwindow.closed) {
if (this.childwindow.RingView) {
this.childwindow.RingView.stopAlarmNotification();
}
}

// prepare to pop out attention screen, ring the ringtone, vibrate
self._onFireAlarm = alarm;
var protocol = window.location.protocol;
var host = window.location.host;
self._onFireChildWindow =
window.open(protocol + '//' + host + '/onring.html',
'ring_screen', 'attention');
self._onFireChildWindow.onload = function childWindowLoaded() {
unlockCpuWakeLock();
};
AlarmsDB.getAlarm(id, function aac_gotAlarm(err, alarm) {
if (err) {
done();
return;
}
this.firedAlarm = alarm;
if (type === 'normal') {
alarm.schedule({
type: 'normal',
first: false
}, alarm.saveCallback(finalizer.onReschedule));
} else {
alarm.cancel('snooze');
alarm.save(finalizer.onReschedule);
}
// prepare to pop out attention screen, ring the ringtone, vibrate
this.firedAlarm = alarm;
this.message = message;
var protocol = window.location.protocol;
var host = window.location.host;
this.childwindow =
window.open(protocol + '//' + host + '/onring.html',
'ring_screen', 'attention');
finalizer.onReceivedAlarm();
}.bind(this));

});
AlarmManager.updateAlarmStatusBar();
}.bind(this));
},

snoozeHandler: function aac_snoozeHandler() {
var id = this._onFireAlarm.id;
AlarmManager.getAlarmById(id, function aac_gotAlarm(alarm) {
alarm.enabled = true;
AlarmManager.putAlarm(alarm, function aac_putAlarm(alarm) {
AlarmManager.set(alarm, true); // set a snooze alarm
Utils.safeCpuLock(30000, function(done) {
var id = this.firedAlarm.id;
AlarmsDB.getAlarm(id, function aac_gotAlarm(err, alarm) {
if (err) {
return;
}
alarm.schedule({
type: 'snooze'
}, alarm.saveCallback(function(err, alarm) {
AlarmList.refreshItem(alarm);
AlarmManager.updateAlarmStatusBar();
done();
}.bind(this)));
});
});
},

getOnFireAlarm: function aac_getOnFireAlarm() {
return this._onFireAlarm;
}.bind(this));
}

};

0 comments on commit 3746b1c

Please sign in to comment.