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

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

Issue 10310163: Refactoring file manager: moving volume mounting related code to a separate class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 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
OLDNEW
(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 /**
6 * FileManager constructor.
7 *
8 * FileManager objects encapsulate the functionality of the file selector
9 * dialogs, as well as the full screen file manager application (though the
10 * latter is not yet implemented).
11 *
12 * @constructor
13 * @param {HTMLElement} dialogDom The DOM node containing the prototypical
14 * dialog UI.
15 */
16 function VolumeManager() {
17 // The list of archives requested to mount. We will show contents once
18 // archive is mounted, but only for mounts from within this filebrowser tab.
19 this.requests_ = {};
20 this.mountedVolumes_ = {};
21
22 this.initMountPoints_();
23 chrome.fileBrowserPrivate.onMountCompleted.addListener(
24 this.onMountCompleted_.bind(this));
25 this.gDataStatus_ = VolumeManager.GDataStatus.UNMOUNTED;
26 }
27
28 VolumeManager.prototype.__proto__ = cr.EventTarget.prototype;
29
30 VolumeManager.Error = {
31 /* Internal errors */
32 NOT_MOUNTED: 'not_mounted',
33 TIMEOUT: 'timeout',
34
35 /* System events */
36 UNKNOWN: 'error_unknown',
37 INTERNAL: 'error_internal',
38 UNKNOWN_FILESYSTEM: 'error_unknown_filesystem',
39 UNSUPPORTED_FILESYSTEM: 'error_unsuported_filesystem',
40 INVALID_ARCHIVE: 'error_invalid_archive',
41 LIBCROS_MISSING: 'error_libcros_missing',
42 AUTHENTICATION: 'error_authentication',
43 PATH_UNMOUNTED: 'error_path_unmounted'
44 };
45
46 VolumeManager.GDataStatus = {
47 UNMOUNTED: 'unmounted',
48 MOUNTING: 'mounting',
49 ERROR: 'error',
50 MOUNTED: 'mounted'
51 };
52
53 VolumeManager.getInstance = function() {
54 return VolumeManager.instance_ = VolumeManager.instance_ || new VolumeManager( );
55 };
56
57 VolumeManager.prototype.setGDataStatus_ = function(newStatus) {
58 if (this.gDataStatus_ != newStatus) {
59 this.gDataStatus_ = newStatus;
60 cr.dispatchSimpleEvent(this, 'gdata-status-changed');
61 }
62 };
63
64 VolumeManager.prototype.getGDataStatus = function() {
65 return this.gDataStatus_;
66 };
67
68 VolumeManager.prototype.isMounted = function(mountPath) {
69 return mountPath in this.mountedVolumes_;
70 };
71
72 VolumeManager.prototype.initMountPoints_ = function() {
73 var mountedVolumes = {};
74 var self = this;
75 var index = 0;
76 var gDataMounted = false;
77 function step(mountPoints) {
78 if (index < mountPoints.length) {
79 var info = mountPoints[index];
80 if (info.mountType == 'gdata')
81 gDataMounted = true;
82 self.makeVolumeInfo_('/' + info.mountPath, info.mountCondition,
83 function(volume) {
84 mountedVolumes[volume.mountPath] = volume;
85 index++;
86 step(mountPoints);
87 });
88 } else {
89 self.mountedVolumes_ = mountedVolumes;
90 // Do not change ERROR status if gData is not mounted.
91 if (self.getGDataStatus() != VolumeManager.GDataStatus.ERROR &&
92 !gDataMounted) {
93 self.setGDataStatus_(gDataMounted ?
94 VolumeManager.GDataStatus.MOUNTED :
95 VolumeManager.GDataStatus.UNMOUNTED);
96 }
97 }
98 }
99
100 chrome.fileBrowserPrivate.getMountPoints(step);
101 };
102
103 /**
104 * Event handler called when some volume was mounted or unmouted.
105 */
106 VolumeManager.prototype.onMountCompleted_ = function(event) {
107 if (event.eventType == 'mount') {
108 if (event.mountPath) {
109 var requestKey = this.makeRequestKey_('mount', event.mountType, event.sour cePath);
110 this.makeVolumeInfo_(event.mountPath, event.status, function(volume) {
111 this.mountedVolumes_[volume.mountPath] = volume;
112 this.finishRequest_(requestKey, event.status, event.mountPath);
113 this.notifyChange_();
114 }.bind(this));
115 } else {
116 console.log('No mount path');
117 this.finishRequest_(requestKey, event.status);
118 }
119 } else if (event.eventType == 'unmount') {
120 var mountPath = '/' + event.mountPath;
121 var status = event.status;
122 if (status == VolumeManager.Error.PATH_UNMOUNTED) {
123 console.log('Volume already unmounted: ', mountPath);
124 status = 'success';
125 }
126 this.finishRequest_(this.makeRequestKey_('mount', '', mountPath), status);
127
128 if (event.status == 'success') {
129 delete this.mountedVolumes_[mountPath];
130 this.notifyChange_();
131 }
132 }
133
134 if (event.mountType == 'gdata') {
135 if (event.status == 'success') {
136 if (event.eventType == 'mount')
137 this.setGDataStatus_(VolumeManager.GDataStatus.MOUNTED);
138 else if (event.eventType == 'unmount' && event.status == 'success')
139 this.setGDataStatus_(VolumeManager.GDataStatus.UMOUNTED);
140 }
141 }
142 };
143
144 VolumeManager.prototype.makeVolumeInfo_ = function(
145 mountPath, status, callback) {
146 chrome.fileBrowserPrivate.getVolumeMetadata(this.makeUrl_(mountPath),
147 function(metadata) {
148 callback({
149 mountPath: mountPath,
150 status: status,
151 readonly: !!metadata && metadata.isReadOnly
152 });
153 }.bind(this));
154 };
155
156 /**
157 * @param {string} requestType 'mount' | 'unmount'
158 * @param {string} mountType 'device' | 'file' | 'network' | 'gdata'.
159 * @param {string?} opt_sourcePath
160 */
161 VolumeManager.prototype.makeRequestKey_ = function(requestType, mountType, opt_m ountPath) {
162 return requestType + ':' + mountType + ':' + (opt_mountPath || '');
163 };
164
165 VolumeManager.prototype.mountGData = function(successCallback, errorCallback) {
166 if (this.getGDataStatus() == VolumeManager.GDataStatus.ERROR) {
167 this.setGDataStatus_(VolumeManager.GDataStatus.UNMOUNTED);
168 }
169 var self = this;
170 var timeout = setTimeout(function() {
171 if (self.getGDataStatus() == VolumeManager.GDataStatus.UNMOUNTED)
172 self.setGDataStatus_(VolumeManager.GDataStatus.MOUNTING);
173 timeout = null;
174 }, 500);
175 this.mount_('', 'gdata', function(mountPath) {
176 if (timeout !== null)
177 clearTimeout(timeout);
178 successCallback(mountPath);
179 }, function(error) {
180 if (self.getGDataStatus() != VolumeManager.GDataStatus.MOUNTED)
181 self.setGDataStatus_(VolumeManager.GDataStatus.ERROR);
182 if (timeout != null)
183 clearTimeout(timeout);
184 errorCallback(error);
185 });
186 };
187
188 VolumeManager.prototype.getMountCondition = function(mountPath) {
189 return this.getVolumeInfo_(mountPath).status;
190 };
191
192 VolumeManager.prototype.isReadOnly = function(mountPath) {
193 return this.getVolumeInfo_(mountPath).readonly;
194 };
195
196 VolumeManager.prototype.getVolumeInfo_ = function(mountPath) {
197 return this.mountedVolumes_[mountPath] || {};
198 };
199
200 /**
201 * Unmounts device.
202 * @param {Entry} entry The entry to unmount.
203 */
204 VolumeManager.prototype.unmount = function(mountPath, successCallback, errorCall back) {
205 var volumeInfo = this.mountedVolumes_[mountPath];
206 if (!volumeInfo) {
207 errorCallback(VolumeManager.Error.NOT_NOUNTED);
208 return;
209 }
210
211 chrome.fileBrowserPrivate.removeMount(this.makeUrl_(mountPath));
212 this.startRequest_(this.makeRequestKey_('unmount', '', mountPath));
213 };
214
215 VolumeManager.prototype.mountArchive = function(fullPath, successCallback,
216 errorCallback) {
217 var requestKey = this.makeRequestKey_('mount', 'file');
218 if (requestKey in this.requests_) {
219 // Parallel requests are not supported. API doesn't provide a way
220 // to find request for specific response.
221 errorCallback('inprogress');
222 return;
223 }
224 this.mount_(this.makeUrl_(fullPath),
225 'file', successCallback, errorCallback);
226 };
227
228 VolumeManager.prototype.makeUrl_ = function(path) {
229 return 'filesystem:' + chrome.extension.getURL('external' + path);
230 };
231
232 VolumeManager.prototype.mount_ = function(url, mountType,
233 successCallback, errorCallback) {
234 console.log('mount ', url, mountType);
235 chrome.fileBrowserPrivate.addMount(url, mountType, {},
236 function(sourcePath) {
237 var requestKey = this.makeRequestKey_('mount', mountType, sourcePath);
238 this.startRequest_(requestKey, successCallback, errorCallback);
239 }.bind(this));
240 };
241
242 VolumeManager.prototype.startRequest_ = function(key,
243 successCallback, errorCallback) {
244 console.log('Start request: ', key);
245 if (key in this.requests_) {
246 var request = this.requests_[key];
247 request.successCallbacks.push(successCallback);
248 request.errorCallbacks.push(errorCallback);
249 } else {
250 this.requests_[key] = {
251 successCallbacks: [successCallback],
252 errorCallbacks: [errorCallback],
253
254 timeout: setTimeout(this.onTimeout_.bind(this, key), 10000)
255 };
256 }
257 };
258
259 VolumeManager.prototype.onTimeout_ = function(key) {
260 this.invokeRequestCallbacks_(this.requests_[key],
261 VolumeManager.Error.TIMEOUT);
262 delete this.requests_[key];
263 };
264
265 VolumeManager.prototype.finishRequest_ = function(key, status, opt_mountPath) {
266 var request = this.requests_[key];
267 if (!request)
268 return;
269
270 clearTimeout(request.timeout);
271 this.invokeRequestCallbacks_(request, status, opt_mountPath);
272 delete this.requests_[key];
273 }
274
275 VolumeManager.prototype.invokeRequestCallbacks_= function(request, status,
276 opt_mountPath) {
277 function callEach(callbacks, self, args) {
278 for (var i = 0; i < callbacks.length; i++) {
279 callbacks[i].call(self, args);
280 }
281 }
282 if (status == 'success')
283 callEach(request.successCallbacks, this, [opt_mountPath]);
284 else
285 callEach(request.errorCallbacks, this, [status]);
286 };
287
288 VolumeManager.prototype.notifyChange_ = function() {
289 cr.dispatchSimpleEvent(this, 'change');
290 };
291
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698