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