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

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: More tests, more comments 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
10 cr.define('device_table', function() { 9 cr.define('device_table', function() {
11
12 var REMOVED_CSS = 'removed'; 10 var REMOVED_CSS = 'removed';
13 11
14 /** 12 /**
15 * A table that lists the devices and responds to changes in the given 13 * A table that lists the devices and responds to changes in the given
16 * DeviceCollection. 14 * DeviceCollection.
17 * @constructor 15 * @constructor
18 * @extends {HTMLTableElement} 16 * @extends {HTMLTableElement}
19 */ 17 */
20 var DeviceTable = cr.ui.define(function() { 18 var DeviceTable = cr.ui.define(function() {
21 this.devices_ = null; 19 this.devices_ = null;
22 20
23 return document.importNode($('table-template').content.children[0], 21 return document.importNode($('table-template').content.children[0],
24 true /* deep */); 22 true /* deep */);
25 }); 23 });
26 DeviceTable.prototype = { 24 DeviceTable.prototype = {
27 __proto__: HTMLTableElement.prototype, 25 __proto__: HTMLTableElement.prototype,
28 26
29 /** 27 /**
30 * Decorates an element as a UI element class. Caches references to the 28 * Decorates an element as a UI element class. Caches references to the
31 * table body and headers. 29 * table body and headers.
32 */ 30 */
33 decorate: function() { 31 decorate: function() {
34 this.body_ = this.tBodies[0]; 32 this.body_ = this.tBodies[0];
(...skipping 23 matching lines...) Expand all
58 56
59 /** 57 /**
60 * Updates table row on change event of the device collection. 58 * Updates table row on change event of the device collection.
61 * @param {!Event} event 59 * @param {!Event} event
62 */ 60 */
63 handleChange_: function(event) { 61 handleChange_: function(event) {
64 this.updateRow_(this.devices_.item(event.index), event.index); 62 this.updateRow_(this.devices_.item(event.index), event.index);
65 }, 63 },
66 64
67 /** 65 /**
66 * Generates a function to handle click events on the connect button for the
67 * given |row|.
68 * @param {HTMLTableRowElement} row The table row that was clicked.
69 * @return {function(Event)}
70 */
71 handleConnectBtn_: function(row) {
72 return function(event) {
73 var cellCount = row.cells.length;
74 var connectCell = row.cells[cellCount - 2];
75 var connectButton = connectCell.children[0];
76 var connectErrorCell = row.cells[cellCount - 1];
77
78 connectErrorCell.textContent = '';
79
80 var device = this.devices_.getByAddress(row.id);
81 if (device.proxy) {
82 connectButton.textContent = 'Disconnecting...';
83 connectButton.disabled = true;
84 device.disconnect();
85 } else {
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 }
95
96 }.bind(this);
97 },
98
99 /**
100 * Creates a connection to the device and updates the device collection.
101 * @param {device_collection.Device} device
102 * @return {Promise} rejects if connection failed, resolves otherwise.
103 */
104 handleConnect_: function(device) {
105 return device.connect().then(function() {
106 this.devices_.addOrUpdate(device.info);
107 }.bind(this));
108 },
109
110 /**
68 * Updates table row on splice event of the device collection. 111 * Updates table row on splice event of the device collection.
69 * @param {!Event} event 112 * @param {!Event} event
70 */ 113 */
71 handleSplice_: function(event) { 114 handleSplice_: function(event) {
72 event.removed.forEach(function() { 115 event.removed.forEach(function() {
73 this.removeRow(event.index); 116 this.removeRow(event.index);
74 }, this); 117 }, this);
75 118
76 event.added.forEach(function(device, index) { 119 event.added.forEach(function(device, index) {
77 this.newRowForDevice_(device, event.index + index); 120 this.newRowForDevice_(device, event.index + index);
78 }, this); 121 }, this);
79 }, 122 },
80 123
81 /** 124 /**
82 * Inserts a new row at |index| and updates it with info from |device|. 125 * Inserts a new row at |index| and updates it with info from |device|.
83 * @param {!device_collection.Device} device 126 * @param {!device_collection.Device} device
84 * @param {?number} index 127 * @param {?number} index
85 */ 128 */
86 newRowForDevice_: function(device, index) { 129 newRowForDevice_: function(device, index) {
87 var row = this.body_.insertRow(index); 130 var row = this.body_.insertRow(index);
88 row.id = device.info.address; 131 row.id = device.info.address;
89 132
90 for (var i = 0; i < this.headers_.length; i++) { 133 for (var i = 0; i < this.headers_.length; i++) {
91 row.insertCell(); 134 row.insertCell();
92 } 135 }
93 136
137 // Make two extra cells for the connect button and connect errors.
138 var connectCell = row.insertCell();
139 var connectErrorCell = row.insertCell();
140
141 var connectButton = document.createElement('button');
142 connectCell.appendChild(connectButton);
143
144 connectButton.textContent = 'Connect';
145 connectButton.addEventListener('click',
146 this.handleConnectBtn_(row).bind(this));
147
94 this.updateRow_(device, row.sectionRowIndex); 148 this.updateRow_(device, row.sectionRowIndex);
95 }, 149 },
96 150
97 /** 151 /**
98 * Deletes and recreates the table using the cached |devices_|. 152 * Deletes and recreates the table using the cached |devices_|.
99 */ 153 */
100 redraw_: function() { 154 redraw_: function() {
101 this.removeChild(this.body_); 155 this.removeChild(this.body_);
102 this.appendChild(document.createElement('tbody')); 156 this.appendChild(document.createElement('tbody'));
103 this.body_ = this.tBodies[0]; 157 this.body_ = this.tBodies[0];
(...skipping 11 matching lines...) Expand all
115 */ 169 */
116 updateRow_: function(device, index) { 170 updateRow_: function(device, index) {
117 var row = this.body_.rows[index]; 171 var row = this.body_.rows[index];
118 172
119 if (device.removed) { 173 if (device.removed) {
120 row.classList.add(REMOVED_CSS); 174 row.classList.add(REMOVED_CSS);
121 } else { 175 } else {
122 row.classList.remove(REMOVED_CSS); 176 row.classList.remove(REMOVED_CSS);
123 } 177 }
124 178
179 var cellCount = row.cells.length;
180 var connectCell = row.cells[cellCount - 2];
181 var connectButton = connectCell.children[0];
182 var connectErrorCell = row.cells[cellCount - 1];
183
184 if (!device.connectionPending) {
185 if (device.info.is_gatt_connected) {
186 connectButton.textContent = 'Disconnect';
187 } else if (device.proxy) {
188 connectButton.textContent = 'Connect';
189 connectErrorCell.textContent = 'Lost connection';
190 device.proxy = null;
191 } else {
192 connectButton.textContent = 'Connect';
193 }
194
195 connectButton.disabled = false;
196 }
197
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