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

Side by Side Diff: chrome/browser/resources/bluetooth_internals/device_table.js

Issue 2448713002: bluetooth: Add Device connection logic and accompanying user interface. (Closed)
Patch Set: Major reorganization of Mojo interface code and DeviceCollection Created 4 years, 1 month 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 /** 5 /**
6 * Javascript for DeviceTable UI, served from 6 * Javascript for DeviceTable UI, served from
7 * chrome://bluetooth-internals/. 7 * chrome://bluetooth-internals/.
8 */ 8 */
9 9
10 /** @typedef {function(device.Device): Promise} */
11 var ConnectionHandler;
12
10 cr.define('device_table', function() { 13 cr.define('device_table', function() {
11
12 var REMOVED_CSS = 'removed'; 14 var REMOVED_CSS = 'removed';
13 15
14 /** 16 /**
15 * A table that lists the devices and responds to changes in the given 17 * A table that lists the devices and responds to changes in the given
16 * DeviceCollection. 18 * DeviceCollection.
17 * @constructor 19 * @constructor
18 * @extends {HTMLTableElement} 20 * @extends {HTMLTableElement}
19 */ 21 */
20 var DeviceTable = cr.ui.define(function() { 22 var DeviceTable = cr.ui.define(function() {
21 this.devices_ = null; 23 this.devices_ = null;
22 24
23 return document.importNode($('table-template').content.children[0], 25 return document.importNode($('table-template').content.children[0],
24 true /* deep */); 26 true /* deep */);
25 }); 27 });
26 DeviceTable.prototype = { 28 DeviceTable.prototype = {
27 __proto__: HTMLTableElement.prototype, 29 __proto__: HTMLTableElement.prototype,
28 30
29 /** 31 /**
30 * Decorates an element as a UI element class. Caches references to the 32 * Decorates an element as a UI element class. Caches references to the
31 * table body and headers. 33 * table body and headers.
32 */ 34 */
33 decorate: function() { 35 decorate: function() {
34 this.body_ = this.tBodies[0]; 36 this.body_ = this.tBodies[0];
(...skipping 23 matching lines...) Expand all
58 60
59 /** 61 /**
60 * Updates table row on change event of the device collection. 62 * Updates table row on change event of the device collection.
61 * @param {!Event} event 63 * @param {!Event} event
62 */ 64 */
63 handleChange_: function(event) { 65 handleChange_: function(event) {
64 this.updateRow_(this.devices_.item(event.index), event.index); 66 this.updateRow_(this.devices_.item(event.index), event.index);
65 }, 67 },
66 68
67 /** 69 /**
70 * Generates a function to handle click events on the connect button for the
71 * given |row|.
72 * @param {HTMLTableRowElement} row The table row that was clicked.
73 * @return {function(Event)}
74 */
75 handleConnectBtn_: function(row) {
76 return function(event) {
77 var cellCount = row.cells.length;
78 var connectCell = row.cells[cellCount - 2];
79 var connectButton = connectCell.children[0];
80 var connectErrorCell = row.cells[cellCount - 1];
81
82 connectErrorCell.textContent = '';
83
84 var device = this.devices_.getByAddress(row.id);
85 if (!device.proxy) {
86 connectButton.textContent = 'Connecting...';
87 connectButton.disabled = true;
88
89 this.handleConnect_(device).catch(function(error) {
90 connectErrorCell.textContent = error.message;
91 connectButton.textContent = 'Connect';
92 connectButton.disabled = false;
93 });
94 } else if (device.proxy) {
95 connectButton.textContent = 'Disconnecting...';
96 connectButton.disabled = true;
97 device.disconnect();
98 }
99 }.bind(this);
100 },
101
102 /**
103 * Creates a connection to the device and updates the device collection.
104 * @param {device_collection.Device} device
105 * @return {Promise} rejects if connection failed, resolves otherwise.
106 */
107 handleConnect_: function(device) {
108 return device.connect().then(function() {
109 this.devices_.addOrUpdate(device.info);
110 }.bind(this));
111 },
112
113 /**
68 * Updates table row on splice event of the device collection. 114 * Updates table row on splice event of the device collection.
69 * @param {!Event} event 115 * @param {!Event} event
70 */ 116 */
71 handleSplice_: function(event) { 117 handleSplice_: function(event) {
72 event.removed.forEach(function() { 118 event.removed.forEach(function() {
73 this.removeRow(event.index); 119 this.removeRow(event.index);
74 }, this); 120 }, this);
75 121
76 event.added.forEach(function(device, index) { 122 event.added.forEach(function(device, index) {
77 this.newRowForDevice_(device, event.index + index); 123 this.newRowForDevice_(device, event.index + index);
78 }, this); 124 }, this);
79 }, 125 },
80 126
81 /** 127 /**
82 * Inserts a new row at |index| and updates it with info from |device|. 128 * Inserts a new row at |index| and updates it with info from |device|.
83 * @param {!Device} device 129 * @param {!Device} device
84 * @param {?number} index 130 * @param {?number} index
85 */ 131 */
86 newRowForDevice_: function(device, index) { 132 newRowForDevice_: function(device, index) {
87 var row = this.body_.insertRow(index); 133 var row = this.body_.insertRow(index);
88 row.id = device.info.address; 134 row.id = device.info.address;
89 135
90 for (var i = 0; i < this.headers_.length; i++) { 136 for (var i = 0; i < this.headers_.length; i++) {
91 row.insertCell(); 137 row.insertCell();
92 } 138 }
93 139
140 // Make two extra cells for the connect button and connect errors.
141 var connectCell = row.insertCell();
142 var connectErrorCell = row.insertCell();
143
144 var connectButton = document.createElement('button');
145 connectCell.appendChild(connectButton);
146
147 connectButton.textContent = 'Connect';
148 connectButton.addEventListener('click',
149 this.handleConnectBtn_(row).bind(this));
150
94 this.updateRow_(device, row.sectionRowIndex); 151 this.updateRow_(device, row.sectionRowIndex);
95 }, 152 },
96 153
97 /** 154 /**
98 * Deletes and recreates the table using the cached |devices_|. 155 * Deletes and recreates the table using the cached |devices_|.
99 */ 156 */
100 redraw_: function() { 157 redraw_: function() {
101 this.removeChild(this.body_); 158 this.removeChild(this.body_);
102 this.appendChild(document.createElement('tbody')); 159 this.appendChild(document.createElement('tbody'));
103 this.body_ = this.tBodies[0]; 160 this.body_ = this.tBodies[0];
(...skipping 11 matching lines...) Expand all
115 */ 172 */
116 updateRow_: function(device, index) { 173 updateRow_: function(device, index) {
117 var row = this.body_.rows[index]; 174 var row = this.body_.rows[index];
118 175
119 if (device.removed) { 176 if (device.removed) {
120 row.classList.add(REMOVED_CSS); 177 row.classList.add(REMOVED_CSS);
121 } else { 178 } else {
122 row.classList.remove(REMOVED_CSS); 179 row.classList.remove(REMOVED_CSS);
123 } 180 }
124 181
182 var cellCount = row.cells.length;
183 var connectCell = row.cells[cellCount - 2];
184 var connectButton = connectCell.children[0];
185 var connectErrorCell = row.cells[cellCount - 1];
186
187 if (device.info.is_gatt_connected) {
188 connectButton.textContent = 'Disconnect';
189 } else if (device.proxy) {
190 connectButton.textContent = 'Connect';
191 connectErrorCell.textContent = 'Lost connection';
192 device.proxy = null;
193 } else {
194 connectButton.textContent = 'Connect';
195 }
196
197 connectButton.disabled = false;
198
125 // Update the properties based on the header field path. 199 // Update the properties based on the header field path.
126 for (var i = 0; i < this.headers_.length; i++) { 200 for (var i = 0; i < this.headers_.length; i++) {
127 var header = this.headers_[i]; 201 var header = this.headers_[i];
128 var propName = header.dataset.field; 202 var propName = header.dataset.field;
129 203
130 var parts = propName.split('.'); 204 var parts = propName.split('.');
131 var obj = device.info; 205 var obj = device.info;
132 while (obj != null && parts.length > 0) { 206 while (obj != null && parts.length > 0) {
133 var part = parts.shift(); 207 var part = parts.shift();
134 obj = obj[part]; 208 obj = obj[part];
135 } 209 }
136 210
137 var cell = row.cells[i]; 211 var cell = row.cells[i];
138 cell.textContent = obj || 'Unknown'; 212 cell.textContent = (obj == null || obj == undefined) ? 'Unknown' : obj;
139 cell.dataset.label = header.innerText; 213 cell.dataset.label = header.textContent;
140 } 214 }
141 }, 215 },
142 }; 216 };
143 217
144 return { 218 return {
145 DeviceTable: DeviceTable, 219 DeviceTable: DeviceTable,
146 }; 220 };
147 }); 221 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698