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 cr.exportPath('settings'); | 5 cr.exportPath('settings'); |
6 | 6 |
7 (function() { | 7 (function() { |
8 | 8 |
9 var PairingEventType = chrome.bluetoothPrivate.PairingEventType; | 9 var PairingEventType = chrome.bluetoothPrivate.PairingEventType; |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... |
39 adapterStateChanged_: function() { | 39 adapterStateChanged_: function() { |
40 if (!this.adapterState.powered) | 40 if (!this.adapterState.powered) |
41 this.fire('close-dialog'); | 41 this.fire('close-dialog'); |
42 }, | 42 }, |
43 | 43 |
44 /** | 44 /** |
45 * @param {!chrome.bluetooth.Device} device | 45 * @param {!chrome.bluetooth.Device} device |
46 * @return {boolean} | 46 * @return {boolean} |
47 * @private | 47 * @private |
48 */ | 48 */ |
49 deviceNotPaired_: function(device) { | 49 deviceNotPaired_: function(device) { return !device.paired; }, |
50 return !device.paired; | |
51 }, | |
52 | 50 |
53 /** | 51 /** |
54 * @param {!Array<!chrome.bluetooth.Device>} deviceList | 52 * @param {!Array<!chrome.bluetooth.Device>} deviceList |
55 * @return {boolean} True if deviceList contains any unpaired devices. | 53 * @return {boolean} True if deviceList contains any unpaired devices. |
56 * @private | 54 * @private |
57 */ | 55 */ |
58 haveDevices_: function(deviceList) { | 56 haveDevices_: function(deviceList) { |
59 return this.deviceList.findIndex(function(d) { return !d.paired; }) != -1; | 57 return this.deviceList.findIndex(function(d) { return !d.paired; }) != -1; |
60 }, | 58 }, |
61 | 59 |
62 /** | 60 /** |
63 * @param {!{detail: {action: string, device: !chrome.bluetooth.Device}}} e | 61 * @param {!{detail: {action: string, device: !chrome.bluetooth.Device}}} e |
64 * @private | 62 * @private |
65 */ | 63 */ |
66 onDeviceEvent_: function(e) { | 64 onDeviceEvent_: function(e) { |
67 this.fire('device-event', e.detail); | 65 this.fire('device-event', e.detail); |
68 /** @type {Event} */(e).stopPropagation(); | 66 /** @type {Event} */ (e).stopPropagation(); |
69 }, | 67 }, |
70 }; | 68 }; |
71 | 69 |
72 /** @polymerBehavior */ | 70 /** @polymerBehavior */ |
73 settings.BluetoothPairDeviceBehavior = { | 71 settings.BluetoothPairDeviceBehavior = { |
74 properties: { | 72 properties: { |
75 /** | 73 /** |
76 * Current Pairing device. | 74 * Current Pairing device. |
77 * @type {?chrome.bluetooth.Device|undefined} | 75 * @type {?chrome.bluetooth.Device|undefined} |
78 */ | 76 */ |
79 pairingDevice: Object, | 77 pairingDevice: Object, |
80 | 78 |
81 /** | 79 /** |
82 * Current Pairing event. | 80 * Current Pairing event. |
83 * @type {?chrome.bluetoothPrivate.PairingEvent|undefined} | 81 * @type {?chrome.bluetoothPrivate.PairingEvent|undefined} |
84 */ | 82 */ |
85 pairingEvent: Object, | 83 pairingEvent: Object, |
86 | 84 |
| 85 /** Pincode or passkey value, used to trigger connect enabled changes. */ |
| 86 pinOrPass: String, |
| 87 |
87 /** | 88 /** |
88 * @const | 89 * @const |
89 * @type {!Array<number>} | 90 * @type {!Array<number>} |
90 */ | 91 */ |
91 digits: { | 92 digits: { |
92 type: Array, | 93 type: Array, |
93 readOnly: true, | 94 readOnly: true, |
94 value: [0, 1, 2, 3, 4, 5], | 95 value: [0, 1, 2, 3, 4, 5], |
95 }, | 96 }, |
96 }, | 97 }, |
97 | 98 |
98 observers: [ | 99 observers: [ |
99 'pairingChanged_(pairingDevice, pairingEvent)', | 100 'pairingChanged_(pairingDevice, pairingEvent)', |
100 ], | 101 ], |
101 | 102 |
102 /** | 103 /** |
103 * @param {?chrome.bluetooth.Device} pairingDevice | 104 * @param {?chrome.bluetooth.Device} pairingDevice |
104 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent | 105 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent |
105 * @private | 106 * @private |
106 */ | 107 */ |
107 pairingChanged_: function(pairingDevice, pairingEvent) { | 108 pairingChanged_: function(pairingDevice, pairingEvent) { |
108 // Auto-close the dialog when pairing completes. | 109 // Auto-close the dialog when pairing completes. |
109 if (pairingDevice && pairingDevice.connected) { | 110 if (pairingDevice && pairingDevice.connected) { |
110 this.fire('close-dialog', ''); | 111 this.fire('close-dialog', ''); |
111 return; | 112 return; |
112 } | 113 } |
| 114 this.pinOrPass = ''; |
113 }, | 115 }, |
114 | 116 |
115 /** | 117 /** |
116 * @param {?chrome.bluetooth.Device} device | 118 * @param {?chrome.bluetooth.Device} device |
117 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent | 119 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent |
118 * @return {string} | 120 * @return {string} |
119 * @private | 121 * @private |
120 */ | 122 */ |
121 getMessage_: function(device, pairingEvent) { | 123 getMessage_: function(device, pairingEvent) { |
122 if (!device) | 124 if (!device) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 | 179 |
178 /** | 180 /** |
179 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent | 181 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent |
180 * @return {boolean} | 182 * @return {boolean} |
181 * @private | 183 * @private |
182 */ | 184 */ |
183 showConnect_: function(pairingEvent) { | 185 showConnect_: function(pairingEvent) { |
184 if (!pairingEvent) | 186 if (!pairingEvent) |
185 return false; | 187 return false; |
186 var pairing = pairingEvent.pairing; | 188 var pairing = pairingEvent.pairing; |
187 if (pairing == PairingEventType.REQUEST_PINCODE) { | 189 return pairing == PairingEventType.REQUEST_PINCODE || |
188 var pincode = /** @type {{invalid: boolean}} */(this.$.pincode); | 190 pairing == PairingEventType.REQUEST_PASSKEY; |
189 return !pincode.invalid; | |
190 } else if (pairing == PairingEventType.REQUEST_PASSKEY) { | |
191 var passkey = /** @type {{invalid: boolean}} */(this.$.passkey); | |
192 return !passkey.invalid; | |
193 } | |
194 return false; | |
195 }, | 191 }, |
196 | 192 |
197 /** | 193 /** |
| 194 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent |
| 195 * @param {string} pinOrPass Unused; call is triggered when this changes. |
| 196 * @return {boolean} |
| 197 * @private |
| 198 */ |
| 199 enableConnect_: function(pairingEvent, pinOrPass) { |
| 200 if (!this.showConnect_(this.pairingEvent)) |
| 201 return false; |
| 202 var inputId = |
| 203 (this.pairingEvent.pairing == PairingEventType.REQUEST_PINCODE) ? |
| 204 '#pincode' : |
| 205 '#passkey'; |
| 206 var paperInput = /** @type {!PaperInputElement} */ (this.$$(inputId)); |
| 207 assert(paperInput); |
| 208 /** @type {string} */ var value = paperInput.value; |
| 209 return !!value && paperInput.validate(); |
| 210 }, |
| 211 |
| 212 /** |
198 * @param {?chrome.bluetooth.Device} device | 213 * @param {?chrome.bluetooth.Device} device |
199 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent | 214 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent |
200 * @return {boolean} | 215 * @return {boolean} |
201 * @private | 216 * @private |
202 */ | 217 */ |
203 showDismiss_: function(device, pairingEvent) { | 218 showDismiss_: function(device, pairingEvent) { |
204 return (!!device && device.paired) || | 219 return (!!device && device.paired) || |
205 (!!pairingEvent && pairingEvent.pairing == PairingEventType.COMPLETE); | 220 (!!pairingEvent && pairingEvent.pairing == PairingEventType.COMPLETE); |
206 }, | 221 }, |
207 | 222 |
(...skipping 20 matching lines...) Expand all Loading... |
228 if (!this.pairingDevice) | 243 if (!this.pairingDevice) |
229 return; | 244 return; |
230 var options = | 245 var options = |
231 /** @type {!chrome.bluetoothPrivate.SetPairingResponseOptions} */ { | 246 /** @type {!chrome.bluetoothPrivate.SetPairingResponseOptions} */ { |
232 device: this.pairingDevice, | 247 device: this.pairingDevice, |
233 response: response | 248 response: response |
234 }; | 249 }; |
235 if (response == chrome.bluetoothPrivate.PairingResponse.CONFIRM) { | 250 if (response == chrome.bluetoothPrivate.PairingResponse.CONFIRM) { |
236 var pairing = this.pairingEvent.pairing; | 251 var pairing = this.pairingEvent.pairing; |
237 if (pairing == PairingEventType.REQUEST_PINCODE) | 252 if (pairing == PairingEventType.REQUEST_PINCODE) |
238 options.pincode = this.$.pincode.value; | 253 options.pincode = this.$$('#pincode').value; |
239 else if (pairing == PairingEventType.REQUEST_PASSKEY) | 254 else if (pairing == PairingEventType.REQUEST_PASSKEY) |
240 options.passkey = parseInt(this.$.passkey.value, 10); | 255 options.passkey = parseInt(this.$$('#passkey').value, 10); |
241 } | 256 } |
242 this.fire('response', options); | 257 this.fire('response', options); |
243 }, | 258 }, |
244 | 259 |
245 /** | 260 /** |
246 * @param {!PairingEventType} eventType | 261 * @param {!PairingEventType} eventType |
247 * @return {string} | 262 * @return {string} |
248 * @private | 263 * @private |
249 */ | 264 */ |
250 getEventDesc_: function(eventType) { | 265 getEventDesc_: function(eventType) { |
251 assert(eventType); | 266 assert(eventType); |
252 if (eventType == PairingEventType.COMPLETE || | 267 if (eventType == PairingEventType.COMPLETE || |
253 eventType == PairingEventType.KEYS_ENTERED || | 268 eventType == PairingEventType.KEYS_ENTERED || |
254 eventType == PairingEventType.REQUEST_AUTHORIZATION) { | 269 eventType == PairingEventType.REQUEST_AUTHORIZATION) { |
255 return 'bluetoothStartConnecting'; | 270 return 'bluetoothStartConnecting'; |
256 } | 271 } |
257 return 'bluetooth_' + /** @type {string} */(eventType); | 272 return 'bluetooth_' + /** @type {string} */ (eventType); |
258 }, | 273 }, |
259 | 274 |
260 /** | 275 /** |
261 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent | 276 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent |
262 * @param {number} index | 277 * @param {number} index |
263 * @return {string} | 278 * @return {string} |
264 * @private | 279 * @private |
265 */ | 280 */ |
266 getPinDigit_: function(pairingEvent, index) { | 281 getPinDigit_: function(pairingEvent, index) { |
267 if (!pairingEvent) | 282 if (!pairingEvent) |
268 return ''; | 283 return ''; |
269 var digit = '0'; | 284 var digit = '0'; |
270 var pairing = pairingEvent.pairing; | 285 var pairing = pairingEvent.pairing; |
271 if (pairing == PairingEventType.DISPLAY_PINCODE && pairingEvent.pincode && | 286 if (pairing == PairingEventType.DISPLAY_PINCODE && pairingEvent.pincode && |
272 index < pairingEvent.pincode.length) { | 287 index < pairingEvent.pincode.length) { |
273 digit = pairingEvent.pincode[index]; | 288 digit = pairingEvent.pincode[index]; |
274 } else if (pairingEvent.passkey && | 289 } else if ( |
275 (pairing == PairingEventType.DISPLAY_PASSKEY || | 290 pairingEvent.passkey && (pairing == PairingEventType.DISPLAY_PASSKEY || |
276 pairing == PairingEventType.KEYS_ENTERED || | 291 pairing == PairingEventType.KEYS_ENTERED || |
277 pairing == PairingEventType.CONFIRM_PASSKEY)) { | 292 pairing == PairingEventType.CONFIRM_PASSKEY)) { |
278 var passkeyString = String(pairingEvent.passkey); | 293 var passkeyString = String(pairingEvent.passkey); |
279 if (index < passkeyString.length) | 294 if (index < passkeyString.length) |
280 digit = passkeyString[index]; | 295 digit = passkeyString[index]; |
281 } | 296 } |
282 return digit; | 297 return digit; |
283 }, | 298 }, |
284 | 299 |
285 /** | 300 /** |
286 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent | 301 * @param {?chrome.bluetoothPrivate.PairingEvent} pairingEvent |
287 * @param {number} index | 302 * @param {number} index |
288 * @return {string} | 303 * @return {string} |
289 * @private | 304 * @private |
290 */ | 305 */ |
291 getPinClass_: function(pairingEvent, index) { | 306 getPinClass_: function(pairingEvent, index) { |
292 if (!pairingEvent) | 307 if (!pairingEvent) |
293 return ''; | 308 return ''; |
294 if (pairingEvent.pairing == PairingEventType.CONFIRM_PASSKEY) | 309 if (pairingEvent.pairing == PairingEventType.CONFIRM_PASSKEY) |
295 return 'confirm'; | 310 return 'confirm'; |
296 var cssClass = 'display'; | 311 var cssClass = 'display'; |
297 if (pairingEvent.pairing == PairingEventType.DISPLAY_PASSKEY) { | 312 if (pairingEvent.pairing == PairingEventType.DISPLAY_PASSKEY) { |
298 if (index == 0) | 313 if (index == 0) |
299 cssClass += ' next'; | 314 cssClass += ' next'; |
300 else | 315 else |
301 cssClass += ' untyped'; | 316 cssClass += ' untyped'; |
302 } else if ( | 317 } else if ( |
303 pairingEvent.pairing == PairingEventType.KEYS_ENTERED && | 318 pairingEvent.pairing == PairingEventType.KEYS_ENTERED && |
304 pairingEvent.enteredKey) { | 319 pairingEvent.enteredKey) { |
305 var enteredKey = pairingEvent.enteredKey; // 1-7 | 320 var enteredKey = pairingEvent.enteredKey; // 1-7 |
306 var lastKey = this.digits.length; // 6 | 321 var lastKey = this.digits.length; // 6 |
307 if ((index == -1 && enteredKey > lastKey) || (index + 1 == enteredKey)) | 322 if ((index == -1 && enteredKey > lastKey) || (index + 1 == enteredKey)) |
308 cssClass += ' next'; | 323 cssClass += ' next'; |
309 else if (index > enteredKey) | 324 else if (index > enteredKey) |
310 cssClass += ' untyped'; | 325 cssClass += ' untyped'; |
311 } | 326 } |
312 return cssClass; | 327 return cssClass; |
313 }, | 328 }, |
314 }; | 329 }; |
315 | 330 |
316 Polymer({ | 331 Polymer({ |
317 is: 'bluetooth-device-dialog', | 332 is: 'bluetooth-device-dialog', |
318 | 333 |
319 behaviors: [ | 334 behaviors: [ |
320 I18nBehavior, | 335 I18nBehavior, |
321 settings.BluetoothAddDeviceBehavior, | 336 settings.BluetoothAddDeviceBehavior, |
322 settings.BluetoothPairDeviceBehavior, | 337 settings.BluetoothPairDeviceBehavior, |
323 ], | 338 ], |
324 | 339 |
325 properties: { | 340 properties: { |
326 /** Which version of this dialog to show (adding or pairing). */ | 341 /** Which version of this dialog to show (adding or pairing). */ |
327 dialogType: String, | 342 dialogId: String, |
328 }, | 343 }, |
329 | 344 |
| 345 open: function() { |
| 346 this.pinOrPass = ''; |
| 347 this.$.dialog.open(); |
| 348 }, |
| 349 |
| 350 close: function() { this.$.dialog.close(); }, |
| 351 |
330 /** @private */ | 352 /** @private */ |
331 deviceListChanged_: function(e) { | 353 deviceListChanged_: function(e) { this.$.dialog.notifyResize(); }, |
332 this.$.dialog.notifyResize(); | 354 |
| 355 /** |
| 356 * @param {string} dialogId |
| 357 * @return {string} The title of for that |dialogId|. |
| 358 */ |
| 359 getTitle_: function(dialogId) { |
| 360 return this.i18n( |
| 361 dialogId == 'addDevice' ? 'bluetoothAddDevicePageTitle' : |
| 362 'bluetoothPairDevicePageTitle'); |
333 }, | 363 }, |
334 | 364 |
335 /** | 365 /** |
336 * @param {string} dialogType | |
337 * @return {string} The title of for that |dialogType|. | |
338 */ | |
339 getTitle_: function(dialogType) { | |
340 return this.i18n(dialogType == 'addDevice' ? | |
341 'bluetoothAddDevicePageTitle' : 'bluetoothPairDevicePageTitle'); | |
342 }, | |
343 | |
344 /** | |
345 * @param {string} currentDialogType | 366 * @param {string} currentDialogType |
346 * @param {string} wantedDialogType | 367 * @param {string} wantedDialogType |
347 * @return {boolean} | 368 * @return {boolean} |
348 * @private | 369 * @private |
349 */ | 370 */ |
350 isDialogType_: function(currentDialogType, wantedDialogType) { | 371 isDialogType_: function(currentDialogType, wantedDialogType) { |
351 return currentDialogType == wantedDialogType; | 372 return currentDialogType == wantedDialogType; |
352 }, | 373 }, |
353 | 374 |
354 /** @private */ | 375 /** @private */ |
355 onCancelTap_: function() { | 376 onCancelTap_: function() { |
356 // NOTE: tapping on an element with [dialog-dismiss] doesn't trigger an | 377 // NOTE: tapping on an element with [dialog-dismiss] doesn't trigger an |
357 // iron-overlay-cancel event, whereas tapping (X) or pressing Esc does. | 378 // iron-overlay-cancel event, whereas tapping (X) or pressing Esc does. |
358 // Using cancel() ensures all 3 ways to close the dialog run the same code. | 379 // Using cancel() ensures all 3 ways to close the dialog run the same code. |
359 this.$.dialog.cancel(); | 380 this.$.dialog.cancel(); |
360 }, | 381 }, |
361 | 382 |
362 /** @private */ | 383 /** @private */ |
363 onIronOverlayCanceled_: function() { | 384 onIronOverlayCanceled_: function() { |
364 if (this.dialogType == 'pairDevice') | 385 if (this.dialogId == 'pairDevice') |
365 this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CANCEL); | 386 this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CANCEL); |
366 }, | 387 }, |
367 | 388 |
368 /** @private */ | 389 /** @private */ |
369 onIronOverlayClosed_: function() { | 390 onIronOverlayClosed_: function() { this.fire('close-dialog', ''); }, |
370 this.fire('close-dialog', ''); | |
371 }, | |
372 | |
373 open: function() { | |
374 this.$.dialog.open(); | |
375 }, | |
376 | |
377 close: function() { | |
378 this.$.dialog.close(); | |
379 }, | |
380 }); | 391 }); |
381 | 392 |
382 })(); | 393 })(); |
OLD | NEW |