Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 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 * @fileoverview | 6 * @fileoverview |
| 7 * 'settings-bluetooth-subpage' is the settings subpage for managing bluetooth | 7 * 'settings-bluetooth-subpage' is the settings subpage for managing bluetooth |
| 8 * properties and devices. | 8 * properties and devices. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 // NOTE(dbeam): even though this behaviors is only used privately, it must | |
|
fukino
2017/02/08 16:58:24
nit: s/behaviors/behavior
stevenjb
2017/02/08 20:27:00
Done.
| |
| 12 // be globally accessible for Closure's --polymer_pass to compile happily. | |
| 13 | |
| 11 Polymer({ | 14 Polymer({ |
| 12 is: 'settings-bluetooth-subpage', | 15 is: 'settings-bluetooth-subpage', |
| 13 | 16 |
| 14 behaviors: [I18nBehavior, CrScrollableBehavior], | 17 behaviors: [ |
| 18 I18nBehavior, | |
| 19 CrScrollableBehavior, | |
| 20 settings.RouteObserverBehavior, | |
| 21 ], | |
| 15 | 22 |
| 16 properties: { | 23 properties: { |
| 17 /** Reflects the bluetooth-page property. */ | 24 /** Reflects the bluetooth-page property. */ |
| 18 bluetoothEnabled: { | 25 bluetoothEnabled: { |
| 19 type: Boolean, | 26 type: Boolean, |
| 27 observer: 'bluetoothEnabledChanged_', | |
| 20 notify: true, | 28 notify: true, |
| 21 }, | 29 }, |
| 22 | 30 |
| 23 /** | 31 /** |
| 24 * The bluetooth adapter state, cached by bluetooth-page. | 32 * The bluetooth adapter state, cached by bluetooth-page. |
| 25 * @type {!chrome.bluetooth.AdapterState|undefined} | 33 * @type {!chrome.bluetooth.AdapterState|undefined} |
| 26 */ | 34 */ |
| 27 adapterState: Object, | 35 adapterState: Object, |
| 28 | 36 |
| 29 /** Informs bluetooth-page whether to show the spinner in the header. */ | 37 /** Informs bluetooth-page whether to show the spinner in the header. */ |
| 30 showSpinner: { | 38 showSpinner_: { |
| 31 type: Boolean, | 39 type: Boolean, |
| 32 notify: true, | 40 notify: true, |
| 33 computed: 'computeShowSpinner_(bluetoothEnabled, dialogId_)', | 41 computed: 'computeShowSpinner_(adapterState.*, dialogId_)', |
| 34 }, | 42 }, |
| 35 | 43 |
| 36 /** | 44 /** |
| 37 * The ordered list of bluetooth devices. | 45 * The ordered list of bluetooth devices. |
| 38 * @type {!Array<!chrome.bluetooth.Device>} | 46 * @type {!Array<!chrome.bluetooth.Device>} |
| 39 * @private | 47 * @private |
| 40 */ | 48 */ |
| 41 deviceList_: { | 49 deviceList_: { |
| 42 type: Array, | 50 type: Array, |
| 43 value: function() { | 51 value: function() { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 54 value: /** @return {Array} */ function() { | 62 value: /** @return {Array} */ function() { |
| 55 return []; | 63 return []; |
| 56 }, | 64 }, |
| 57 }, | 65 }, |
| 58 | 66 |
| 59 /** | 67 /** |
| 60 * Reflects the iron-list selecteditem property. | 68 * Reflects the iron-list selecteditem property. |
| 61 * @type {!chrome.bluetooth.Device} | 69 * @type {!chrome.bluetooth.Device} |
| 62 * @private | 70 * @private |
| 63 */ | 71 */ |
| 64 selectedItem_: { | 72 selectedPairedItem_: { |
| 65 type: Object, | 73 type: Object, |
| 66 observer: 'selectedItemChanged_', | 74 observer: 'selectedPairedItemChanged_', |
| 75 }, | |
| 76 | |
| 77 /** | |
| 78 * The ordered list of unpaired bluetooth devices. | |
| 79 * @type {!Array<!chrome.bluetooth.Device>} | |
| 80 */ | |
| 81 unpairedDeviceList_: { | |
| 82 type: Array, | |
| 83 value: /** @return {Array} */ function() { | |
| 84 return []; | |
| 85 }, | |
| 86 }, | |
| 87 | |
| 88 /** | |
| 89 * Reflects the iron-list selecteditem property. | |
| 90 * @type {!chrome.bluetooth.Device} | |
| 91 */ | |
| 92 selectedUnpairedItem_: { | |
| 93 type: Object, | |
| 94 observer: 'selectedUnpairedItemChanged_', | |
| 67 }, | 95 }, |
| 68 | 96 |
| 69 /** | 97 /** |
| 70 * Set to the name of the dialog to show. This page uses a single | 98 * Set to the name of the dialog to show. This page uses a single |
| 71 * paper-dialog to host one of three dialog elements, 'addDevice', | 99 * paper-dialog to host one of two dialog elements: 'pairDevice' or |
| 72 * 'pairDevice', or 'connectError'. This allows a seamless transition | 100 * 'connectError'. This allows a seamless transition between dialogs. |
| 73 * between dialogs. Note: This property should be set before opening the | 101 * Note: This property should be set before opening the dialog and setting |
| 74 * dialog and setting the property will not itself cause the dialog to open. | 102 * the property will not itself cause the dialog to open. |
| 75 * @private | 103 * @private |
| 76 */ | 104 */ |
| 77 dialogId_: { | 105 dialogId_: { |
| 78 type: String, | 106 type: String, |
| 79 value: '', | 107 value: '', |
| 80 }, | 108 }, |
| 81 | 109 |
| 82 /** | 110 /** |
| 83 * Current Pairing device. | 111 * Current Pairing device. |
| 84 * @type {!chrome.bluetooth.Device|undefined} | 112 * @type {!chrome.bluetooth.Device|undefined} |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 this.bluetoothAdapterStateChangedListener_); | 182 this.bluetoothAdapterStateChangedListener_); |
| 155 } | 183 } |
| 156 if (this.bluetoothDeviceUpdatedListener_) { | 184 if (this.bluetoothDeviceUpdatedListener_) { |
| 157 this.bluetooth.onDeviceAdded.removeListener( | 185 this.bluetooth.onDeviceAdded.removeListener( |
| 158 this.bluetoothDeviceUpdatedListener_); | 186 this.bluetoothDeviceUpdatedListener_); |
| 159 this.bluetooth.onDeviceChanged.removeListener( | 187 this.bluetooth.onDeviceChanged.removeListener( |
| 160 this.bluetoothDeviceUpdatedListener_); | 188 this.bluetoothDeviceUpdatedListener_); |
| 161 } | 189 } |
| 162 }, | 190 }, |
| 163 | 191 |
| 192 /** | |
| 193 * settings.RouteObserverBehavior | |
| 194 * @param {!settings.Route} route | |
| 195 * @protected | |
| 196 */ | |
| 197 currentRouteChanged: function(route) { | |
| 198 if (route == settings.Route.BLUETOOTH_DEVICES) { | |
| 199 if (this.bluetoothEnabled) | |
| 200 this.startDiscovery_(); | |
| 201 } else { | |
| 202 this.stopDiscovery_(); | |
| 203 } | |
| 204 }, | |
| 205 | |
| 164 /** @private */ | 206 /** @private */ |
| 165 computeShowSpinner_: function() { | 207 computeShowSpinner_: function() { |
| 166 return this.bluetoothEnabled && !this.dialogId_; | 208 return !this.dialogId_ && this.get('adapterState.discovering'); |
| 167 }, | 209 }, |
| 168 | 210 |
| 169 /** @private */ | 211 /** @private */ |
| 170 adapterStateChanged_: function() { | 212 adapterStateChanged_: function() { |
| 171 this.updateDeviceList_(); | 213 this.updateDeviceList_(); |
| 172 }, | 214 }, |
| 173 | 215 |
| 174 /** @private */ | 216 /** @private */ |
| 217 bluetoothEnabledChanged_: function() { | |
| 218 if (settings.getCurrentRoute() == settings.Route.BLUETOOTH_DEVICES && | |
| 219 this.bluetoothEnabled) { | |
| 220 this.startDiscovery_(); | |
| 221 } else{ | |
|
fukino
2017/02/08 16:58:23
nit: space after else
stevenjb
2017/02/08 20:27:01
Done.
| |
| 222 this.stopDiscovery_(); | |
| 223 } | |
| 224 }, | |
| 225 | |
| 226 /** @private */ | |
| 175 deviceListChanged_: function() { | 227 deviceListChanged_: function() { |
| 176 this.saveScroll(this.$.devices); | 228 this.saveScroll(this.$.pairedDevices); |
| 229 this.saveScroll(this.$.unpairedDevices); | |
| 177 this.pairedDeviceList_ = this.deviceList_.filter(function(device) { | 230 this.pairedDeviceList_ = this.deviceList_.filter(function(device) { |
| 178 return !!device.paired || !!device.connecting; | 231 return !!device.paired || !!device.connecting; |
| 179 }); | 232 }); |
| 233 this.unpairedDeviceList_ = this.deviceList_.filter(function(device) { | |
| 234 return !device.paired; | |
| 235 }); | |
| 180 this.updateScrollableContents(); | 236 this.updateScrollableContents(); |
| 181 this.restoreScroll(this.$.devices); | 237 this.restoreScroll(this.$.unpairedDevices); |
| 238 this.restoreScroll(this.$.pairedDevices); | |
| 182 }, | 239 }, |
| 183 | 240 |
| 184 /** @private */ | 241 /** @private */ |
| 185 selectedItemChanged_: function() { | 242 selectedPairedItemChanged_: function() { |
| 186 if (this.selectedItem_) | 243 if (this.selectedPairedItem_) |
| 187 this.connectDevice_(this.selectedItem_); | 244 this.connectDevice_(this.selectedPairedItem_); |
| 245 }, | |
| 246 | |
| 247 /** @private */ | |
| 248 selectedUnpairedItemChanged_: function() { | |
| 249 if (this.selectedUnpairedItem_) | |
| 250 this.connectDevice_(this.selectedUnpairedItem_); | |
| 188 }, | 251 }, |
| 189 | 252 |
| 190 /** | 253 /** |
| 191 * If bluetooth is enabled, request the complete list of devices and update | 254 * If bluetooth is enabled, request the complete list of devices and update |
| 192 * this.deviceList_. | 255 * this.deviceList_. |
| 193 * @private | 256 * @private |
| 194 */ | 257 */ |
| 195 updateDeviceList_: function() { | 258 updateDeviceList_: function() { |
| 196 if (!this.bluetoothEnabled) { | 259 if (!this.bluetoothEnabled) { |
| 197 this.deviceList_ = []; | 260 this.deviceList_ = []; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 var lastError = chrome.runtime.lastError; | 324 var lastError = chrome.runtime.lastError; |
| 262 if (lastError) { | 325 if (lastError) { |
| 263 if (lastError.message == 'Failed to stop discovery') | 326 if (lastError.message == 'Failed to stop discovery') |
| 264 return; // May happen if also stopped elsewhere, ignore. | 327 return; // May happen if also stopped elsewhere, ignore. |
| 265 console.error('stopDiscovery Error: ' + lastError.message); | 328 console.error('stopDiscovery Error: ' + lastError.message); |
| 266 } | 329 } |
| 267 }); | 330 }); |
| 268 }, | 331 }, |
| 269 | 332 |
| 270 /** | 333 /** |
| 271 * @param {!Event} e | |
| 272 * @private | |
| 273 */ | |
| 274 onAddDeviceTap_: function(e) { | |
| 275 e.preventDefault(); | |
| 276 this.openDialog_('addDevice'); | |
| 277 }, | |
| 278 | |
| 279 /** | |
| 280 * @param {!{detail: {action: string, device: !chrome.bluetooth.Device}}} e | 334 * @param {!{detail: {action: string, device: !chrome.bluetooth.Device}}} e |
| 281 * @private | 335 * @private |
| 282 */ | 336 */ |
| 283 onDeviceEvent_: function(e) { | 337 onDeviceEvent_: function(e) { |
| 284 var action = e.detail.action; | 338 var action = e.detail.action; |
| 285 var device = e.detail.device; | 339 var device = e.detail.device; |
| 286 if (action == 'connect') | 340 if (action == 'connect') |
| 287 this.connectDevice_(device); | 341 this.connectDevice_(device); |
| 288 else if (action == 'disconnect') | 342 else if (action == 'disconnect') |
| 289 this.disconnectDevice_(device); | 343 this.disconnectDevice_(device); |
| 290 else if (action == 'remove') | 344 else if (action == 'remove') |
| 291 this.forgetDevice_(device); | 345 this.forgetDevice_(device); |
| 292 else | 346 else |
| 293 console.error('Unexected action: ' + action); | 347 console.error('Unexected action: ' + action); |
| 294 }, | 348 }, |
| 295 | 349 |
| 296 /** | 350 /** |
| 297 * @return {string} | 351 * @return {string} |
| 298 * @private | 352 * @private |
| 299 */ | 353 */ |
| 300 getOffOnString_: function() { | 354 getOffOnString_: function() { |
| 301 return this.i18n(this.bluetoothEnabled ? 'bluetoothOn' : 'bluetoothOff'); | 355 return this.i18n(this.bluetoothEnabled ? 'bluetoothOn' : 'bluetoothOff'); |
| 302 }, | 356 }, |
| 303 | 357 |
| 304 /** | 358 /** |
| 359 * @param {boolean} bluetoothEnabled | |
| 360 * @param {!Array<!chrome.bluetooth.Device>} deviceList | |
| 305 * @return {boolean} | 361 * @return {boolean} |
| 306 * @private | 362 * @private |
| 307 */ | 363 */ |
| 308 showDevices_: function() { | 364 showDevices_: function(bluetoothEnabled, deviceList) { |
| 309 return this.bluetoothEnabled && this.pairedDeviceList_.length > 0; | 365 return bluetoothEnabled && deviceList.length > 0; |
| 310 }, | 366 }, |
| 311 | 367 |
| 312 /** | 368 /** |
| 369 * @param {boolean} bluetoothEnabled | |
| 370 * @param {!Array<!chrome.bluetooth.Device>} deviceList | |
| 313 * @return {boolean} | 371 * @return {boolean} |
| 314 * @private | 372 * @private |
| 315 */ | 373 */ |
| 316 showNoDevices_: function() { | 374 showNoDevices_: function(bluetoothEnabled, deviceList) { |
| 317 return this.bluetoothEnabled && this.pairedDeviceList_.length == 0; | 375 return bluetoothEnabled && deviceList.length == 0; |
| 318 }, | 376 }, |
| 319 | 377 |
| 320 /** | 378 /** |
| 321 * @param {!chrome.bluetooth.Device} device | 379 * @param {!chrome.bluetooth.Device} device |
| 322 * @private | 380 * @private |
| 323 */ | 381 */ |
| 324 connectDevice_: function(device) { | 382 connectDevice_: function(device) { |
| 325 // If the device is not paired, show the pairing dialog before connecting. | 383 // If the device is not paired, show the pairing dialog before connecting. |
| 326 if (!device.paired) { | 384 if (!device.paired) { |
| 327 this.pairingDevice_ = device; | 385 this.pairingDevice_ = device; |
| 328 this.openDialog_('pairDevice'); | 386 this.openDialog_('pairDevice'); |
| 329 } | 387 } |
| 330 | 388 |
| 331 this.bluetoothPrivate.connect(device.address, function(result) { | 389 this.bluetoothPrivate.connect(device.address, function(result) { |
| 332 var error; | 390 var error; |
| 333 if (chrome.runtime.lastError) { | 391 if (chrome.runtime.lastError) { |
| 334 error = chrome.runtime.lastError.message; | 392 error = chrome.runtime.lastError.message; |
| 335 } else { | 393 } else { |
| 336 switch (result) { | 394 switch (result) { |
| 395 case chrome.bluetoothPrivate.ConnectResultType.IN_PROGRESS: | |
| 396 return; // Do not close the dialog | |
| 337 case chrome.bluetoothPrivate.ConnectResultType.ALREADY_CONNECTED: | 397 case chrome.bluetoothPrivate.ConnectResultType.ALREADY_CONNECTED: |
| 338 case chrome.bluetoothPrivate.ConnectResultType.AUTH_CANCELED: | 398 case chrome.bluetoothPrivate.ConnectResultType.AUTH_CANCELED: |
| 339 case chrome.bluetoothPrivate.ConnectResultType.IN_PROGRESS: | |
| 340 case chrome.bluetoothPrivate.ConnectResultType.SUCCESS: | 399 case chrome.bluetoothPrivate.ConnectResultType.SUCCESS: |
| 341 break; | 400 break; |
| 342 default: | 401 default: |
| 343 error = result; | 402 error = result; |
| 344 } | 403 } |
| 345 } | 404 } |
| 346 | 405 |
| 347 if (!error) { | 406 if (!error) { |
| 348 this.$.deviceDialog.close(); | 407 this.$.deviceDialog.close(); |
| 349 return; | 408 return; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 397 openDialog_: function(dialogId) { | 456 openDialog_: function(dialogId) { |
| 398 if (this.dialogId_) { | 457 if (this.dialogId_) { |
| 399 // Dialog already opened, just update the contents. | 458 // Dialog already opened, just update the contents. |
| 400 this.dialogId_ = dialogId; | 459 this.dialogId_ = dialogId; |
| 401 return; | 460 return; |
| 402 } | 461 } |
| 403 this.dialogId_ = dialogId; | 462 this.dialogId_ = dialogId; |
| 404 // Call flush so that the dialog gets sized correctly before it is opened. | 463 // Call flush so that the dialog gets sized correctly before it is opened. |
| 405 Polymer.dom.flush(); | 464 Polymer.dom.flush(); |
| 406 this.$.deviceDialog.open(); | 465 this.$.deviceDialog.open(); |
| 407 this.startDiscovery_(); | |
| 408 }, | 466 }, |
| 409 | 467 |
| 410 /** @private */ | 468 /** @private */ |
| 411 onDialogClosed_: function() { | 469 onDialogClosed_: function() { |
| 412 this.stopDiscovery_(); | |
| 413 this.dialogId_ = ''; | 470 this.dialogId_ = ''; |
| 414 this.pairingDevice_ = undefined; | 471 this.pairingDevice_ = undefined; |
| 415 }, | 472 }, |
| 416 }); | 473 }); |
| OLD | NEW |