Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(475)

Side by Side Diff: chrome/browser/resources/file_manager/js/file_copy_manager.js

Issue 22373002: Extract copy operation related to Drive to fileOperationUtil. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 'use strict'; 5 'use strict';
6 6
7 /** 7 /**
8 * Utilities for FileCopyManager. 8 * Utilities for FileCopyManager.
9 */ 9 */
10 var fileOperationUtil = {}; 10 var fileOperationUtil = {};
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 * Sets last modified date to the entry. 49 * Sets last modified date to the entry.
50 * @param {Entry} entry The entry to which the last modified is set. 50 * @param {Entry} entry The entry to which the last modified is set.
51 * @param {Date} modificationTime The last modified time. 51 * @param {Date} modificationTime The last modified time.
52 */ 52 */
53 fileOperationUtil.setLastModified = function(entry, modificationTime) { 53 fileOperationUtil.setLastModified = function(entry, modificationTime) {
54 chrome.fileBrowserPrivate.setLastModified( 54 chrome.fileBrowserPrivate.setLastModified(
55 entry.toURL(), '' + Math.round(modificationTime.getTime() / 1000)); 55 entry.toURL(), '' + Math.round(modificationTime.getTime() / 1000));
56 }; 56 };
57 57
58 /** 58 /**
59 * Copies a file a) from Drive to local, b) from local to Drive, or c) from
60 * Drive to Drive.
61 * Currently, we need to take care about following two things for Drive:
62 *
63 * 1) Copying hosted document.
64 * In theory, it is impossible to actual copy a hosted document to other
65 * file system. Thus, instead, Drive file system backend creates a JSON file
66 * referring to the hosted document. Also, when it is uploaded by copyTo,
67 * the hosted document is copied on the server. Note that, this doesn't work
68 * when a user creates a file by FileWriter (as copyFileEntry_ does).
69 *
70 * 2) File transfer between local and Drive server.
71 * There are two directions of file transfer; from local to Drive and from
72 * Drive to local.
73 * The file transfer from local to Drive is done as a part of file system
74 * background sync (kicked after the copy operation is done). So we don't need
75 * to take care about it here. To copy the file from Drive to local (or Drive
76 * to Drive with GData WAPI), we need to download the file content (if it is
77 * not locally cached). During the downloading, we can listen the periodical
78 * updating and cancel the downloding via private API.
79 *
80 * This function supports progress updating and cancelling partially.
81 * Unfortunately, FileEntry.copyTo doesn't support progress updating nor
82 * cancelling, so we support them only during file downloading.
83 *
84 * Note: we're planning to move copyTo logic into c++ side. crbug.com/261492
85 *
86 * @param {FileEntry} source The entry of the file to be copied.
87 * @param {DirectoryEntry} parent The entry of the destination directory.
88 * @param {string} newName The name of the copied file.
89 * @param {function(FileEntry, number)} progressCallback Callback periodically
90 * invoked during file transfer with the source and the number of
91 * transferred bytes from the last call.
92 * @param {function(FileEntry)} successCallback Callback invoked when the
93 * file copy is successfully done with the entry of the copied file.
94 * @param {function(FileError)} errorCallback Callback invoked when an error
95 * is found.
96 * @return {function()} Callback to cancel the current file copy operation.
97 * When the cancel is done, errorCallback will be called. The returned
98 * callback must not be called more than once.
99 */
100 fileOperationUtil.copyFileOnDrive = function(
101 source, parent, newName, progressCallback, successCallback, errorCallback) {
102 // Set to true when cancel is requested.
103 var cancelRequested = false;
104 var cancelCallback = null;
105
106 var onCopyToCompleted = null;
107
108 // Progress callback.
109 // Because the uploading the file from local cache to Drive server will be
110 // done as a part of background Drive file system sync, so for this copy
111 // operation, what we need to take care about is only file downloading.
112 var numTransferredBytes = 0;
113 if (PathUtil.isDriveBasedPath(source.fullPath)) {
114 var sourceUrl = source.toURL();
115 var sourcePath = util.extractFilePath(sourceUrl);
116 var onFileTransfersUpdated = function(statusList) {
117 for (var i = 0; i < statusList.length; i++) {
118 var status = statusList[i];
119
120 // Comparing urls is unreliable, since they may use different
121 // url encoding schemes (eg. rfc2396 vs. rfc3986).
122 var filePath = util.extractFilePath(status.fileUrl);
123 if (filePath == sourcePath) {
124 var processed = status.processed;
125 if (processed > numTransferredBytes) {
126 progressCallback(source, processed - numTransferredBytes);
127 numTransferredBytes = processed;
128 }
129 return;
130 }
131 }
132 };
133
134 // Subscribe to listen file transfer updating notifications.
135 chrome.fileBrowserPrivate.onFileTransfersUpdated.addListener(
136 onFileTransfersUpdated);
137
138 // Currently, we do NOT upload the file during the copy operation.
139 // It will be done as a part of file system sync after copy operation.
140 // So, we can cancel only file downloading.
141 cancelCallback = function() {
142 chrome.fileBrowserPrivate.cancelFileTransfers(
143 [sourceUrl], function() {});
144 };
145
146 // We need to clean up on copyTo completion regardless if it is
147 // successfully done or not.
148 onCopyToCompleted = function() {
149 cancelCallback = null;
150 chrome.fileBrowserPrivate.onFileTransfersUpdated.removeListener(
151 onFileTransfersUpdated);
152 };
153 }
154
155 source.copyTo(
156 parent, newName,
157 function(entry) {
158 if (onCopyToCompleted)
159 onCopyToCompleted();
160
161 if (cancelRequested) {
162 errorCallback(util.createFileError(FileError.ABORT_ERR));
163 return;
164 }
165
166 entry.getMetadata(function(metadata) {
167 if (metadata.size > numTransferredBytes)
168 progressCallback(source, metadata.size - numTransferredBytes);
169 successCallback(entry);
170 }, errorCallback);
171 },
172 function(error) {
173 if (onCopyToCompleted)
174 onCopyToCompleted();
175
176 errorCallback(error);
177 });
178
179 return function() {
180 cancelRequested = true;
181 if (cancelCallback) {
182 cancelCallback();
183 cancelCallback = null;
184 }
185 };
186 };
187
188 /**
59 * Thin wrapper of chrome.fileBrowserPrivate.zipSelection to adapt its 189 * Thin wrapper of chrome.fileBrowserPrivate.zipSelection to adapt its
60 * interface similar to copyTo(). 190 * interface similar to copyTo().
61 * 191 *
62 * @param {Array.<Entry>} sources The array of entries to be archived. 192 * @param {Array.<Entry>} sources The array of entries to be archived.
63 * @param {DirectoryEntry} parent The entry of the destination directory. 193 * @param {DirectoryEntry} parent The entry of the destination directory.
64 * @param {string} newName The name of the archive to be created. 194 * @param {string} newName The name of the archive to be created.
65 * @param {function(FileEntry)} successCallback Callback invoked when the 195 * @param {function(FileEntry)} successCallback Callback invoked when the
66 * operation is successfully done with the entry of the created archive. 196 * operation is successfully done with the entry of the created archive.
67 * @param {function(FileError)} errorCallback Callback invoked when an error 197 * @param {function(FileError)} errorCallback Callback invoked when an error
68 * is found. 198 * is found.
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 onCopyComplete(entry, size); 1074 onCopyComplete(entry, size);
945 }, 1075 },
946 function(error) { 1076 function(error) {
947 self.cancelCallback_ = null; 1077 self.cancelCallback_ = null;
948 onFilesystemError(error); 1078 onFilesystemError(error);
949 }); 1079 });
950 }, 1080 },
951 util.flog('Error getting file: ' + targetRelativePath, 1081 util.flog('Error getting file: ' + targetRelativePath,
952 onFilesystemError)); 1082 onFilesystemError));
953 return; 1083 return;
1084 } else {
1085 // Sending a file from a) Drive to Drive, b) Drive to local or c) local
1086 // to Drive.
1087 targetDirEntry.getDirectory(
1088 PathUtil.dirname(targetRelativePath), {create: false},
1089 function(dirEntry) {
1090 self.cancelCallback_ = fileOperationUtil.copyFileOnDrive(
1091 sourceEntry, dirEntry, PathUtil.basename(targetRelativePath),
1092 onCopyProgress,
1093 function(entry) {
1094 self.cancelCallback_ = null;
1095 onCopyComplete(entry, 0);
1096 },
1097 function(error) {
1098 self.cancelCallback_ = null;
1099 onFilesystemError(error);
1100 });
1101 },
1102 onFilesystemError);
954 } 1103 }
955
956 // TODO(hidehiko): Move following code to fileOperationUtil.
957
958 // Sending a file from a) Drive to Drive, b) Drive to local or c) local to
959 // Drive.
960 var sourceFileUrl = sourceEntry.toURL();
961 var sourceFilePath = util.extractFilePath(sourceFileUrl);
962
963 // Progress callback.
964 // Because the uploading the file from local cache to Drive server will be
965 // done as a part of background Drive file system sync, so for this copy
966 // operation, what we need to take care about is only file downloading.
967 var numTransferredBytes = 0;
968 var onFileTransfersUpdated = null;
969 if (isSourceOnDrive) {
970 onFileTransfersUpdated = function(statusList) {
971 for (var i = 0; i < statusList.length; i++) {
972 var status = statusList[i];
973
974 // Comparing urls is unreliable, since they may use different
975 // url encoding schemes (eg. rfc2396 vs. rfc3986).
976 var filePath = util.extractFilePath(status.fileUrl);
977 if (filePath == sourceFilePath) {
978 var processed = status.processed;
979 if (processed > numTransferredBytes) {
980 onCopyProgress(sourceEntry, processed - numTransferredBytes);
981 numTransferredBytes = processed;
982 }
983 return;
984 }
985 }
986 };
987
988 // Currently, we do NOT upload the file during the copy operation.
989 // It will be done as a part of file system sync after copy operation.
990 // So, we can cancel only file downloading.
991 self.cancelCallback_ = function() {
992 self.cancelCallback_ = null;
993 chrome.fileBrowserPrivate.cancelFileTransfers(
994 [sourceFileUrl], function() {});
995 };
996 }
997
998 // If this is the copy operation from Drive file system,
999 // we use copyTo method.
1000 targetDirEntry.getDirectory(
1001 PathUtil.dirname(targetRelativePath), {create: false},
1002 function(dirEntry) {
1003 if (onFileTransfersUpdated)
1004 chrome.fileBrowserPrivate.onFileTransfersUpdated
1005 .addListener(onFileTransfersUpdated);
1006
1007 sourceEntry.copyTo(
1008 dirEntry, PathUtil.basename(targetRelativePath),
1009 function(entry) {
1010 self.cancelCallback_ = null;
1011 if (onFileTransfersUpdated)
1012 chrome.fileBrowserPrivate.onFileTransfersUpdated
1013 .removeListener(onFileTransfersUpdated);
1014
1015 entry.getMetadata(function(metadata) {
1016 if (metadata.size > numTransferredBytes)
1017 onCopyProgress(
1018 sourceEntry, metadata.size - numTransferredBytes);
1019 onCopyComplete(entry, 0);
1020 });
1021 },
1022 function(error) {
1023 self.cancelCallback_ = null;
1024 chrome.fileBrowserPrivate.onFileTransfersUpdated.removeListener(
1025 onFileTransfersUpdated);
1026 onFilesystemError(error);
1027 });
1028 },
1029 onFilesystemError);
1030 }; 1104 };
1031 1105
1032 fileOperationUtil.deduplicatePath( 1106 fileOperationUtil.deduplicatePath(
1033 targetDirEntry, originalPath, onDeduplicated, errorCallback); 1107 targetDirEntry, originalPath, onDeduplicated, errorCallback);
1034 }; 1108 };
1035 1109
1036 /** 1110 /**
1037 * Copies the contents of sourceEntry into targetEntry. 1111 * Copies the contents of sourceEntry into targetEntry.
1038 * TODO(hidehiko): Move this method into fileOperationUtil. 1112 * TODO(hidehiko): Move this method into fileOperationUtil.
1039 * 1113 *
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1416 // Assume self.cancelRequested_ == false. 1490 // Assume self.cancelRequested_ == false.
1417 // This moved us from 0 to 1 active tasks, let the servicing begin! 1491 // This moved us from 0 to 1 active tasks, let the servicing begin!
1418 self.serviceAllTasks_(); 1492 self.serviceAllTasks_();
1419 } else { 1493 } else {
1420 // Force to update the progress of butter bar when there are new tasks 1494 // Force to update the progress of butter bar when there are new tasks
1421 // coming while servicing current task. 1495 // coming while servicing current task.
1422 self.eventRouter_.sendProgressEvent('PROGRESS', self.getStatus()); 1496 self.eventRouter_.sendProgressEvent('PROGRESS', self.getStatus());
1423 } 1497 }
1424 }); 1498 });
1425 }; 1499 };
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698