Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: chrome/browser/resources/settings/bluetooth_page/bluetooth_device_dialog.js

Issue 2655043005: MD Settings: Bluetooth: Move device list to subpage (Closed)
Patch Set: Fix clang, ES6 Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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() {
8
9 var PairingEventType = chrome.bluetoothPrivate.PairingEventType; 7 var PairingEventType = chrome.bluetoothPrivate.PairingEventType;
10 8
11 // NOTE(dbeam): even though these behaviors are only used privately, they must 9 // NOTE(dbeam): even though these behaviors are only used privately, they must
12 // be globally accessible for Closure's --polymer_pass to compile happily. 10 // be globally accessible for Closure's --polymer_pass to compile happily.
13 11
14 /** @polymerBehavior */ 12 /** @polymerBehavior */
15 settings.BluetoothAddDeviceBehavior = { 13 settings.BluetoothAddDeviceBehavior = {
16 properties: { 14 properties: {
17 /** 15 /**
18 * The cached bluetooth adapter state. 16 * The cached bluetooth adapter state.
(...skipping 19 matching lines...) Expand all
38 /** 36 /**
39 * Reflects the iron-list selecteditem property. 37 * Reflects the iron-list selecteditem property.
40 * @type {!chrome.bluetooth.Device} 38 * @type {!chrome.bluetooth.Device}
41 */ 39 */
42 selectedItem: { 40 selectedItem: {
43 type: Object, 41 type: Object,
44 observer: 'selectedItemChanged_', 42 observer: 'selectedItemChanged_',
45 }, 43 },
46 }, 44 },
47 45
48 /** @type {boolean} */ itemWasFocused_: false, 46 /** @type {boolean} */
47 itemWasFocused_: false,
49 48
50 /** @private */ 49 /** @private */
51 adapterStateChanged_: function() { 50 adapterStateChanged_: function() {
52 if (!this.adapterState.powered) 51 if (!this.adapterState.powered)
53 this.close(); 52 this.close();
54 }, 53 },
55 54
56 /** @private */ 55 /** @private */
57 deviceListChanged_: function() { 56 deviceListChanged_: function() {
58 this.updateScrollableContents(); 57 this.updateScrollableContents();
59 if (this.itemWasFocused_ || !this.getUnpaired_().length) 58 if (this.itemWasFocused_ || !this.getUnpaired_().length)
60 return; 59 return;
61 // If the iron-list is populated with at least one visible item then 60 // If the iron-list is populated with at least one visible item then
62 // focus it. 61 // focus it.
63 var item = this.$$('iron-list bluetooth-device-list-item'); 62 var item = this.$$('iron-list bluetooth-device-list-item');
64 if (item && item.offsetParent != null) { 63 if (item && item.offsetParent != null) {
65 item.focus(); 64 item.focus();
66 this.itemWasFocused_ = true; 65 this.itemWasFocused_ = true;
67 return; 66 return;
68 } 67 }
69 // Otherwise try again. 68 // Otherwise try again.
70 setTimeout(function() { this.deviceListChanged_(); }.bind(this), 100); 69 setTimeout(function() {
70 this.deviceListChanged_();
71 }.bind(this), 100);
71 }, 72 },
72 73
73 /** @private */ 74 /** @private */
74 selectedItemChanged_: function() { 75 selectedItemChanged_: function() {
75 if (this.selectedItem) 76 if (this.selectedItem)
76 this.fire('device-event', {action: 'connect', device: this.selectedItem}); 77 this.fire('device-event', {action: 'connect', device: this.selectedItem});
77 }, 78 },
78 79
79 /** 80 /**
80 * @return {!Array<!chrome.bluetooth.Device>} 81 * @return {!Array<!chrome.bluetooth.Device>}
(...skipping 12 matching lines...) Expand all
93 haveUnpaired_: function(deviceList) { 94 haveUnpaired_: function(deviceList) {
94 return this.getUnpaired_().length > 0; 95 return this.getUnpaired_().length > 0;
95 }, 96 },
96 }; 97 };
97 98
98 /** @polymerBehavior */ 99 /** @polymerBehavior */
99 settings.BluetoothPairDeviceBehavior = { 100 settings.BluetoothPairDeviceBehavior = {
100 properties: { 101 properties: {
101 /** 102 /**
102 * Current Pairing device. 103 * Current Pairing device.
103 * @type {?chrome.bluetooth.Device|undefined} 104 * @type {!chrome.bluetooth.Device|undefined}
104 */ 105 */
105 pairingDevice: Object, 106 pairingDevice: Object,
106 107
107 /** 108 /**
108 * Current Pairing event. 109 * Current Pairing event.
109 * @type {?chrome.bluetoothPrivate.PairingEvent|undefined} 110 * @type {?chrome.bluetoothPrivate.PairingEvent}
110 */ 111 */
111 pairingEvent: Object, 112 pairingEvent_: {
113 type: Object,
114 value: null,
115 },
112 116
113 /** Pincode or passkey value, used to trigger connect enabled changes. */ 117 /** Pincode or passkey value, used to trigger connect enabled changes. */
114 pinOrPass: String, 118 pinOrPass: String,
115 119
116 /** 120 /**
121 * Interface for bluetoothPrivate calls. Set in bluetooth-page.
122 * @type {BluetoothPrivate}
123 * @private
124 */
125 bluetoothPrivate: {
126 type: Object,
127 value: chrome.bluetoothPrivate,
128 },
129
130 /**
117 * @const 131 * @const
118 * @type {!Array<number>} 132 * @type {!Array<number>}
119 */ 133 */
120 digits: { 134 digits: {
121 type: Array, 135 type: Array,
122 readOnly: true, 136 readOnly: true,
123 value: [0, 1, 2, 3, 4, 5], 137 value: [0, 1, 2, 3, 4, 5],
124 }, 138 },
125 }, 139 },
126 140
127 observers: [ 141 observers: [
128 'pairingChanged_(pairingDevice, pairingEvent)', 142 'pairingChanged_(pairingDevice, pairingEvent_)',
129 ], 143 ],
130 144
145 /**
146 * Listener for chrome.bluetoothPrivate.onPairing events.
147 * @type {?function(!chrome.bluetoothPrivate.PairingEvent)}
148 * @private
149 */
150 bluetoothPrivateOnPairingListener_: null,
151
152 /** Called when the dialog is opened. Starts listening for pairing events. */
153 startPairing: function() {
154 if (!this.bluetoothPrivateOnPairingListener_) {
155 this.bluetoothPrivateOnPairingListener_ =
156 this.onBluetoothPrivateOnPairing_.bind(this);
157 this.bluetoothPrivate.onPairing.addListener(
158 this.bluetoothPrivateOnPairingListener_);
159 }
160 },
161
162 /** Called when the dialog is closed. */
163 endPairing: function() {
164 if (this.bluetoothPrivateOnPairingListener_) {
165 this.bluetoothPrivate.onPairing.removeListener(
166 this.bluetoothPrivateOnPairingListener_);
167 this.bluetoothPrivateOnPairingListener_ = null;
168 }
169 this.pairingEvent_ = null;
170 },
171
172 /**
173 * Process bluetoothPrivate.onPairing events.
174 * @param {!chrome.bluetoothPrivate.PairingEvent} event
175 * @private
176 */
177 onBluetoothPrivateOnPairing_: function(event) {
178 if (!this.pairingDevice ||
179 event.device.address != this.pairingDevice.address) {
180 return;
181 }
182 if (event.pairing == PairingEventType.KEYS_ENTERED &&
183 event.passkey === undefined && this.pairingEvent_) {
184 // 'keysEntered' event might not include the updated passkey so preserve
185 // the current one.
186 event.passkey = this.pairingEvent_.passkey;
187 }
188 this.pairingEvent_ = event;
189 },
190
131 /** @private */ 191 /** @private */
132 pairingChanged_: function() { 192 pairingChanged_: function() {
133 // Auto-close the dialog when pairing completes. 193 // Auto-close the dialog when pairing completes.
134 if (this.pairingDevice && this.pairingDevice.connected) { 194 if (this.pairingDevice.connected) {
135 this.close(); 195 this.close();
136 return; 196 return;
137 } 197 }
138 this.pinOrPass = ''; 198 this.pinOrPass = '';
139 }, 199 },
140 200
141 /** 201 /**
142 * @return {string} 202 * @return {string}
143 * @private 203 * @private
144 */ 204 */
145 getMessage_: function() { 205 getMessage_: function() {
146 if (!this.pairingDevice)
147 return '';
148 var message; 206 var message;
149 if (!this.pairingEvent) 207 if (!this.pairingEvent_)
150 message = 'bluetoothStartConnecting'; 208 message = 'bluetoothStartConnecting';
151 else 209 else
152 message = this.getEventDesc_(this.pairingEvent.pairing); 210 message = this.getEventDesc_(this.pairingEvent_.pairing);
153 return this.i18n(message, this.pairingDevice.name); 211 return this.i18n(message, this.pairingDevice.name);
154 }, 212 },
155 213
156 /** 214 /**
157 * @return {boolean} 215 * @return {boolean}
158 * @private 216 * @private
159 */ 217 */
160 showEnterPincode_: function() { 218 showEnterPincode_: function() {
161 return !!this.pairingEvent && 219 return !!this.pairingEvent_ &&
162 this.pairingEvent.pairing == PairingEventType.REQUEST_PINCODE; 220 this.pairingEvent_.pairing == PairingEventType.REQUEST_PINCODE;
163 }, 221 },
164 222
165 /** 223 /**
166 * @return {boolean} 224 * @return {boolean}
167 * @private 225 * @private
168 */ 226 */
169 showEnterPasskey_: function() { 227 showEnterPasskey_: function() {
170 return !!this.pairingEvent && 228 return !!this.pairingEvent_ &&
171 this.pairingEvent.pairing == PairingEventType.REQUEST_PASSKEY; 229 this.pairingEvent_.pairing == PairingEventType.REQUEST_PASSKEY;
172 }, 230 },
173 231
174 /** 232 /**
175 * @return {boolean} 233 * @return {boolean}
176 * @private 234 * @private
177 */ 235 */
178 showDisplayPassOrPin_: function() { 236 showDisplayPassOrPin_: function() {
179 if (!this.pairingEvent) 237 if (!this.pairingEvent_)
180 return false; 238 return false;
181 var pairing = this.pairingEvent.pairing; 239 var pairing = this.pairingEvent_.pairing;
182 return ( 240 return (
183 pairing == PairingEventType.DISPLAY_PINCODE || 241 pairing == PairingEventType.DISPLAY_PINCODE ||
184 pairing == PairingEventType.DISPLAY_PASSKEY || 242 pairing == PairingEventType.DISPLAY_PASSKEY ||
185 pairing == PairingEventType.CONFIRM_PASSKEY || 243 pairing == PairingEventType.CONFIRM_PASSKEY ||
186 pairing == PairingEventType.KEYS_ENTERED); 244 pairing == PairingEventType.KEYS_ENTERED);
187 }, 245 },
188 246
189 /** 247 /**
190 * @return {boolean} 248 * @return {boolean}
191 * @private 249 * @private
192 */ 250 */
193 showAcceptReject_: function() { 251 showAcceptReject_: function() {
194 return !!this.pairingEvent && 252 return !!this.pairingEvent_ &&
195 this.pairingEvent.pairing == PairingEventType.CONFIRM_PASSKEY; 253 this.pairingEvent_.pairing == PairingEventType.CONFIRM_PASSKEY;
196 }, 254 },
197 255
198 /** 256 /**
199 * @return {boolean} 257 * @return {boolean}
200 * @private 258 * @private
201 */ 259 */
202 showConnect_: function() { 260 showConnect_: function() {
203 if (!this.pairingEvent) 261 if (!this.pairingEvent_)
204 return false; 262 return false;
205 var pairing = this.pairingEvent.pairing; 263 var pairing = this.pairingEvent_.pairing;
206 return pairing == PairingEventType.REQUEST_PINCODE || 264 return pairing == PairingEventType.REQUEST_PINCODE ||
207 pairing == PairingEventType.REQUEST_PASSKEY; 265 pairing == PairingEventType.REQUEST_PASSKEY;
208 }, 266 },
209 267
210 /** 268 /**
211 * @return {boolean} 269 * @return {boolean}
212 * @private 270 * @private
213 */ 271 */
214 enableConnect_: function() { 272 enableConnect_: function() {
215 if (!this.showConnect_()) 273 if (!this.showConnect_())
216 return false; 274 return false;
217 var inputId = 275 var inputId =
218 (this.pairingEvent.pairing == PairingEventType.REQUEST_PINCODE) ? 276 (this.pairingEvent_.pairing == PairingEventType.REQUEST_PINCODE) ?
219 '#pincode' : 277 '#pincode' :
220 '#passkey'; 278 '#passkey';
221 var paperInput = /** @type {!PaperInputElement} */ (this.$$(inputId)); 279 var paperInput = /** @type {!PaperInputElement} */ (this.$$(inputId));
222 assert(paperInput); 280 assert(paperInput);
223 /** @type {string} */ var value = paperInput.value; 281 /** @type {string} */ var value = paperInput.value;
224 return !!value && paperInput.validate(); 282 return !!value && paperInput.validate();
225 }, 283 },
226 284
227 /** 285 /**
228 * @return {boolean} 286 * @return {boolean}
229 * @private 287 * @private
230 */ 288 */
231 showDismiss_: function() { 289 showDismiss_: function() {
232 return (!!this.paringDevice && this.pairingDevice.paired) || 290 return this.pairingDevice.paired ||
233 (!!this.pairingEvent && 291 (!!this.pairingEvent_ &&
234 this.pairingEvent.pairing == PairingEventType.COMPLETE); 292 this.pairingEvent_.pairing == PairingEventType.COMPLETE);
235 }, 293 },
236 294
237 /** @private */ 295 /** @private */
238 onAcceptTap_: function() { 296 onAcceptTap_: function() {
239 this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CONFIRM); 297 this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CONFIRM);
240 }, 298 },
241 299
242 /** @private */ 300 /** @private */
243 onConnectTap_: function() { 301 onConnectTap_: function() {
244 this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CONFIRM); 302 this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CONFIRM);
(...skipping 10 matching lines...) Expand all
255 */ 313 */
256 sendResponse_: function(response) { 314 sendResponse_: function(response) {
257 if (!this.pairingDevice) 315 if (!this.pairingDevice)
258 return; 316 return;
259 var options = 317 var options =
260 /** @type {!chrome.bluetoothPrivate.SetPairingResponseOptions} */ { 318 /** @type {!chrome.bluetoothPrivate.SetPairingResponseOptions} */ {
261 device: this.pairingDevice, 319 device: this.pairingDevice,
262 response: response 320 response: response
263 }; 321 };
264 if (response == chrome.bluetoothPrivate.PairingResponse.CONFIRM) { 322 if (response == chrome.bluetoothPrivate.PairingResponse.CONFIRM) {
265 var pairing = this.pairingEvent.pairing; 323 var pairing = this.pairingEvent_.pairing;
266 if (pairing == PairingEventType.REQUEST_PINCODE) 324 if (pairing == PairingEventType.REQUEST_PINCODE)
267 options.pincode = this.$$('#pincode').value; 325 options.pincode = this.$$('#pincode').value;
268 else if (pairing == PairingEventType.REQUEST_PASSKEY) 326 else if (pairing == PairingEventType.REQUEST_PASSKEY)
269 options.passkey = parseInt(this.$$('#passkey').value, 10); 327 options.passkey = parseInt(this.$$('#passkey').value, 10);
270 } 328 }
329 this.bluetoothPrivate.setPairingResponse(options, function() {
330 if (chrome.runtime.lastError) {
331 // TODO(stevenjb): Show error.
332 console.error(
333 'Error setting pairing response: ' + options.device.name +
334 ': Response: ' + options.response +
335 ': Error: ' + chrome.runtime.lastError.message);
336 }
337 this.close();
338 }.bind(this));
339
271 this.fire('response', options); 340 this.fire('response', options);
272 }, 341 },
273 342
274 /** 343 /**
275 * @param {!PairingEventType} eventType 344 * @param {!PairingEventType} eventType
276 * @return {string} 345 * @return {string}
277 * @private 346 * @private
278 */ 347 */
279 getEventDesc_: function(eventType) { 348 getEventDesc_: function(eventType) {
280 assert(eventType); 349 assert(eventType);
281 if (eventType == PairingEventType.COMPLETE || 350 if (eventType == PairingEventType.COMPLETE ||
282 eventType == PairingEventType.KEYS_ENTERED || 351 eventType == PairingEventType.KEYS_ENTERED ||
283 eventType == PairingEventType.REQUEST_AUTHORIZATION) { 352 eventType == PairingEventType.REQUEST_AUTHORIZATION) {
284 return 'bluetoothStartConnecting'; 353 return 'bluetoothStartConnecting';
285 } 354 }
286 return 'bluetooth_' + /** @type {string} */ (eventType); 355 return 'bluetooth_' + /** @type {string} */ (eventType);
287 }, 356 },
288 357
289 /** 358 /**
290 * @param {number} index 359 * @param {number} index
291 * @return {string} 360 * @return {string}
292 * @private 361 * @private
293 */ 362 */
294 getPinDigit_: function(index) { 363 getPinDigit_: function(index) {
295 if (!this.pairingEvent) 364 if (!this.pairingEvent_)
296 return ''; 365 return '';
297 var digit = '0'; 366 var digit = '0';
298 var pairing = this.pairingEvent.pairing; 367 var pairing = this.pairingEvent_.pairing;
299 if (pairing == PairingEventType.DISPLAY_PINCODE && 368 if (pairing == PairingEventType.DISPLAY_PINCODE &&
300 this.pairingEvent.pincode && index < this.pairingEvent.pincode.length) { 369 this.pairingEvent_.pincode &&
301 digit = this.pairingEvent.pincode[index]; 370 index < this.pairingEvent_.pincode.length) {
371 digit = this.pairingEvent_.pincode[index];
302 } else if ( 372 } else if (
303 this.pairingEvent.passkey && 373 this.pairingEvent_.passkey &&
304 (pairing == PairingEventType.DISPLAY_PASSKEY || 374 (pairing == PairingEventType.DISPLAY_PASSKEY ||
305 pairing == PairingEventType.KEYS_ENTERED || 375 pairing == PairingEventType.KEYS_ENTERED ||
306 pairing == PairingEventType.CONFIRM_PASSKEY)) { 376 pairing == PairingEventType.CONFIRM_PASSKEY)) {
307 var passkeyString = String(this.pairingEvent.passkey); 377 var passkeyString = String(this.pairingEvent_.passkey);
308 if (index < passkeyString.length) 378 if (index < passkeyString.length)
309 digit = passkeyString[index]; 379 digit = passkeyString[index];
310 } 380 }
311 return digit; 381 return digit;
312 }, 382 },
313 383
314 /** 384 /**
315 * @param {number} index 385 * @param {number} index
316 * @return {string} 386 * @return {string}
317 * @private 387 * @private
318 */ 388 */
319 getPinClass_: function(index) { 389 getPinClass_: function(index) {
320 if (!this.pairingEvent) 390 if (!this.pairingEvent_)
321 return ''; 391 return '';
322 if (this.pairingEvent.pairing == PairingEventType.CONFIRM_PASSKEY) 392 if (this.pairingEvent_.pairing == PairingEventType.CONFIRM_PASSKEY)
323 return 'confirm'; 393 return 'confirm';
324 var cssClass = 'display'; 394 var cssClass = 'display';
325 if (this.pairingEvent.pairing == PairingEventType.DISPLAY_PASSKEY) { 395 if (this.pairingEvent_.pairing == PairingEventType.DISPLAY_PASSKEY) {
326 if (index == 0) 396 if (index == 0)
327 cssClass += ' next'; 397 cssClass += ' next';
328 else 398 else
329 cssClass += ' untyped'; 399 cssClass += ' untyped';
330 } else if ( 400 } else if (
331 this.pairingEvent.pairing == PairingEventType.KEYS_ENTERED && 401 this.pairingEvent_.pairing == PairingEventType.KEYS_ENTERED &&
332 this.pairingEvent.enteredKey) { 402 this.pairingEvent_.enteredKey) {
333 var enteredKey = this.pairingEvent.enteredKey; // 1-7 403 var enteredKey = this.pairingEvent_.enteredKey; // 1-7
334 var lastKey = this.digits.length; // 6 404 var lastKey = this.digits.length; // 6
335 if ((index == -1 && enteredKey > lastKey) || (index + 1 == enteredKey)) 405 if ((index == -1 && enteredKey > lastKey) || (index + 1 == enteredKey))
336 cssClass += ' next'; 406 cssClass += ' next';
337 else if (index > enteredKey) 407 else if (index > enteredKey)
338 cssClass += ' untyped'; 408 cssClass += ' untyped';
339 } 409 }
340 return cssClass; 410 return cssClass;
341 }, 411 },
342 }; 412 };
343 413
344 Polymer({ 414 Polymer({
345 is: 'bluetooth-device-dialog', 415 is: 'bluetooth-device-dialog',
346 416
347 behaviors: [ 417 behaviors: [
348 I18nBehavior, 418 I18nBehavior,
349 CrScrollableBehavior, 419 CrScrollableBehavior,
350 settings.BluetoothAddDeviceBehavior, 420 settings.BluetoothAddDeviceBehavior,
351 settings.BluetoothPairDeviceBehavior, 421 settings.BluetoothPairDeviceBehavior,
352 ], 422 ],
353 423
354 properties: { 424 properties: {
355 /** 425 /**
356 * The version of this dialog to show: 'addDevice', 'pairDevice', or 426 * The version of this dialog to show: 'addDevice', 'pairDevice', or
357 * 'connectError'. Must be set before the dialog is opened. 427 * 'connectError'. Must be set before the dialog is opened.
358 */ 428 */
359 dialogId: String, 429 dialogId: String,
360 }, 430 },
361 431
362 observers: [ 432 observers: [
363 'dialogUpdated_(dialogId, pairingEvent)', 433 'dialogUpdated_(dialogId, pairingEvent_)',
364 ], 434 ],
365 435
366 open: function() { 436 open: function() {
437 this.startPairing();
367 this.pinOrPass = ''; 438 this.pinOrPass = '';
368 this.getDialog_().showModal(); 439 this.getDialog_().showModal();
369 this.itemWasFocused_ = false; 440 this.itemWasFocused_ = false;
370 }, 441 },
371 442
372 close: function() { 443 close: function() {
444 this.endPairing();
373 var dialog = this.getDialog_(); 445 var dialog = this.getDialog_();
374 if (dialog.open) 446 if (dialog.open)
375 dialog.close(); 447 dialog.close();
376 }, 448 },
377 449
378 /** @private */ 450 /** @private */
379 dialogUpdated_: function() { 451 dialogUpdated_: function() {
380 if (this.showEnterPincode_()) 452 if (this.showEnterPincode_())
381 this.$$('#pincode').focus(); 453 this.$$('#pincode').focus();
382 else if (this.showEnterPasskey_()) 454 else if (this.showEnterPasskey_())
(...skipping 19 matching lines...) Expand all
402 474
403 /** @private */ 475 /** @private */
404 onCancelTap_: function() { 476 onCancelTap_: function() {
405 this.getDialog_().cancel(); 477 this.getDialog_().cancel();
406 }, 478 },
407 479
408 /** @private */ 480 /** @private */
409 onDialogCanceled_: function() { 481 onDialogCanceled_: function() {
410 if (this.dialogId == 'pairDevice') 482 if (this.dialogId == 'pairDevice')
411 this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CANCEL); 483 this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CANCEL);
484 this.endPairing();
412 }, 485 },
413 }); 486 });
414
415 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698