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