| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 * Represents each volume, such as "drive", "download directory", each "USB | 6 * Represents each volume, such as "drive", "download directory", each "USB |
| 7 * flush storage", or "mounted zip archive" etc. | 7 * flush storage", or "mounted zip archive" etc. |
| 8 * | 8 * |
| 9 * @constructor | 9 * @constructor |
| 10 * @struct | 10 * @struct |
| 11 * | 11 * |
| 12 * @param {VolumeManagerCommon.VolumeType} volumeType The type of the volume. | 12 * @param {VolumeManagerCommon.VolumeType} volumeType The type of the volume. |
| 13 * @param {string} volumeId ID of the volume. | 13 * @param {string} volumeId ID of the volume. |
| 14 * @param {FileSystem} fileSystem The file system object for this volume. | 14 * @param {FileSystem} fileSystem The file system object for this volume. |
| 15 * @param {(string|undefined)} error The error if an error is found. | 15 * @param {(string|undefined)} error The error if an error is found. |
| 16 * @param {(string|undefined)} deviceType The type of device | 16 * @param {(string|undefined)} deviceType The type of device |
| 17 * ('usb'|'sd'|'optical'|'mobile'|'unknown') (as defined in | 17 * ('usb'|'sd'|'optical'|'mobile'|'unknown') (as defined in |
| 18 * chromeos/disks/disk_mount_manager.cc). Can be undefined. | 18 * chromeos/disks/disk_mount_manager.cc). Can be undefined. |
| 19 * @param {(string|undefined)} devicePath Identifier of the device that the | 19 * @param {(string|undefined)} devicePath Identifier of the device that the |
| 20 * volume belongs to. Can be undefined. | 20 * volume belongs to. Can be undefined. |
| 21 * @param {boolean} isReadOnly True if the volume is read only. | 21 * @param {boolean} isReadOnly True if the volume is read only. |
| 22 * @param {!{displayName:string, isCurrentProfile:boolean}} profile Profile | 22 * @param {!{displayName:string, isCurrentProfile:boolean}} profile Profile |
| 23 * information. | 23 * information. |
| 24 * @param {string} label Label of the volume. | 24 * @param {string} label Label of the volume. |
| 25 * @param {(string|undefined)} extensionId Id of the extension providing this | 25 * @param {(string|undefined)} extensionId Id of the extension providing this |
| 26 * volume. Empty for native volumes. | 26 * volume. Empty for native volumes. |
| 27 * @param {boolean} hasMedia When true the volume has been identified | 27 * @param {boolean} hasMedia When true the volume has been identified |
| 28 * as containing media such as photos or videos. | 28 * as containing media such as photos or videos. |
| 29 * @param {boolean} configurable When true, then the volume can be configured. | 29 * @param {boolean} configurable When true, then the volume can be configured. |
| 30 * @param {VolumeManagerCommon.Source} source Source of the volume's data. |
| 30 */ | 31 */ |
| 31 function VolumeInfo( | 32 function VolumeInfo( |
| 32 volumeType, | 33 volumeType, |
| 33 volumeId, | 34 volumeId, |
| 34 fileSystem, | 35 fileSystem, |
| 35 error, | 36 error, |
| 36 deviceType, | 37 deviceType, |
| 37 devicePath, | 38 devicePath, |
| 38 isReadOnly, | 39 isReadOnly, |
| 39 profile, | 40 profile, |
| 40 label, | 41 label, |
| 41 extensionId, | 42 extensionId, |
| 42 hasMedia, | 43 hasMedia, |
| 43 configurable) { | 44 configurable, |
| 45 source) { |
| 44 this.volumeType_ = volumeType; | 46 this.volumeType_ = volumeType; |
| 45 this.volumeId_ = volumeId; | 47 this.volumeId_ = volumeId; |
| 46 this.fileSystem_ = fileSystem; | 48 this.fileSystem_ = fileSystem; |
| 47 this.label_ = label; | 49 this.label_ = label; |
| 48 this.displayRoot_ = null; | 50 this.displayRoot_ = null; |
| 49 | 51 |
| 50 /** @type {Object.<string, !FakeEntry>} */ | 52 /** @type {Object.<string, !FakeEntry>} */ |
| 51 this.fakeEntries_ = {}; | 53 this.fakeEntries_ = {}; |
| 52 | 54 |
| 53 /** @type {Promise.<!DirectoryEntry>} */ | 55 /** @type {Promise.<!DirectoryEntry>} */ |
| (...skipping 22 matching lines...) Expand all Loading... |
| 76 // or not. (If error is empty string, the mount is successfully done). | 78 // or not. (If error is empty string, the mount is successfully done). |
| 77 // TODO(hidehiko): Rename to make this more understandable. | 79 // TODO(hidehiko): Rename to make this more understandable. |
| 78 this.error_ = error; | 80 this.error_ = error; |
| 79 this.deviceType_ = deviceType; | 81 this.deviceType_ = deviceType; |
| 80 this.devicePath_ = devicePath; | 82 this.devicePath_ = devicePath; |
| 81 this.isReadOnly_ = isReadOnly; | 83 this.isReadOnly_ = isReadOnly; |
| 82 this.profile_ = Object.freeze(profile); | 84 this.profile_ = Object.freeze(profile); |
| 83 this.extensionId_ = extensionId; | 85 this.extensionId_ = extensionId; |
| 84 this.hasMedia_ = hasMedia; | 86 this.hasMedia_ = hasMedia; |
| 85 this.configurable_ = configurable; | 87 this.configurable_ = configurable; |
| 88 this.source_ = source; |
| 86 } | 89 } |
| 87 | 90 |
| 88 VolumeInfo.prototype = /** @struct */ { | 91 VolumeInfo.prototype = /** @struct */ { |
| 89 /** | 92 /** |
| 90 * @return {VolumeManagerCommon.VolumeType} Volume type. | 93 * @return {VolumeManagerCommon.VolumeType} Volume type. |
| 91 */ | 94 */ |
| 92 get volumeType() { | 95 get volumeType() { |
| 93 return this.volumeType_; | 96 return this.volumeType_; |
| 94 }, | 97 }, |
| 95 /** | 98 /** |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 * @return {boolean} True if the volume contains media. | 166 * @return {boolean} True if the volume contains media. |
| 164 */ | 167 */ |
| 165 get hasMedia() { | 168 get hasMedia() { |
| 166 return this.hasMedia_; | 169 return this.hasMedia_; |
| 167 }, | 170 }, |
| 168 /** | 171 /** |
| 169 * @return {boolean} True if the volume is configurable. | 172 * @return {boolean} True if the volume is configurable. |
| 170 */ | 173 */ |
| 171 get configurable() { | 174 get configurable() { |
| 172 return this.configurable_; | 175 return this.configurable_; |
| 176 }, |
| 177 /** |
| 178 * @return {VolumeManagerCommon.Source} Source of the volume's data. |
| 179 */ |
| 180 get source() { |
| 181 return this.source_; |
| 173 } | 182 } |
| 174 }; | 183 }; |
| 175 | 184 |
| 176 /** | 185 /** |
| 177 * Starts resolving the display root and obtains it. It may take long time for | 186 * Starts resolving the display root and obtains it. It may take long time for |
| 178 * Drive. Once resolved, it is cached. | 187 * Drive. Once resolved, it is cached. |
| 179 * | 188 * |
| 180 * @param {function(!DirectoryEntry)=} opt_onSuccess Success callback with the | 189 * @param {function(!DirectoryEntry)=} opt_onSuccess Success callback with the |
| 181 * display root directory as an argument. | 190 * display root directory as an argument. |
| 182 * @param {function(*)=} opt_onFailure Failure callback. | 191 * @param {function(*)=} opt_onFailure Failure callback. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 break; | 256 break; |
| 248 default: | 257 default: |
| 249 // TODO(mtomasz): Calculate volumeLabel for all types of volumes in the | 258 // TODO(mtomasz): Calculate volumeLabel for all types of volumes in the |
| 250 // C++ layer. | 259 // C++ layer. |
| 251 localizedLabel = volumeMetadata.volumeLabel || | 260 localizedLabel = volumeMetadata.volumeLabel || |
| 252 volumeMetadata.volumeId.split(':', 2)[1]; | 261 volumeMetadata.volumeId.split(':', 2)[1]; |
| 253 break; | 262 break; |
| 254 } | 263 } |
| 255 | 264 |
| 256 console.debug('Requesting file system.'); | 265 console.debug('Requesting file system.'); |
| 257 var configurable = false; | |
| 258 | |
| 259 return new Promise( | 266 return new Promise( |
| 260 function(resolve, reject) { | 267 function(resolve, reject) { |
| 261 if (volumeMetadata.volumeType !== | 268 chrome.fileSystem.requestFileSystem( |
| 262 VolumeManagerCommon.VolumeType.PROVIDED) { | 269 { |
| 263 resolve(); | 270 volumeId: volumeMetadata.volumeId, |
| 264 } | 271 writable: !volumeMetadata.isReadOnly |
| 265 | 272 }, |
| 266 chrome.fileManagerPrivate.getProvidingExtensions( | 273 function(isolatedFileSystem) { |
| 267 function(extensions) { | 274 if (chrome.runtime.lastError) |
| 268 if (chrome.runtime.lastError) { | |
| 269 reject(chrome.runtime.lastError.message); | 275 reject(chrome.runtime.lastError.message); |
| 270 return; | 276 else |
| 271 } | 277 resolve(isolatedFileSystem); |
| 272 configurable = extensions.some(function(extension) { | |
| 273 return extension.extensionId === volumeMetadata.extensionId && | |
| 274 extension.configurable; | |
| 275 }); | |
| 276 resolve(); | |
| 277 }); | 278 }); |
| 278 }) | 279 }) |
| 279 .then( | 280 .then( |
| 280 function() { | 281 /** |
| 281 return new Promise(function(resolve, reject) { | 282 * @param {!FileSystem} isolatedFileSystem |
| 282 chrome.fileSystem.requestFileSystem( | 283 */ |
| 283 { | 284 function(isolatedFileSystem) { |
| 284 volumeId: volumeMetadata.volumeId, | 285 // Since File System API works on isolated entries only, we need to |
| 285 writable: !volumeMetadata.isReadOnly | 286 // convert it back to external one. |
| 286 }, | 287 // TODO(mtomasz): Make Files app work on isolated entries. |
| 287 function(isolatedFileSystem) { | 288 return new Promise(function(resolve, reject) { |
| 288 if (chrome.runtime.lastError) | 289 chrome.fileManagerPrivate.resolveIsolatedEntries( |
| 289 reject(chrome.runtime.lastError.message); | 290 [isolatedFileSystem.root], |
| 290 else | 291 function(entries) { |
| 291 resolve(isolatedFileSystem); | 292 if (chrome.runtime.lastError) |
| 292 }); | 293 reject(chrome.runtime.lastError.message); |
| 293 }); | 294 else if (!entries[0]) |
| 294 }) | 295 reject('Resolving for external context failed.'); |
| 295 .then( | 296 else |
| 296 /** | 297 resolve(entries[0].filesystem); |
| 297 * @param {!FileSystem} isolatedFileSystem | |
| 298 */ | |
| 299 function(isolatedFileSystem) { | |
| 300 // Since File System API works on isolated entries only, we need to | |
| 301 // convert it back to external one. | |
| 302 // TODO(mtomasz): Make Files app work on isolated entries. | |
| 303 return new Promise(function(resolve, reject) { | |
| 304 chrome.fileManagerPrivate.resolveIsolatedEntries( | |
| 305 [isolatedFileSystem.root], | |
| 306 function(entries) { | |
| 307 if (chrome.runtime.lastError) | |
| 308 reject(chrome.runtime.lastError.message); | |
| 309 else if (!entries[0]) | |
| 310 reject('Resolving for external context failed.'); | |
| 311 else | |
| 312 resolve(entries[0].filesystem); | |
| 313 }); | |
| 314 }); | 298 }); |
| 315 }) | |
| 316 .then( | |
| 317 /** | |
| 318 * @param {!FileSystem} fileSystem | |
| 319 */ | |
| 320 function(fileSystem) { | |
| 321 console.debug('File system obtained: ' + volumeMetadata.volumeId); | |
| 322 if (volumeMetadata.volumeType === | |
| 323 VolumeManagerCommon.VolumeType.DRIVE) { | |
| 324 // After file system is mounted, we "read" drive grand root | |
| 325 // entry at first. This triggers full feed fetch on background. | |
| 326 // Note: we don't need to handle errors here, because even if | |
| 327 // it fails, accessing to some path later will just become | |
| 328 // a fast-fetch and it re-triggers full-feed fetch. | |
| 329 fileSystem.root.createReader().readEntries( | |
| 330 function() { /* do nothing */ }, | |
| 331 function(error) { | |
| 332 console.error( | |
| 333 'Triggering full feed fetch is failed: ' + | |
| 334 error.name); | |
| 335 }); | |
| 336 } | |
| 337 return new VolumeInfo( | |
| 338 /** @type {VolumeManagerCommon.VolumeType} */ | |
| 339 (volumeMetadata.volumeType), | |
| 340 volumeMetadata.volumeId, | |
| 341 fileSystem, | |
| 342 volumeMetadata.mountCondition, | |
| 343 volumeMetadata.deviceType, | |
| 344 volumeMetadata.devicePath, | |
| 345 volumeMetadata.isReadOnly, | |
| 346 volumeMetadata.profile, | |
| 347 localizedLabel, | |
| 348 volumeMetadata.extensionId, | |
| 349 volumeMetadata.hasMedia, | |
| 350 configurable); | |
| 351 }) | |
| 352 .catch( | |
| 353 /** | |
| 354 * @param {*} error | |
| 355 */ | |
| 356 function(error) { | |
| 357 console.error('Failed to mount a file system: ' + | |
| 358 volumeMetadata.volumeId + ' because of: ' + | |
| 359 (error.stack || error)); | |
| 360 return new VolumeInfo( | |
| 361 /** @type {VolumeManagerCommon.VolumeType} */ | |
| 362 (volumeMetadata.volumeType), | |
| 363 volumeMetadata.volumeId, | |
| 364 null, // File system is not found. | |
| 365 volumeMetadata.mountCondition, | |
| 366 volumeMetadata.deviceType, | |
| 367 volumeMetadata.devicePath, | |
| 368 volumeMetadata.isReadOnly, | |
| 369 volumeMetadata.profile, | |
| 370 localizedLabel, | |
| 371 volumeMetadata.extensionId, | |
| 372 volumeMetadata.hasMedia, | |
| 373 configurable); | |
| 374 }); | 299 }); |
| 300 }) |
| 301 .then( |
| 302 /** |
| 303 * @param {!FileSystem} fileSystem |
| 304 */ |
| 305 function(fileSystem) { |
| 306 console.debug('File system obtained: ' + volumeMetadata.volumeId); |
| 307 if (volumeMetadata.volumeType === |
| 308 VolumeManagerCommon.VolumeType.DRIVE) { |
| 309 // After file system is mounted, we "read" drive grand root |
| 310 // entry at first. This triggers full feed fetch on background. |
| 311 // Note: we don't need to handle errors here, because even if |
| 312 // it fails, accessing to some path later will just become |
| 313 // a fast-fetch and it re-triggers full-feed fetch. |
| 314 fileSystem.root.createReader().readEntries( |
| 315 function() { /* do nothing */ }, |
| 316 function(error) { |
| 317 console.error( |
| 318 'Triggering full feed fetch is failed: ' + |
| 319 error.name); |
| 320 }); |
| 321 } |
| 322 return new VolumeInfo( |
| 323 /** @type {VolumeManagerCommon.VolumeType} */ |
| 324 (volumeMetadata.volumeType), |
| 325 volumeMetadata.volumeId, |
| 326 fileSystem, |
| 327 volumeMetadata.mountCondition, |
| 328 volumeMetadata.deviceType, |
| 329 volumeMetadata.devicePath, |
| 330 volumeMetadata.isReadOnly, |
| 331 volumeMetadata.profile, |
| 332 localizedLabel, |
| 333 volumeMetadata.extensionId, |
| 334 volumeMetadata.hasMedia, |
| 335 volumeMetadata.configurable, |
| 336 /** @type {VolumeManagerCommon.Source} */ |
| 337 (volumeMetadata.source)); |
| 338 }) |
| 339 .catch( |
| 340 /** |
| 341 * @param {*} error |
| 342 */ |
| 343 function(error) { |
| 344 console.error('Failed to mount a file system: ' + |
| 345 volumeMetadata.volumeId + ' because of: ' + |
| 346 (error.stack || error)); |
| 347 return new VolumeInfo( |
| 348 /** @type {VolumeManagerCommon.VolumeType} */ |
| 349 (volumeMetadata.volumeType), |
| 350 volumeMetadata.volumeId, |
| 351 null, // File system is not found. |
| 352 volumeMetadata.mountCondition, |
| 353 volumeMetadata.deviceType, |
| 354 volumeMetadata.devicePath, |
| 355 volumeMetadata.isReadOnly, |
| 356 volumeMetadata.profile, |
| 357 localizedLabel, |
| 358 volumeMetadata.extensionId, |
| 359 volumeMetadata.hasMedia, |
| 360 volumeMetadata.configurable, |
| 361 /** @type {VolumeManagerCommon.Source} */ |
| 362 (volumeMetadata.source)); |
| 363 }); |
| 375 }; | 364 }; |
| 376 | 365 |
| 377 /** | 366 /** |
| 378 * The order of the volume list based on root type. | 367 * The order of the volume list based on root type. |
| 379 * @type {Array.<VolumeManagerCommon.VolumeType>} | 368 * @type {Array.<VolumeManagerCommon.VolumeType>} |
| 380 * @const | 369 * @const |
| 381 * @private | 370 * @private |
| 382 */ | 371 */ |
| 383 volumeManagerUtil.volumeListOrder_ = [ | 372 volumeManagerUtil.volumeListOrder_ = [ |
| 384 VolumeManagerCommon.VolumeType.DRIVE, | 373 VolumeManagerCommon.VolumeType.DRIVE, |
| (...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1112 this.isDriveBased; | 1101 this.isDriveBased; |
| 1113 | 1102 |
| 1114 /** | 1103 /** |
| 1115 * Whether the entry is read only or not. | 1104 * Whether the entry is read only or not. |
| 1116 * @type {boolean} | 1105 * @type {boolean} |
| 1117 */ | 1106 */ |
| 1118 this.isReadOnly = isReadOnly; | 1107 this.isReadOnly = isReadOnly; |
| 1119 | 1108 |
| 1120 Object.freeze(this); | 1109 Object.freeze(this); |
| 1121 } | 1110 } |
| OLD | NEW |