OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 cr.define('options.system.bluetooth', function() { | |
6 const ArrayDataModel = cr.ui.ArrayDataModel; | |
7 const DeletableItem = options.DeletableItem; | |
8 const DeletableItemList = options.DeletableItemList; | |
9 | |
10 /** | |
11 * Bluetooth settings constants. | |
12 */ | |
13 function Constants() {} | |
14 | |
15 /** | |
16 * Enumeration of supported device types. | |
17 * @enum {string} | |
18 */ | |
19 // TODO(kevers): Prune list based on the set of devices that will be | |
20 // supported for V1 of the feature. The set will likely be restricted to | |
21 // mouse and keyboard. Others are temporarily included for testing device | |
22 // discovery. | |
23 Constants.DEVICE_TYPE = { | |
24 COMPUTER: 'computer', | |
25 HEADSET: 'headset', | |
26 KEYBOARD: 'input-keyboard', | |
27 MOUSE: 'input-mouse', | |
28 PHONE: 'phone', | |
29 }; | |
30 | |
31 /** | |
32 * Creates a new bluetooth list item. | |
33 * @param {{name: string, | |
34 * address: string, | |
35 * icon: Constants.DEVICE_TYPE, | |
36 * paired: boolean, | |
37 * connected: boolean, | |
38 * pairing: string|undefined, | |
39 * passkey: number|undefined, | |
40 * entered: number|undefined}} device | |
41 * Description of the Bluetooth device. | |
42 * @constructor | |
43 * @extends {options.DeletableItem} | |
44 */ | |
45 function BluetoothListItem(device) { | |
46 var el = cr.doc.createElement('div'); | |
47 el.__proto__ = BluetoothListItem.prototype; | |
48 el.data = {}; | |
49 for (var key in device) | |
50 el.data[key] = device[key]; | |
51 el.decorate(); | |
52 // Only show the close button for paired devices. | |
53 el.deletable = device.paired; | |
54 return el; | |
55 } | |
56 | |
57 BluetoothListItem.prototype = { | |
58 __proto__: DeletableItem.prototype, | |
59 | |
60 /** | |
61 * Description of the Bluetooth device. | |
62 * @type {{name: string, | |
63 * address: string, | |
64 * icon: Constants.DEVICE_TYPE, | |
65 * paired: boolean, | |
66 * connected: boolean, | |
67 * pairing: string|undefined, | |
68 * passkey: number|undefined, | |
69 * entered: number|undefined}} | |
70 */ | |
71 data: null, | |
72 | |
73 /** @inheritDoc */ | |
74 decorate: function() { | |
75 DeletableItem.prototype.decorate.call(this); | |
76 var label = this.ownerDocument.createElement('div'); | |
77 label.className = 'bluetooth-device-label'; | |
78 this.classList.add('bluetooth-device'); | |
79 this.connected = this.data.connected; | |
80 // Though strictly speaking, a connected device will also be paired, we | |
81 // are interested in tracking paired devices that are not connected. | |
82 this.paired = this.data.paired && !this.data.connected; | |
83 this.connecting = !!this.data.pairing; | |
84 var content = this.data.name; | |
85 // Update label for devices that are paired but not connected. | |
86 if (this.paired) { | |
87 content = content + ' (' + | |
88 templateData['bluetoothDeviceNotConnected'] + ')'; | |
89 } | |
90 label.textContent = content; | |
91 this.contentElement.appendChild(label); | |
92 }, | |
93 }; | |
94 | |
95 /** | |
96 * Class for displaying a list of Bluetooth devices. | |
97 * @constructor | |
98 * @extends {options.DeletableItemList} | |
99 */ | |
100 var BluetoothDeviceList = cr.ui.define('list'); | |
101 | |
102 BluetoothDeviceList.prototype = { | |
103 __proto__: DeletableItemList.prototype, | |
104 | |
105 /** @inheritDoc */ | |
106 decorate: function() { | |
107 DeletableItemList.prototype.decorate.call(this); | |
108 this.addEventListener('blur', this.onBlur_); | |
109 this.clear(); | |
110 }, | |
111 | |
112 /** | |
113 * When the list loses focus, unselect all items in the list. | |
114 * @private | |
115 */ | |
116 onBlur_: function() { | |
117 // TODO(kevers): Should this be pushed up to the list class? | |
118 this.selectionModel.unselectAll(); | |
119 }, | |
120 | |
121 /** | |
122 * Adds a bluetooth device to the list of available devices. A check is | |
123 * made to see if the device is already in the list, in which case the | |
124 * existing device is updated. | |
125 * @param {{name: string, | |
126 * address: string, | |
127 * icon: Constants.DEVICE_TYPE, | |
128 * paired: boolean, | |
129 * connected: boolean, | |
130 * pairing: string|undefined, | |
131 * passkey: number|undefined, | |
132 * entered: number|undefined}} device | |
133 * Description of the bluetooth device. | |
134 * @return {boolean} True if the devies was successfully added or updated. | |
135 */ | |
136 appendDevice: function(device) { | |
137 if (!this.isSupported_(device)) | |
138 return false; | |
139 var index = this.find(device.address); | |
140 if (index == undefined) { | |
141 this.dataModel.push(device); | |
142 this.redraw(); | |
143 } else { | |
144 this.dataModel.splice(index, 1, device); | |
145 this.redrawItem(index); | |
146 } | |
147 this.updateListVisibility_(); | |
148 return true; | |
149 }, | |
150 | |
151 /** | |
152 * Perges all devices from the list. | |
153 */ | |
154 clear: function() { | |
155 this.dataModel = new ArrayDataModel([]); | |
156 this.redraw(); | |
157 this.updateListVisibility_(); | |
158 }, | |
159 | |
160 /** | |
161 * Returns the index of the list entry with the matching address. | |
162 * @param {string} address Unique address of the Bluetooth device. | |
163 * @return {number|undefined} Index of the matching entry or | |
164 * undefined if no match found. | |
165 */ | |
166 find: function(address) { | |
167 var size = this.dataModel.length; | |
168 for (var i = 0; i < size; i++) { | |
169 var entry = this.dataModel.item(i); | |
170 if (entry.address == address) | |
171 return i; | |
172 } | |
173 }, | |
174 | |
175 /** @inheritDoc */ | |
176 createItem: function(entry) { | |
177 return new BluetoothListItem(entry); | |
178 }, | |
179 | |
180 /** @inheritDoc */ | |
181 deleteItemAtIndex: function(index) { | |
182 var item = this.dataModel.item(index); | |
183 if (item && (item.connected || item.paired)) { | |
184 // Inform the bluetooth adapter that we are disconnecting the device. | |
185 chrome.send('updateBluetoothDevice', | |
186 [item.address, item.connected ? 'disconnect' : 'forget']); | |
187 } | |
188 this.dataModel.splice(index, 1); | |
189 // Invalidate the list since it has a stale cache after a splice | |
190 // involving a deletion. | |
191 this.invalidate(); | |
192 this.redraw(); | |
193 this.updateListVisibility_(); | |
194 }, | |
195 | |
196 /** | |
197 * Tests if the bluetooth device is supported based on the type of device. | |
198 * @param {Object.<string,string>} device Desription of the device. | |
199 * @return {boolean} true if the device is supported. | |
200 * @private | |
201 */ | |
202 isSupported_: function(device) { | |
203 var target = device.icon; | |
204 for (var key in Constants.DEVICE_TYPE) { | |
205 if (Constants.DEVICE_TYPE[key] == target) | |
206 return true; | |
207 } | |
208 return false; | |
209 }, | |
210 | |
211 /** | |
212 * If the list has an associated empty list placholder then update the | |
213 * visibility of the list and placeholder. | |
214 * @private | |
215 */ | |
216 updateListVisibility_: function() { | |
217 var empty = this.dataModel.length == 0; | |
218 var listPlaceHolderID = this.id + '-empty-placeholder'; | |
219 if ($(listPlaceHolderID)) { | |
220 this.hidden = empty; | |
221 $(listPlaceHolderID).hidden = !empty; | |
222 } | |
223 }, | |
224 }; | |
225 | |
226 cr.defineProperty(BluetoothListItem, 'connected', cr.PropertyKind.BOOL_ATTR); | |
227 | |
228 cr.defineProperty(BluetoothListItem, 'paired', cr.PropertyKind.BOOL_ATTR); | |
229 | |
230 cr.defineProperty(BluetoothListItem, 'connecting', cr.PropertyKind.BOOL_ATTR); | |
231 | |
232 return { | |
233 BluetoothListItem: BluetoothListItem, | |
234 BluetoothDeviceList: BluetoothDeviceList, | |
235 Constants: Constants | |
236 }; | |
237 }); | |
OLD | NEW |