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

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

Issue 2576603002: bluetooth: Add device details page with basic properties to internals page. (Closed)
Patch Set: Fix formatting, fix comments, fix test, change service/rssi display Created 3 years, 11 months 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
(Empty)
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
3 // found in the LICENSE file.
4
5 /**
6 * Javascript for DeviceDetailsPage which displays all of the details of a
7 * device. The page is generated and managed dynamically in bluetooth_internals.
8 * served from chrome://bluetooth-internals/.
9 */
10
11 cr.define('device_details_page', function() {
12 /** @const */ var Page = cr.ui.pageManager.Page;
13 /** @const */ var Snackbar = snackbar.Snackbar;
14 /** @const */ var SnackbarType = snackbar.SnackbarType;
15
16 /**
17 * Property names that will be displayed in the ObjectFieldSet which contains
18 * the DeviceInfo object.
19 */
20 var PROPERTY_NAMES = {
21 name: 'Name',
22 address: 'Address',
23 is_gatt_connected: 'GATT Connected',
24 'rssi.value': 'Latest RSSI',
25 'services.length': 'Services',
26 };
27
28 /**
29 * Page that displays all of the details of a device. This page is generated
30 * and managed dynamically in bluetooth_internals. This page is the owner of
31 * the DevicePtr when a connection is created. Therefore, it manages the
32 * connection to the Bluetooth device and performs all Device interface
33 * related actions.
34 * @constructor
35 * @param {string} id
36 * @param {!interfaces.BluetoothDevice.DeviceInfo} deviceInfo
37 * @extends {cr.ui.pageManager.Page}
38 */
39 function DeviceDetailsPage(id, deviceInfo) {
40 Page.call(this, id, deviceInfo.name_for_display, id);
41
42 /** @type {interfaces.BluetoothDevice.DeviceInfo} */
43 this.deviceInfo = deviceInfo;
44
45 /** @type {interfaces.BluetoothDevice.Device.ptrClass} */
46 this.devicePtr = null;
47
48 /** @type {!object_fieldset.ObjectFieldSet} */
49 this.deviceFieldSet = new object_fieldset.ObjectFieldSet();
50 this.deviceFieldSet.setPropertyDisplayNames(PROPERTY_NAMES);
51
52 /** @private {!device_collection.ConnectionStatus} */
53 this.status_ = device_collection.ConnectionStatus.DISCONNECTED;
54
55 /** @private {?HTMLElement} */
56 this.connectBtn_ = null;
57
58 this.pageDiv.appendChild(
59 document.importNode($('device-details-template').content,
60 true /* deep */));
61
62 this.pageDiv.querySelector('.device-details').appendChild(
63 this.deviceFieldSet);
64
65 this.pageDiv.querySelector('.forget').addEventListener(
66 'click', function() {
67 this.disconnect();
68 this.pageDiv.dispatchEvent(new CustomEvent('forgetpressed', {
69 detail: {
70 address: this.deviceInfo.address,
71 },
72 }));
73 }.bind(this));
74
75 this.connectBtn_ = this.pageDiv.querySelector('.disconnect');
76 this.connectBtn_.addEventListener('click', function() {
77 this.devicePtr !== null ? this.disconnect() : this.connect();
78 }.bind(this));
79
80 this.redraw();
81 }
82
83 DeviceDetailsPage.prototype = {
84 __proto__: Page.prototype,
85
86 /** Creates a connection to the Bluetooth device. */
87 connect: function() {
88 if (this.status_ !== device_collection.ConnectionStatus.DISCONNECTED)
89 return;
90
91 this.updateConnectionStatus_(
92 device_collection.ConnectionStatus.CONNECTING);
93
94 adapter_broker.getAdapterBroker().then(function(adapterBroker) {
95 return adapterBroker.connectToDevice(this.deviceInfo.address);
96 }.bind(this)).then(function(devicePtr) {
97 this.devicePtr = devicePtr;
98
99 this.updateConnectionStatus_(
100 device_collection.ConnectionStatus.CONNECTED);
101
102 // Fetch services asynchronously.
103 return this.devicePtr.getServices();
104 }.bind(this)).then(function(response) {
105 this.deviceInfo.services = response.services;
106 this.redraw();
107 this.fireDeviceInfoChanged_();
108 }.bind(this)).catch(function(error) {
109 // If a connection error occurs while fetching the services, the
110 // devicePtr reference must be removed.
111 if (this.devicePtr) {
112 this.devicePtr.disconnect();
113 this.devicePtr = null;
114 }
115
116 Snackbar.show(
117 this.deviceInfo.name_for_display + ': ' + error.message,
118 SnackbarType.DANGER, 'Retry', this.connect.bind(this));
119
120 this.updateConnectionStatus_(
121 device_collection.ConnectionStatus.DISCONNECTED);
122 }.bind(this));
123 },
124
125 /** Disconnects the page from the Bluetooth device. */
126 disconnect: function() {
127 if (!this.devicePtr) return;
128
129 this.devicePtr.disconnect();
130 this.devicePtr = null;
131 this.updateConnectionStatus_(
132 device_collection.ConnectionStatus.DISCONNECTED);
133 },
134
135 /** Redraws the contents of the page with the current |deviceInfo|. */
136 redraw: function() {
137 var isConnected = this.deviceInfo.is_gatt_connected;
138
139 // Update status if connection was dropped.
140 if (!isConnected) this.disconnect();
141 var connectedText = isConnected ? 'Connected' : 'Not Connected';
142
143 var rssi = this.deviceInfo.rssi || {};
144 var services = this.deviceInfo.services;
145
146 var rssiValue = 'Unknown';
147 if (rssi.value != null && rssi.value <= 0)
148 rssiValue = rssi.value;
149
150 var serviceCount = 'Unknown';
151 if (services != null && services.length >= 0)
152 serviceCount = services.length;
153
154 var deviceViewObj = {
155 name: this.deviceInfo.name_for_display,
156 address: this.deviceInfo.address,
157 is_gatt_connected: connectedText,
158 'rssi.value': rssiValue,
159 'services.length': serviceCount,
160 };
161
162 this.deviceFieldSet.setObject(deviceViewObj);
163 },
164
165 /**
166 * Sets the page's device info and forces a redraw.
167 * @param {!interfaces.BluetoothDevice.DeviceInfo}
168 */
169 setDeviceInfo: function(info) {
170 this.deviceInfo = info;
171 this.redraw();
172 },
173
174 /**
175 * Fires an 'infochanged' event with the current |deviceInfo|
176 * @private
177 */
178 fireDeviceInfoChanged_: function() {
179 this.pageDiv.dispatchEvent(new CustomEvent('infochanged', {
180 bubbles: true,
181 detail: {
182 info: this.deviceInfo,
183 },
184 }));
185 },
186
187 /**
188 * Updates the current connection status. Caches the latest status, updates
189 * the connection button message, and fires a 'connectionchanged' event when
190 * finished.
191 * @param {!device_collection.ConnectionStatus} status
192 * @private
193 */
194 updateConnectionStatus_: function(status) {
195 if (this.status === status)
196 return;
197
198 this.status_ = status;
199 if (status === device_collection.ConnectionStatus.DISCONNECTED) {
200 this.connectBtn_.textContent = 'Connect';
201 this.connectBtn_.disabled = false;
202 } else if (status === device_collection.ConnectionStatus.CONNECTING) {
203 this.connectBtn_.textContent = 'Connecting';
204 this.connectBtn_.disabled = true;
205 } else {
206 this.connectBtn_.textContent = 'Disconnect';
207 this.connectBtn_.disabled = false;
208 }
209
210 this.pageDiv.dispatchEvent(new CustomEvent('connectionchanged', {
211 bubbles: true,
212 detail: {
213 address: this.deviceInfo.address,
214 status: status,
215 }
216 }));
217 },
218 };
219
220 return {
221 DeviceDetailsPage: DeviceDetailsPage,
222 };
223 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698