| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 * Utilities for FileOperationManager. | 8 * Utilities for FileOperationManager. |
| 9 */ | 9 */ |
| 10 var fileOperationUtil = {}; | 10 var fileOperationUtil = {}; |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 }); | 291 }); |
| 292 }; | 292 }; |
| 293 | 293 |
| 294 /** | 294 /** |
| 295 * @constructor | 295 * @constructor |
| 296 */ | 296 */ |
| 297 function FileOperationManager() { | 297 function FileOperationManager() { |
| 298 this.copyTasks_ = []; | 298 this.copyTasks_ = []; |
| 299 this.deleteTasks_ = []; | 299 this.deleteTasks_ = []; |
| 300 this.taskIdCounter_ = 0; | 300 this.taskIdCounter_ = 0; |
| 301 | |
| 302 this.eventRouter_ = new FileOperationManager.EventRouter(); | 301 this.eventRouter_ = new FileOperationManager.EventRouter(); |
| 303 | 302 |
| 304 Object.seal(this); | 303 Object.seal(this); |
| 305 } | 304 } |
| 306 | 305 |
| 307 /** | 306 /** |
| 308 * Get FileOperationManager instance. In case is hasn't been initialized, a new | 307 * Get FileOperationManager instance. In case is hasn't been initialized, a new |
| 309 * instance is created. | 308 * instance is created. |
| 310 * | 309 * |
| 311 * @return {FileOperationManager} A FileOperationManager instance. | 310 * @return {FileOperationManager} A FileOperationManager instance. |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 entry.processedBytes = 0; | 573 entry.processedBytes = 0; |
| 575 resolvedEntryMap[entry.toURL()] = entry; | 574 resolvedEntryMap[entry.toURL()] = entry; |
| 576 } | 575 } |
| 577 this.processingEntries[index] = resolvedEntryMap; | 576 this.processingEntries[index] = resolvedEntryMap; |
| 578 callback(); | 577 callback(); |
| 579 }.bind(this), | 578 }.bind(this), |
| 580 function(error) { | 579 function(error) { |
| 581 console.error( | 580 console.error( |
| 582 'Failed to resolve for copy: %s', | 581 'Failed to resolve for copy: %s', |
| 583 util.getFileErrorMnemonic(error.code)); | 582 util.getFileErrorMnemonic(error.code)); |
| 583 callback(); |
| 584 }); | 584 }); |
| 585 }.bind(this, i)); | 585 }.bind(this, i)); |
| 586 } | 586 } |
| 587 | 587 |
| 588 group.run(function() { | 588 group.run(function() { |
| 589 // Fill totalBytes. | 589 // Fill totalBytes. |
| 590 this.totalBytes = 0; | 590 this.totalBytes = 0; |
| 591 for (var i = 0; i < this.processingEntries.length; i++) { | 591 for (var i = 0; i < this.processingEntries.length; i++) { |
| 592 for (var entryURL in this.processingEntries[i]) | 592 for (var entryURL in this.processingEntries[i]) |
| 593 this.totalBytes += this.processingEntries[i][entryURL].size; | 593 this.totalBytes += this.processingEntries[i][entryURL].size; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 var group = new AsyncUtil.Group(); | 901 var group = new AsyncUtil.Group(); |
| 902 for (var i = 0; i < this.sourceEntries.length; i++) { | 902 for (var i = 0; i < this.sourceEntries.length; i++) { |
| 903 group.add(function(index, callback) { | 903 group.add(function(index, callback) { |
| 904 fileOperationUtil.resolveRecursively( | 904 fileOperationUtil.resolveRecursively( |
| 905 this.sourceEntries[index], | 905 this.sourceEntries[index], |
| 906 function(entries) { | 906 function(entries) { |
| 907 for (var j = 0; j < entries.length; j++) | 907 for (var j = 0; j < entries.length; j++) |
| 908 resolvedEntryMap[entries[j].toURL()] = entries[j]; | 908 resolvedEntryMap[entries[j].toURL()] = entries[j]; |
| 909 callback(); | 909 callback(); |
| 910 }, | 910 }, |
| 911 function(error) {}); | 911 callback); |
| 912 }.bind(this, i)); | 912 }.bind(this, i)); |
| 913 } | 913 } |
| 914 | 914 |
| 915 group.run(function() { | 915 group.run(function() { |
| 916 // For zip archiving, all the entries are processed at once. | 916 // For zip archiving, all the entries are processed at once. |
| 917 this.processingEntries = [resolvedEntryMap]; | 917 this.processingEntries = [resolvedEntryMap]; |
| 918 | 918 |
| 919 this.totalBytes = 0; | 919 this.totalBytes = 0; |
| 920 for (var url in resolvedEntryMap) | 920 for (var url in resolvedEntryMap) |
| 921 this.totalBytes += resolvedEntryMap[url].size; | 921 this.totalBytes += resolvedEntryMap[url].size; |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 // Do nothing, if we have no entries to be pasted. | 1158 // Do nothing, if we have no entries to be pasted. |
| 1159 if (filteredEntries.length === 0) | 1159 if (filteredEntries.length === 0) |
| 1160 return; | 1160 return; |
| 1161 | 1161 |
| 1162 this.queueCopy_(targetEntry, filteredEntries, isMove); | 1162 this.queueCopy_(targetEntry, filteredEntries, isMove); |
| 1163 }.bind(this)); | 1163 }.bind(this)); |
| 1164 }; | 1164 }; |
| 1165 | 1165 |
| 1166 /** | 1166 /** |
| 1167 * Checks if the move operation is available between the given two locations. | 1167 * Checks if the move operation is available between the given two locations. |
| 1168 * This method uses the volume manager, which is lazily created, therefore the |
| 1169 * result is returned asynchronously. |
| 1168 * | 1170 * |
| 1169 * @param {DirectoryEntry} sourceEntry An entry from the source. | 1171 * @param {DirectoryEntry} sourceEntry An entry from the source. |
| 1170 * @param {DirectoryEntry} targetDirEntry Directory entry for the target. | 1172 * @param {DirectoryEntry} targetDirEntry Directory entry for the target. |
| 1171 * @return {boolean} Whether we can move from the source to the target. | 1173 * @param {function(boolean)} callback Callback with result whether the entries |
| 1174 * can be directly moved. |
| 1175 * @private |
| 1172 */ | 1176 */ |
| 1173 FileOperationManager.prototype.isMovable = function( | 1177 FileOperationManager.prototype.isMovable_ = function( |
| 1174 sourceEntry, targetDirEntry) { | 1178 sourceEntry, targetDirEntry, callback) { |
| 1175 var sourceLocationInfo = this.volumeManager_.getLocationInfo(sourceEntry); | 1179 VolumeManager.getInstance(function(volumeManager) { |
| 1176 var targetDirLocationInfo = this.volumeManager_.getLocationInfo( | 1180 var sourceLocationInfo = volumeManager.getLocationInfo(sourceEntry); |
| 1177 targetDirEntry); | 1181 var targetDirLocationInfo = volumeManager.getLocationInfo(targetDirEntry); |
| 1178 | 1182 callback( |
| 1179 return sourceLocationInfo && targetDirLocationInfo && | 1183 sourceLocationInfo && targetDirLocationInfo && |
| 1180 sourceLocationInfo.volumeInfo === targetDirLocationInfo.volumeInfo; | 1184 sourceLocationInfo.volumeInfo === targetDirLocationInfo.volumeInfo); |
| 1185 }); |
| 1181 }; | 1186 }; |
| 1182 | 1187 |
| 1183 /** | 1188 /** |
| 1184 * Initiate a file copy. | 1189 * Initiate a file copy. When copying files, null can be specified as source |
| 1190 * directory. |
| 1185 * | 1191 * |
| 1186 * @param {DirectoryEntry} targetDirEntry Target directory. | 1192 * @param {DirectoryEntry} targetDirEntry Target directory. |
| 1187 * @param {Array.<Entry>} entries Entries to copy. | 1193 * @param {Array.<Entry>} entries Entries to copy. |
| 1188 * @param {boolean} isMove In case of move. | 1194 * @param {boolean} isMove In case of move. |
| 1189 * @return {FileOperationManager.Task} Copy task. | |
| 1190 * @private | 1195 * @private |
| 1191 */ | 1196 */ |
| 1192 FileOperationManager.prototype.queueCopy_ = function( | 1197 FileOperationManager.prototype.queueCopy_ = function( |
| 1193 targetDirEntry, entries, isMove) { | 1198 targetDirEntry, entries, isMove) { |
| 1194 // When copying files, null can be specified as source directory. | 1199 var createTask = function(task) { |
| 1200 task.taskId = this.generateTaskId_(); |
| 1201 task.initialize(function() { |
| 1202 this.copyTasks_.push(task); |
| 1203 this.eventRouter_.sendProgressEvent( |
| 1204 'BEGIN', task.getStatus(), task.taskId); |
| 1205 if (this.copyTasks_.length === 1) |
| 1206 this.serviceAllTasks_(); |
| 1207 }.bind(this)); |
| 1208 }.bind(this); |
| 1209 |
| 1195 var task; | 1210 var task; |
| 1196 if (isMove) { | 1211 if (isMove) { |
| 1197 if (this.isMovable(entries[0], targetDirEntry)) { | 1212 // When moving between different volumes, moving is implemented as a copy |
| 1198 task = new FileOperationManager.MoveTask(entries, targetDirEntry); | 1213 // and delete. This is because moving between volumes is slow, and moveTo() |
| 1199 } else { | 1214 // is not cancellable nor provides progress feedback. |
| 1200 task = new FileOperationManager.CopyTask(entries, targetDirEntry); | 1215 this.isMovable_(entries[0], targetDirEntry, function(isMovable) { |
| 1201 task.deleteAfterCopy = true; | 1216 if (isMovable) { |
| 1202 } | 1217 createTask(new FileOperationManager.MoveTask(entries, targetDirEntry)); |
| 1218 } else { |
| 1219 var task = new FileOperationManager.CopyTask(entries, targetDirEntry); |
| 1220 task.deleteAfterCopy = true; |
| 1221 createTask(task); |
| 1222 } |
| 1223 }); |
| 1203 } else { | 1224 } else { |
| 1204 task = new FileOperationManager.CopyTask(entries, targetDirEntry); | 1225 createTask(new FileOperationManager.CopyTask(entries, targetDirEntry)); |
| 1205 } | 1226 } |
| 1206 | |
| 1207 task.taskId = this.generateTaskId_(); | |
| 1208 task.initialize(function() { | |
| 1209 this.copyTasks_.push(task); | |
| 1210 this.eventRouter_.sendProgressEvent('BEGIN', task.getStatus(), task.taskId); | |
| 1211 if (this.copyTasks_.length == 1) | |
| 1212 this.serviceAllTasks_(); | |
| 1213 }.bind(this)); | |
| 1214 | |
| 1215 return task; | |
| 1216 }; | 1227 }; |
| 1217 | 1228 |
| 1218 /** | 1229 /** |
| 1219 * Service all pending tasks, as well as any that might appear during the | 1230 * Service all pending tasks, as well as any that might appear during the |
| 1220 * copy. | 1231 * copy. |
| 1221 * | 1232 * |
| 1222 * @private | 1233 * @private |
| 1223 */ | 1234 */ |
| 1224 FileOperationManager.prototype.serviceAllTasks_ = function() { | 1235 FileOperationManager.prototype.serviceAllTasks_ = function() { |
| 1225 if (!this.copyTasks_.length) { | 1236 if (!this.copyTasks_.length) { |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1407 | 1418 |
| 1408 /** | 1419 /** |
| 1409 * Generates new task ID. | 1420 * Generates new task ID. |
| 1410 * | 1421 * |
| 1411 * @return {string} New task ID. | 1422 * @return {string} New task ID. |
| 1412 * @private | 1423 * @private |
| 1413 */ | 1424 */ |
| 1414 FileOperationManager.prototype.generateTaskId_ = function() { | 1425 FileOperationManager.prototype.generateTaskId_ = function() { |
| 1415 return 'file-operation-' + this.taskIdCounter_++; | 1426 return 'file-operation-' + this.taskIdCounter_++; |
| 1416 }; | 1427 }; |
| OLD | NEW |