Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * Javascript for DeviceDetailsPage which displays all of the details of a | |
| 7 * device. The page is generated and managed dynamically in bluetooth_internals. | |
| 8 * served from chrome://bluetooth-internals/. | |
| 9 */ | |
| 10 | |
| 11 cr.define('device_details_page', function() { | |
| 12 /** @const */ var Page = cr.ui.pageManager.Page; | |
| 13 /** @const */ var Snackbar = snackbar.Snackbar; | |
| 14 /** @const */ var SnackbarType = snackbar.SnackbarType; | |
| 15 | |
| 16 /** | |
| 17 * Property names that will be displayed in the ObjectFieldSet which contains | |
| 18 * the DeviceInfo object. | |
| 19 */ | |
| 20 var PROPERTY_NAMES = { | |
| 21 name: 'Name', | |
| 22 address: 'Address', | |
| 23 is_gatt_connected: 'GATT Connected', | |
| 24 'rssi.value': 'Latest RSSI', | |
| 25 'services.length': 'Services', | |
| 26 }; | |
| 27 | |
| 28 /** | |
| 29 * Page that displays all of the details of a device. This page is generated | |
| 30 * and managed dynamically in bluetooth_internals. This page is the owner of | |
| 31 * the DevicePtr when a connection is created. Therefore, it manages the | |
| 32 * connection to the Bluetooth device and performs all Device interface | |
| 33 * related actions. | |
| 34 * @constructor | |
| 35 * @param {string} id | |
| 36 * @param {!interfaces.BluetoothDevice.DeviceInfo} deviceInfo | |
| 37 * @extends {cr.ui.pageManager.Page} | |
| 38 */ | |
| 39 function DeviceDetailsPage(id, deviceInfo) { | |
| 40 Page.call(this, id, deviceInfo.name_for_display, id); | |
| 41 | |
| 42 this.deviceInfo = deviceInfo; | |
| 43 | |
| 44 /** @type {interfaces.BluetoothDevice.Device.ptrClass} */ | |
| 45 this.devicePtr = null; | |
| 46 /** @private {!device_collection.ConnectionStatus} */ | |
| 47 this.status_ = device_collection.ConnectionStatus.DISCONNECTED; | |
| 48 | |
| 49 this.pageDiv.appendChild( | |
| 50 document.importNode($('device-details-template').content, | |
| 51 true /* deep */)); | |
| 52 | |
| 53 this.pageDiv.querySelector('.forget-btn').addEventListener('click', | |
| 54 function() { | |
| 55 this.disconnect(); | |
| 56 this.pageDiv.dispatchEvent(new CustomEvent('forgetpressed', { | |
| 57 detail: { | |
| 58 address: this.deviceInfo.address, | |
| 59 }, | |
| 60 })); | |
| 61 }.bind(this)); | |
| 62 | |
| 63 this.disconnectBtn_ = this.pageDiv.querySelector('.disconnect-btn'); | |
| 64 this.disconnectBtn_.addEventListener('click', function() { | |
| 65 if (this.devicePtr) { | |
| 66 this.disconnect(); | |
| 67 return; | |
| 68 } | |
| 69 this.connect(); | |
| 70 }.bind(this)); | |
| 71 | |
| 72 this.deviceFieldSet = new object_fieldset.ObjectFieldSet(); | |
| 73 this.deviceFieldSet.setPropertyDisplayNames(PROPERTY_NAMES); | |
| 74 this.pageDiv.querySelector('.device-details').appendChild( | |
| 75 this.deviceFieldSet); | |
| 76 | |
| 77 this.redraw(); | |
| 78 } | |
| 79 | |
| 80 DeviceDetailsPage.prototype = { | |
| 81 __proto__: Page.prototype, | |
| 82 | |
| 83 /** Creates a connection to the Bluetooth device. */ | |
| 84 connect: function() { | |
| 85 if (this.status_ !== device_collection.ConnectionStatus.DISCONNECTED) | |
| 86 return; | |
| 87 | |
| 88 this.updateConnectionStatus_( | |
| 89 device_collection.ConnectionStatus.CONNECTING); | |
| 90 this.connecting_ = true; | |
| 91 | |
| 92 adapter_broker.getAdapterBroker().then(function(adapterBroker) { | |
| 93 adapterBroker.connectToDevice(this.deviceInfo.address).then( | |
| 94 function(devicePtr) { | |
| 95 this.devicePtr = devicePtr; | |
| 96 | |
| 97 this.updateConnectionStatus_( | |
| 98 device_collection.ConnectionStatus.CONNECTED); | |
| 99 | |
| 100 // Fetch services asynchronously. | |
| 101 return this.devicePtr.getServices(); | |
| 102 }.bind(this)).then(function(response) { | |
| 103 this.deviceInfo.services = response.services; | |
| 104 this.redraw(); | |
| 105 this.fireDeviceInfoChanged_(); | |
| 106 }.bind(this)).catch(function(error) { | |
| 107 // If a connection error occurs while fetching the services, the | |
| 108 // devicePtr reference must be removed. | |
| 109 if (this.devicePtr) { | |
| 110 this.devicePtr.disconnect(); | |
| 111 this.devicePtr = null; | |
| 112 } | |
| 113 | |
| 114 Snackbar.show( | |
| 115 this.deviceInfo.name_for_display + ': ' + error.message, | |
| 116 SnackbarType.DANGER, 'Retry', function() { | |
| 117 this.connect(); | |
| 118 }.bind(this)); | |
| 119 | |
| 120 this.updateConnectionStatus_( | |
| 121 device_collection.ConnectionStatus.DISCONNECTED); | |
| 122 }.bind(this)); | |
| 123 }.bind(this)); | |
| 124 }, | |
| 125 | |
| 126 /** Disconnects the page from the Bluetooth device. */ | |
| 127 disconnect: function() { | |
| 128 if (!this.devicePtr) return; | |
| 129 | |
| 130 this.devicePtr.disconnect(); | |
| 131 this.devicePtr = null; | |
| 132 this.updateConnectionStatus_( | |
| 133 device_collection.ConnectionStatus.DISCONNECTED); | |
| 134 }, | |
| 135 | |
| 136 /** Redraws the contents of the page with the current |deviceInfo|. */ | |
| 137 redraw: function() { | |
| 138 var isConnected = this.deviceInfo.is_gatt_connected; | |
| 139 | |
| 140 // Update status if connection was dropped. | |
| 141 if (!isConnected) this.disconnect(); | |
|
scheib
2017/01/11 02:16:14
This condition seems odd here, it's not really par
mbrunson
2017/01/11 21:22:59
It's general maintenance. Redraw is called when th
| |
| 142 var connectedText = isConnected ? 'Connected' : 'Not Connected'; | |
| 143 | |
| 144 var rssi = this.deviceInfo.rssi; | |
| 145 var services = this.deviceInfo.services; | |
| 146 | |
| 147 var deviceViewObj = { | |
| 148 name: this.deviceInfo.name_for_display, | |
| 149 address: this.deviceInfo.address, | |
| 150 is_gatt_connected: connectedText, | |
| 151 'rssi.value': (rssi && rssi.value) || 'Unknown', | |
| 152 'services.length': (services && services.length) || 'Unknown', | |
| 153 }; | |
| 154 | |
| 155 this.deviceFieldSet.setObject(deviceViewObj); | |
| 156 }, | |
| 157 | |
| 158 /** | |
| 159 * Sets the page's device info and forces a redraw. | |
| 160 * @param {!interfaces.BluetoothDevice.DeviceInfo} | |
| 161 */ | |
| 162 setDeviceInfo: function(info) { | |
| 163 this.deviceInfo = info; | |
| 164 this.redraw(); | |
| 165 }, | |
| 166 | |
| 167 /** Fires an 'infochanged' event with the current |deviceInfo| */ | |
| 168 fireDeviceInfoChanged_: function() { | |
| 169 this.pageDiv.dispatchEvent(new CustomEvent('infochanged', { | |
| 170 bubbles: true, | |
| 171 detail: { | |
| 172 info: this.deviceInfo, | |
| 173 }, | |
| 174 })); | |
| 175 }, | |
| 176 | |
| 177 /** | |
| 178 * Updates the current connection status. Caches the latest status, updates | |
| 179 * the connection button message, and fires a 'connectionchanged' event when | |
| 180 * finished. | |
| 181 * @param {!device_collection.ConnectionStatus} status | |
| 182 * @param {Error=} opt_error | |
| 183 */ | |
| 184 updateConnectionStatus_: function(status) { | |
| 185 this.status_ = status; | |
| 186 if (status === device_collection.ConnectionStatus.DISCONNECTED) { | |
| 187 this.disconnectBtn_.textContent = 'Connect'; | |
| 188 this.disconnectBtn_.disabled = false; | |
| 189 } else if (status === device_collection.ConnectionStatus.CONNECTING) { | |
| 190 this.disconnectBtn_.textContent = 'Connecting'; | |
| 191 this.disconnectBtn_.disabled = true; | |
| 192 } else { | |
| 193 this.disconnectBtn_.textContent = 'Disconnect'; | |
| 194 this.disconnectBtn_.disabled = false; | |
| 195 } | |
| 196 | |
| 197 this.pageDiv.dispatchEvent(new CustomEvent('connectionchanged', { | |
| 198 bubbles: true, | |
| 199 detail: { | |
| 200 address: this.deviceInfo.address, | |
| 201 status: status, | |
| 202 } | |
| 203 })); | |
| 204 }, | |
| 205 }; | |
| 206 | |
| 207 return { | |
| 208 DeviceDetailsPage: DeviceDetailsPage, | |
| 209 }; | |
| 210 }); | |
| OLD | NEW |