Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
279 lines
7.1 KiB
JavaScript
Executable file
279 lines
7.1 KiB
JavaScript
Executable file
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
|
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
|
|
|
/* global SettingsCache, SettingsListener, MozActivity, NotificationHelper,
|
|
ScreenManager */
|
|
'use strict';
|
|
|
|
var PowerSaveHandler = (function PowerSaveHandler() {
|
|
|
|
var _powerSaveResume = {};
|
|
var _powerSaveEnabled = false;
|
|
var _states = {
|
|
'wifi.enabled' : false,
|
|
'bluetooth.enabled' : false,
|
|
'geolocation.enabled' : false
|
|
};
|
|
|
|
var _powerSaveEnabledLock = false;
|
|
|
|
function init() {
|
|
SettingsCache.observe('powersave.enabled', false,
|
|
function sl_getPowerSave(value) {
|
|
var enabled = value;
|
|
if (enabled) {
|
|
enablePowerSave();
|
|
} else {
|
|
disablePowerSave();
|
|
}
|
|
_powerSaveEnabled = enabled;
|
|
});
|
|
|
|
function getState(state, value) {
|
|
_states[state] = value;
|
|
}
|
|
|
|
// Monitor the states of various modules
|
|
for (var j in _states) {
|
|
SettingsCache.observe(j, true, getState.bind(null, j));
|
|
}
|
|
}
|
|
|
|
// XXX Break down obj keys in a for each loop because mozSettings
|
|
// does not currently supports multiple keys in one set()
|
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=779381
|
|
function setMozSettings(keypairs) {
|
|
var setlock = SettingsListener.getSettingsLock();
|
|
for (var key in keypairs) {
|
|
var obj = {};
|
|
obj[key] = keypairs[key];
|
|
setlock.set(obj);
|
|
}
|
|
}
|
|
|
|
function enablePowerSave() {
|
|
// Keep the original states of various modules
|
|
for (var j in _states) {
|
|
_powerSaveResume[j] = _states[j];
|
|
}
|
|
|
|
var settingsToSet = {
|
|
// Turn off Wifi
|
|
'wifi.enabled' : false,
|
|
// Turn off Bluetooth
|
|
'bluetooth.enabled' : false,
|
|
// Turn off Geolocation
|
|
'geolocation.enabled' : false
|
|
};
|
|
|
|
setMozSettings(settingsToSet);
|
|
|
|
_powerSaveEnabledLock = false;
|
|
}
|
|
|
|
function disablePowerSave() {
|
|
|
|
var settingsToSet = {};
|
|
|
|
for (var state in _powerSaveResume) {
|
|
if (_powerSaveResume[state] === true) {
|
|
settingsToSet[state] = true;
|
|
}
|
|
}
|
|
|
|
setMozSettings(settingsToSet);
|
|
}
|
|
|
|
function showPowerSavingNotification() {
|
|
|
|
var clickCB = function() {
|
|
/*jshint nonew: false */
|
|
new MozActivity({
|
|
name: 'configure',
|
|
data: {
|
|
target: 'device',
|
|
section: 'battery'
|
|
}
|
|
});
|
|
};
|
|
|
|
NotificationHelper.send('notification-powersaving-mode-on-title', {
|
|
'bodyL10n': 'notification-powersaving-mode-on-description',
|
|
'icon': 'style/icons/Power_saving_mode.png'
|
|
}).then(function(notification) {
|
|
notification.addEventListener('click', clickCB);
|
|
});
|
|
}
|
|
|
|
function onBatteryChange() {
|
|
var battery = BatteryManager._battery;
|
|
|
|
if (battery.charging) {
|
|
if (_powerSaveEnabled) {
|
|
setMozSettings({'powersave.enabled' : false});
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
SettingsCache.observe('powersave.threshold', -1,
|
|
function getThreshold(value) {
|
|
// If 'turn on automatically' is set to 'never', don't change the
|
|
// power saving state
|
|
if (value == -1) {
|
|
return;
|
|
}
|
|
|
|
if (battery.level <= value && !_powerSaveEnabled) {
|
|
setMozSettings({'powersave.enabled' : true});
|
|
if (!_powerSaveEnabledLock) {
|
|
showPowerSavingNotification();
|
|
_powerSaveEnabledLock = true;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (battery.level > value && _powerSaveEnabled) {
|
|
setMozSettings({'powersave.enabled' : false});
|
|
return;
|
|
}
|
|
});
|
|
}
|
|
|
|
return {
|
|
init: init,
|
|
onBatteryChange: onBatteryChange
|
|
};
|
|
})();
|
|
|
|
/* jslint latedef:false */
|
|
var BatteryManager = {
|
|
TOASTER_TIMEOUT: 5000,
|
|
TRANSITION_SPEED: 1.8,
|
|
TRANSITION_FRACTION: 0.30,
|
|
|
|
AUTO_SHUTDOWN_LEVEL: 0.00,
|
|
EMPTY_BATTERY_LEVEL: 0.1,
|
|
|
|
_battery: window.navigator.battery,
|
|
_notification: null,
|
|
|
|
getAllElements: function bm_getAllElements() {
|
|
this.screen = document.getElementById('screen');
|
|
this.overlay = document.getElementById('system-overlay');
|
|
this.notification = document.getElementById('battery');
|
|
},
|
|
|
|
checkBatteryDrainage: function bm_checkBatteryDrainage() {
|
|
var battery = this._battery;
|
|
if (!battery) {
|
|
return;
|
|
}
|
|
if (battery.level <= this.AUTO_SHUTDOWN_LEVEL && !battery.charging) {
|
|
// Fire a event to inform sleepMenu perform shutdown.
|
|
window.dispatchEvent(new CustomEvent('batteryshutdown'));
|
|
}
|
|
},
|
|
|
|
init: function bm_init() {
|
|
this.getAllElements();
|
|
var battery = this._battery;
|
|
if (battery) {
|
|
// When the device is booted, check if the battery is drained.
|
|
// If so, batteryshutdown would be triggered to inform sleepMenu shutdown.
|
|
window.addEventListener('homescreenwindowmanager-ready',
|
|
this.checkBatteryDrainage.bind(this));
|
|
|
|
battery.addEventListener('levelchange', this);
|
|
battery.addEventListener('chargingchange', this);
|
|
}
|
|
window.addEventListener('screenchange', this);
|
|
|
|
this._screenOn = true;
|
|
this._wasEmptyBatteryNotificationDisplayed = false;
|
|
|
|
this.displayIfNecessary();
|
|
},
|
|
|
|
handleEvent: function bm_handleEvent(evt) {
|
|
var battery;
|
|
switch (evt.type) {
|
|
case 'screenchange':
|
|
this._screenOn = evt.detail.screenEnabled;
|
|
this.displayIfNecessary();
|
|
break;
|
|
|
|
case 'levelchange':
|
|
battery = this._battery;
|
|
if (!battery) {
|
|
return;
|
|
}
|
|
|
|
this.checkBatteryDrainage();
|
|
this.displayIfNecessary();
|
|
|
|
PowerSaveHandler.onBatteryChange();
|
|
break;
|
|
case 'chargingchange':
|
|
PowerSaveHandler.onBatteryChange();
|
|
|
|
battery = this._battery;
|
|
// We turn the screen on if needed in order to let
|
|
// the user knows the device is charging
|
|
|
|
if (battery && battery.charging) {
|
|
this.hide();
|
|
this._wasEmptyBatteryNotificationDisplayed = false;
|
|
|
|
if (!this._screenOn) {
|
|
ScreenManager.turnScreenOn();
|
|
}
|
|
} else {
|
|
this.displayIfNecessary();
|
|
}
|
|
break;
|
|
}
|
|
},
|
|
|
|
_shouldWeDisplay: function bm_shouldWeDisplay() {
|
|
var battery = this._battery;
|
|
if (!battery) {
|
|
return false;
|
|
}
|
|
|
|
return (!this._wasEmptyBatteryNotificationDisplayed &&
|
|
!battery.charging &&
|
|
battery.level <= this.EMPTY_BATTERY_LEVEL &&
|
|
this._screenOn);
|
|
},
|
|
|
|
displayIfNecessary: function bm_display() {
|
|
if (! this._shouldWeDisplay()) {
|
|
return;
|
|
}
|
|
|
|
// we know it's here, it's checked in shouldWeDisplay()
|
|
this.overlay.classList.add('battery');
|
|
|
|
this._wasEmptyBatteryNotificationDisplayed = true;
|
|
|
|
if (this._toasterTimeout) {
|
|
clearTimeout(this._toasterTimeout);
|
|
}
|
|
|
|
this._toasterTimeout = setTimeout(this.hide.bind(this),
|
|
this.TOASTER_TIMEOUT);
|
|
},
|
|
|
|
hide: function bm_hide() {
|
|
var overlayCss = this.overlay.classList;
|
|
if (overlayCss.contains('battery')) {
|
|
this.overlay.classList.remove('battery');
|
|
this._toasterTimeout = null;
|
|
}
|
|
}
|
|
};
|
|
|
|
// init PowerSaveHandler first, since it will be used by BatteryManager
|
|
PowerSaveHandler.init();
|
|
BatteryManager.init();
|