VulpesOS/gaia/tv_apps/smart-system/js/wifi.js
OverSu b38dea0597 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.
2026-09-30 23:13:03 +02:00

327 lines
10 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, ScreenManager */
'use strict';
var Wifi = {
wifiWakeLocked: false,
wifiEnabled: true,
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.
screenOffTimeout: 0,
// if Wifi is enabled but disconnected, try to scan for networks every
// kScanInterval ms.
kScanInterval: 20 * 1000,
_scanTimer: null,
init: function wf_init() {
if (!window.navigator.mozSettings) {
return;
}
if (!window.navigator.mozWifiManager) {
return;
}
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';
SettingsCache.get(name, function gotWifiDisabledByWakelock(value) {
if (!value) {
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 });
});
var self = this;
var wifiManager = window.navigator.mozWifiManager;
// when wifi is really enabled, emit event to notify QuickSettings
wifiManager.onenabled = function onWifiEnabled() {
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('wifi-enabled',
/* canBubble */ true, /* cancelable */ false, null);
window.dispatchEvent(evt);
};
// when wifi is really disabled, emit event to notify QuickSettings
wifiManager.ondisabled = function onWifiDisabled() {
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('wifi-disabled',
/* canBubble */ true, /* cancelable */ false, null);
window.dispatchEvent(evt);
};
// 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);
};
SettingsCache.observe(
'wifi.screen_off_timeout', 600000, function(value) {
self.screenOffTimeout = value;
});
// Track the wifi.enabled mozSettings value
SettingsCache.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;
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();
}
});
});
var power = navigator.mozPower;
power.addWakeLockListener(function wifi_handleWakeLock(topic, state) {
if (topic !== 'wifi') {
return;
}
self.wifiWakeLocked = (state == 'locked-foreground' ||
state == 'locked-background');
self.maybeToggleWifi();
});
},
handleEvent: function wifi_handleEvent(evt) {
this.maybeToggleWifi();
},
// Check the status of screen, wifi wake lock and power source
// and turn on/off wifi accordingly
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.
// But if wifi wake lock is held, turn wifi into power save mode instead of
// turning wifi off.
if (!ScreenManager.screenEnabled && !battery.charging) {
// Wifi wake lock is held while screen and wifi are off, turn on wifi and
// get into power save mode.
if (!this.wifiEnabled && this.wifiWakeLocked) {
lock.set({ 'wifi.enabled': true });
window.addEventListener('wifi-enabled', function() {
wifiManager.setPowerSavingMode(true);
releaseCpuLock();
});
return;
}
// 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();
// Start with a timer, only turn off wifi till timeout.
var date = new Date(Date.now() + this.screenOffTimeout);
var self = this;
var req = navigator.mozAlarms.add(date, 'ignoreTimezone', 'wifi-off');
req.onsuccess = function wifi_offAlarmSet() {
self._alarmId = req.result;
releaseCpuLock();
};
req.onerror = function wifi_offAlarmSetFailed() {
console.warn('Fail to set wifi sleep timer on Alarm API. ' +
'Turn off wifi immediately.');
self.sleep();
releaseCpuLock();
};
}
// ... and quietly turn it back on or cancel the timer otherwise
else {
if (this._alarmId) {
navigator.mozAlarms.remove(this._alarmId);
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) {
// Restore from power save mode is wifi is already enabled.
wifiManager.setPowerSavingMode(false);
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;
// If Wifi wake lock is held, change wifi to power save mode instead of
// disable it.
if (this.wifiWakeLocked) {
var wifiManager = window.navigator.mozWifiManager;
if (wifiManager) {
request = wifiManager.setPowerSavingMode(true);
request.onsuccess = releaseWakeLockForWifi;
request.onerror = releaseWakeLockForWifi;
return;
}
}
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 |init()| because of bug 797803
setSystemMessageHandler: function wifi_setSystemMessageHandler() {
if (this._systemMessageHandlerRegistered) {
return;
}
this._systemMessageHandlerRegistered = true;
var self = this;
navigator.mozSetMessageHandler('alarm', function gotAlarm(message) {
if (message.data !== 'wifi-off') {
return;
}
self.sleep();
});
}
};
Wifi.init();