added locale privilege
[profile/ivi/SettingsApp.git] / js / panel-wifi.js
1 /*
2  * Copyright (c) 2013, Intel Corporation.
3  *
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
7  *
8  */
9 var wifiScanInProgress = false;
10
11 function wifiPanelInit() {
12
13     /* WiFi Settings Panel */
14     $('#page_wifi').on('pageshow', function(event, data) {
15         if (data.prevPage.attr('id') === 'page_wifi_detail') return;
16
17         settings.wifi.subscribeEvents(wifiEventReceived);
18         var adapter = settings.wifi.getDefaultAdapter();
19         if (adapter === null) {
20             showMsg('Error', 'WiFi adapter not found');
21             return;
22         }
23
24         if (adapter.name != undefined) {
25             $('#label_wifi_adapter').html(adapter.name);
26         } else {
27             $('#label_wifi_adapter').html('WiFi adapter not found');
28         }
29
30         adapter.getPowered(function(is_powered) {
31             if (is_powered) {
32                 wifiToggleOn();
33                 if ($('ul#listview_network_known li').length === 0 && $('ul#listview_network_available li').length === 0) {
34                     wifiClearKnownList();
35                     wifiClearAvailableList();
36                     setTimeout(function() {
37                         wifiScan(adapter);
38                     }, 1000);
39                 }
40             } else {
41                 wifiToggleOff();
42             }
43         }, function(e) {
44             showMsg('Error', 'Cannot get WiFi state: ' + e);
45         });
46     });
47
48     $('#toggle_wifi').change(function() {
49         if (wifiScanInProgress) return;
50
51         var adapter = settings.wifi.getDefaultAdapter();
52         if (adapter === null) {
53             showMsg('Error', 'WiFi adapter not found');
54             wifiToggleOff();
55             return;
56         }
57
58         if ($('#toggle_wifi').val() === 'off') {
59             adapter.setPowered(false, function() {
60                 /* success */
61                 console.log('Successfully disable wifi subsystem');
62                 wifiToggleOff();
63             }, function(e) {
64                 /* error */
65                 wifiToggleOn();
66                 showMsg('Error', 'Cannot disable WiFi subsystem: ' + e);
67             });
68         } else {
69             adapter.setPowered(true, function() {
70                 /* success */
71                 console.log('Successfully enable WiFi subsystem');
72                 wifiClearKnownList();
73                 wifiClearAvailableList();
74                 wifiToggleOn();
75                 setTimeout(function() {
76                     wifiScan(adapter);
77                 }, 1000);
78             }, function(e) {
79                 /* error */
80                 wifiToggleOff();
81                 showMsg('Error', 'Cannot enable WiFi subsystem: ' + e);
82             });
83         }
84     });
85
86     $('#button_wifi_refresh').on('click', function() {
87         var adapter = settings.wifi.getDefaultAdapter();
88         if (adapter === null) {
89             showErr('Error', 'WiFi adapter not found');
90         }
91
92         wifiScan(adapter);
93     });
94
95     $('#button_wifi_add').on('click', function() {
96         if (wifiScanInProgress) return;
97
98         /* Not fully implemented, disable for now */
99         showMsg('Error', 'Not supported');
100         return;
101
102         var adapter = settings.wifi.getDefaultAdapter();
103         if (adapter === null) {
104             showMsg('Error', 'WiFi adapter not found');
105         }
106
107         $.mobile.changePage('#page_wifi_add');
108     });
109
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);
116     });
117
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');
124     });
125
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();
131
132         if (ssid === '') {
133             showMsg('Error', 'Enter SSID');
134             return;
135         }
136         if (security_option !== 'None') {
137             showMsg('Error', 'Not supported');
138             return;
139         }
140
141         showSpinner(false, 'Connecting...');
142         adapter.connectNetwork(ssid, security_option, passcode, function() {
143             /* success */
144             hideSpinner();
145             $.mobile.changePage('#page_wifi');
146
147         }, function(e) {
148             /* error */
149             hideSpinner();
150             showMsg('Error', 'WiFi connect failed: ' + e);
151         });
152     });
153
154     $('#select_wifi_security').on('change', function(event, data) {
155         var security = this.value;
156
157         if (security === 'None') {
158             $('#input_wifi_password').textinput('disable');
159             $('#input_wifi_password').val('');
160         } else {
161             $('#input_wifi_password').textinput('enable');
162         }
163     });
164 }
165
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') {
169         return;
170     }
171
172     if (event.name === 'ServicesChanged') {
173         wifiHandleServicesChanged(event.id, event.value);
174     } else if (event.name === 'PropertyChanged') {
175         wifiHandlePropertyChanged(event.id, event.value);
176     } else {
177         console.log('Unsupported WiFi event received: ' + event.name);
178     }
179 }
180
181 function wifiHandleServicesChanged(object_path, services) {
182     var servicesChanged = services[0];
183     var servicesRemoved = services[1];
184
185     if ($('#toggle_wifi').val() === 'off') return;
186
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');
191             continue;
192         }
193
194         if (servicesChanged[i][1].Type === 'wifi') {
195             var network = $(jqId(servicesChanged[i][0])).data('network-object');
196
197             if (network == null) {
198                 console.log('could not find network object ' + servicesChanged[i][0]);
199                 continue;
200             }
201
202             var network = new settings.wifi.WiFiNetwork(servicesChanged[i][0]);
203             if (servicesChanged[i][1].Name !== undefined) {
204                 network.ssid = servicesChanged[i][1].Name;
205             }
206             if (servicesChanged[i][1].State === 'ready') {
207                 network.connected = true;
208             } else if (servicesChanged[i][1].State === 'idle') {
209                 network.connected = false;
210             }
211             if (servicesChanged[i][1].EncryptionMode !== undefined) {
212                 network.encryption = servicesChanged[i][1].EncryptionMode;
213             }
214             if (servicesChanged[i][1].Strength !== undefined) {
215                 network.strength = servicesChanged[i][1].Strength;
216             }
217             if (servicesChanged[i][1].IPv4.Address !== undefined) {
218                 network.ipAddress = servicesChanged[i][1].IPv4.Address;
219             }
220             if (servicesChanged[i][1].IPv4.Gateway !== undefined) {
221                 network.gateway = servicesChanged[i][1].IPv4.Gateway;
222             }
223             if (servicesChanged[i][1].IPv4.Netmask !== undefined) {
224                 network.netmask = servicesChanged[i][1].IPv4.Netmask;
225             }
226
227             if ($.mobile.activePage.attr('id') === 'page_wifi') {
228                 console.log('Network updated');
229                 wifiUpdateNetwork(network);
230             }
231         }
232     }
233
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');
238             continue;
239         }
240
241         wifiRemoveFromKnownList(servicesRemoved[i]);
242         wifiRemoveFromAvailableList(servicesRemoved[i]);
243     }
244 }
245
246 function wifiHandlePropertyChanged(id, property) {
247     if (property[0] === 'Powered') {
248         if (property[1] === true) {
249             wifiClearKnownList();
250             wifiClearAvailableList();
251             wifiToggleOn();
252             setTimeout(function() {
253                 var adapter = settings.wifi.getDefaultAdapter();
254                 wifiScan(adapter);
255             }, 1000);
256         } else {
257             wifiToggleOff();
258         }
259     }
260
261     /* if wifi is off, ignore all the propertyChanged events */
262     if ($('#toggle_wifi').val() === 'off') return;
263
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');
269             return;
270         }
271
272         if (property[1] === 'ready') {
273             network.connected = true;
274         } else if (property[1] === 'idle') {
275             network.connected = false;
276         }
277
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);
284     }
285 }
286
287 function wifiClearKnownList() {
288     $('#listview_network_known').html('');
289 }
290
291 function wifiClearAvailableList() {
292     $('#listview_network_available').html('');
293 }
294
295 function wifiScan(adapter) {
296     if (wifiScanInProgress) return;
297
298     console.log('Start wifi scan');
299     /* clear the network list with new scan */
300     wifiClearKnownList();
301     wifiClearAvailableList();
302
303     showSpinner(false, 'Scanning...');
304     wifiScanInProgress = true;
305     $('#toggle_wifi').slider('disable');
306     $('#toggle_wifi').slider('refresh');
307     adapter.scan(function(networks) {
308         hideSpinner();
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);
317             } else {
318                 console.log('Skipping hidden network - ' + network.ipAddress);
319             }
320         }
321     }, function(e) {
322         hideSpinner();
323         wifiScanInProgress = false;
324         $('#toggle_wifi').slider('enable');
325         $('#toggle_wifi').slider('refresh');
326         showMsg('Error', 'Cannot scan: ' + e);
327     });
328 }
329
330 function wifiSync(adapter, success_cb, error_cb) {
331     if (wifiScanInProgress) return;
332
333     console.log('Start wifi sync');
334     /* clear the network list with new scan */
335     wifiClearKnownList();
336     wifiClearAvailableList();
337
338     wifiScanInProgress = true;
339     $('#toggle_wifi').slider('disable');
340     $('#toggle_wifi').slider('refresh');
341     adapter.scan(function(networks) {
342         hideSpinner();
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);
351             }
352         }
353         if (success_cb) {
354             success_cb();
355         }
356     }, function(e) {
357         wifiScanInProgress = false;
358         $('#toggle_wifi').slider('enable');
359         $('#toggle_wifi').slider('refresh');
360         if (error_cb) {
361             error_cb(e);
362         }
363     });
364 }
365
366 function wifiRefreshList() {
367     $('#listview_network_known').listview('refresh');
368     $('#listview_network_available').listview('refresh');
369 }
370
371 function wifiAppendToKnownList(network) {
372     if ($('#listview_network_known').find(jqId(network.id)).length != 0) return;
373
374     var parent = '#listview_network_known';
375     wifiConstructNetworkElement(parent, network);
376     wifiUpdateNetworkButton(network);
377     wifiRefreshList();
378 }
379
380 function wifiRemoveFromKnownList(network_id) {
381     var removeThis = $('#listview_network_known li').filter(function() {
382         return $(this).find(jqId(network_id)).length === 1;
383     });
384
385     if (removeThis.length !== 0) {
386         removeThis.remove();
387         wifiRefreshList();
388     }
389 }
390
391 function wifiAppendToAvailableList(network) {
392     if ($('#listview_network_available').find(jqId(network.id)).length != 0) return;
393
394     var parent = '#listview_network_available';
395     wifiConstructNetworkElement(parent, network);
396     wifiUpdateNetworkButton(network);
397     wifiRefreshList();
398 }
399
400 function wifiRemoveFromAvailableList(network_id) {
401     var removeThis = $('#listview_network_available li').filter(function() {
402         return $(this).find(jqId(network_id)).length === 1;
403     });
404
405     if (removeThis.length !== 0) {
406         removeThis.remove();
407         wifiRefreshList();
408     }
409 }
410
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';
423     }
424     return signal_strength;
425 }
426
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>';
434     html += '</a></li>';
435     $(parent).append(html).trigger('create');
436
437     /* store network object in the element so we can reference it later */
438     $(jqId(network.id)).data('network-object', network);
439
440     $(jqId(network.id)).on('click', function() {
441         localStorage.setItem('wifi_network_id', network.id);
442         $.mobile.changePage('#page_wifi_detail');
443     });
444
445     $(jqId(network.id)).find('div.network-action-button').on('click', function(e) {
446         var parent = $(this).parent().attr('id');
447
448         /*
449          * prevent the click event to propagate up
450          */
451         e.stopImmediatePropagation();
452         e.preventDefault();
453
454         var adapter = settings.wifi.getDefaultAdapter();
455         if (adapter === null) return;
456
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');
461             return;
462         }
463
464         if (!network.connected && network.encryption !== 'none') {
465             /* Encryption based connection not supported now */
466             showMsg('Error', 'Only open networks are supported');
467             return;
468         }
469
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() {
475                     /* success */
476                     wifiSync(adapter, function() {
477                         hideSpinner();
478                     }, function(e) {
479                         /* changing from disconnected to connected */
480                         hideSpinner();
481                         network.connected = true;
482                         wifiUpdateNetwork(network);
483                     })
484                 }, function(e) {
485                     /* error */
486                     hideSpinner();
487                     showMsg('Error', 'WiFi connect failed: ' + e);
488                 });
489             });
490         } else {
491             console.log('Wifi disconnect from network: ' + network.ssid);
492             showSpinner(false, 'Disconnecting...');
493             adapter.disconnectNetwork(network.id, function() {
494                 /* success */
495                 wifiSync(adapter, function() {
496                     hideSpinner();
497                 }, function(e) {
498                     /* changing from connected to disconnected */
499                     hideSpinner();
500                     network.connected = false;
501                     wifiUpdateNetwork(network);
502                 })
503             }, function(e) {
504                 /* error */
505                 hideSpinner();
506                 showMsg('Error', 'Network disconnect failed: ' + e);
507             });
508         }
509     });
510 }
511
512 function wifiUpdateNetwork(network) {
513     /* reposition device if it's connected or disconnected */
514     if (network.connected) {
515         wifiRemoveFromAvailableList(network.id);
516         wifiAppendToKnownList(network);
517     } else {
518         wifiRemoveFromKnownList(network.id);
519         wifiAppendToAvailableList(network);
520     }
521
522     /* update network button for allowed action */
523     wifiUpdateNetworkButton(network);
524
525     /* update network connection status */
526     wifiUpdateConnectionStatus(network);
527
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);
535         }
536     }
537 }
538
539 function wifiUpdateNetworkButton(network) {
540     if (network.connected) {
541         $(jqId(network.id)).find('div.network-action-button').find('span').text('Disconnect');
542     } else {
543         $(jqId(network.id)).find('div.network-action-button').find('span').text('Connect');
544     }
545 }
546
547 function wifiUpdateConnectionStatus(network) {
548     var status = 'disconnected';
549     if (network.connected) {
550         $(jqId(network.id)).addClass('network-connected');
551         status = 'connected';
552     } else {
553         status = 'disconnected';
554         $(jqId(network.id)).removeClass('network-connected');
555     }
556
557     wifiUpdateConnectionStatusText(network, status);
558 }
559
560 function wifiUpdateConnectionStatusText(network, status) {
561     $(jqId(network.id)).find('div.network-status').text(status);
562 }
563
564 function wifiConstructDetailPanel(network) {
565     var status_connected = 'No';
566
567     if (network == null) return;
568     if (network.connected) status_connected = 'Yes';
569
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>';
580     }
581     html += '</ul>';
582     $('#page_wifi_detail_content').append(html).trigger('create');
583     $('#listview_wifi_detail').listview('refresh');
584 }
585
586 function wifiUpdateDetailPanel(network) {
587     var status_connected = 'No';
588
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');
593 }
594
595 function wifiToggleOn() {
596     setTimeout(function() {
597         $('#wifi_networks').show();
598         $('#toggle_wifi').val('on').slider('refresh');
599     }, 100);
600 }
601
602 function wifiToggleOff() {
603     setTimeout(function() {
604         $('#wifi_networks').hide();
605         $('#toggle_wifi').val('off').slider('refresh');
606     }, 100);
607 }