Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
383 lines
9.9 KiB
JavaScript
Executable file
383 lines
9.9 KiB
JavaScript
Executable file
'use strict';
|
|
/* global Event */
|
|
/* global Service */
|
|
/* global SettingsListener */
|
|
|
|
(function(exports) {
|
|
|
|
/**
|
|
* SleepMenu controls functionality found in the menu after long-pressing on
|
|
* the power button. Controls include: airplane mode, silence incoming calls,
|
|
* restart, and power off. This file also currently contains a
|
|
* developerOptions object which is not currently in use.
|
|
* @class SleepMenu
|
|
* @requires InitLogoHandler
|
|
* @requires LogoLoader
|
|
* @requires Service
|
|
* @requires SettingsListener
|
|
*/
|
|
function SleepMenu() {}
|
|
|
|
SleepMenu.prototype = {
|
|
|
|
/**
|
|
* Indicate setting status of ril.radio.disabled
|
|
* @memberof SleepMenu.prototype
|
|
* @type {Boolean}
|
|
*/
|
|
isFlightModeEnabled: false,
|
|
|
|
/**
|
|
* Indicate setting status of developer.menu.enabled
|
|
* @memberof SleepMenu.prototype
|
|
* @type {Boolean}
|
|
*/
|
|
isDeveloperMenuEnabled: false,
|
|
|
|
/**
|
|
* Additional options to show in the menu if developer menu is enabled.
|
|
* @memberof SleepMenu.prototype
|
|
* @type {Object}
|
|
*/
|
|
developerOptions: {
|
|
},
|
|
|
|
/**
|
|
* Indicate setting status of volume
|
|
* @memberof SleepMenu.prototype
|
|
* @type {Boolean}
|
|
*/
|
|
isSilentModeEnabled: false,
|
|
|
|
/**
|
|
* Additional developer option to view source code of apps.
|
|
* @memberof @SleepMenu.prototype
|
|
* @type {Boolean}
|
|
*/
|
|
isViewSourceEnabled: false,
|
|
|
|
/**
|
|
* References to elements in the menu.
|
|
* @memberof SleepMenu.prototype
|
|
* @type {Object}
|
|
*/
|
|
elements: {},
|
|
|
|
/**
|
|
* Whether or not the sleep menu is visibile.
|
|
* @memberof SleepMenu.prototype
|
|
* @return {Boolean}
|
|
*/
|
|
get visible() {
|
|
return this.elements.overlay.classList.contains('visible');
|
|
},
|
|
|
|
/**
|
|
* Populates this.elements with references to elements.
|
|
* @memberof SleepMenu.prototype
|
|
*/
|
|
getAllElements: function sm_getAllElements() {
|
|
this.elements.overlay = document.getElementById('sleep-menu');
|
|
this.elements.container =
|
|
document.querySelector('#sleep-menu-container ul');
|
|
this.elements.cancel = document.querySelector('#sleep-menu button');
|
|
},
|
|
|
|
/**
|
|
* Start listening for events and settings changes.
|
|
* @memberof SleepMenu.prototype
|
|
*/
|
|
start: function sm_init() {
|
|
this.getAllElements();
|
|
window.addEventListener('holdsleep', this.show.bind(this));
|
|
window.addEventListener('click', this, true);
|
|
window.addEventListener('screenchange', this, true);
|
|
window.addEventListener('home', this);
|
|
window.addEventListener('batteryshutdown', this);
|
|
window.addEventListener('cardviewbeforeshow', this);
|
|
|
|
window.addEventListener('attentionopened', this);
|
|
this.elements.cancel.addEventListener('click', this);
|
|
|
|
var self = this;
|
|
SettingsListener.observe('ril.radio.disabled', false, function(value) {
|
|
self.isFlightModeEnabled = value;
|
|
});
|
|
|
|
SettingsListener.observe('developer.menu.enabled', false,
|
|
function(value) {
|
|
self.isDeveloperMenuEnabled = value;
|
|
});
|
|
|
|
for (var option in this.developerOptions) {
|
|
/* jshint loopfunc: true */
|
|
(function attachListenerToDeveloperOption(opt) {
|
|
SettingsListener.observe(opt.setting, opt.value, function(value) {
|
|
opt.value = value;
|
|
});
|
|
})(this.developerOptions[option]);
|
|
}
|
|
|
|
SettingsListener.observe('audio.volume.notification', 7, function(value) {
|
|
self.isSilentModeEnabled = (value === 0);
|
|
});
|
|
|
|
SettingsListener.observe('dev.gaia.view_source', false, function(value) {
|
|
self.isViewSourceEnabled = value;
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Generates menu items.
|
|
* @memberof SleepMenu.prototype
|
|
*/
|
|
generateItems: function sm_generateItems() {
|
|
var items = [];
|
|
var _ = navigator.mozL10n.get;
|
|
var options = {
|
|
airplane: {
|
|
label: _('airplane'),
|
|
value: 'airplane'
|
|
},
|
|
airplaneOff: {
|
|
label: _('airplaneOff'),
|
|
value: 'airplane'
|
|
},
|
|
silent: {
|
|
label: _('silent'),
|
|
value: 'silent'
|
|
},
|
|
silentOff: {
|
|
label: _('normal'),
|
|
value: 'silentOff'
|
|
},
|
|
restart: {
|
|
label: _('restart'),
|
|
value: 'restart'
|
|
},
|
|
power: {
|
|
label: _('power'),
|
|
value: 'power'
|
|
},
|
|
viewSource: {
|
|
label: _('viewSource'),
|
|
value: 'viewSource'
|
|
}
|
|
};
|
|
|
|
if (this.isFlightModeEnabled) {
|
|
items.push(options.airplaneOff);
|
|
} else {
|
|
items.push(options.airplane);
|
|
}
|
|
|
|
if (navigator.mozTelephony) {
|
|
if (!this.isSilentModeEnabled) {
|
|
items.push(options.silent);
|
|
} else {
|
|
items.push(options.silentOff);
|
|
}
|
|
}
|
|
|
|
items.push(options.restart);
|
|
items.push(options.power);
|
|
|
|
// Add the developer options at the end.
|
|
if (this.isDeveloperMenuEnabled) {
|
|
for (var option in this.developerOptions) {
|
|
if (this.developerOptions[option].value) {
|
|
items.push(options[option]);
|
|
} else {
|
|
items.push(options[option + 'Off']);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.isDeveloperMenuEnabled && this.isViewSourceEnabled) {
|
|
items.push(options.viewSource);
|
|
}
|
|
|
|
return items;
|
|
},
|
|
|
|
/**
|
|
* Shows the sleep menu.
|
|
* @memberof SleepMenu.prototype
|
|
*/
|
|
show: function sm_show() {
|
|
this.elements.container.innerHTML = '';
|
|
this.buildMenu(this.generateItems());
|
|
this.elements.overlay.classList.add('visible');
|
|
// Lock to default orientation
|
|
screen.mozLockOrientation(Service.query('defaultOrientation'));
|
|
},
|
|
|
|
/**
|
|
* Builds markup for all menu items.
|
|
* @memberof SleepMenu.prototype
|
|
* @param {Array} items A list of items.
|
|
*/
|
|
buildMenu: function sm_buildMenu(items) {
|
|
items.forEach(function traveseItems(item) {
|
|
var item_li = document.createElement('li');
|
|
item_li.dataset.value = item.value;
|
|
item_li.textContent = item.label;
|
|
item_li.setAttribute('role', 'menuitem');
|
|
this.elements.container.appendChild(item_li);
|
|
}, this);
|
|
},
|
|
|
|
/**
|
|
* Hides the sleep menu.
|
|
* @memberof SleepMenu.prototype
|
|
*/
|
|
hide: function lm_hide() {
|
|
if (!this.elements.overlay.classList.contains('visible')) {
|
|
return;
|
|
}
|
|
this.elements.overlay.classList.remove('visible');
|
|
window.dispatchEvent(new Event('sleepmenuhide'));
|
|
},
|
|
|
|
/**
|
|
* General event handler.
|
|
* @memberof SleepMenu.prototype
|
|
* @param {Event} evt The event to handle.
|
|
*/
|
|
handleEvent: function sm_handleEvent(evt) {
|
|
switch (evt.type) {
|
|
case 'cardviewbeforeshow':
|
|
this.hide();
|
|
break;
|
|
|
|
case 'batteryshutdown':
|
|
window.dispatchEvent(
|
|
new CustomEvent('requestshutdown', {detail: this}));
|
|
break;
|
|
|
|
case 'screenchange':
|
|
if (!evt.detail.screenEnabled) {
|
|
this.hide();
|
|
}
|
|
break;
|
|
|
|
case 'click':
|
|
if (!this.visible) {
|
|
return;
|
|
}
|
|
|
|
if (evt.currentTarget === this.elements.cancel) {
|
|
this.hide();
|
|
return;
|
|
}
|
|
|
|
var action = evt.target.dataset.value;
|
|
if (!action) {
|
|
return;
|
|
}
|
|
this.clickHandler(action);
|
|
break;
|
|
|
|
case 'home':
|
|
case 'attentionopened':
|
|
if (this.visible) {
|
|
this.hide();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
},
|
|
|
|
publish: function(evtName) {
|
|
window.dispatchEvent(new CustomEvent(evtName));
|
|
},
|
|
|
|
/**
|
|
* Handles click events on menu items.
|
|
* @memberof SleepMenu.prototype
|
|
* @param {String} action The action of the clicked menu item.
|
|
*/
|
|
clickHandler: function sm_clickHandler(action) {
|
|
switch (action) {
|
|
case 'airplane':
|
|
this.hide();
|
|
// Airplane mode should turn off
|
|
//
|
|
// Radio ('ril.radio.disabled'`)
|
|
// Data ('ril.data.enabled'`)
|
|
// Wifi
|
|
// Bluetooth
|
|
// Geolocation
|
|
//
|
|
// It should also save the status of the latter 4 items so when
|
|
// leaving the airplane mode we could know which one to turn on.
|
|
this.publish(this.isFlightModeEnabled ?
|
|
'request-airplane-mode-disable' :
|
|
'request-airplane-mode-enable');
|
|
break;
|
|
|
|
// About silent and silentOff
|
|
// * Turn on silent mode will cause:
|
|
// send a custom event 'mute' to sound manager
|
|
// * Turn off silent mode will cause:
|
|
// send a custom event 'unmute' to sound manager
|
|
case 'silent':
|
|
this.hide();
|
|
window.dispatchEvent(new Event('mute'));
|
|
this.isSilentModeEnabled = true;
|
|
|
|
break;
|
|
|
|
case 'silentOff':
|
|
this.hide();
|
|
window.dispatchEvent(new Event('unmute'));
|
|
this.isSilentModeEnabled = false;
|
|
|
|
break;
|
|
|
|
case 'restart':
|
|
this.startPowerOff(true);
|
|
|
|
break;
|
|
|
|
case 'power':
|
|
this.startPowerOff(false);
|
|
|
|
break;
|
|
|
|
case 'viewSource':
|
|
this.hide();
|
|
this.viewSource();
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Begins the power off of the device. Also reboots the device if
|
|
* requested.
|
|
* @memberof SleepMenu.prototype
|
|
* @param {Boolean} reboot Whether or not to reboot the phone.
|
|
*/
|
|
startPowerOff: function sm_startPowerOff(reboot) {
|
|
Service.request('poweroff', reboot);
|
|
},
|
|
|
|
/**
|
|
* Dispatches 'viewsource' event to display source of the current active
|
|
* app.
|
|
* @memberof SleepMenu.prototype
|
|
*/
|
|
viewSource: function sm_viewSource() {
|
|
Service.request('viewsource');
|
|
}
|
|
};
|
|
|
|
exports.SleepMenu = SleepMenu;
|
|
|
|
}(window));
|