Fixes TIVI-2784 - Wifi password is not empty
[profile/ivi/SettingsApp.git] / js / panel-bluetooth.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
10 function bluetoothPanelInit() {
11
12     /* Bluetooth Settings Panel */
13     $('#page_bluetooth').on('pageshow', function(event, data) {
14         if (data.prevPage.attr('id') === 'page_bluetooth_detail') return;
15
16         wsAPI.subscribeEvents(bluetoothEventReceived);
17         var adapter = settings.bluetooth.getDefaultAdapter();
18         if (adapter === null) {
19             showMsg('Error', 'Bluetooth adapter not found');
20             return;
21         }
22         console.log('Default BT adapter: ', adapter.name);
23
24         if (adapter.name != undefined) {
25             $('#label_bluetooth_adapter').html(adapter.name);
26         } else {
27             $('#label_bluetooth_adapter').html('Bluetooth adapter not found');
28         }
29
30         if (adapter.powered) {
31             bluetoothToggleOn();
32             adapter.stopScanDevices(function() {
33                 bluetoothStartScan(adapter);
34             }, null);
35         } else {
36             bluetoothToggleOff();
37         }
38     });
39
40     $('#toggle_bluetooth').change(function() {
41         var adapter = settings.bluetooth.getDefaultAdapter();
42         if (adapter === null) {
43             showMsg('Error', 'Bluetooth adapter not found');
44             bluetoothToggleOff();
45             return;
46         }
47
48         if ($('#toggle_bluetooth').val() === 'off') {
49             /* stop scan, then disable bluetooth */
50             adapter.stopScanDevices(function() {
51                 /* success */
52                 console.log('Bluetooth scan canceled');
53                 $('#button_bluetooth_scan .ui-btn-text').text('Scan');
54                 adapter.setPowered(false, function() {
55                     /* success */
56                     console.log('Power off adapter success, adapter is powered: ' + adapter.powered);
57                     bluetoothToggleOff();
58                 }, function(e) {
59                     /* error */
60                     bluetoothToggleOn();
61                     showMsg('Error', 'Cannot turn off bluetooth adapter: ' + e);
62                 });
63             }, function(e) {
64                 /* error */
65                 $('#toggle_bluetooth').val('on').slider('refresh');
66                 showMsg('Error', 'Cannot cancel scan: ' + e);
67             });
68         } else {
69             adapter.setPowered(true, function() {
70                 /* success */
71                 console.log('Power on adapter success, adapter is powered: ' + adapter.powered);
72                 bluetoothToggleOn();
73                 bluetoothStartScan(adapter);
74             }, function(e) {
75                 /* error */
76                 bluetoothToggleOff();
77                 showMsg('Error', 'Cannot turn on bluetooth adapter: ' + e);
78             });
79         }
80     });
81
82     $('#button_bluetooth_scan').on('click', function() {
83         var adapter = settings.bluetooth.getDefaultAdapter();
84         if (adapter === null) {
85             showMsg('Error', 'Bluetooth adapter not found');
86             return;
87         }
88         if ($('#button_bluetooth_scan').text() === 'Scan') {
89             bluetoothStartScan(adapter);
90         } else {
91             bluetoothStopScan(adapter);
92         }
93     });
94
95     /* Bluetooth device detail page */
96     $('#page_bluetooth_detail').on('pageshow', function(event, data) {
97         var device_id = localStorage.getItem('bluetooth_device_id');
98         if (device_id == undefined) return;
99         var device = $(jqId(device_id)).data('device-object');
100         bluetoothConstructDetailPanel(device);
101     });
102 }
103
104 function bluetoothEventReceived(event) {
105     if (event.type === WS_EVENT_TYPE.BLUETOOTH || event.type === WS_EVENT_TYPE.CONNMAN) {
106         if ($.mobile.activePage.attr('id') !== 'page_bluetooth' || $.mobile.activePage.attr('id') !== 'page_bluetooth_detail') {
107             return;
108         }
109
110         if (event.type === WS_EVENT_TYPE.CONNMAN && event.id === '/net/connman/technology/bluetooth' && event.name === 'PropertyChanged') {
111             bluetoothHandlePropertyChanged(event.value);
112         } else if (event.type === WS_EVENT_TYPE.SYNC) {
113
114         } else {
115             console.log('Unsupported bluetooth event received: ' + event.name);
116         }
117     }
118 }
119
120 function bluetoothHandlePropertyChanged(property) {
121     if (property[0] === 'Powered') {
122         if (property[1] === true) {
123             bluetoothToggleOn();
124             adapter.stopScanDevices(function() {
125                 bluetoothStartScan(adapter);
126             }, null);
127         } else {
128             bluetoothToggleOff();
129         }
130     }
131 }
132
133 function bluetoothClearAvailableList() {
134     $('#listview_device_available').html('');
135 }
136
137 function bluetoothStartScan(adapter) {
138     /* clear the device list with new scan */
139     bluetoothClearAvailableList();
140
141     adapter.startScanDevices({
142         /* success */
143         onstarted: function() {
144             console.log('Bluetooth scan started...');
145             $('#button_bluetooth_scan .ui-btn-text').text('Stop');
146         },
147         ondevicefound: function(device) {
148             console.log('Bluetoth device found - name: ' + device.name + ', address: ' + device.address + ', is paired: ' + device.paired + ', is connected: ' + device.connected);
149             bluetoothUpdateDevice(device);
150         },
151         ondevicedisappeared: function(address) {
152             if ($(jqId(address)).length) {
153                 bluetoothRemoveFromAvailableList(address);
154             }
155         },
156         onfinished: function(devices) {
157             $('#button_bluetooth_scan .ui-btn-text').text('Scan');
158             for (var i = 0; i < devices.length; i++) {
159                 if (!$(jqId(devices[i].address)).length) {
160                     bluetoothUpdateDevice(devices[i]);
161                 }
162             }
163         }
164     }, function(e) {
165         /* error */
166         showMsg('Error', 'Cannot scan: ' + e);
167     });
168 }
169
170 function bluetoothRefreshList() {
171     $('#listview_device_paired').listview('refresh');
172     $('#listview_device_available').listview('refresh');
173 }
174
175 function bluetoothStopScan(adapter) {
176     adapter.stopScanDevices(function() {
177         /* success */
178         console.log('Bluetooth scan canceled');
179         $('#button_bluetooth_scan .ui-btn-text').text('Scan');
180     }, function(e) {
181         /* error */
182         showMsg('Error', 'Cannot cancel scan: ' + e);
183     });
184 }
185
186 function bluetoothAppendToPairedList(device) {
187     if ($('#listview_device_paired').find(jqId(device.address)).length != 0) return;
188
189     var parent = '#listview_device_paired';
190     bluetoothConstructDeviceElement(parent, device);
191     bluetoothUpdateDeviceButton(device);
192     bluetoothRefreshList();
193 }
194
195 function bluetoothRemoveFromPairedList(device_addr) {
196     var removeThis = $('#listview_device_paired li').filter(function() {
197         return $(this).find(jqId(device_addr)).length === 1;
198     });
199
200     if (removeThis.length !== 0) {
201         removeThis.remove();
202         bluetoothRefreshList();
203     }
204 }
205
206 function bluetoothAppendToAvailableList(device) {
207     if ($('#listview_device_available').find(jqId(device.address)).length != 0) return;
208
209     var parent = '#listview_device_available';
210     bluetoothConstructDeviceElement(parent, device);
211     bluetoothUpdateDeviceButton(device);
212     bluetoothRefreshList();
213 }
214
215 function bluetoothRemoveFromAvailableList(device_addr) {
216     var removeThis = $('#listview_device_available li').filter(function() {
217         return $(this).find(jqId(device_addr)).length === 1;
218     });
219
220     if (removeThis.length !== 0) {
221         removeThis.remove();
222         bluetoothRefreshList();
223     }
224 }
225
226 function bluetoothConstructDeviceElement(parent, device) {
227     var html = '<li data-icon="false"><a href="#" id="' + jqId(device.address).replace('#', '') + '">';
228     html += '<img src="images/bluetooth.png" class="device-icon ui-li-icon"></img>';
229     html += '<div class="device-name">' + device.name + '</div>';
230     html += '<div class="device-address">' + device.address + '</div>';
231     html += '<div class="device-status"></div>';
232     html += '<div data-role="button" class="device-action-button ui-li-aside" data-inline="true"></div>';
233     html += '</a></li>';
234     $(parent).append(html).trigger('create');
235
236     /* store device object in the element so we can reference it later */
237     $(jqId(device.address)).data('device-object', device);
238
239     $(jqId(device.address)).on('click', function() {
240         localStorage.setItem('bluetooth_device_id', device.address);
241         $.mobile.changePage('#page_bluetooth_detail');
242     });
243
244     $(jqId(device.address)).find('div.device-action-button').on('click', function(e) {
245         var parent = $(this).parent().attr('id');
246
247         /*
248          * prevent the click event to propagate up
249          */
250         e.stopImmediatePropagation();
251         e.preventDefault();
252
253         var adapter = settings.bluetooth.getDefaultAdapter();
254         if (adapter === null) return;
255
256         /* retrieve the device object from element */
257         var device = $(jqId(parent)).data('device-object');
258         if (device == undefined) {
259             console.error('Bluetooth device not found');
260             return;
261         }
262
263         if (!device.paired) {
264             createPopupDialog(false, false, 'Pair with', device.name, 'Pair', 'Cancel', function() {
265                 console.log('Bluetooth pair with device: ' + device.address);
266                 showSpinner(false, 'Pairing...');
267                 adapter.pairDevice(device.address, function() {
268                     /* success */
269                     hideSpinner();
270                     device.paired = true;
271
272                     /* changing from unpaired to paried */
273                     bluetoothUpdateDevice(device);
274                 }, function(e) {
275                     /* error */
276                     hideSpinner();
277                     showMsg('Error', 'Bluetooth pair failed: ' + e);
278                 });
279             });
280         } else if (device.paired && !device.connected) {
281             console.log('Bluetooth connect with device: ' + device.address);
282             showMsg('Error', 'Not suppported');
283         } else if (device.connected) {
284             console.log('Bluetooth disconnect with device: ' + device.address);
285             showMsg('Error', 'Not suppported');
286         }
287     });
288 }
289
290 function bluetoothUpdateDevice(device) {
291     /* reposition device if it's paired or unpaired */
292     if (device.paired) {
293         bluetoothRemoveFromAvailableList(device.address);
294         bluetoothAppendToPairedList(device);
295     } else {
296         bluetoothRemoveFromPairedList(device.address);
297         bluetoothAppendToAvailableList(device);
298     }
299
300     /* update device button for allowed action */
301     bluetoothUpdateDeviceButton(device);
302
303     /* update device connection status */
304     bluetoothUpdateConnectionStatus(device);
305 }
306
307 function bluetoothUpdateDeviceButton(device) {
308     if (device.paired) {
309         if (device.connected) {
310             $(jqId(device.address)).find('div.device-action-button').find('span').text('Disconnect');
311         } else {
312             $(jqId(device.address)).find('div.device-action-button').find('span').text('Connect');
313         }
314     } else {
315         $(jqId(device.address)).find('div.device-action-button').find('span').text('Pair');
316     }
317 }
318
319 function bluetoothUpdateConnectionStatus(device) {
320     var status = 'unpaired';
321     if (device.paired) {
322         $(jqId(device.address)).addClass('device-paired');
323         if (device.connected) {
324             status = 'connected';
325             $(jqId(device.address)).addClass('device-connected');
326         } else {
327             status = 'disconnected';
328             $(jqId(device.address)).removeClass('device-connected');
329         }
330     } else {
331         $(jqId(device.address)).removeClass('device-paired');
332         $(jqId(device.address)).removeClass('device-connected');
333     }
334
335     bluetoothUpdateConnectionStatusText(device, status);
336 }
337
338 function bluetoothUpdateConnectionStatusText(device, status) {
339     $(jqId(device.address)).find('div.device-status').text(status);
340 }
341
342 function bluetoothConstructDetailPanel(device) {
343     var status_paired = 'No';
344     var status_connected = 'No';
345
346     if (device == null) return;
347     if (device.paired) status_paired = 'Yes';
348     if (device.connected) status_connected = 'Yes';
349
350     $('#page_bluetooth_detail_content').html('');
351     var html = '<ul data-role="listview" id="listview_bluetooth_detail" data-inset="true" ' + 'class="device-list ui-listview">';
352     html += '<li id="bluetooth_detail_name"><h2>Device Name: ' + device.name + '</h2></li>';
353     html += '<li id="bluetooth_detail_address"><h2>Device Address: ' + device.address + '</h2></li>';
354     html += '<li id="bluetooth_detail_paired"><h2>Paired: ' + status_paired + '</h2></li>';
355     html += '<li id="bluetooth_detail_connected"><h2>Connected: ' + status_connected + '</h2></li>';
356     html += '</ul>';
357     $('#page_bluetooth_detail_content').append(html).trigger('create');
358
359     if (device.paired) {
360         html = '<div data-role="button" id="button_bluetooth_unpair">Unpair</div>';
361         $('#page_bluetooth_detail_content').append(html).trigger('create');
362
363         $('#button_bluetooth_unpair').on('click', function(e) {
364             console.log('Bluetooth unpair with device: ' + device.address);
365             var adapter = settings.bluetooth.getDefaultAdapter();
366             if (adapter === null) return;
367
368             createPopupDialog(false, false, 'Unpair with device', device.name, 'Unpair', 'Cancel', function() {
369                 showSpinner(false, 'Unpairing...');
370                 adapter.unpairDevice(device.address, function() {
371                     /* success */
372                     hideSpinner();
373                     device.paired = false;
374                     device.connected = false;
375                     $('#button_bluetooth_unpair').remove();
376
377                     /* changing from paired to unparied */
378                     bluetoothUpdateDevice(device);
379                     setTimeout(function() {
380                         $.mobile.changePage('#page_bluetooth');
381                     }, 1000);
382                 }, function(e) {
383                     /* error */
384                     hideSpinner();
385                     showMsg('Error', 'Bluetooth unpair failed: ' + e);
386
387                     /* Something is wrong, remove from paired list */
388                     bluetoothRemoveFromPairedList(device.address);
389                 });
390             });
391         });
392     }
393     $('#listview_bluetooth_detail').listview('refresh');
394 }
395
396 function bluetoothUpdateDetailPanel(device) {
397     var status_paired = 'No';
398     var status_connected = 'No';
399
400     if (device == null) return;
401     if (device.paired) status_paired = 'Yes';
402     if (device.connected) status_connected = 'Yes';
403     $('#bluetooth_detail_paired').text(connected);
404     $('#bluetooth_detail_connected').text(status_connected);
405     $('#listview_bluetooth_detail').listview('refresh');
406 }
407
408 function bluetoothToggleOn() {
409     setTimeout(function() {
410         $('#bluetooth_devices').show();
411         $('#toggle_bluetooth').val('on').slider('refresh');
412     }, 100);
413 }
414
415 function bluetoothToggleOff() {
416     setTimeout(function() {
417         $('#bluetooth_devices').hide();
418         $('#toggle_bluetooth').val('off').slider('refresh');
419     }, 100);
420 }