OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * Handler of device event. | 8 * Handler of device event. |
9 * @constructor | 9 * @constructor |
10 * @extends {cr.EventTarget} | 10 * @extends {cr.EventTarget} |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 */ | 90 */ |
91 this.buttonLabel = opt_buttonLabel || null; | 91 this.buttonLabel = opt_buttonLabel || null; |
92 | 92 |
93 /** | 93 /** |
94 * Queue of API call. | 94 * Queue of API call. |
95 * @type {AsyncUtil.Queue} | 95 * @type {AsyncUtil.Queue} |
96 * @private | 96 * @private |
97 */ | 97 */ |
98 this.queue_ = new AsyncUtil.Queue(); | 98 this.queue_ = new AsyncUtil.Queue(); |
99 | 99 |
100 /** | |
101 * Timeout ID. | |
102 * @type {number} | |
103 * @private | |
104 */ | |
105 this.pendingShowTimerId_ = 0; | |
106 | |
107 Object.seal(this); | 100 Object.seal(this); |
108 }; | 101 }; |
109 | 102 |
110 /** | 103 /** |
111 * @type {DeviceHandler.Notification} | 104 * @type {DeviceHandler.Notification} |
112 * @const | 105 * @const |
113 */ | 106 */ |
114 DeviceHandler.Notification.DEVICE = new DeviceHandler.Notification( | 107 DeviceHandler.Notification.DEVICE = new DeviceHandler.Notification( |
115 'device', | 108 'device', |
116 'REMOVABLE_DEVICE_DETECTION_TITLE', | 109 'REMOVABLE_DEVICE_DETECTION_TITLE', |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 'FORMATTING_OF_DEVICE_FAILED_TITLE', | 175 'FORMATTING_OF_DEVICE_FAILED_TITLE', |
183 'FORMATTING_FINISHED_FAILURE_MESSAGE'); | 176 'FORMATTING_FINISHED_FAILURE_MESSAGE'); |
184 | 177 |
185 /** | 178 /** |
186 * Shows the notification for the device path. | 179 * Shows the notification for the device path. |
187 * @param {string} devicePath Device path. | 180 * @param {string} devicePath Device path. |
188 * @param {string=} opt_message Message overrides the default message. | 181 * @param {string=} opt_message Message overrides the default message. |
189 * @return {string} Notification ID. | 182 * @return {string} Notification ID. |
190 */ | 183 */ |
191 DeviceHandler.Notification.prototype.show = function(devicePath, opt_message) { | 184 DeviceHandler.Notification.prototype.show = function(devicePath, opt_message) { |
192 this.clearTimeout_(); | |
193 var notificationId = this.makeId_(devicePath); | 185 var notificationId = this.makeId_(devicePath); |
194 this.queue_.run(function(callback) { | 186 this.queue_.run(function(callback) { |
195 var buttons = | 187 var buttons = |
196 this.buttonLabel ? [{title: str(this.buttonLabel)}] : undefined; | 188 this.buttonLabel ? [{title: str(this.buttonLabel)}] : undefined; |
197 chrome.notifications.create( | 189 chrome.notifications.create( |
198 notificationId, | 190 notificationId, |
199 { | 191 { |
200 type: 'basic', | 192 type: 'basic', |
201 title: str(this.title), | 193 title: str(this.title), |
202 message: opt_message || str(this.message), | 194 message: opt_message || str(this.message), |
203 iconUrl: chrome.runtime.getURL('/common/images/icon96.png'), | 195 iconUrl: chrome.runtime.getURL('/common/images/icon96.png'), |
204 buttons: buttons | 196 buttons: buttons |
205 }, | 197 }, |
206 callback); | 198 callback); |
207 }.bind(this)); | 199 }.bind(this)); |
208 return notificationId; | 200 return notificationId; |
209 }; | 201 }; |
210 | 202 |
211 /** | 203 /** |
212 * Shows the notification after 5 seconds. | |
213 * @param {string} devicePath Device path. | |
214 */ | |
215 DeviceHandler.Notification.prototype.showLater = function(devicePath) { | |
216 this.clearTimeout_(); | |
217 this.pendingShowTimerId_ = setTimeout(this.show.bind(this, devicePath), 5000); | |
218 }; | |
219 | |
220 /** | |
221 * Hides the notification for the device path. | 204 * Hides the notification for the device path. |
222 * @param {string} devicePath Device path. | 205 * @param {string} devicePath Device path. |
223 */ | 206 */ |
224 DeviceHandler.Notification.prototype.hide = function(devicePath) { | 207 DeviceHandler.Notification.prototype.hide = function(devicePath) { |
225 this.clearTimeout_(); | |
226 this.queue_.run(function(callback) { | 208 this.queue_.run(function(callback) { |
227 chrome.notifications.clear(this.makeId_(devicePath), callback); | 209 chrome.notifications.clear(this.makeId_(devicePath), callback); |
228 }.bind(this)); | 210 }.bind(this)); |
229 }; | 211 }; |
230 | 212 |
231 /** | 213 /** |
232 * Makes a notification ID for the device path. | 214 * Makes a notification ID for the device path. |
233 * @param {string} devicePath Device path. | 215 * @param {string} devicePath Device path. |
234 * @return {string} Notification ID. | 216 * @return {string} Notification ID. |
235 * @private | 217 * @private |
236 */ | 218 */ |
237 DeviceHandler.Notification.prototype.makeId_ = function(devicePath) { | 219 DeviceHandler.Notification.prototype.makeId_ = function(devicePath) { |
238 return this.prefix + ':' + devicePath; | 220 return this.prefix + ':' + devicePath; |
239 }; | 221 }; |
240 | 222 |
241 /** | 223 /** |
242 * Cancels the timeout request. | |
243 * @private | |
244 */ | |
245 DeviceHandler.Notification.prototype.clearTimeout_ = function() { | |
246 if (this.pendingShowTimerId_) { | |
247 clearTimeout(this.pendingShowTimerId_); | |
248 this.pendingShowTimerId_ = 0; | |
249 } | |
250 }; | |
251 | |
252 /** | |
253 * Handles notifications from C++ sides. | 224 * Handles notifications from C++ sides. |
254 * @param {DeviceEvent} event Device event. | 225 * @param {DeviceEvent} event Device event. |
255 * @private | 226 * @private |
256 */ | 227 */ |
257 DeviceHandler.prototype.onDeviceChanged_ = function(event) { | 228 DeviceHandler.prototype.onDeviceChanged_ = function(event) { |
258 switch (event.type) { | 229 switch (event.type) { |
259 case 'added': | 230 case 'scan_started': |
260 if (!this.isStartup_) | 231 DeviceHandler.Notification.DEVICE.show(event.devicePath); |
261 DeviceHandler.Notification.DEVICE.showLater(event.devicePath); | 232 break; |
262 this.mountStatus_[event.devicePath] = DeviceHandler.MountStatus.NO_RESULT; | 233 case 'scan_cancelled': |
| 234 DeviceHandler.Notification.DEVICE.hide(event.devicePath); |
263 break; | 235 break; |
264 case 'disabled': | 236 case 'disabled': |
265 DeviceHandler.Notification.DEVICE_EXTERNAL_STORAGE_DISABLED.show( | 237 DeviceHandler.Notification.DEVICE_EXTERNAL_STORAGE_DISABLED.show( |
266 event.devicePath); | 238 event.devicePath); |
267 break; | 239 break; |
268 case 'scan_canceled': | |
269 DeviceHandler.Notification.DEVICE.hide(event.devicePath); | |
270 break; | |
271 case 'removed': | 240 case 'removed': |
272 DeviceHandler.Notification.DEVICE.hide(event.devicePath); | 241 DeviceHandler.Notification.DEVICE.hide(event.devicePath); |
273 DeviceHandler.Notification.DEVICE_FAIL.hide(event.devicePath); | 242 DeviceHandler.Notification.DEVICE_FAIL.hide(event.devicePath); |
274 DeviceHandler.Notification.DEVICE_EXTERNAL_STORAGE_DISABLED.hide( | 243 DeviceHandler.Notification.DEVICE_EXTERNAL_STORAGE_DISABLED.hide( |
275 event.devicePath); | 244 event.devicePath); |
276 delete this.mountStatus_[event.devicePath]; | 245 delete this.mountStatus_[event.devicePath]; |
277 break; | 246 break; |
278 case 'hard_unplugged': | 247 case 'hard_unplugged': |
279 if (!this.isStartup_) { | 248 if (!this.isStartup_) { |
280 DeviceHandler.Notification.DEVICE_HARD_UNPLUGGED.show( | 249 DeviceHandler.Notification.DEVICE_HARD_UNPLUGGED.show( |
281 event.devicePath); | 250 event.devicePath); |
282 } | 251 } |
283 break; | 252 break; |
284 case 'format_start': | 253 case 'format_start': |
285 DeviceHandler.Notification.FORMAT_START.show(event.devicePath); | 254 DeviceHandler.Notification.FORMAT_START.show(event.devicePath); |
286 break; | 255 break; |
287 case 'format_success': | 256 case 'format_success': |
288 DeviceHandler.Notification.FORMAT_START.hide(event.devicePath); | 257 DeviceHandler.Notification.FORMAT_START.hide(event.devicePath); |
289 DeviceHandler.Notification.FORMAT_SUCCESS.show(event.devicePath); | 258 DeviceHandler.Notification.FORMAT_SUCCESS.show(event.devicePath); |
290 break; | 259 break; |
291 case 'format_fail': | 260 case 'format_fail': |
292 DeviceHandler.Notification.FORMAT_START.hide(event.devicePath); | 261 DeviceHandler.Notification.FORMAT_START.hide(event.devicePath); |
293 DeviceHandler.Notification.FORMAT_FAIL.show(event.devicePath); | 262 DeviceHandler.Notification.FORMAT_FAIL.show(event.devicePath); |
294 break; | 263 break; |
| 264 default: |
| 265 console.error('Unknown event tyep: ' + event.type); |
| 266 break; |
295 } | 267 } |
296 }; | 268 }; |
297 | 269 |
298 /** | 270 /** |
299 * Mount status for the device. | 271 * Mount status for the device. |
300 * Each multi-partition devices can obtain multiple mount completed events. | 272 * Each multi-partition devices can obtain multiple mount completed events. |
301 * This status shows what results are already obtained for the device. | 273 * This status shows what results are already obtained for the device. |
302 * @enum {string} | 274 * @enum {string} |
303 * @const | 275 * @const |
304 */ | 276 */ |
(...skipping 12 matching lines...) Expand all Loading... |
317 | 289 |
318 /** | 290 /** |
319 * Handles mount completed events to show notifications for removable devices. | 291 * Handles mount completed events to show notifications for removable devices. |
320 * @param {MountCompletedEvent} event Mount completed event. | 292 * @param {MountCompletedEvent} event Mount completed event. |
321 * @private | 293 * @private |
322 */ | 294 */ |
323 DeviceHandler.prototype.onMountCompleted_ = function(event) { | 295 DeviceHandler.prototype.onMountCompleted_ = function(event) { |
324 // If this is remounting, which happens when resuming ChromeOS, the device has | 296 // If this is remounting, which happens when resuming ChromeOS, the device has |
325 // already inserted to the computer. So we suppress the notification. | 297 // already inserted to the computer. So we suppress the notification. |
326 var volume = event.volumeMetadata; | 298 var volume = event.volumeMetadata; |
327 if (!volume.deviceType || event.isRemounting) | 299 if (!volume.deviceType || !event.shouldNotify) |
328 return; | 300 return; |
329 | 301 |
330 // If the current volume status is succeed and it should be handled in | 302 // If the current volume status is succeed and it should be handled in |
331 // Files.app, show the notification to navigate the volume. | 303 // Files.app, show the notification to navigate the volume. |
332 if (event.status === 'success' && event.shouldNotify) { | 304 if (event.eventType === 'mount' && |
| 305 event.status === 'success') { |
333 if (this.navigationVolumes_[event.volumeMetadata.devicePath]) { | 306 if (this.navigationVolumes_[event.volumeMetadata.devicePath]) { |
334 // The notification has already shown for the device. It seems the device | 307 // The notification has already shown for the device. It seems the device |
335 // has multiple volumes. The order of mount events of volumes are | 308 // has multiple volumes. The order of mount events of volumes are |
336 // undetermind, so it compares the volume Id and uses the earier order ID | 309 // undetermind, so it compares the volume Id and uses the earier order ID |
337 // to prevent Files.app from navigating to different volumes for each | 310 // to prevent Files.app from navigating to different volumes for each |
338 // time. | 311 // time. |
339 if (event.volumeMetadata.volumeId < | 312 if (event.volumeMetadata.volumeId < |
340 this.navigationVolumes_[event.volumeMetadata.devicePath]) { | 313 this.navigationVolumes_[event.volumeMetadata.devicePath]) { |
341 this.navigationVolumes_[event.volumeMetadata.devicePath] = | 314 this.navigationVolumes_[event.volumeMetadata.devicePath] = |
342 event.volumeMetadata.volumeId; | 315 event.volumeMetadata.volumeId; |
(...skipping 16 matching lines...) Expand all Loading... |
359 var getFirstStatus = function(event) { | 332 var getFirstStatus = function(event) { |
360 if (event.status === 'success') | 333 if (event.status === 'success') |
361 return DeviceHandler.MountStatus.SUCCESS; | 334 return DeviceHandler.MountStatus.SUCCESS; |
362 else if (event.volumeMetadata.isParentDevice) | 335 else if (event.volumeMetadata.isParentDevice) |
363 return DeviceHandler.MountStatus.ONLY_PARENT_ERROR; | 336 return DeviceHandler.MountStatus.ONLY_PARENT_ERROR; |
364 else | 337 else |
365 return DeviceHandler.MountStatus.CHILD_ERROR; | 338 return DeviceHandler.MountStatus.CHILD_ERROR; |
366 }; | 339 }; |
367 | 340 |
368 // Update the current status. | 341 // Update the current status. |
| 342 if (!this.mountStatus_[volume.devicePath]) |
| 343 this.mountStatus_[volume.devicePath] = DeviceHandler.MountStatus.NO_RESULT; |
369 switch (this.mountStatus_[volume.devicePath]) { | 344 switch (this.mountStatus_[volume.devicePath]) { |
370 // If there is no related device, do nothing. | |
371 case undefined: | |
372 return; | |
373 // If the multipart error message has already shown, do nothing because the | 345 // If the multipart error message has already shown, do nothing because the |
374 // message does not changed by the following mount results. | 346 // message does not changed by the following mount results. |
375 case DeviceHandler.MountStatus.MULTIPART_ERROR: | 347 case DeviceHandler.MountStatus.MULTIPART_ERROR: |
376 return; | 348 return; |
377 // If this is the first result, hide the scanning notification. | 349 // If this is the first result, hide the scanning notification. |
378 case DeviceHandler.MountStatus.NO_RESULT: | 350 case DeviceHandler.MountStatus.NO_RESULT: |
379 DeviceHandler.Notification.DEVICE.hide(volume.devicePath); | 351 DeviceHandler.Notification.DEVICE.hide(volume.devicePath); |
380 this.mountStatus_[volume.devicePath] = getFirstStatus(event); | 352 this.mountStatus_[volume.devicePath] = getFirstStatus(event); |
381 break; | 353 break; |
382 // If there are only parent errors, and the new result is child's one, hide | 354 // If there are only parent errors, and the new result is child's one, hide |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 this.dispatchEvent(event); | 420 this.dispatchEvent(event); |
449 } | 421 } |
450 }; | 422 }; |
451 | 423 |
452 DeviceHandler.prototype.onStartup_ = function() { | 424 DeviceHandler.prototype.onStartup_ = function() { |
453 this.isStartup_ = true; | 425 this.isStartup_ = true; |
454 setTimeout(function() { | 426 setTimeout(function() { |
455 this.isStartup_ = false; | 427 this.isStartup_ = false; |
456 }.bind(this), 5000); | 428 }.bind(this), 5000); |
457 }; | 429 }; |
OLD | NEW |