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 DeviceDetailsPage which displays all of the details of a | 6 * Javascript for DeviceDetailsPage which displays all of the details of a |
7 * device. The page is generated and managed dynamically in bluetooth_internals. | 7 * device. The page is generated and managed dynamically in bluetooth_internals. |
8 * served from chrome://bluetooth-internals/. | 8 * served from chrome://bluetooth-internals/. |
9 */ | 9 */ |
10 | 10 |
11 cr.define('device_details_page', function() { | 11 cr.define('device_details_page', function() { |
12 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; | |
13 /** @const */ var Page = cr.ui.pageManager.Page; | 12 /** @const */ var Page = cr.ui.pageManager.Page; |
14 /** @const */ var Snackbar = snackbar.Snackbar; | 13 /** @const */ var Snackbar = snackbar.Snackbar; |
15 /** @const */ var SnackbarType = snackbar.SnackbarType; | 14 /** @const */ var SnackbarType = snackbar.SnackbarType; |
16 | 15 |
17 /** | 16 /** |
18 * Property names that will be displayed in the ObjectFieldSet which contains | 17 * Property names that will be displayed in the ObjectFieldSet which contains |
19 * the DeviceInfo object. | 18 * the DeviceInfo object. |
20 */ | 19 */ |
21 var PROPERTY_NAMES = { | 20 var PROPERTY_NAMES = { |
22 name: 'Name', | 21 name: 'Name', |
23 address: 'Address', | 22 address: 'Address', |
24 is_gatt_connected: 'GATT Connected', | 23 is_gatt_connected: 'GATT Connected', |
25 'rssi.value': 'Latest RSSI', | 24 'rssi.value': 'Latest RSSI', |
26 'services.length': 'Services', | 25 'services.length': 'Services', |
27 }; | 26 }; |
28 | 27 |
29 /** | 28 /** |
30 * Page that displays all of the details of a device. This page is generated | 29 * Page that displays all of the details of a device. This page is generated |
31 * and managed dynamically in bluetooth_internals. This page is the owner of | 30 * and managed dynamically in bluetooth_internals. The page contains two |
32 * the DevicePtr when a connection is created. Therefore, it manages the | 31 * sections: Status and Services. The Status section displays information from |
33 * connection to the Bluetooth device and performs all Device interface | 32 * the DeviceInfo object and the Services section contains a ServiceList |
34 * related actions. | 33 * compononent that lists all of the active services on the device. |
35 * @constructor | 34 * @constructor |
36 * @param {string} id | 35 * @param {string} id |
37 * @param {!interfaces.BluetoothDevice.DeviceInfo} deviceInfo | 36 * @param {!interfaces.BluetoothDevice.DeviceInfo} deviceInfo |
38 * @extends {cr.ui.pageManager.Page} | 37 * @extends {cr.ui.pageManager.Page} |
39 */ | 38 */ |
40 function DeviceDetailsPage(id, deviceInfo) { | 39 function DeviceDetailsPage(id, deviceInfo) { |
41 Page.call(this, id, deviceInfo.name_for_display, id); | 40 Page.call(this, id, deviceInfo.name_for_display, id); |
42 | 41 |
43 /** @type {interfaces.BluetoothDevice.DeviceInfo} */ | 42 /** @type {interfaces.BluetoothDevice.DeviceInfo} */ |
44 this.deviceInfo = deviceInfo; | 43 this.deviceInfo = deviceInfo; |
45 | 44 |
46 /** @type {?interfaces.BluetoothDevice.Device.ptrClass} */ | 45 /** @private {?interfaces.BluetoothDevice.Device.ptrClass} */ |
47 this.devicePtr = null; | 46 this.devicePtr_ = null; |
48 | 47 |
49 /** @type {!object_fieldset.ObjectFieldSet} */ | 48 /** @private {!object_fieldset.ObjectFieldSet} */ |
50 this.deviceFieldSet = new object_fieldset.ObjectFieldSet(); | 49 this.deviceFieldSet_ = new object_fieldset.ObjectFieldSet(); |
51 this.deviceFieldSet.setPropertyDisplayNames(PROPERTY_NAMES); | 50 this.deviceFieldSet_.setPropertyDisplayNames(PROPERTY_NAMES); |
52 | 51 |
53 /** @type {!service_list.ServiceList} */ | 52 /** @private {!service_list.ServiceList} */ |
54 this.serviceList = new service_list.ServiceList(); | 53 this.serviceList_ = new service_list.ServiceList(); |
55 this.serviceList.setLoading(true); | |
56 | 54 |
57 /** @private {!device_collection.ConnectionStatus} */ | 55 /** @private {!device_collection.ConnectionStatus} */ |
58 this.status_ = device_collection.ConnectionStatus.DISCONNECTED; | 56 this.status_ = device_collection.ConnectionStatus.DISCONNECTED; |
59 | 57 |
60 /** @private {?HTMLElement} */ | 58 /** @private {?HTMLElement} */ |
61 this.connectBtn_ = null; | 59 this.connectBtn_ = null; |
62 | 60 |
63 this.pageDiv.appendChild( | 61 this.pageDiv.appendChild( |
64 document.importNode($('device-details-template').content, | 62 document.importNode($('device-details-template').content, |
65 true /* deep */)); | 63 true /* deep */)); |
66 | 64 |
67 this.pageDiv.querySelector('.device-details').appendChild( | 65 this.pageDiv.querySelector('.device-details').appendChild( |
68 this.deviceFieldSet); | 66 this.deviceFieldSet_); |
69 this.pageDiv.querySelector('.services').appendChild(this.serviceList); | 67 this.pageDiv.querySelector('.services').appendChild(this.serviceList_); |
70 | 68 |
71 this.pageDiv.querySelector('.forget').addEventListener( | 69 this.pageDiv.querySelector('.forget').addEventListener( |
72 'click', function() { | 70 'click', function() { |
73 this.disconnect(); | 71 this.disconnect(); |
74 this.pageDiv.dispatchEvent(new CustomEvent('forgetpressed', { | 72 this.pageDiv.dispatchEvent(new CustomEvent('forgetpressed', { |
75 detail: { | 73 detail: { |
76 address: this.deviceInfo.address, | 74 address: this.deviceInfo.address, |
77 }, | 75 }, |
78 })); | 76 })); |
79 }.bind(this)); | 77 }.bind(this)); |
80 | 78 |
81 this.connectBtn_ = this.pageDiv.querySelector('.disconnect'); | 79 this.connectBtn_ = this.pageDiv.querySelector('.disconnect'); |
82 this.connectBtn_.addEventListener('click', function() { | 80 this.connectBtn_.addEventListener('click', function() { |
83 this.devicePtr !== null ? this.disconnect() : this.connect(); | 81 this.devicePtr_ !== null ? this.disconnect() : this.connect(); |
84 }.bind(this)); | 82 }.bind(this)); |
85 | 83 |
86 this.redraw(); | 84 this.redraw(); |
87 } | 85 } |
88 | 86 |
89 DeviceDetailsPage.prototype = { | 87 DeviceDetailsPage.prototype = { |
90 __proto__: Page.prototype, | 88 __proto__: Page.prototype, |
91 | 89 |
92 /** Creates a connection to the Bluetooth device. */ | 90 /** Creates a connection to the Bluetooth device. */ |
93 connect: function() { | 91 connect: function() { |
94 if (this.status_ !== device_collection.ConnectionStatus.DISCONNECTED) | 92 if (this.status_ !== device_collection.ConnectionStatus.DISCONNECTED) |
95 return; | 93 return; |
96 | 94 |
97 this.updateConnectionStatus_( | 95 this.updateConnectionStatus_( |
98 device_collection.ConnectionStatus.CONNECTING); | 96 device_collection.ConnectionStatus.CONNECTING); |
99 | 97 |
100 adapter_broker.getAdapterBroker().then(function(adapterBroker) { | 98 device_broker.connectToDevice(this.deviceInfo.address).then( |
101 return adapterBroker.connectToDevice(this.deviceInfo.address); | 99 function(devicePtr) { |
102 }.bind(this)).then(function(devicePtr) { | 100 this.devicePtr_ = devicePtr; |
103 this.devicePtr = devicePtr; | |
104 | 101 |
105 this.updateConnectionStatus_( | 102 this.updateConnectionStatus_( |
106 device_collection.ConnectionStatus.CONNECTED); | 103 device_collection.ConnectionStatus.CONNECTED); |
107 | 104 |
108 // Fetch services asynchronously. | 105 // Fetch services asynchronously. |
109 return this.devicePtr.getServices(); | 106 return this.devicePtr_.getServices(); |
110 }.bind(this)).then(function(response) { | 107 }.bind(this)).then(function(response) { |
111 this.serviceList.setData(new ArrayDataModel(response.services)); | 108 this.deviceInfo.services = response.services; |
112 this.deviceInfo.services = this.serviceList.dataModel; | 109 this.serviceList_.load(this.deviceInfo.address); |
113 this.serviceList.setLoading(false); | 110 this.redraw(); |
| 111 this.fireDeviceInfoChanged_(); |
| 112 }.bind(this)).catch(function(error) { |
| 113 // If a connection error occurs while fetching the services, the |
| 114 // devicePtr reference must be removed. |
| 115 if (this.devicePtr_) { |
| 116 this.devicePtr_.disconnect(); |
| 117 this.devicePtr_ = null; |
| 118 } |
114 | 119 |
115 this.redraw(); | 120 Snackbar.show( |
116 this.fireDeviceInfoChanged_(); | 121 this.deviceInfo.name_for_display + ': ' + error.message, |
117 }.bind(this)).catch(function(error) { | 122 SnackbarType.ERROR, 'Retry', this.connect.bind(this)); |
118 // If a connection error occurs while fetching the services, the | |
119 // devicePtr reference must be removed. | |
120 if (this.devicePtr) { | |
121 this.devicePtr.disconnect(); | |
122 this.devicePtr = null; | |
123 } | |
124 | 123 |
125 Snackbar.show( | 124 this.updateConnectionStatus_( |
126 this.deviceInfo.name_for_display + ': ' + error.message, | 125 device_collection.ConnectionStatus.DISCONNECTED); |
127 SnackbarType.DANGER, 'Retry', this.connect.bind(this)); | 126 }.bind(this)); |
128 | |
129 this.updateConnectionStatus_( | |
130 device_collection.ConnectionStatus.DISCONNECTED); | |
131 }.bind(this)); | |
132 }, | 127 }, |
133 | 128 |
134 /** Disconnects the page from the Bluetooth device. */ | 129 /** Disconnects the page from the Bluetooth device. */ |
135 disconnect: function() { | 130 disconnect: function() { |
136 if (!this.devicePtr) return; | 131 if (!this.devicePtr_) return; |
137 | 132 |
138 this.devicePtr.disconnect(); | 133 this.devicePtr_.disconnect(); |
139 this.devicePtr = null; | 134 this.devicePtr_ = null; |
140 this.updateConnectionStatus_( | 135 this.updateConnectionStatus_( |
141 device_collection.ConnectionStatus.DISCONNECTED); | 136 device_collection.ConnectionStatus.DISCONNECTED); |
142 }, | 137 }, |
143 | 138 |
144 /** Redraws the contents of the page with the current |deviceInfo|. */ | 139 /** Redraws the contents of the page with the current |deviceInfo|. */ |
145 redraw: function() { | 140 redraw: function() { |
146 var isConnected = this.deviceInfo.is_gatt_connected; | 141 var isConnected = this.deviceInfo.is_gatt_connected; |
147 | 142 |
148 // Update status if connection was dropped. | 143 // Update status if connection has changed. |
149 if (!isConnected) this.disconnect(); | 144 if (isConnected) |
| 145 this.connect(); |
| 146 else |
| 147 this.disconnect(); |
| 148 |
150 var connectedText = isConnected ? 'Connected' : 'Not Connected'; | 149 var connectedText = isConnected ? 'Connected' : 'Not Connected'; |
151 | 150 |
152 var rssi = this.deviceInfo.rssi || {}; | 151 var rssi = this.deviceInfo.rssi || {}; |
153 var services = this.deviceInfo.services; | 152 var services = this.deviceInfo.services; |
154 | 153 |
155 var rssiValue = 'Unknown'; | 154 var rssiValue = 'Unknown'; |
156 if (rssi.value != null && rssi.value <= 0) | 155 if (rssi.value != null && rssi.value <= 0) |
157 rssiValue = rssi.value; | 156 rssiValue = rssi.value; |
158 | 157 |
159 var serviceCount = 'Unknown'; | 158 var serviceCount = 'Unknown'; |
160 if (services != null && services.length >= 0) | 159 if (services != null && services.length >= 0) |
161 serviceCount = services.length; | 160 serviceCount = services.length; |
162 | 161 |
163 var deviceViewObj = { | 162 var deviceViewObj = { |
164 name: this.deviceInfo.name_for_display, | 163 name: this.deviceInfo.name_for_display, |
165 address: this.deviceInfo.address, | 164 address: this.deviceInfo.address, |
166 is_gatt_connected: connectedText, | 165 is_gatt_connected: connectedText, |
167 'rssi.value': rssiValue, | 166 'rssi.value': rssiValue, |
168 'services.length': serviceCount, | 167 'services.length': serviceCount, |
169 }; | 168 }; |
170 | 169 |
171 this.deviceFieldSet.setObject(deviceViewObj); | 170 this.deviceFieldSet_.setObject(deviceViewObj); |
172 this.serviceList.redraw(); | 171 this.serviceList_.redraw(); |
173 }, | 172 }, |
174 | 173 |
175 /** | 174 /** |
176 * Sets the page's device info and forces a redraw. | 175 * Sets the page's device info and forces a redraw. |
177 * @param {!interfaces.BluetoothDevice.DeviceInfo} | 176 * @param {!interfaces.BluetoothDevice.DeviceInfo} |
178 */ | 177 */ |
179 setDeviceInfo: function(info) { | 178 setDeviceInfo: function(info) { |
180 this.deviceInfo = info; | 179 this.deviceInfo = info; |
181 this.redraw(); | 180 this.redraw(); |
182 }, | 181 }, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 status: status, | 223 status: status, |
225 } | 224 } |
226 })); | 225 })); |
227 }, | 226 }, |
228 }; | 227 }; |
229 | 228 |
230 return { | 229 return { |
231 DeviceDetailsPage: DeviceDetailsPage, | 230 DeviceDetailsPage: DeviceDetailsPage, |
232 }; | 231 }; |
233 }); | 232 }); |
OLD | NEW |