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 * Javascript for ValueControl, served from chrome://bluetooth-internals/. | 6 * Javascript for ValueControl, served from chrome://bluetooth-internals/. |
7 */ | 7 */ |
8 | 8 |
9 cr.define('value_control', function() { | 9 cr.define('value_control', function() { |
10 /** @const */ var Snackbar = snackbar.Snackbar; | 10 /** @const */ var Snackbar = snackbar.Snackbar; |
11 /** @const */ var SnackbarType = snackbar.SnackbarType; | 11 /** @const */ var SnackbarType = snackbar.SnackbarType; |
12 | 12 |
| 13 /** @typedef {{ |
| 14 * deviceAddress: string, |
| 15 * serviceId: string, |
| 16 * characteristicId: string, |
| 17 * descriptorId: (string|undefined) |
| 18 * properties: (number|undefined) |
| 19 * }} |
| 20 */ |
| 21 var ValueLoadOptions; |
| 22 |
13 /** @enum {string} */ | 23 /** @enum {string} */ |
14 var ValueDataType = { | 24 var ValueDataType = { |
15 HEXADECIMAL: 'Hexadecimal', | 25 HEXADECIMAL: 'Hexadecimal', |
16 UTF8: 'UTF-8', | 26 UTF8: 'UTF-8', |
17 DECIMAL: 'Decimal', | 27 DECIMAL: 'Decimal', |
18 }; | 28 }; |
19 | 29 |
20 /** | 30 /** |
21 * A container for an array value that needs to be converted to multiple | 31 * A container for an array value that needs to be converted to multiple |
22 * display formats. Internally, the value is stored as an array and converted | 32 * display formats. Internally, the value is stored as an array and converted |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 */ | 210 */ |
201 decorate: function() { | 211 decorate: function() { |
202 this.classList.add('value-control'); | 212 this.classList.add('value-control'); |
203 | 213 |
204 /** @private {!Value} */ | 214 /** @private {!Value} */ |
205 this.value_ = new Value([]); | 215 this.value_ = new Value([]); |
206 /** @private {?string} */ | 216 /** @private {?string} */ |
207 this.deviceAddress_ = null; | 217 this.deviceAddress_ = null; |
208 /** @private {?string} */ | 218 /** @private {?string} */ |
209 this.serviceId_ = null; | 219 this.serviceId_ = null; |
210 /** @private {?interfaces.BluetoothDevice.CharacteristicInfo} */ | 220 /** @private {?string} */ |
211 this.characteristicInfo_ = null; | 221 this.characteristicId_ = null; |
| 222 /** @private {?string} */ |
| 223 this.descriptorId_ = null; |
| 224 /** @private {number} */ |
| 225 this.properties_ = Number.MAX_SAFE_INTEGER; |
212 | 226 |
213 this.unavailableMessage_ = document.createElement('h3'); | 227 this.unavailableMessage_ = document.createElement('h3'); |
214 this.unavailableMessage_.textContent = 'Value cannot be read or written.'; | 228 this.unavailableMessage_.textContent = 'Value cannot be read or written.'; |
215 | 229 |
216 this.valueInput_ = document.createElement('input'); | 230 this.valueInput_ = document.createElement('input'); |
217 this.valueInput_.addEventListener('change', function() { | 231 this.valueInput_.addEventListener('change', function() { |
218 try { | 232 try { |
219 this.value_.setAs(this.typeSelect_.value, this.valueInput_.value); | 233 this.value_.setAs(this.typeSelect_.value, this.valueInput_.value); |
220 } catch (e) { | 234 } catch (e) { |
221 Snackbar.show(e.message, SnackbarType.ERROR); | 235 Snackbar.show(e.message, SnackbarType.ERROR); |
(...skipping 28 matching lines...) Expand all Loading... |
250 buttonsDiv.appendChild(this.readBtn_); | 264 buttonsDiv.appendChild(this.readBtn_); |
251 buttonsDiv.appendChild(this.writeBtn_); | 265 buttonsDiv.appendChild(this.writeBtn_); |
252 | 266 |
253 this.appendChild(this.unavailableMessage_); | 267 this.appendChild(this.unavailableMessage_); |
254 this.appendChild(inputDiv); | 268 this.appendChild(inputDiv); |
255 this.appendChild(buttonsDiv); | 269 this.appendChild(buttonsDiv); |
256 }, | 270 }, |
257 | 271 |
258 /** | 272 /** |
259 * Sets the settings used by the value control and redraws the control to | 273 * Sets the settings used by the value control and redraws the control to |
260 * match the read/write settings provided in | 274 * match the read/write settings in |options.properties|. If properties |
261 * |characteristicInfo.properties|. | 275 * are not provided, no restrictions on reading/writing are applied. |
262 * @param {string} deviceAddress | 276 * @param {!ValueLoadOptions} options |
263 * @param {string} serviceId | |
264 * @param {!interfaces.BluetoothDevice.CharacteristicInfo} | |
265 * characteristicInfo | |
266 */ | 277 */ |
267 load: function(deviceAddress, serviceId, characteristicInfo) { | 278 load: function(options) { |
268 this.deviceAddress_ = deviceAddress; | 279 this.deviceAddress_ = options.deviceAddress; |
269 this.serviceId_ = serviceId; | 280 this.serviceId_ = options.serviceId; |
270 this.characteristicInfo_ = characteristicInfo; | 281 this.characteristicId_ = options.characteristicId; |
| 282 this.descriptorId_ = options.descriptorId; |
| 283 |
| 284 if (options.properties) |
| 285 this.properties_ = options.properties; |
271 | 286 |
272 this.redraw(); | 287 this.redraw(); |
273 }, | 288 }, |
274 | 289 |
275 /** | 290 /** |
276 * Redraws the value control with updated layout depending on the | 291 * Redraws the value control with updated layout depending on the |
277 * availability of reads and writes and the current cached value. | 292 * availability of reads and writes and the current cached value. |
278 */ | 293 */ |
279 redraw: function() { | 294 redraw: function() { |
280 this.readBtn_.hidden = (this.characteristicInfo_.properties & | 295 this.readBtn_.hidden = |
281 interfaces.BluetoothDevice.Property.READ) === 0; | 296 (this.properties_ & interfaces.BluetoothDevice.Property.READ) === 0; |
282 this.writeBtn_.hidden = (this.characteristicInfo_.properties & | 297 this.writeBtn_.hidden = |
283 interfaces.BluetoothDevice.Property.WRITE) === 0; | 298 (this.properties_ & interfaces.BluetoothDevice.Property.WRITE) === 0; |
284 | 299 |
285 var isAvailable = !this.readBtn_.hidden || !this.writeBtn_.hidden; | 300 var isAvailable = !this.readBtn_.hidden || !this.writeBtn_.hidden; |
286 this.unavailableMessage_.hidden = isAvailable; | 301 this.unavailableMessage_.hidden = isAvailable; |
287 this.valueInput_.hidden = !isAvailable; | 302 this.valueInput_.hidden = !isAvailable; |
288 this.typeSelect_.hidden = !isAvailable; | 303 this.typeSelect_.hidden = !isAvailable; |
289 | 304 |
290 if (!isAvailable) | 305 if (!isAvailable) |
291 return; | 306 return; |
292 | 307 |
293 this.valueInput_.value = this.value_.getAs(this.typeSelect_.value); | 308 this.valueInput_.value = this.value_.getAs(this.typeSelect_.value); |
(...skipping 18 matching lines...) Expand all Loading... |
312 // messages. | 327 // messages. |
313 var GattResult = interfaces.BluetoothDevice.GattResult; | 328 var GattResult = interfaces.BluetoothDevice.GattResult; |
314 return Object.keys(GattResult).find(function(key) { | 329 return Object.keys(GattResult).find(function(key) { |
315 return GattResult[key] === result; | 330 return GattResult[key] === result; |
316 }); | 331 }); |
317 }, | 332 }, |
318 | 333 |
319 /** | 334 /** |
320 * Called when the read button is pressed. Connects to the device and | 335 * Called when the read button is pressed. Connects to the device and |
321 * retrieves the current value of the characteristic in the |service_id| | 336 * retrieves the current value of the characteristic in the |service_id| |
322 * with id |characteristic_id| | 337 * with id |characteristic_id|. If |descriptor_id| is defined, the |
| 338 * descriptor value with |descriptor_id| is read instead. |
323 * @private | 339 * @private |
324 */ | 340 */ |
325 readValue_: function() { | 341 readValue_: function() { |
326 this.readBtn_.disabled = true; | 342 this.readBtn_.disabled = true; |
327 | 343 |
328 device_broker.connectToDevice(this.deviceAddress_).then(function(device) { | 344 device_broker.connectToDevice(this.deviceAddress_).then(function(device) { |
| 345 if (this.descriptorId_) { |
| 346 return device.readValueForDescriptor( |
| 347 this.serviceId_, this.characteristicId_, this.descriptorId_); |
| 348 } |
| 349 |
329 return device.readValueForCharacteristic( | 350 return device.readValueForCharacteristic( |
330 this.serviceId_, this.characteristicInfo_.id); | 351 this.serviceId_, this.characteristicId_); |
331 }.bind(this)).then(function(response) { | 352 }.bind(this)).then(function(response) { |
332 this.readBtn_.disabled = false; | 353 this.readBtn_.disabled = false; |
333 | 354 |
334 if (response.result === interfaces.BluetoothDevice.GattResult.SUCCESS) { | 355 if (response.result === interfaces.BluetoothDevice.GattResult.SUCCESS) { |
335 this.setValue(response.value); | 356 this.setValue(response.value); |
336 Snackbar.show( | 357 Snackbar.show( |
337 this.deviceAddress_ + ': Read succeeded', SnackbarType.SUCCESS); | 358 this.deviceAddress_ + ': Read succeeded', SnackbarType.SUCCESS); |
338 return; | 359 return; |
339 } | 360 } |
340 | 361 |
341 var errorString = this.getErrorString_(response.result); | 362 var errorString = this.getErrorString_(response.result); |
342 Snackbar.show( | 363 Snackbar.show( |
343 this.deviceAddress_ + ': ' + errorString, SnackbarType.ERROR, | 364 this.deviceAddress_ + ': ' + errorString, SnackbarType.ERROR, |
344 'Retry', this.readValue_.bind(this)); | 365 'Retry', this.readValue_.bind(this)); |
345 }.bind(this)); | 366 }.bind(this)); |
346 }, | 367 }, |
347 | 368 |
348 /** | 369 /** |
349 * Called when the write button is pressed. Connects to the device and | 370 * Called when the write button is pressed. Connects to the device and |
350 * retrieves the current value of the characteristic in the |service_id| | 371 * retrieves the current value of the characteristic in the |
351 * with id |characteristic_id| | 372 * |service_id| with id |characteristic_id|. If |descriptor_id| is defined, |
| 373 * the descriptor value with |descriptor_id| is written instead. |
352 * @private | 374 * @private |
353 */ | 375 */ |
354 writeValue_: function() { | 376 writeValue_: function() { |
355 this.writeBtn_.disabled = true; | 377 this.writeBtn_.disabled = true; |
356 | 378 |
357 device_broker.connectToDevice(this.deviceAddress_).then(function(device) { | 379 device_broker.connectToDevice(this.deviceAddress_).then(function(device) { |
| 380 if (this.descriptorId_) { |
| 381 return device.writeValueForDescriptor( |
| 382 this.serviceId_, this.characteristicId_, this.descriptorId_, |
| 383 this.value_.getArray()); |
| 384 } |
| 385 |
358 return device.writeValueForCharacteristic( | 386 return device.writeValueForCharacteristic( |
359 this.serviceId_, this.characteristicInfo_.id, | 387 this.serviceId_, this.characteristicId_, this.value_.getArray()); |
360 this.value_.getArray()); | |
361 }.bind(this)).then(function(response) { | 388 }.bind(this)).then(function(response) { |
362 this.writeBtn_.disabled = false; | 389 this.writeBtn_.disabled = false; |
363 | 390 |
364 if (response.result === interfaces.BluetoothDevice.GattResult.SUCCESS) { | 391 if (response.result === interfaces.BluetoothDevice.GattResult.SUCCESS) { |
365 Snackbar.show( | 392 Snackbar.show( |
366 this.deviceAddress_ + ': Write succeeded', SnackbarType.SUCCESS); | 393 this.deviceAddress_ + ': Write succeeded', SnackbarType.SUCCESS); |
367 return; | 394 return; |
368 } | 395 } |
369 | 396 |
370 var errorString = this.getErrorString_(response.result); | 397 var errorString = this.getErrorString_(response.result); |
371 Snackbar.show( | 398 Snackbar.show( |
372 this.deviceAddress_ + ': ' + errorString, SnackbarType.ERROR, | 399 this.deviceAddress_ + ': ' + errorString, SnackbarType.ERROR, |
373 'Retry', this.writeValue_.bind(this)); | 400 'Retry', this.writeValue_.bind(this)); |
374 }.bind(this)); | 401 }.bind(this)); |
375 }, | 402 }, |
376 } | 403 } |
377 | 404 |
378 return { | 405 return { |
379 ValueControl: ValueControl, | 406 ValueControl: ValueControl, |
380 ValueDataType: ValueDataType, | 407 ValueDataType: ValueDataType, |
381 }; | 408 }; |
382 }); | 409 }); |
OLD | NEW |