Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
441
overrides/system.gaiamobile.org/js/wifi.js
Normal file
441
overrides/system.gaiamobile.org/js/wifi.js
Normal file
|
|
@ -0,0 +1,441 @@
|
|||
/* global LazyLoader, Service, SettingsListener,
|
||||
WifiIcon, WifiWakeLockManager */
|
||||
|
||||
'use strict';
|
||||
(function(exports) {
|
||||
var Wifi = {
|
||||
name: 'Wifi',
|
||||
|
||||
// Sync with mozSettings wifi.enabled key with an observer.
|
||||
// Note that there is a timing difference with _enabled and enabled.
|
||||
wifiEnabled: true,
|
||||
|
||||
// True if we have disabled the wifi so we would remember to quietly turn
|
||||
// it back on.
|
||||
// (TODO: this should be named wifiDisabledByTimeout)
|
||||
wifiDisabledByWakelock: false,
|
||||
|
||||
// Without an wifi wake lock, wait for screenOffTimeout milliseconds
|
||||
// to turn wifi off after the conditions are met.
|
||||
// If it's set to 0, wifi will never be turn off.
|
||||
// This is in sync with mozSettings wifi.screen_off_timeout.
|
||||
screenOffTimeout: 0,
|
||||
|
||||
// When wifiSleepMode is true and the screenOffTimeout is not zero,
|
||||
// Wi-Fi will be automatically turned off during sleep to save battery
|
||||
// power.
|
||||
// This is in sync with mozSettings wifi.sleepMode.
|
||||
wifiSleepMode: false,
|
||||
|
||||
// if Wifi is enabled but disconnected, try to scan for networks every
|
||||
// kScanInterval ms.
|
||||
kScanInterval: 20 * 1000,
|
||||
|
||||
_scanTimer: null,
|
||||
|
||||
// Sync with the hardware (mozWifiManager) state by listening to the
|
||||
// two events.
|
||||
_enabled: false,
|
||||
|
||||
get enabled() {
|
||||
return this._enabled;
|
||||
},
|
||||
|
||||
// true if there is an alarm or if there is an alarm being set.
|
||||
_hasAlarm: false,
|
||||
|
||||
// keep the id returned by mozAlarms API
|
||||
_alarmId: null,
|
||||
|
||||
start: function() {
|
||||
if (!window.navigator.mozSettings) {
|
||||
console.error('Wifi: No mozSettings!');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!window.navigator.mozWifiManager) {
|
||||
console.error('Wifi: No mozWifiManager!');
|
||||
return;
|
||||
}
|
||||
|
||||
this.wifiManager = window.navigator.mozWifiManager;
|
||||
|
||||
LazyLoader.load(['js/captive_portal.js']);
|
||||
Service.request('stepReady', '#wifi').then(function() {
|
||||
return LazyLoader.load(['js/wifi_icon.js']);
|
||||
}.bind(this)).then(function() {
|
||||
this.icon = new WifiIcon(this);
|
||||
this.icon.start();
|
||||
}.bind(this))['catch'](function(err) { // XXX: workaround gjslint
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
window.addEventListener('screenchange', this);
|
||||
|
||||
var battery = window.navigator.battery;
|
||||
battery.addEventListener('chargingchange', this);
|
||||
|
||||
|
||||
// If wifi is turned off by us and phone got rebooted,
|
||||
// bring wifi back.
|
||||
var name = 'wifi.disabled_by_wakelock';
|
||||
var req = SettingsListener.getSettingsLock().get(name);
|
||||
req.onsuccess = function gotWifiDisabledByWakelock() {
|
||||
if (!req.result[name]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-enable wifi and reset wifi.disabled_by_wakelock
|
||||
// SettingsListener.getSettingsLock() always return invalid lock
|
||||
// in our usage here.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=793239
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
lock.set({ 'wifi.enabled': true });
|
||||
lock.set({ 'wifi.disabled_by_wakelock': false });
|
||||
};
|
||||
|
||||
this._wakeLockManager = new WifiWakeLockManager();
|
||||
this._wakeLockManager.onwakelockchange = this.maybeToggleWifi.bind(this);
|
||||
this._wakeLockManager.start();
|
||||
|
||||
var self = this;
|
||||
var wifiManager = window.navigator.mozWifiManager;
|
||||
// when wifi is really enabled, emit event to notify QuickSettings
|
||||
wifiManager.onenabled = function onWifiEnabled() {
|
||||
self._enabled = true;
|
||||
var evt = document.createEvent('CustomEvent');
|
||||
evt.initCustomEvent('wifi-enabled',
|
||||
/* canBubble */ true, /* cancelable */ false, null);
|
||||
window.dispatchEvent(evt);
|
||||
self.icon && self.icon.update();
|
||||
};
|
||||
|
||||
// when wifi is really disabled, emit event to notify QuickSettings
|
||||
wifiManager.ondisabled = function onWifiDisabled() {
|
||||
this._enabled = false;
|
||||
var evt = document.createEvent('CustomEvent');
|
||||
evt.initCustomEvent('wifi-disabled',
|
||||
/* canBubble */ true, /* cancelable */ false, null);
|
||||
window.dispatchEvent(evt);
|
||||
if (self.icon) {
|
||||
self.icon.update();
|
||||
}
|
||||
};
|
||||
|
||||
// when wifi status change, emit event to notify Statusbar/UpdateManager
|
||||
wifiManager.onstatuschange = function onWifiDisabled() {
|
||||
var evt = document.createEvent('CustomEvent');
|
||||
evt.initCustomEvent('wifi-statuschange',
|
||||
/* canBubble */ true, /* cancelable */ false, null);
|
||||
window.dispatchEvent(evt);
|
||||
self.icon && self.icon.update();
|
||||
};
|
||||
|
||||
wifiManager.onconnectioninfoupdate = function() {
|
||||
self.icon && self.icon.update();
|
||||
};
|
||||
|
||||
SettingsListener.observe(
|
||||
'wifi.screen_off_timeout', 600000, function(value) {
|
||||
self.screenOffTimeout = value;
|
||||
});
|
||||
|
||||
SettingsListener.observe('wifi.sleepMode', true, function(value) {
|
||||
self.wifiSleepMode = value;
|
||||
});
|
||||
|
||||
Service.registerState('enabled', this);
|
||||
|
||||
// Track the wifi.enabled mozSettings value
|
||||
SettingsListener.observe('wifi.enabled', true, function(value) {
|
||||
if (!wifiManager && value) {
|
||||
self.wifiEnabled = false;
|
||||
|
||||
// roll back the setting value to notify the UIs
|
||||
// that wifi interface is not available
|
||||
if (value) {
|
||||
SettingsListener.getSettingsLock().set({
|
||||
'wifi.enabled': false
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self.wifiEnabled = value;
|
||||
if (self.icon) {
|
||||
self.icon && self.icon.update();
|
||||
}
|
||||
|
||||
clearTimeout(self._scanTimer);
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If wifi is enabled but disconnected.
|
||||
// we would need to call getNetworks() continuously
|
||||
// so we could join known wifi network
|
||||
self._scanTimer = setInterval(function wifi_scan() {
|
||||
if (wifiManager.connection.status == 'disconnected') {
|
||||
wifiManager.getNetworks();
|
||||
}
|
||||
}, self.kScanInterval);
|
||||
});
|
||||
},
|
||||
|
||||
handleEvent: function wifi_handleEvent(evt) {
|
||||
this.maybeToggleWifi();
|
||||
},
|
||||
|
||||
/**
|
||||
* Check the status of screen, wifi wake lock, and power source
|
||||
* and turn on/off wifi accordingly.
|
||||
*
|
||||
* You can think of this as a gigantic state machine where the input
|
||||
* is the states and the output is triggering the timer to turn wifi off,
|
||||
* or turning the wifi back on (if it is turned off by us).
|
||||
*
|
||||
* |--------------------------------|---------------------|
|
||||
* | Conditions | |
|
||||
* |--------|-----------|-----------| End state |
|
||||
* | Screen | Power | Wake lock | |
|
||||
* |--------|-----------|-----------|---------------------|
|
||||
* | off | unplugged | not hold | set timer to off (1)|
|
||||
* |--------|-----------|-----------|---------------------|
|
||||
* | off | unplugged | hold | turn back on |
|
||||
* | | | | if turned off by |
|
||||
* | | | | timer (2) |
|
||||
* |--------|-----------|-----------|---------------------|
|
||||
* | off | plugged | not hold | turn back on |
|
||||
* | | | | if turned off by |
|
||||
* | | | | timer (3) |
|
||||
* |--------|-----------|-----------|---------------------|
|
||||
* | off | plugged | hold | turn back on |
|
||||
* | | | | if turned off by |
|
||||
* | | | | timer (4) |
|
||||
* |--------|-----------|-----------|---------------------|
|
||||
* | on | unplugged | not hold | turn back on |
|
||||
* | | | | if turned off by |
|
||||
* | | | | timer (5) |
|
||||
* |--------|-----------|-----------|---------------------|
|
||||
* | on | unplugged | hold | turn back on |
|
||||
* | | | | if turned off by |
|
||||
* | | | | timer (6) |
|
||||
* |--------|-----------|-----------|---------------------|
|
||||
* | on | plugged | not hold | turn back on |
|
||||
* | | | | if turned off by |
|
||||
* | | | | timer (7) |
|
||||
* |--------|-----------|-----------|---------------------|
|
||||
* | on | plugged | hold | turn back on |
|
||||
* | | | | if turned off by |
|
||||
* | | | | timer (8) |
|
||||
* |--------|-----------|-----------|---------------------|
|
||||
*
|
||||
* The rest of the code are housekeepers making sure we keep an CPU lock
|
||||
* during the operations, and try not to set the timer twice etc.
|
||||
*
|
||||
* It is also assumed setting mozSettings w/ the same value would be a
|
||||
* no-op with no side effects so we don't really protect that.
|
||||
*
|
||||
* As the entry point to of the state machine, it is very important to
|
||||
* keep this function making the right decisions at all times.
|
||||
*/
|
||||
maybeToggleWifi: function wifi_maybeToggleWifi() {
|
||||
// Keep CPU awake to ensure the flow is done.
|
||||
var cpuLock = navigator.requestWakeLock('cpu');
|
||||
|
||||
var releaseCpuLock = function() {
|
||||
if (cpuLock) {
|
||||
cpuLock.unlock();
|
||||
cpuLock = null;
|
||||
}
|
||||
|
||||
if (timeoutId) {
|
||||
window.clearTimeout(timeoutId);
|
||||
timeoutId = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// To prevent the CPU awake forever (if anything goes run)
|
||||
var timeoutId = window.setTimeout(releaseCpuLock, 30000);
|
||||
|
||||
// Do nothing if we are being disabled.
|
||||
if (!this.screenOffTimeout) {
|
||||
releaseCpuLock();
|
||||
return;
|
||||
}
|
||||
|
||||
var battery = window.navigator.battery;
|
||||
var wifiManager = window.navigator.mozWifiManager;
|
||||
if (!battery || !wifiManager ||
|
||||
// We don't need to do anything if wifi is not disabled by system app.
|
||||
(!this.wifiEnabled && !this.wifiDisabledByWakelock)) {
|
||||
releaseCpuLock();
|
||||
return;
|
||||
}
|
||||
|
||||
var lock = SettingsListener.getSettingsLock();
|
||||
// Let's quietly turn off wifi if there is no wake lock and
|
||||
// the screen is off and we are not on a power source.
|
||||
if (!Service.query('screenEnabled') && !battery.charging &&
|
||||
!this._wakeLockManager.isHeld) {
|
||||
// We still need to turn of wifi even if there is no Alarm API
|
||||
if (!navigator.mozAlarms) {
|
||||
console.warn('Turning off wifi without sleep timer because' +
|
||||
' Alarm API is not available');
|
||||
this.sleep();
|
||||
releaseCpuLock();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set System Message Handler,
|
||||
// so we will be notified when alarm goes off.
|
||||
this.setSystemMessageHandler();
|
||||
|
||||
// When user wants to allow wifi off then start with a timer,
|
||||
// only turn off wifi till timeout.
|
||||
if (this.wifiSleepMode === true) {
|
||||
// maybeToggleWifi state machine state #1
|
||||
|
||||
// We should not try to set more than one alarms.
|
||||
if (this._hasAlarm) {
|
||||
releaseCpuLock();
|
||||
return;
|
||||
}
|
||||
|
||||
this._hasAlarm = true;
|
||||
var date = new Date(Date.now() + this.screenOffTimeout);
|
||||
var req = navigator.mozAlarms.add(date, 'ignoreTimezone', 'wifi-off');
|
||||
req.onsuccess = function wifi_offAlarmSet() {
|
||||
this._alarmId = req.result;
|
||||
releaseCpuLock();
|
||||
}.bind(this);
|
||||
req.onerror = function wifi_offAlarmSetFailed() {
|
||||
console.warn('Fail to set wifi sleep timer on Alarm API. ' +
|
||||
'Turn off wifi immediately.');
|
||||
this._hasAlarm = false;
|
||||
this.sleep();
|
||||
releaseCpuLock();
|
||||
}.bind(this);
|
||||
} else {
|
||||
releaseCpuLock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// ... and quietly turn it back on or cancel the timer otherwise
|
||||
else {
|
||||
// maybeToggleWifi state machine state #2 to #8
|
||||
if (this._alarmId) {
|
||||
navigator.mozAlarms.remove(this._alarmId);
|
||||
this._hasAlarm = false;
|
||||
this._alarmId = null;
|
||||
}
|
||||
|
||||
// If wifi is enabled but disconnected.
|
||||
// we would need to call getNetworks()
|
||||
// so we could join known wifi network
|
||||
if (this.wifiEnabled &&
|
||||
wifiManager.connection.status == 'disconnected') {
|
||||
wifiManager.getNetworks();
|
||||
}
|
||||
|
||||
// We don't need to do anything if
|
||||
// we didn't disable wifi at first place.
|
||||
if (!this.wifiDisabledByWakelock) {
|
||||
releaseCpuLock();
|
||||
return;
|
||||
}
|
||||
|
||||
this.wifiDisabledByWakelock = false;
|
||||
|
||||
if (this.wifiEnabled) {
|
||||
releaseCpuLock();
|
||||
return;
|
||||
}
|
||||
|
||||
// turn wifi back on.
|
||||
lock.set({ 'wifi.enabled': true });
|
||||
lock.set({ 'wifi.disabled_by_wakelock': false });
|
||||
window.addEventListener('wifi-enabled', function() {
|
||||
releaseCpuLock();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// Quietly turn off wifi for real, set wifiDisabledByWakelock to true
|
||||
// so we will turn it back on.
|
||||
sleep: function wifi_sleep() {
|
||||
// The |sleep| might be triggered when an alarm comes.
|
||||
// If the CPU is in suspend mode at this moment, alarm servcie would wake
|
||||
// up the CPU to run the handler and turn it back to suspend immediately
|
||||
// |sleep| is finished.
|
||||
// In this case, we acquire a CPU wake lock to prevent
|
||||
// the CPU goes to suspend mode before the switching is done.
|
||||
var wakeLockForWifi = navigator.requestWakeLock('cpu');
|
||||
|
||||
var releaseWakeLockForWifi = function() {
|
||||
if (wakeLockForWifi) {
|
||||
wakeLockForWifi.unlock();
|
||||
wakeLockForWifi = null;
|
||||
}
|
||||
if (timeoutId) {
|
||||
window.clearTimeout(timeoutId);
|
||||
timeoutId = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// To prevent the CPU awake forever (if wifi cannot be disabled)
|
||||
var timeoutId = window.setTimeout(releaseWakeLockForWifi, 30000);
|
||||
|
||||
// Remember that it was turned off by us.
|
||||
this.wifiDisabledByWakelock = true;
|
||||
|
||||
var request = null;
|
||||
var lock = SettingsListener.getSettingsLock();
|
||||
|
||||
// Actually turn off the wifi
|
||||
var wakeLockForSettings = navigator.requestWakeLock('cpu');
|
||||
lock.set({ 'wifi.enabled': false });
|
||||
window.addEventListener('wifi-disabled', releaseWakeLockForWifi);
|
||||
|
||||
// Keep this value in disk so if the phone reboots we'll
|
||||
// be able to turn the wifi back on.
|
||||
request = lock.set({ 'wifi.disabled_by_wakelock': true });
|
||||
request.onsuccess = function() { wakeLockForSettings.unlock(); };
|
||||
request.onerror = request.onsuccess;
|
||||
},
|
||||
|
||||
// Register for handling system message,
|
||||
// this cannot be done during |start()| because of bug 797803
|
||||
setSystemMessageHandler: function wifi_setSystemMessageHandler() {
|
||||
if (this._systemMessageHandlerRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._systemMessageHandlerRegistered = true;
|
||||
navigator.mozSetMessageHandler('alarm', function gotAlarm(message) {
|
||||
if (message.data !== 'wifi-off') {
|
||||
return;
|
||||
}
|
||||
|
||||
this._hasAlarm = false;
|
||||
this._alarmId = null;
|
||||
|
||||
// Wifi shall not sleep if the condition to turn this off has changed.
|
||||
// (Alarm should have been removed when condition changes, but for
|
||||
// reason unknown to us it still triggers.)
|
||||
var battery = window.navigator.battery;
|
||||
if (Service.query('screenEnabled') ||
|
||||
battery.charging ||
|
||||
this._wakeLockManager.isHeld) {
|
||||
console.error(
|
||||
'Wifi: mozAlarms should be cancelled but still triggers.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.sleep();
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
exports.Wifi = Wifi;
|
||||
}(window));
|
||||
Loading…
Reference in a new issue