Restore Gaia settings and media workflows, extend native network adapters, and align the APK payload. Generate French/English changelogs and website entries from the simplified JSON source. Validation: shared JS and Tundra unit tests; desktop workflows and persistence; signed APK payload parity; Sargo RAM and installed startup with boot readback. Android runtime qualification is recorded separately.
265 lines
No EOL
18 KiB
JavaScript
265 lines
No EOL
18 KiB
JavaScript
|
|
define('panels/wifi/wifi_wps',['require','shared/wifi_helper'],function(require){'use strict';var WifiHelper=require('shared/wifi_helper');var wifiManager=WifiHelper.getWifiManager();var WifiWps=function(){var wifiWps={inProgress:false,_statusResetEventListeners:[],statusReset:function(){this._statusResetEventListeners.forEach(function(handler){handler();});},connect:function(options){var self=this;var req;var onSuccess=options.onSuccess||function(){};var onError=options.onError||function(){};var bssid=options.selectedAp;var method=options.selectedMethod;var pin=options.pin;if(method==='pbc'){req=wifiManager.wps({method:'pbc'});}else if(method==='myPin'){req=wifiManager.wps({method:'pin',bssid:bssid});}else{req=wifiManager.wps({method:'pin',bssid:bssid,pin:pin});}
|
|
req.onsuccess=function(){if(method==='myPin'){document.l10n.formatValue('wpsPinInput',{pin:req.result}).then(msg=>{alert(msg);self.inProgress=true;onSuccess();});}else{self.inProgress=true;onSuccess();}};req.onerror=function(){onError(req.error);};},cancel:function(options){var self=this;var onError=options.onError||function(){};var onSuccess=options.onSuccess||function(){};var req=wifiManager.wps({method:'cancel'});req.onsuccess=function(){self.inProgress=false;self.statusReset();onSuccess();};req.onerror=function(){onError(req.error);};},addEventListener:function(eventName,callback){if(eventName==='statusreset'){this._statusResetEventListeners.push(callback);}},removeEventListener:function(eventName,callback){if(eventName==='statusreset'){var index=this._statusResetEventListeners.indexOf(callback);if(index>=0){this._statusResetEventListeners.splice(index,1);}}}};return wifiWps;};return WifiWps;});define('panels/wifi/wifi_network_list',["require", "modules/dialog_service", "modules/wifi_utils", "shared/wifi_helper", "modules/wifi_context"],function(require) {
|
|
'use strict';
|
|
|
|
var DialogService = require('modules/dialog_service');
|
|
var WifiUtils = require('modules/wifi_utils');
|
|
var WifiHelper = require('shared/wifi_helper');
|
|
var WifiContext = require('modules/wifi_context');
|
|
var wifiManager = WifiHelper.getWifiManager();
|
|
|
|
var WifiNetworkList = function(elements) {
|
|
var list = elements.wifiAvailableNetworks;
|
|
|
|
var wifiNetworkList = {
|
|
_scanRate: 5000, // 5s after last scan results
|
|
_scanning: false,
|
|
_autoscan: false,
|
|
_index: {}, // index of all scanned networks
|
|
_networks: {},
|
|
_list: elements.wifiAvailableNetworks,
|
|
clear: function(addScanningItem) {
|
|
// clear the network list
|
|
this._index = {};
|
|
this._networks = {};
|
|
|
|
// remove all items except the text expl.
|
|
// and the "search again" button
|
|
var wifiItems = list.querySelectorAll('li:not([data-state])');
|
|
var len = wifiItems.length;
|
|
for (var i = len - 1; i >= 0; i--) {
|
|
list.removeChild(wifiItems[i]);
|
|
}
|
|
|
|
list.dataset.state = addScanningItem ? 'on' : 'off';
|
|
},
|
|
scan: function() {
|
|
window.performance.measure('settingsPanelWifiVisible', 'wifiListStart');
|
|
|
|
// scan wifi networks and display them in the list
|
|
var self = this;
|
|
if (this._scanning) {
|
|
return;
|
|
}
|
|
|
|
// stop auto-scanning if wifi disabled or the app is hidden
|
|
if (!wifiManager.enabled || document.hidden) {
|
|
this._scanning = false;
|
|
return;
|
|
}
|
|
|
|
this._scanning = true;
|
|
var req = WifiHelper.getAvailableAndKnownNetworks();
|
|
|
|
req.onsuccess = function onScanSuccess() {
|
|
self.clear(false);
|
|
var allNetworks = req.result;
|
|
var network;
|
|
|
|
for (var i = 0; i < allNetworks.length; ++i) {
|
|
network = allNetworks[i];
|
|
var key = WifiUtils.getNetworkKey(network);
|
|
// keep connected network first, or select the highest strength
|
|
if (!self._networks[key] || network.connected) {
|
|
self._networks[key] = network;
|
|
} else {
|
|
if (!self._networks[key].connected &&
|
|
network.relSignalStrength >
|
|
self._networks[key].relSignalStrength) {
|
|
self._networks[key] = network;
|
|
}
|
|
}
|
|
}
|
|
|
|
var networkKeys = Object.getOwnPropertyNames(self._networks);
|
|
|
|
// display network list
|
|
if (networkKeys.length) {
|
|
// sort networks by name and signal strength
|
|
networkKeys.sort(function(a, b) {
|
|
let barDelta =
|
|
WifiHelper.getSignalLevel(self._networks[b]) -
|
|
WifiHelper.getSignalLevel(self._networks[a]);
|
|
// If two networks have the same signal strength,
|
|
// then sort by name.
|
|
return (barDelta ? barDelta : a.localeCompare(b));
|
|
});
|
|
|
|
// add detected networks
|
|
for (var j = 0; j < networkKeys.length; j++) {
|
|
network = self._networks[networkKeys[j]];
|
|
var listItem = WifiUtils.newListItem({
|
|
network: network,
|
|
onClick: self._toggleNetwork.bind(self),
|
|
showNotInRange: true
|
|
});
|
|
// put connected network on top of list
|
|
if (WifiHelper.isConnected(network)) {
|
|
list.insertBefore(listItem,
|
|
elements.infoItem.nextSibling);
|
|
} else {
|
|
list.insertBefore(listItem, elements.scanItem);
|
|
}
|
|
// add composited key to index
|
|
self._index[networkKeys[j]] = listItem;
|
|
}
|
|
} else {
|
|
// display a "no networks found" message if necessary
|
|
list.insertBefore(
|
|
WifiUtils.newExplanationItem('noNetworksFound'),
|
|
elements.scanItem);
|
|
}
|
|
|
|
// display the "Search Again" button
|
|
list.dataset.state = 'ready';
|
|
|
|
window.performance.measure('settingsPanelWifiReady', 'wifiListStart');
|
|
|
|
// auto-rescan if requested
|
|
if (self._autoscan) {
|
|
window.setTimeout(self.scan.bind(self), self._scanRate);
|
|
}
|
|
|
|
self._scanning = false;
|
|
};
|
|
|
|
req.onerror = function onScanError(error) {
|
|
self._scanning = false;
|
|
self.clear(false);
|
|
var explanation = document.createElement('li');
|
|
explanation.className = 'explanation';
|
|
explanation.setAttribute('role', 'status');
|
|
explanation.textContent = document.documentElement.lang.startsWith('fr') ?
|
|
'Recherche Wi-Fi indisponible. Réessayez dans un instant.' :
|
|
'Wi-Fi scan unavailable. Try again in a moment.';
|
|
list.insertBefore(explanation, elements.scanItem);
|
|
list.dataset.state = 'ready';
|
|
console.warn('Wi-Fi scan failed', req.error);
|
|
// The existing Search Again button lets the user retry. Do not turn
|
|
// a permanent broker failure into an endless invisible retry loop.
|
|
};
|
|
},
|
|
getWpsAvailableNetworks: function() {
|
|
// get WPS available networks
|
|
var ssids = Object.getOwnPropertyNames(this._networks);
|
|
var wpsAvailableNetworks = [];
|
|
for (var i = 0; i < ssids.length; i++) {
|
|
var network = this._networks[ssids[i]];
|
|
if (WifiHelper.isWpsAvailable(network)) {
|
|
wpsAvailableNetworks.push(network);
|
|
}
|
|
}
|
|
return wpsAvailableNetworks;
|
|
},
|
|
set autoscan(value) {
|
|
this._autoscan = value;
|
|
},
|
|
get autoscan() {
|
|
return this._autoscan;
|
|
},
|
|
get scanning() {
|
|
return this._scanning;
|
|
},
|
|
_toggleNetwork: function(network) {
|
|
var self = this;
|
|
|
|
var keys = WifiHelper.getSecurity(network);
|
|
var security = (keys && keys.length) ? keys.join(', ') : '';
|
|
var sl = WifiHelper.getSignalLevel(network);
|
|
|
|
if (WifiHelper.isConnected(network)) {
|
|
// online: show status + offer to disconnect
|
|
DialogService.show('wifi-status', {
|
|
sl: sl,
|
|
network: network,
|
|
security: security,
|
|
}).then(function(result) {
|
|
var type = result.type;
|
|
if (type === 'submit') {
|
|
WifiContext.forgetNetwork(network, function() {
|
|
self.scan();
|
|
});
|
|
}
|
|
});
|
|
} else if (network.password && (network.password == '*')) {
|
|
// offline, known network (hence the '*' password value):
|
|
// no further authentication required.
|
|
WifiHelper.setPassword(network);
|
|
WifiContext.associateNetwork(network);
|
|
} else {
|
|
// offline, unknown network: propose to connect
|
|
var key = WifiHelper.getKeyManagement(network);
|
|
switch (key) {
|
|
case 'WEP':
|
|
case 'WPA-PSK':
|
|
case 'WPA-EAP':
|
|
DialogService.show('wifi-auth', {
|
|
sl: sl,
|
|
security: security,
|
|
network: network,
|
|
}).then(function(result) {
|
|
var type = result.type;
|
|
var authOptions = result.value;
|
|
if (type === 'submit') {
|
|
WifiHelper.setPassword(
|
|
network,
|
|
authOptions.password,
|
|
authOptions.identity,
|
|
authOptions.eap,
|
|
authOptions.authPhase2,
|
|
authOptions.certificate
|
|
);
|
|
WifiContext.associateNetwork(network);
|
|
}
|
|
});
|
|
break;
|
|
default:
|
|
WifiContext.associateNetwork(network);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// networkStatus has one of the following values:
|
|
// connecting, associated, connected, connectingfailed, disconnected.
|
|
WifiContext.addEventListener('wifiEnabled', function(event) {
|
|
WifiUtils.updateListItemStatus({
|
|
listItems: wifiNetworkList._index,
|
|
activeItemDOM: list.querySelector('.active'),
|
|
network: event.network,
|
|
networkStatus: event.status
|
|
});
|
|
});
|
|
|
|
WifiContext.addEventListener('wifiStatusChange', function(event) {
|
|
WifiUtils.updateListItemStatus({
|
|
listItems: wifiNetworkList._index,
|
|
activeItemDOM: list.querySelector('.active'),
|
|
network: event.network,
|
|
networkStatus: event.status
|
|
});
|
|
});
|
|
|
|
WifiContext.addEventListener('wifiConnectionInfoUpdate', function(event) {
|
|
WifiUtils.updateNetworkSignal(event.network, event.relSignalStrength);
|
|
});
|
|
|
|
WifiContext.addEventListener('wifiNetworkForgotten', event => {
|
|
var networkKey = WifiUtils.getNetworkKey(event.network);
|
|
var forgottenNetwork = wifiNetworkList._networks[networkKey];
|
|
if (forgottenNetwork) {
|
|
forgottenNetwork.password = '';
|
|
}
|
|
});
|
|
|
|
return wifiNetworkList;
|
|
};
|
|
|
|
return WifiNetworkList;
|
|
});
|
|
define('panels/wifi/panel',['require','modules/dialog_service','modules/settings_panel','shared/settings_listener','panels/wifi/wifi_wps','modules/wifi_context','shared/wifi_helper'],function(require){'use strict';var DialogService=require('modules/dialog_service');var SettingsPanel=require('modules/settings_panel');var SettingsListener=require('shared/settings_listener');var WifiWps=require('panels/wifi/wifi_wps');var WifiContext=require('modules/wifi_context');var WifiHelper=require('shared/wifi_helper');var wifiManager=WifiHelper.getWifiManager();return function ctor_wifi(){var elements;return SettingsPanel({onInit:function(panel){this._settings=navigator.mozSettings;this._wifiSectionVisible=true;this._scanPending=false;this._networkListPromise=null;this._initialized=false;elements={panel:panel,wifi:panel,wpsColumn:panel.querySelector('.wps-column'),wpsInfoBlock:panel.querySelector('.wps-column small'),wpsPbcLabelBlock:panel.querySelector('.wps-column span'),wifiCheckbox:panel.querySelector('.wifi-enabled gaia-switch'),wifiAvailableNetworks:panel.querySelector('.wifi-availableNetworks'),dialogElement:panel.querySelector('.wifi-bad-credentials-dialog'),okBtn:panel.querySelector('.wifi-bad-credentials-confirm'),cancelBtn:panel.querySelector('.wifi-bad-credentials-cancel')};elements.infoItem=elements.wifiAvailableNetworks.querySelector('li[data-state="on"]');elements.scanItem=elements.wifiAvailableNetworks.querySelector('li[data-state="ready"]');elements.wifiItem=elements.wifiAvailableNetworks.querySelector('li:not([data-state])');elements.networklist={infoItem:elements.infoItem,scanItem:elements.scanItem,wifiAvailableNetworks:elements.wifiAvailableNetworks};elements.wps={wpsColumn:elements.wpsColumn,wpsInfoBlock:elements.wpsInfoBlock,wpsPbcLabelBlock:elements.wpsPbcLabelBlock};this._wps=WifiWps();this._wps.addEventListener('statusreset',function(){elements.wps.wpsPbcLabelBlock.setAttribute('data-l10n-id','wpsMessage');setTimeout(function resetWpsInfoBlock(){elements.wps.wpsPbcLabelBlock.setAttribute('data-l10n-id','wpsDescription2');},1500);});elements.scanItem.addEventListener('click',this._onScanItemClick.bind(this));elements.wifiCheckbox.addEventListener('change',this._onWifiCheckboxChange.bind(this));elements.wpsColumn.addEventListener('click',this._onWpsColumnClick.bind(this));WifiContext.addEventListener('wifiEnabled',function(){elements.wifiCheckbox.removeAttribute('disabled');this._updateNetworkState();this._networkList().then((networkList)=>{networkList.scan();});}.bind(this));WifiContext.addEventListener('wifiDisabled',function(){elements.wifiCheckbox.removeAttribute('disabled');this._networkList().then((networkList)=>{networkList.clear(false);networkList.autoscan=false;});}.bind(this));WifiContext.addEventListener('wifiStatusChange',function(event){var scanStates=new Set(['connected','connectingfailed','disconnected']);this._updateNetworkState();if(scanStates.has(event.status)){if(this._wifiSectionVisible){this._networkList().then((networkList)=>{networkList.scan();});}else{this._scanPending=true;}}}.bind(this));WifiContext.addEventListener('wifiWrongPassword',function(event){var currentNetwork=WifiContext.currentNetwork;if(currentNetwork.known===false){this._openBadCredentialsDialog(currentNetwork);}}.bind(this));window.performance.mark('wifiListStart');},onBeforeShow:function(){this._wifiSectionVisible=true;this._updateVisibilityStatus();},onShow:function(){if(!this._initialized){this._initialized=true;SettingsListener.observe('wifi.enabled',true,function(enabled){this._setMozSettingsEnabled(enabled);if(enabled){this._updateNetworkState();this._networkList().then((networkList)=>{networkList.scan();});}}.bind(this));}},onBeforeHide:function(){this._wifiSectionVisible=false;},_onWpsColumnClick:function(){var self=this;if(this._wps.inProgress){this._wps.cancel({onSuccess:function(){elements.wpsInfoBlock.setAttribute('data-l10n-id','fullStatus-wps-canceled');},onError:function(error){document.l10n.setAttributes(elements.wpsInfoBlock,'wpsCancelFailedMessageError',{error:error.name});}});}else{DialogService.show('wifi-wps',{wpsAvailableNetworks:function(){return self._networkList().then((networkList)=>{return networkList.getWpsAvailableNetworks();});}}).then(function(result){var type=result.type;var value=result.value;if(type==='submit'){self._wps.connect({pin:value.pin,selectedAp:value.selectedAp,selectedMethod:value.selectedMethod,onSuccess:function(){elements.wps.wpsPbcLabelBlock.setAttribute('data-l10n-id','wpsCancelMessage');elements.wps.wpsInfoBlock.setAttribute('data-l10n-id','fullStatus-wps-inprogress');},onError:function(error){document.l10n.setAttributes(elements.wpsInfoBlock,'fullStatus-wps-failed-error',{error:error.name});}});}});}},_onWifiCheckboxChange:function(e){var checkbox=elements.wifiCheckbox;this._settings.createLock().set({'wifi.enabled':checkbox.checked}).onerror=function(){checkbox.removeAttribute('disabled');};checkbox.setAttribute('disabled',true);},_onScanItemClick:function(){this._networkList().then((networkList)=>{networkList.clear(true);networkList.scan();});},_updateVisibilityStatus:function(){this._networkList().then((networkList)=>{if(this._scanPending){networkList.scan();this._scanPending=false;}});},_setMozSettingsEnabled:function(enabled){this._networkList().then((networkList)=>{elements.wifiCheckbox.checked=enabled;if(enabled){networkList.clear(true);elements.wpsColumn.hidden=false;}else{if(this._wps.inProgress){elements.wpsInfoBlock.setAttribute('data-l10n-id',WifiContext.wifiStatusText.id);if(WifiContext.wifiStatusText.args){elements.wpsInfoBlock.setAttribute('data-l10n-args',JSON.stringify(WifiContext.wifiStatusText.args));}else{elements.wpsInfoBlock.removeAttribute('data-l10n-args');}}
|
|
networkList.clear(false);networkList.autoscan=false;elements.wpsColumn.hidden=true;}});},_updateNetworkState:function(){var networkStatus=wifiManager.connection.status;if(this._wps.inProgress){if(networkStatus!=='disconnected'){elements.wpsInfoBlock.setAttribute('data-l10n-id',WifiContext.wifiStatusText.id);if(WifiContext.wifiStatusText.args){elements.wpsInfoBlock.setAttribute('data-l10n-args',JSON.stringify(WifiContext.wifiStatusText.args));}else{elements.wpsInfoBlock.removeAttribute('data-l10n-args');}}
|
|
if(networkStatus==='connected'||networkStatus==='wps-timedout'||networkStatus==='wps-failed'||networkStatus==='wps-overlapped'){this._wps.inProgress=false;this._wps.statusReset();}}},_openBadCredentialsDialog:function(network){DialogService.confirm({id:'wifi-bad-credentials-confirm',args:{ssid:network.ssid}},{title:'wifi-bad-credentials-title',submitButton:{id:'ok',style:'recommend'},cancelButton:'cancel',}).then((result)=>{if(result.type==='submit'){this._networkList().then((networkList)=>{networkList._toggleNetwork(network);});}});},_networkList:function(){if(!this._networkListPromise){this._networkListPromise=new Promise((resolve)=>{require(['panels/wifi/wifi_network_list'],(WifiNetworkList)=>{resolve(WifiNetworkList(elements.networklist));});});}
|
|
return this._networkListPromise;}});};}); |