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 ServiceList and ServiceListItem, served from | 6 * Javascript for ServiceList and ServiceListItem, served from |
7 * chrome://bluetooth-internals/. | 7 * chrome://bluetooth-internals/. |
8 */ | 8 */ |
9 | 9 |
10 cr.define('service_list', function() { | 10 cr.define('service_list', function() { |
| 11 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; |
11 /** @const */ var ExpandableList = expandable_list.ExpandableList; | 12 /** @const */ var ExpandableList = expandable_list.ExpandableList; |
12 /** @const */ var ExpandableListItem = expandable_list.ExpandableListItem; | 13 /** @const */ var ExpandableListItem = expandable_list.ExpandableListItem; |
| 14 /** @const */ var Snackbar = snackbar.Snackbar; |
| 15 /** @const */ var SnackbarType = snackbar.SnackbarType; |
13 | 16 |
14 /** | 17 /** |
15 * Property names that will be displayed in the ObjectFieldSet which contains | 18 * Property names that will be displayed in the ObjectFieldSet which contains |
16 * the ServiceInfo object. | 19 * the ServiceInfo object. |
17 */ | 20 */ |
18 var PROPERTY_NAMES = { | 21 var PROPERTY_NAMES = { |
19 id: 'ID', | 22 id: 'ID', |
20 'uuid.uuid': 'UUID', | 23 'uuid.uuid': 'UUID', |
21 is_primary: 'Type', | 24 is_primary: 'Type', |
22 }; | 25 }; |
23 | 26 |
24 /** | 27 /** |
25 * A list item that displays the data in a ServiceInfo object. The brief | 28 * A list item that displays the data in a ServiceInfo object. The brief |
26 * section contains the UUID of the given |serviceInfo|. The expanded section | 29 * section contains the UUID of the given |serviceInfo|. The expanded section |
27 * contains an ObjectFieldSet that displays all of the properties in the | 30 * contains an ObjectFieldSet that displays all of the properties in the |
28 * given |serviceInfo|. | 31 * given |serviceInfo|. Data is not loaded until the ServiceListItem is |
| 32 * expanded for the first time. |
29 * @param {!interfaces.BluetoothDevice.ServiceInfo} serviceInfo | 33 * @param {!interfaces.BluetoothDevice.ServiceInfo} serviceInfo |
| 34 * @param {string} deviceAddress |
30 * @constructor | 35 * @constructor |
31 */ | 36 */ |
32 function ServiceListItem(serviceInfo) { | 37 function ServiceListItem(serviceInfo, deviceAddress) { |
33 var listItem = new ExpandableListItem(); | 38 var listItem = new ExpandableListItem(); |
34 listItem.__proto__ = ServiceListItem.prototype; | 39 listItem.__proto__ = ServiceListItem.prototype; |
35 | 40 |
36 listItem.info = serviceInfo; | 41 listItem.info = serviceInfo; |
| 42 listItem.deviceAddress_ = deviceAddress; |
37 listItem.decorate(); | 43 listItem.decorate(); |
38 | 44 |
39 return listItem; | 45 return listItem; |
40 } | 46 } |
41 | 47 |
42 ServiceListItem.prototype = { | 48 ServiceListItem.prototype = { |
43 __proto__: ExpandableListItem.prototype, | 49 __proto__: ExpandableListItem.prototype, |
44 | 50 |
45 /** | 51 /** |
46 * Decorates the element as a service list item. Creates layout and caches | 52 * Decorates the element as a service list item. Creates layout and caches |
47 * references to the created header and fieldset. | 53 * references to the created header and fieldset. |
48 * @override | 54 * @override |
49 */ | 55 */ |
50 decorate: function() { | 56 decorate: function() { |
51 this.classList.add('service-list-item'); | 57 this.classList.add('service-list-item'); |
52 | 58 |
53 /** @private {!HTMLElement} */ | |
54 this.infoDiv_ = document.createElement('div'); | |
55 this.infoDiv_.classList.add('info-container'); | |
56 | |
57 /** @private {!object_fieldset.ObjectFieldSet} */ | 59 /** @private {!object_fieldset.ObjectFieldSet} */ |
58 this.serviceFieldSet_ = object_fieldset.ObjectFieldSet(); | 60 this.serviceFieldSet_ = object_fieldset.ObjectFieldSet(); |
59 this.serviceFieldSet_.setPropertyDisplayNames(PROPERTY_NAMES); | 61 this.serviceFieldSet_.setPropertyDisplayNames(PROPERTY_NAMES); |
60 this.serviceFieldSet_.setObject({ | 62 this.serviceFieldSet_.setObject({ |
61 id: this.info.id, | 63 id: this.info.id, |
62 'uuid.uuid': this.info.uuid.uuid, | 64 'uuid.uuid': this.info.uuid.uuid, |
63 is_primary: this.info.is_primary ? 'Primary' : 'Secondary', | 65 is_primary: this.info.is_primary ? 'Primary' : 'Secondary', |
64 }); | 66 }); |
65 | 67 |
66 // Create content for display in brief content container. | 68 // Create content for display in brief content container. |
67 var serviceHeaderText = document.createElement('div'); | 69 var serviceHeaderText = document.createElement('div'); |
68 serviceHeaderText.textContent = 'Service:'; | 70 serviceHeaderText.textContent = 'Service:'; |
69 | 71 |
70 var serviceHeaderValue = document.createElement('div'); | 72 var serviceHeaderValue = document.createElement('div'); |
71 serviceHeaderValue.textContent = this.info.uuid.uuid; | 73 serviceHeaderValue.textContent = this.info.uuid.uuid; |
72 | 74 |
73 var serviceHeader = document.createElement('div'); | 75 var serviceHeader = document.createElement('div'); |
74 serviceHeader.appendChild(serviceHeaderText); | 76 serviceHeader.appendChild(serviceHeaderText); |
75 serviceHeader.appendChild(serviceHeaderValue); | 77 serviceHeader.appendChild(serviceHeaderValue); |
76 this.briefContent_.appendChild(serviceHeader); | 78 this.briefContent_.appendChild(serviceHeader); |
77 | 79 |
78 // Create content for display in expanded content container. | 80 // Create content for display in expanded content container. |
79 var serviceInfoHeader = document.createElement('h4'); | 81 var serviceInfoHeader = document.createElement('h4'); |
80 serviceInfoHeader.textContent = 'Service Info'; | 82 serviceInfoHeader.textContent = 'Service Info'; |
81 | 83 |
82 var serviceDiv = document.createElement('div'); | 84 var serviceDiv = document.createElement('div'); |
83 serviceDiv.classList.add('flex'); | 85 serviceDiv.classList.add('flex'); |
84 serviceDiv.appendChild(this.serviceFieldSet_); | 86 serviceDiv.appendChild(this.serviceFieldSet_); |
85 | 87 |
86 this.infoDiv_.appendChild(serviceInfoHeader); | 88 var characteristicsListHeader = document.createElement('h4'); |
87 this.infoDiv_.appendChild(serviceDiv); | 89 characteristicsListHeader.textContent = 'Characteristics'; |
88 this.expandedContent_.appendChild(this.infoDiv_); | 90 this.characteristicList_ = new characteristic_list.CharacteristicList(); |
| 91 |
| 92 var infoDiv = document.createElement('div'); |
| 93 infoDiv.classList.add('info-container'); |
| 94 infoDiv.appendChild(serviceInfoHeader); |
| 95 infoDiv.appendChild(serviceDiv); |
| 96 infoDiv.appendChild(characteristicsListHeader); |
| 97 infoDiv.appendChild(this.characteristicList_); |
| 98 |
| 99 this.expandedContent_.appendChild(infoDiv); |
| 100 }, |
| 101 |
| 102 /** @override */ |
| 103 onExpandInternal: function(expanded) { |
| 104 this.characteristicList_.load(this.deviceAddress_, this.info.id); |
89 }, | 105 }, |
90 }; | 106 }; |
91 | 107 |
92 /** | 108 /** |
93 * A list that displays ServiceListItems. | 109 * A list that displays ServiceListItems. |
94 * @constructor | 110 * @constructor |
95 */ | 111 */ |
96 var ServiceList = cr.ui.define('list'); | 112 var ServiceList = cr.ui.define('list'); |
97 | 113 |
98 ServiceList.prototype = { | 114 ServiceList.prototype = { |
99 __proto__: ExpandableList.prototype, | 115 __proto__: ExpandableList.prototype, |
100 | 116 |
101 /** @override */ | 117 /** @override */ |
102 decorate: function() { | 118 decorate: function() { |
103 ExpandableList.prototype.decorate.call(this); | 119 ExpandableList.prototype.decorate.call(this); |
| 120 |
| 121 /** @private {string} */ |
| 122 this.deviceAddress_ = null; |
| 123 /** @private {boolean} */ |
| 124 this.servicesRequested_ = false; |
| 125 |
104 this.classList.add('service-list'); | 126 this.classList.add('service-list'); |
105 this.setEmptyMessage('No Services Found'); | 127 this.setEmptyMessage('No Services Found'); |
106 }, | 128 }, |
107 | 129 |
108 /** @override */ | 130 /** @override */ |
109 createItem: function(data) { | 131 createItem: function(data) { |
110 return new ServiceListItem(data); | 132 return new ServiceListItem(data, this.deviceAddress_); |
| 133 }, |
| 134 |
| 135 /** |
| 136 * Loads the service list with an array of ServiceInfo from the |
| 137 * device with |deviceAddress|. If no active connection to the device |
| 138 * exists, one is created. |
| 139 * @param {string} deviceAddress |
| 140 */ |
| 141 load: function(deviceAddress) { |
| 142 if (this.servicesRequested_ || !this.isLoading()) |
| 143 return; |
| 144 |
| 145 this.deviceAddress_ = deviceAddress; |
| 146 this.servicesRequested_ = true; |
| 147 |
| 148 device_broker.connectToDevice(this.deviceAddress_).then( |
| 149 function(device) { |
| 150 return device.getServices(); |
| 151 }.bind(this)).then(function(response) { |
| 152 this.setData(new ArrayDataModel(response.services)); |
| 153 this.setLoading(false); |
| 154 this.servicesRequested_ = false; |
| 155 }.bind(this)).catch(function(error) { |
| 156 this.servicesRequested_ = false; |
| 157 Snackbar.show( |
| 158 deviceAddress + ': ' + error.message, SnackbarType.ERROR, |
| 159 'Retry', function() { this.load(deviceAddress); }.bind(this)); |
| 160 }.bind(this)); |
111 }, | 161 }, |
112 }; | 162 }; |
113 | 163 |
114 return { | 164 return { |
115 ServiceList: ServiceList, | 165 ServiceList: ServiceList, |
116 ServiceListItem: ServiceListItem, | 166 ServiceListItem: ServiceListItem, |
117 }; | 167 }; |
118 }); | 168 }); |
OLD | NEW |