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
10 function bluetoothPanelInit() {
12 /* Bluetooth Settings Panel */
13 $('#page_bluetooth').on('pageshow', function(event, data) {
14 if (data.prevPage.attr('id') === 'page_bluetooth_detail') return;
16 wsAPI.subscribeEvents(bluetoothEventReceived);
17 var adapter = settings.bluetooth.getDefaultAdapter();
18 if (adapter === null) {
19 showMsg('Error', 'Bluetooth adapter not found');
22 console.log('Default BT adapter: ', adapter.name);
24 if (adapter.name != undefined) {
25 $('#label_bluetooth_adapter').html(adapter.name);
27 $('#label_bluetooth_adapter').html('Bluetooth adapter not found');
30 if (adapter.powered) {
32 adapter.stopScanDevices(function() {
33 bluetoothStartScan(adapter);
40 $('#toggle_bluetooth').change(function() {
41 var adapter = settings.bluetooth.getDefaultAdapter();
42 if (adapter === null) {
43 showMsg('Error', 'Bluetooth adapter not found');
48 if ($('#toggle_bluetooth').val() === 'off') {
49 /* stop scan, then disable bluetooth */
50 adapter.stopScanDevices(function() {
52 console.log('Bluetooth scan canceled');
53 $('#button_bluetooth_scan .ui-btn-text').text('Scan');
54 adapter.setPowered(false, function() {
56 console.log('Power off adapter success, adapter is powered: ' + adapter.powered);
61 showMsg('Error', 'Cannot turn off bluetooth adapter: ' + e);
65 $('#toggle_bluetooth').val('on').slider('refresh');
66 showMsg('Error', 'Cannot cancel scan: ' + e);
69 adapter.setPowered(true, function() {
71 console.log('Power on adapter success, adapter is powered: ' + adapter.powered);
73 bluetoothStartScan(adapter);
77 showMsg('Error', 'Cannot turn on bluetooth adapter: ' + e);
82 $('#button_bluetooth_scan').on('click', function() {
83 var adapter = settings.bluetooth.getDefaultAdapter();
84 if (adapter === null) {
85 showMsg('Error', 'Bluetooth adapter not found');
88 if ($('#button_bluetooth_scan').text() === 'Scan') {
89 bluetoothStartScan(adapter);
91 bluetoothStopScan(adapter);
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);
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') {
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) {
115 console.log('Unsupported bluetooth event received: ' + event.name);
120 function bluetoothHandlePropertyChanged(property) {
121 if (property[0] === 'Powered') {
122 if (property[1] === true) {
124 adapter.stopScanDevices(function() {
125 bluetoothStartScan(adapter);
128 bluetoothToggleOff();
133 function bluetoothClearAvailableList() {
134 $('#listview_device_available').html('');
137 function bluetoothStartScan(adapter) {
138 /* clear the device list with new scan */
139 bluetoothClearAvailableList();
141 adapter.startScanDevices({
143 onstarted: function() {
144 console.log('Bluetooth scan started...');
145 $('#button_bluetooth_scan .ui-btn-text').text('Stop');
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);
151 ondevicedisappeared: function(address) {
152 if ($(jqId(address)).length) {
153 bluetoothRemoveFromAvailableList(address);
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]);
166 showMsg('Error', 'Cannot scan: ' + e);
170 function bluetoothRefreshList() {
171 $('#listview_device_paired').listview('refresh');
172 $('#listview_device_available').listview('refresh');
175 function bluetoothStopScan(adapter) {
176 adapter.stopScanDevices(function() {
178 console.log('Bluetooth scan canceled');
179 $('#button_bluetooth_scan .ui-btn-text').text('Scan');
182 showMsg('Error', 'Cannot cancel scan: ' + e);
186 function bluetoothAppendToPairedList(device) {
187 if ($('#listview_device_paired').find(jqId(device.address)).length != 0) return;
189 var parent = '#listview_device_paired';
190 bluetoothConstructDeviceElement(parent, device);
191 bluetoothUpdateDeviceButton(device);
192 bluetoothRefreshList();
195 function bluetoothRemoveFromPairedList(device_addr) {
196 var removeThis = $('#listview_device_paired li').filter(function() {
197 return $(this).find(jqId(device_addr)).length === 1;
200 if (removeThis.length !== 0) {
202 bluetoothRefreshList();
206 function bluetoothAppendToAvailableList(device) {
207 if ($('#listview_device_available').find(jqId(device.address)).length != 0) return;
209 var parent = '#listview_device_available';
210 bluetoothConstructDeviceElement(parent, device);
211 bluetoothUpdateDeviceButton(device);
212 bluetoothRefreshList();
215 function bluetoothRemoveFromAvailableList(device_addr) {
216 var removeThis = $('#listview_device_available li').filter(function() {
217 return $(this).find(jqId(device_addr)).length === 1;
220 if (removeThis.length !== 0) {
222 bluetoothRefreshList();
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>';
234 $(parent).append(html).trigger('create');
236 /* store device object in the element so we can reference it later */
237 $(jqId(device.address)).data('device-object', device);
239 $(jqId(device.address)).on('click', function() {
240 localStorage.setItem('bluetooth_device_id', device.address);
241 $.mobile.changePage('#page_bluetooth_detail');
244 $(jqId(device.address)).find('div.device-action-button').on('click', function(e) {
245 var parent = $(this).parent().attr('id');
248 * prevent the click event to propagate up
250 e.stopImmediatePropagation();
253 var adapter = settings.bluetooth.getDefaultAdapter();
254 if (adapter === null) return;
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');
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() {
270 device.paired = true;
272 /* changing from unpaired to paried */
273 bluetoothUpdateDevice(device);
277 showMsg('Error', 'Bluetooth pair failed: ' + e);
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');
290 function bluetoothUpdateDevice(device) {
291 /* reposition device if it's paired or unpaired */
293 bluetoothRemoveFromAvailableList(device.address);
294 bluetoothAppendToPairedList(device);
296 bluetoothRemoveFromPairedList(device.address);
297 bluetoothAppendToAvailableList(device);
300 /* update device button for allowed action */
301 bluetoothUpdateDeviceButton(device);
303 /* update device connection status */
304 bluetoothUpdateConnectionStatus(device);
307 function bluetoothUpdateDeviceButton(device) {
309 if (device.connected) {
310 $(jqId(device.address)).find('div.device-action-button').find('span').text('Disconnect');
312 $(jqId(device.address)).find('div.device-action-button').find('span').text('Connect');
315 $(jqId(device.address)).find('div.device-action-button').find('span').text('Pair');
319 function bluetoothUpdateConnectionStatus(device) {
320 var status = 'unpaired';
322 $(jqId(device.address)).addClass('device-paired');
323 if (device.connected) {
324 status = 'connected';
325 $(jqId(device.address)).addClass('device-connected');
327 status = 'disconnected';
328 $(jqId(device.address)).removeClass('device-connected');
331 $(jqId(device.address)).removeClass('device-paired');
332 $(jqId(device.address)).removeClass('device-connected');
335 bluetoothUpdateConnectionStatusText(device, status);
338 function bluetoothUpdateConnectionStatusText(device, status) {
339 $(jqId(device.address)).find('div.device-status').text(status);
342 function bluetoothConstructDetailPanel(device) {
343 var status_paired = 'No';
344 var status_connected = 'No';
346 if (device == null) return;
347 if (device.paired) status_paired = 'Yes';
348 if (device.connected) status_connected = 'Yes';
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>';
357 $('#page_bluetooth_detail_content').append(html).trigger('create');
360 html = '<div data-role="button" id="button_bluetooth_unpair">Unpair</div>';
361 $('#page_bluetooth_detail_content').append(html).trigger('create');
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;
368 createPopupDialog(false, false, 'Unpair with device', device.name, 'Unpair', 'Cancel', function() {
369 showSpinner(false, 'Unpairing...');
370 adapter.unpairDevice(device.address, function() {
373 device.paired = false;
374 device.connected = false;
375 $('#button_bluetooth_unpair').remove();
377 /* changing from paired to unparied */
378 bluetoothUpdateDevice(device);
379 setTimeout(function() {
380 $.mobile.changePage('#page_bluetooth');
385 showMsg('Error', 'Bluetooth unpair failed: ' + e);
387 /* Something is wrong, remove from paired list */
388 bluetoothRemoveFromPairedList(device.address);
393 $('#listview_bluetooth_detail').listview('refresh');
396 function bluetoothUpdateDetailPanel(device) {
397 var status_paired = 'No';
398 var status_connected = 'No';
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');
408 function bluetoothToggleOn() {
409 setTimeout(function() {
410 $('#bluetooth_devices').show();
411 $('#toggle_bluetooth').val('on').slider('refresh');
415 function bluetoothToggleOff() {
416 setTimeout(function() {
417 $('#bluetooth_devices').hide();
418 $('#toggle_bluetooth').val('off').slider('refresh');