Chromium Code Reviews| 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 (function() { | 10 (function() { |
| 11 var adapter, adapterClient, bluetoothAdapter, bluetoothDevice, connection; | 11 var adapter, adapterClient, bluetoothAdapter, bluetoothDevice, connection; |
| 12 | 12 |
| 13 // Dictionary for address->Device cache. | 13 // Dictionary for address->Device cache. |
| 14 var devices = {}; | 14 var devices = {}; |
| 15 | 15 |
| 16 // Data model for a cached device. | 16 // Data model for a cached device. |
| 17 function Device() {}; | 17 function Device() {}; |
| 18 Device.prototype = { info: null }; | 18 Device.prototype = { info: null }; |
| 19 | 19 |
| 20 /** | 20 /** |
| 21 * The implementation of AdapterClient in | 21 * The implementation of AdapterClient in |
| 22 * device/bluetooth/public/interfaces/adapter.mojom. | 22 * device/bluetooth/public/interfaces/adapter.mojom. |
| 23 */ | 23 */ |
| 24 var AdapterClient = function() {}; | 24 var AdapterClient = function() {}; |
| 25 AdapterClient.prototype = { | 25 AdapterClient.prototype = { |
| 26 /** | 26 /** |
| 27 * Logs added device to console and caches the device info. | 27 * Caches the device info and updates the device list. |
| 28 * @param {!bluetoothDevice.DeviceInfo} device | 28 * @param {!bluetoothDevice.DeviceInfo} deviceInfo |
| 29 */ | 29 */ |
| 30 deviceAdded: function(deviceInfo) { | 30 deviceAdded: function(deviceInfo) { |
| 31 console.log('Device added', deviceInfo); | 31 addDevice(deviceInfo); |
| 32 devices[deviceInfo.address] = new Device(); | |
| 33 devices[deviceInfo.address].info = deviceInfo; | |
| 34 }, | 32 }, |
| 35 | 33 |
| 36 /** | 34 /** |
| 37 * Logs removed device to console and removes the cached device. | 35 * Removes the cached device and updates the device list. |
| 38 * @param {!bluetoothDevice.DeviceInfo} device | 36 * @param {!bluetoothDevice.DeviceInfo} deviceInfo |
| 39 */ | 37 */ |
| 40 deviceRemoved: function(deviceInfo) { | 38 deviceRemoved: function(deviceInfo) { |
| 41 console.log('Device removed', deviceInfo); | 39 removeDevice(deviceInfo); |
| 42 delete devices[deviceInfo.address]; | |
| 43 }, | 40 }, |
| 44 | 41 |
| 45 /** | 42 /** |
| 46 * Logs changed device info to console and updates the cached device. | 43 * Caches the last valid RSSI and refreshes the device list. |
| 47 * @param {!bluetoothDevice.DeviceInfo} deviceInfo | 44 * @param {!bluetoothDevice.DeviceInfo} deviceInfo |
| 48 */ | 45 */ |
| 49 deviceChanged: function(deviceInfo) { | 46 deviceChanged: function(deviceInfo) { |
| 50 console.log(new Date(), deviceInfo); | 47 updateDevice(deviceInfo); |
| 51 devices[deviceInfo.address].info = deviceInfo; | |
| 52 } | 48 } |
| 53 }; | 49 }; |
| 54 | 50 |
| 55 /** | 51 /** |
| 56 * TODO(crbug.com/652361): Move to shared location. | 52 * TODO(crbug.com/652361): Move to shared location. |
| 57 * Helper to convert callback-based define() API to a promise-based API. | 53 * Helper to convert callback-based define() API to a promise-based API. |
| 58 * @param {!Array<string>} moduleNames | 54 * @param {!Array<string>} moduleNames |
| 59 * @return {!Promise} | 55 * @return {!Promise} |
| 60 */ | 56 */ |
| 61 function importModules(moduleNames) { | 57 function importModules(moduleNames) { |
| 62 return new Promise(function(resolve, reject) { | 58 return new Promise(function(resolve, reject) { |
| 63 define(moduleNames, function(var_args) { | 59 define(moduleNames, function(var_args) { |
| 64 resolve(Array.prototype.slice.call(arguments, 0)); | 60 resolve(Array.prototype.slice.call(arguments, 0)); |
| 65 }); | 61 }); |
| 66 }); | 62 }); |
| 67 } | 63 } |
| 68 | 64 |
| 69 /** | 65 /** |
| 70 * Initializes Mojo proxies for page and Bluetooth services. | 66 * Initializes Mojo proxies for page and Bluetooth services. |
| 71 * @return {!Promise} resolves if adapter is acquired, rejects if Bluetooth | 67 * @return {!Promise} resolves if adapter is acquired, rejects if Bluetooth |
| 72 * is not supported. | 68 * is not supported. |
| 73 */ | 69 */ |
| 74 function initializeProxies() { | 70 function initializeProxies() { |
| 75 return importModules([ | 71 return importModules([ |
| 76 'content/public/renderer/frame_interfaces', | 72 'content/public/renderer/frame_interfaces', |
| 77 'device/bluetooth/public/interfaces/adapter.mojom', | 73 'device/bluetooth/public/interfaces/adapter.mojom', |
| 78 'device/bluetooth/public/interfaces/device.mojom', | 74 'device/bluetooth/public/interfaces/device.mojom', |
| 79 'mojo/public/js/connection', | 75 'mojo/public/js/connection', |
| 80 ]).then(function([frameInterfaces, ...modules]) { | 76 ]).then(function([frameInterfaces, ...modules]) { |
| 81 console.log('Loaded modules'); | |
| 82 | |
| 83 // Destructure here to assign global variables. | 77 // Destructure here to assign global variables. |
| 84 [bluetoothAdapter, bluetoothDevice, connection] = modules; | 78 [bluetoothAdapter, bluetoothDevice, connection] = modules; |
| 85 | 79 |
| 86 // Hook up the instance properties. | 80 // Hook up the instance properties. |
| 87 AdapterClient.prototype.__proto__ = | 81 AdapterClient.prototype.__proto__ = |
| 88 bluetoothAdapter.AdapterClient.stubClass.prototype; | 82 bluetoothAdapter.AdapterClient.stubClass.prototype; |
| 89 | 83 |
| 90 var adapterFactory = connection.bindHandleToProxy( | 84 var adapterFactory = connection.bindHandleToProxy( |
| 91 frameInterfaces.getInterface(bluetoothAdapter.AdapterFactory.name), | 85 frameInterfaces.getInterface(bluetoothAdapter.AdapterFactory.name), |
| 92 bluetoothAdapter.AdapterFactory); | 86 bluetoothAdapter.AdapterFactory); |
| 93 | 87 |
| 94 // Get an Adapter service. | 88 // Get an Adapter service. |
| 95 return adapterFactory.getAdapter(); | 89 return adapterFactory.getAdapter(); |
| 96 }).then(function(response) { | 90 }).then(function(response) { |
| 97 if (!response.adapter) { | 91 if (!response.adapter) { |
| 98 throw new Error('Bluetooth Not Supported on this platform.'); | 92 throw new Error('Bluetooth Not Supported on this platform.'); |
| 99 } | 93 } |
| 100 | 94 |
| 101 adapter = connection.bindHandleToProxy(response.adapter, | 95 adapter = connection.bindHandleToProxy(response.adapter, |
| 102 bluetoothAdapter.Adapter); | 96 bluetoothAdapter.Adapter); |
| 103 | 97 |
| 104 // Create a message pipe and bind one end to client | 98 // Create a message pipe and bind one end to client |
| 105 // implementation and the other to the Adapter service. | 99 // implementation and the other to the Adapter service. |
| 106 adapterClient = new AdapterClient(); | 100 adapterClient = new AdapterClient(); |
| 107 adapter.setClient(connection.bindStubDerivedImpl(adapterClient)); | 101 adapter.setClient(connection.bindStubDerivedImpl(adapterClient)); |
| 108 }); | 102 }); |
| 109 } | 103 } |
| 110 | 104 |
| 105 /** | |
| 106 * Adds a device to the device list and caches the values in the device | |
| 107 * dictionary. | |
| 108 * @param {!bluetoothDevice.DeviceInfo} deviceInfo | |
| 109 */ | |
| 110 function addDevice(deviceInfo) { | |
| 111 devices[deviceInfo.address] = new Device(); | |
| 112 devices[deviceInfo.address].info = deviceInfo; | |
| 113 | |
| 114 var deviceRowTemplate = $('device-row-template'); | |
| 115 var deviceList = $('device-list'); | |
|
ortuno
2016/10/21 00:56:36
nit: Move this down to where it's used.
mbrunson
2016/10/21 02:09:34
Done.
| |
| 116 | |
| 117 var deviceRow = deviceRowTemplate.content.children[0].cloneNode(true); | |
|
ortuno
2016/10/21 00:56:36
nit: cloneNode(true /* deep */);
mbrunson
2016/10/21 02:09:33
Done.
| |
| 118 deviceRow.id = deviceInfo.address; | |
| 119 deviceList.appendChild(deviceRow); | |
| 120 | |
| 121 updateDevice(deviceInfo); | |
| 122 } | |
| 123 | |
| 124 /** | |
| 125 * Removes a device from the device list and device dictionary with the | |
| 126 * matching address in the given |deviceInfo|. | |
| 127 * @param {!bluetoothDevice.DeviceInfo} deviceInfo | |
| 128 */ | |
| 129 function removeDevice(deviceInfo) { | |
| 130 delete devices[deviceInfo.address]; | |
| 131 var deviceElement = $(deviceInfo.address); | |
| 132 | |
| 133 if (deviceElement) { | |
| 134 var deviceList = $('device-list'); | |
| 135 deviceList.removeChild(deviceElement); | |
|
ortuno
2016/10/21 00:56:36
I don't think we want to completely remove element
mbrunson
2016/10/21 02:09:33
Done.
| |
| 136 } | |
| 137 } | |
| 138 | |
| 139 /** | |
| 140 * Updates a device in the device list and device dictionary with the given | |
| 141 * |deviceInfo|. | |
| 142 * @param {!bluetoothDevice.DeviceInfo} deviceInfo | |
| 143 */ | |
| 144 function updateDevice(deviceInfo) { | |
| 145 var deviceRow = $(deviceInfo.address); | |
| 146 if (deviceRow) { | |
|
ortuno
2016/10/21 00:56:36
When would you receive a DeviceChanged for a devic
mbrunson
2016/10/21 02:09:33
Isn't the order of messages in Mojo not guaranteed
ortuno
2016/10/21 02:16:55
The order is not guaranteed between pipes e.g. the
mbrunson
2016/10/21 18:16:28
Ah ok. I'll just throw an exception here for that.
| |
| 147 deviceRow.querySelector('.device-name').innerText = | |
| 148 deviceInfo.name_for_display; | |
| 149 deviceRow.querySelector('.device-address').innerText = deviceInfo.address; | |
| 150 | |
| 151 var rssi = (deviceInfo.rssi && deviceInfo.rssi.value) || | |
| 152 deviceRow.querySelector('.device-rssi').innerText; | |
| 153 deviceRow.querySelector('.device-rssi').innerText = rssi; | |
| 154 } | |
| 155 } | |
| 156 | |
| 111 document.addEventListener('DOMContentLoaded', function() { | 157 document.addEventListener('DOMContentLoaded', function() { |
| 112 initializeProxies() | 158 initializeProxies() |
| 113 .then(function() { return adapter.getInfo(); }) | 159 .then(function() { return adapter.getInfo(); }) |
| 114 .then(function(response) { console.log('adapter', response.info); }) | 160 .then(function(response) { console.log('adapter', response.info); }) |
| 115 .then(function() { return adapter.getDevices(); }) | 161 .then(function() { return adapter.getDevices(); }) |
| 116 .then(function(response) { | 162 .then(function(response) { response.devices.forEach(addDevice); }) |
| 117 console.log('devices', response.devices.length); | |
| 118 | |
| 119 response.devices.forEach(function(deviceInfo) { | |
| 120 devices[deviceInfo.address] = new Device(); | |
| 121 devices[deviceInfo.address].info = deviceInfo; | |
| 122 console.log(deviceInfo.name_for_display, deviceInfo); | |
| 123 }); | |
| 124 }) | |
| 125 .catch(function(error) { console.error(error); }); | 163 .catch(function(error) { console.error(error); }); |
| 126 }); | 164 }); |
| 127 })(); | 165 })(); |
| OLD | NEW |