OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Javascript for bluetooth_internals.html, served from | 6 * Javascript for bluetooth_internals.html, served from |
7 * chrome://bluetooth-internals/. | 7 * chrome://bluetooth-internals/. |
8 */ | 8 */ |
9 | 9 |
10 // Expose for testing. | 10 // Expose for testing. |
11 var adapterBroker = null; | 11 var adapterBroker = null; |
12 var devices = null; | 12 var devices = null; |
13 | 13 |
14 cr.define('bluetooth_internals', function() { | 14 cr.define('bluetooth_internals', function() { |
| 15 /** @const */ var DevicesPage = devices_page.DevicesPage; |
| 16 /** @const */ var PageManager = cr.ui.pageManager.PageManager; |
| 17 |
| 18 /** |
| 19 * Observer for page changes. Used to update page title header. |
| 20 * @extends {cr.ui.pageManager.PageManager.Observer} |
| 21 */ |
| 22 var PageObserver = function() {}; |
| 23 |
| 24 PageObserver.prototype = { |
| 25 __proto__: PageManager.Observer.prototype, |
| 26 |
| 27 updateHistory: function(path) { |
| 28 window.location.hash = '#' + path; |
| 29 }, |
| 30 |
| 31 /** |
| 32 * Sets the page title. Called by PageManager. |
| 33 * @override |
| 34 * @param {string} title |
| 35 */ |
| 36 updateTitle: function(title) { |
| 37 document.querySelector('.page-title').textContent = title; |
| 38 }, |
| 39 }; |
15 | 40 |
16 /** @type {!Map<string, !interfaces.BluetoothDevice.Device.proxyClass>} */ | 41 /** @type {!Map<string, !interfaces.BluetoothDevice.Device.proxyClass>} */ |
17 var deviceAddressToProxy = new Map(); | 42 var deviceAddressToProxy = new Map(); |
18 | 43 |
| 44 /** @type {!device_collection.DeviceCollection} */ |
| 45 devices = new device_collection.DeviceCollection([]); |
| 46 |
| 47 /** @type {devices_page.DevicesPage} */ |
| 48 var devicesPage = null; |
| 49 |
| 50 function setupDeviceSystem(response) { |
| 51 // Hook up device collection events. |
| 52 adapterBroker.addEventListener('deviceadded', function(event) { |
| 53 devices.addOrUpdate(event.detail.deviceInfo); |
| 54 }); |
| 55 adapterBroker.addEventListener('devicechanged', function(event) { |
| 56 devices.addOrUpdate(event.detail.deviceInfo); |
| 57 }); |
| 58 adapterBroker.addEventListener('deviceremoved', function(event) { |
| 59 devices.remove(event.detail.deviceInfo); |
| 60 }); |
| 61 |
| 62 response.devices.forEach(devices.addOrUpdate, devices /* this */); |
| 63 |
| 64 devicesPage.setDevices(devices); |
| 65 devicesPage.pageDiv.addEventListener('inspectpressed', function() { |
| 66 // TODO(crbug.com/663470): Move connection logic to DeviceDetailsView |
| 67 // when it's added in chrome://bluetooth-internals. |
| 68 var address = event.detail.address; |
| 69 var proxy = deviceAddressToProxy.get(address); |
| 70 |
| 71 if (proxy) { |
| 72 // Device is already connected, so disconnect. |
| 73 proxy.disconnect(); |
| 74 deviceAddressToProxy.delete(address); |
| 75 devices.updateConnectionStatus( |
| 76 address, device_collection.ConnectionStatus.DISCONNECTED); |
| 77 return; |
| 78 } |
| 79 |
| 80 devices.updateConnectionStatus( |
| 81 address, device_collection.ConnectionStatus.CONNECTING); |
| 82 |
| 83 adapterBroker.connectToDevice(address).then(function(deviceProxy) { |
| 84 if (!devices.getByAddress(address)) { |
| 85 // Device no longer in list, so drop the connection. |
| 86 deviceProxy.disconnect(); |
| 87 return; |
| 88 } |
| 89 |
| 90 deviceAddressToProxy.set(address, deviceProxy); |
| 91 devices.updateConnectionStatus( |
| 92 address, device_collection.ConnectionStatus.CONNECTED); |
| 93 |
| 94 // Fetch services asynchronously. |
| 95 return deviceProxy.getServices(); |
| 96 }).then(function(response) { |
| 97 if (!response) return; |
| 98 |
| 99 var deviceInfo = devices.getByAddress(address); |
| 100 deviceInfo.services = response.services; |
| 101 devices.addOrUpdate(deviceInfo); |
| 102 }).catch(function(error) { |
| 103 devices.updateConnectionStatus( |
| 104 address, |
| 105 device_collection.ConnectionStatus.DISCONNECTED, |
| 106 error); |
| 107 }); |
| 108 }); |
| 109 } |
| 110 |
| 111 function setupPages() { |
| 112 var sidebar = new window.sidebar.Sidebar($('sidebar')); |
| 113 $('menu-btn').addEventListener('click', function() { sidebar.open(); }); |
| 114 PageManager.addObserver(sidebar); |
| 115 PageManager.addObserver(new PageObserver()); |
| 116 |
| 117 devicesPage = new DevicesPage(); |
| 118 PageManager.register(devicesPage); |
| 119 |
| 120 // Set up hash-based navigation. |
| 121 window.addEventListener('hashchange', function() { |
| 122 PageManager.showPageByName(window.location.hash.substr(1)); |
| 123 }); |
| 124 |
| 125 if (!window.location.hash) { |
| 126 PageManager.showPageByName(devicesPage.name); |
| 127 return; |
| 128 } |
| 129 |
| 130 PageManager.showPageByName(window.location.hash.substr(1)); |
| 131 } |
| 132 |
19 function initializeViews() { | 133 function initializeViews() { |
| 134 setupPages(); |
| 135 |
20 adapter_broker.getAdapterBroker() | 136 adapter_broker.getAdapterBroker() |
21 .then(function(broker) { adapterBroker = broker; }) | 137 .then(function(broker) { adapterBroker = broker; }) |
22 .then(function() { return adapterBroker.getInfo(); }) | 138 .then(function() { return adapterBroker.getInfo(); }) |
23 .then(function(response) { console.log('adapter', response.info); }) | 139 .then(function(response) { console.log('adapter', response.info); }) |
24 .then(function() { return adapterBroker.getDevices(); }) | 140 .then(function() { return adapterBroker.getDevices(); }) |
25 .then(function(response) { | 141 .then(setupDeviceSystem) |
26 // Hook up device collection events. | |
27 devices = new device_collection.DeviceCollection([]); | |
28 adapterBroker.addEventListener('deviceadded', function(event) { | |
29 devices.addOrUpdate(event.detail.deviceInfo); | |
30 }); | |
31 adapterBroker.addEventListener('devicechanged', function(event) { | |
32 devices.addOrUpdate(event.detail.deviceInfo); | |
33 }); | |
34 adapterBroker.addEventListener('deviceremoved', function(event) { | |
35 devices.remove(event.detail.deviceInfo); | |
36 }); | |
37 | |
38 response.devices.forEach(devices.addOrUpdate, | |
39 devices /* this */); | |
40 | |
41 var deviceTable = new device_table.DeviceTable(); | |
42 | |
43 deviceTable.addEventListener('inspectpressed', function(event) { | |
44 // TODO(crbug.com/663470): Move connection logic to DeviceDetailsView | |
45 // when it's added in chrome://bluetooth-internals. | |
46 var address = event.detail.address; | |
47 var proxy = deviceAddressToProxy.get(address); | |
48 | |
49 if (proxy) { | |
50 // Device is already connected, so disconnect. | |
51 proxy.disconnect(); | |
52 deviceAddressToProxy.delete(address); | |
53 devices.updateConnectionStatus( | |
54 address, device_collection.ConnectionStatus.DISCONNECTED); | |
55 return; | |
56 } | |
57 | |
58 devices.updateConnectionStatus( | |
59 address, device_collection.ConnectionStatus.CONNECTING); | |
60 adapterBroker.connectToDevice(address).then(function(deviceProxy) { | |
61 if (!devices.getByAddress(address)) { | |
62 // Device no longer in list, so drop the connection. | |
63 deviceProxy.disconnect(); | |
64 return; | |
65 } | |
66 | |
67 deviceAddressToProxy.set(address, deviceProxy); | |
68 devices.updateConnectionStatus( | |
69 address, device_collection.ConnectionStatus.CONNECTED); | |
70 | |
71 // Fetch services asynchronously. | |
72 return deviceProxy.getServices(); | |
73 }).then(function(response) { | |
74 var deviceInfo = devices.getByAddress(address); | |
75 deviceInfo.services = response.services; | |
76 devices.addOrUpdate(deviceInfo); | |
77 }).catch(function(error) { | |
78 devices.updateConnectionStatus( | |
79 address, | |
80 device_collection.ConnectionStatus.DISCONNECTED, | |
81 error); | |
82 }); | |
83 }); | |
84 | |
85 deviceTable.setDevices(devices); | |
86 deviceTable.id = 'device-table'; | |
87 | |
88 document.body.appendChild(deviceTable); | |
89 }) | |
90 .catch(function(error) { console.error(error); }); | 142 .catch(function(error) { console.error(error); }); |
91 } | 143 } |
92 | 144 |
93 return { | 145 return { |
94 initializeViews: initializeViews | 146 initializeViews: initializeViews |
95 }; | 147 }; |
96 }); | 148 }); |
97 | 149 |
98 document.addEventListener( | 150 document.addEventListener( |
99 'DOMContentLoaded', bluetooth_internals.initializeViews); | 151 'DOMContentLoaded', bluetooth_internals.initializeViews); |
OLD | NEW |