2 * Copyright (c) 2013, Intel Corporation.
4 * This program is licensed under the terms and conditions of the
5 * Apache License, version 2.0. The full text of the Apache License is at
6 * http://www.apache.org/licenses/LICENSE-2.0
9 var wifiScanInProgress = false;
11 function wifiPanelInit() {
13 /* WiFi Settings Panel */
14 $('#page_wifi').on('pageshow', function(event, data) {
15 if (data.prevPage.attr('id') === 'page_wifi_detail') return;
17 settings.wifi.subscribeEvents(wifiEventReceived);
18 var adapter = settings.wifi.getDefaultAdapter();
19 if (adapter === null) {
20 showMsg('Error', 'WiFi adapter not found');
24 if (adapter.name != undefined) {
25 $('#label_wifi_adapter').html(adapter.name);
27 $('#label_wifi_adapter').html('WiFi adapter not found');
30 adapter.getPowered(function(is_powered) {
33 if ($('ul#listview_network_known li').length === 0 && $('ul#listview_network_available li').length === 0) {
35 wifiClearAvailableList();
36 setTimeout(function() {
44 showMsg('Error', 'Cannot get WiFi state: ' + e);
48 $('#toggle_wifi').change(function() {
49 if (wifiScanInProgress) return;
51 var adapter = settings.wifi.getDefaultAdapter();
52 if (adapter === null) {
53 showMsg('Error', 'WiFi adapter not found');
58 if ($('#toggle_wifi').val() === 'off') {
59 adapter.setPowered(false, function() {
61 console.log('Successfully disable wifi subsystem');
66 showMsg('Error', 'Cannot disable WiFi subsystem: ' + e);
69 adapter.setPowered(true, function() {
71 console.log('Successfully enable WiFi subsystem');
73 wifiClearAvailableList();
75 setTimeout(function() {
81 showMsg('Error', 'Cannot enable WiFi subsystem: ' + e);
86 $('#button_wifi_refresh').on('click', function() {
87 var adapter = settings.wifi.getDefaultAdapter();
88 if (adapter === null) {
89 showErr('Error', 'WiFi adapter not found');
95 $('#button_wifi_add').on('click', function() {
96 if (wifiScanInProgress) return;
98 /* Not fully implemented, disable for now */
99 showMsg('Error', 'Not supported');
102 var adapter = settings.wifi.getDefaultAdapter();
103 if (adapter === null) {
104 showMsg('Error', 'WiFi adapter not found');
107 $.mobile.changePage('#page_wifi_add');
110 /* WiFi network detail page */
111 $('#page_wifi_detail').on('pageshow', function(event, data) {
112 var network_id = localStorage.getItem('wifi_network_id');
113 if (network_id == undefined) return;
114 var network = $(jqId(network_id)).data('network-object');
115 wifiConstructDetailPanel(network);
118 /* WiFi add new network page */
119 $('#page_wifi_add').on('pagebeforeshow', function(event, data) {
120 $('#input_wifi_ssid').val('');
121 $('#input_wifi_password').val('');
122 $('#select_wifi_security').val('None').change();
123 $('#input_wifi_password').textinput('disable');
126 $('#page_wifi_button_add').on('click', function() {
127 var adapter = settings.wifi.getDefaultAdapter();
128 var ssid = $('#input_wifi_ssid').val();
129 var security_option = $('#select_wifi_security').val();
130 var passcode = $('#input_wifi_password').val();
133 showMsg('Error', 'Enter SSID');
136 if (security_option !== 'None') {
137 showMsg('Error', 'Not supported');
141 showSpinner(false, 'Connecting...');
142 adapter.connectNetwork(ssid, security_option, passcode, function() {
145 $.mobile.changePage('#page_wifi');
150 showMsg('Error', 'WiFi connect failed: ' + e);
154 $('#select_wifi_security').on('change', function(event, data) {
155 var security = this.value;
157 if (security === 'None') {
158 $('#input_wifi_password').textinput('disable');
159 $('#input_wifi_password').val('');
161 $('#input_wifi_password').textinput('enable');
166 function wifiEventReceived(event) {
167 if (event.type !== WS_EVENT_TYPE.WIFI) return;
168 if ($.mobile.activePage.attr('id') !== 'page_wifi' && $.mobile.activePage.attr('id') !== 'page_wifi_detail') {
172 if (event.name === 'ServicesChanged') {
173 wifiHandleServicesChanged(event.id, event.value);
174 } else if (event.name === 'PropertyChanged') {
175 wifiHandlePropertyChanged(event.id, event.value);
177 console.log('Unsupported WiFi event received: ' + event.name);
181 function wifiHandleServicesChanged(object_path, services) {
182 var servicesChanged = services[0];
183 var servicesRemoved = services[1];
185 if ($('#toggle_wifi').val() === 'off') return;
187 console.log(servicesChanged.length + ' networks changed');
188 for (var i = 0; i < servicesChanged.length; i++) {
189 if (servicesChanged[i][0] === undefined) {
190 console.log('Invalid parameters, missing object path');
194 if (servicesChanged[i][1].Type === 'wifi') {
195 var network = $(jqId(servicesChanged[i][0])).data('network-object');
197 if (network == null) {
198 console.log('could not find network object ' + servicesChanged[i][0]);
202 var network = new settings.wifi.WiFiNetwork(servicesChanged[i][0]);
203 if (servicesChanged[i][1].Name !== undefined) {
204 network.ssid = servicesChanged[i][1].Name;
206 if (servicesChanged[i][1].State === 'ready') {
207 network.connected = true;
208 } else if (servicesChanged[i][1].State === 'idle') {
209 network.connected = false;
211 if (servicesChanged[i][1].EncryptionMode !== undefined) {
212 network.encryption = servicesChanged[i][1].EncryptionMode;
214 if (servicesChanged[i][1].Strength !== undefined) {
215 network.strength = servicesChanged[i][1].Strength;
217 if (servicesChanged[i][1].IPv4.Address !== undefined) {
218 network.ipAddress = servicesChanged[i][1].IPv4.Address;
220 if (servicesChanged[i][1].IPv4.Gateway !== undefined) {
221 network.gateway = servicesChanged[i][1].IPv4.Gateway;
223 if (servicesChanged[i][1].IPv4.Netmask !== undefined) {
224 network.netmask = servicesChanged[i][1].IPv4.Netmask;
227 if ($.mobile.activePage.attr('id') === 'page_wifi') {
228 console.log('Network updated');
229 wifiUpdateNetwork(network);
234 console.log(servicesRemoved.length + ' networks removed');
235 for (var i = 0; i < servicesRemoved.length; i++) {
236 if (servicesRemoved[i] === undefined) {
237 console.log('Invalid parameters, missing object path');
241 wifiRemoveFromKnownList(servicesRemoved[i]);
242 wifiRemoveFromAvailableList(servicesRemoved[i]);
246 function wifiHandlePropertyChanged(id, property) {
247 if (property[0] === 'Powered') {
248 if (property[1] === true) {
249 wifiClearKnownList();
250 wifiClearAvailableList();
252 setTimeout(function() {
253 var adapter = settings.wifi.getDefaultAdapter();
261 /* if wifi is off, ignore all the propertyChanged events */
262 if ($('#toggle_wifi').val() === 'off') return;
264 if (property[0] === 'State') {
265 /* specific network has changed */
266 var network = $(jqId(parent)).data('network-object');
267 if (network == null) {
268 console.error('Wifi network not found');
272 if (property[1] === 'ready') {
273 network.connected = true;
274 } else if (property[1] === 'idle') {
275 network.connected = false;
278 wifiUpdateNetwork(network);
279 } else if (property[0] === 'Connected') {
280 /* unknown network has changed, sync WiFi network */
281 console.log('Unknown network connected property changed');
282 var adapter = settings.wifi.getDefaultAdapter();
283 wifiSync(adapter, null, null);
287 function wifiClearKnownList() {
288 $('#listview_network_known').html('');
291 function wifiClearAvailableList() {
292 $('#listview_network_available').html('');
295 function wifiScan(adapter) {
296 if (wifiScanInProgress) return;
298 console.log('Start wifi scan');
299 /* clear the network list with new scan */
300 wifiClearKnownList();
301 wifiClearAvailableList();
303 showSpinner(false, 'Scanning...');
304 wifiScanInProgress = true;
305 $('#toggle_wifi').slider('disable');
306 $('#toggle_wifi').slider('refresh');
307 adapter.scan(function(networks) {
309 wifiScanInProgress = false;
310 $('#toggle_wifi').slider('enable');
311 $('#toggle_wifi').slider('refresh');
312 console.log('found ' + networks.length + ' wifi networks');
313 for (var i = 0; i < networks.length; i++) {
314 var network = networks[i];
315 if (network.ssid && network.ssid !== '') {
316 wifiUpdateNetwork(network);
318 console.log('Skipping hidden network - ' + network.ipAddress);
323 wifiScanInProgress = false;
324 $('#toggle_wifi').slider('enable');
325 $('#toggle_wifi').slider('refresh');
326 showMsg('Error', 'Cannot scan: ' + e);
330 function wifiSync(adapter, success_cb, error_cb) {
331 if (wifiScanInProgress) return;
333 console.log('Start wifi sync');
334 /* clear the network list with new scan */
335 wifiClearKnownList();
336 wifiClearAvailableList();
338 wifiScanInProgress = true;
339 $('#toggle_wifi').slider('disable');
340 $('#toggle_wifi').slider('refresh');
341 adapter.scan(function(networks) {
343 wifiScanInProgress = false;
344 $('#toggle_wifi').slider('enable');
345 $('#toggle_wifi').slider('refresh');
346 console.log('found ' + networks.length + ' wifi networks');
347 for (var i = 0; i < networks.length; i++) {
348 var network = networks[i];
349 if (network.ssid && network.ssid !== '') {
350 wifiUpdateNetwork(network);
357 wifiScanInProgress = false;
358 $('#toggle_wifi').slider('enable');
359 $('#toggle_wifi').slider('refresh');
366 function wifiRefreshList() {
367 $('#listview_network_known').listview('refresh');
368 $('#listview_network_available').listview('refresh');
371 function wifiAppendToKnownList(network) {
372 if ($('#listview_network_known').find(jqId(network.id)).length != 0) return;
374 var parent = '#listview_network_known';
375 wifiConstructNetworkElement(parent, network);
376 wifiUpdateNetworkButton(network);
380 function wifiRemoveFromKnownList(network_id) {
381 var removeThis = $('#listview_network_known li').filter(function() {
382 return $(this).find(jqId(network_id)).length === 1;
385 if (removeThis.length !== 0) {
391 function wifiAppendToAvailableList(network) {
392 if ($('#listview_network_available').find(jqId(network.id)).length != 0) return;
394 var parent = '#listview_network_available';
395 wifiConstructNetworkElement(parent, network);
396 wifiUpdateNetworkButton(network);
400 function wifiRemoveFromAvailableList(network_id) {
401 var removeThis = $('#listview_network_available li').filter(function() {
402 return $(this).find(jqId(network_id)).length === 1;
405 if (removeThis.length !== 0) {
411 function getSignalStrengthStr(strength) {
412 var signal_strength = 'unknown';
413 if (strength > 0 && strength <= 20) {
414 strength = 'very poor';
415 } else if (strength > 20 && strength <= 40) {
416 signal_strength = 'poor';
417 } else if (strength > 40 && strength <= 70) {
418 signal_strength = 'average';
419 } else if (strength > 70 && strength <= 90) {
420 signal_strength = 'good';
421 } else if (strength > 90 && strength <= 100) {
422 signal_strength = 'excellent';
424 return signal_strength;
427 function wifiConstructNetworkElement(parent, network) {
428 var html = '<li data-icon="false"><a href="#" id="' + jqId(network.id).replace('#', '') + '">';
429 html += '<div class="network-ssid">' + network.ssid + '</div>';
430 html += '<div class="network-encryption">Encryption: ' + network.encryption + '</div>';
431 html += '<div class="network-strength">Signal: ' + getSignalStrengthStr(network.strength) + '</div>';
432 html += '<div class="network-status"></div>';
433 html += '<div data-role="button" class="network-action-button ui-li-aside" data-inline="true"></div>';
435 $(parent).append(html).trigger('create');
437 /* store network object in the element so we can reference it later */
438 $(jqId(network.id)).data('network-object', network);
440 $(jqId(network.id)).on('click', function() {
441 localStorage.setItem('wifi_network_id', network.id);
442 $.mobile.changePage('#page_wifi_detail');
445 $(jqId(network.id)).find('div.network-action-button').on('click', function(e) {
446 var parent = $(this).parent().attr('id');
449 * prevent the click event to propagate up
451 e.stopImmediatePropagation();
454 var adapter = settings.wifi.getDefaultAdapter();
455 if (adapter === null) return;
457 /* retrieve the network object from element */
458 var network = $(jqId(parent)).data('network-object');
459 if (network == null) {
460 console.error('Wifi network not found');
464 if (!network.connected && network.encryption !== 'none') {
465 /* Encryption based connection not supported now */
466 showMsg('Error', 'Only open networks are supported');
470 if (!network.connected) {
471 createPopupDialog(false, false, 'Connect to network', network.ssid, 'Connect', 'Cancel', function() {
472 console.log('WiFi connect to network: ' + network.ssid);
473 showSpinner(false, 'Connecting...');
474 adapter.connectNetwork(network.id, null, null, function() {
476 wifiSync(adapter, function() {
479 /* changing from disconnected to connected */
481 network.connected = true;
482 wifiUpdateNetwork(network);
487 showMsg('Error', 'WiFi connect failed: ' + e);
491 console.log('Wifi disconnect from network: ' + network.ssid);
492 showSpinner(false, 'Disconnecting...');
493 adapter.disconnectNetwork(network.id, function() {
495 wifiSync(adapter, function() {
498 /* changing from connected to disconnected */
500 network.connected = false;
501 wifiUpdateNetwork(network);
506 showMsg('Error', 'Network disconnect failed: ' + e);
512 function wifiUpdateNetwork(network) {
513 /* reposition device if it's connected or disconnected */
514 if (network.connected) {
515 wifiRemoveFromAvailableList(network.id);
516 wifiAppendToKnownList(network);
518 wifiRemoveFromKnownList(network.id);
519 wifiAppendToAvailableList(network);
522 /* update network button for allowed action */
523 wifiUpdateNetworkButton(network);
525 /* update network connection status */
526 wifiUpdateConnectionStatus(network);
528 /* update network detail panel */
529 if ($.mobile.activePage.attr('id') === 'page_wifi_detail') {
530 var network_id = localStorage.getItem('wifi_network_id');
531 if (network_id == undefined) return;
532 var network_object = $(jqId(network_id)).data('network-object');
533 if (network.id === network_object.id) {
534 wifiConstructDetailPanel(network);
539 function wifiUpdateNetworkButton(network) {
540 if (network.connected) {
541 $(jqId(network.id)).find('div.network-action-button').find('span').text('Disconnect');
543 $(jqId(network.id)).find('div.network-action-button').find('span').text('Connect');
547 function wifiUpdateConnectionStatus(network) {
548 var status = 'disconnected';
549 if (network.connected) {
550 $(jqId(network.id)).addClass('network-connected');
551 status = 'connected';
553 status = 'disconnected';
554 $(jqId(network.id)).removeClass('network-connected');
557 wifiUpdateConnectionStatusText(network, status);
560 function wifiUpdateConnectionStatusText(network, status) {
561 $(jqId(network.id)).find('div.network-status').text(status);
564 function wifiConstructDetailPanel(network) {
565 var status_connected = 'No';
567 if (network == null) return;
568 if (network.connected) status_connected = 'Yes';
570 $('#page_wifi_detail_content').html('');
571 var html = '<ul data-role="listview" id="listview_network_detail" data-inset="true" ' + 'class="network-list ui-listview">';
572 html += '<li id="network_detail_ssid"><h2>SSID: ' + network.ssid + '</h2></li>';
573 html += '<li id="network_detail_encryption"><h2>Encryption: ' + network.encryption + '</h2></li>';
574 html += '<li id="network_detail_strength"><h2>Signal Strength: ' + network.strength + '</h2></li>';
575 html += '<li id="network_detail_connected"><h2>Connected: ' + status_connected + '</h2></li>';
576 if (network.connected) {
577 html += '<li id="network_detail_ip_address"><h2>IP Address: ' + network.ipAddress + '</h2></li>';
578 html += '<li id="network_detail_gateway"><h2>Gateway: ' + network.gateway + '</h2></li>';
579 html += '<li id="network_detail_netmask"><h2>Netmask: ' + network.netmask + '</h2></li>';
582 $('#page_wifi_detail_content').append(html).trigger('create');
583 $('#listview_wifi_detail').listview('refresh');
586 function wifiUpdateDetailPanel(network) {
587 var status_connected = 'No';
589 if (network == null) return;
590 if (network.connected) status_connected = 'Yes';
591 $('#wifi_detail_connected').text(status_connected);
592 $('#listview_wifi_detail').listview('refresh');
595 function wifiToggleOn() {
596 setTimeout(function() {
597 $('#wifi_networks').show();
598 $('#toggle_wifi').val('on').slider('refresh');
602 function wifiToggleOff() {
603 setTimeout(function() {
604 $('#wifi_networks').hide();
605 $('#toggle_wifi').val('off').slider('refresh');