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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/file_manager/js/volume_manager.js
diff --git a/chrome/browser/resources/file_manager/js/volume_manager.js b/chrome/browser/resources/file_manager/js/volume_manager.js
new file mode 100644
index 0000000000000000000000000000000000000000..76734af698f064211614b0d500d3909f8aa6cead
--- /dev/null
+++ b/chrome/browser/resources/file_manager/js/volume_manager.js
@@ -0,0 +1,291 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * FileManager constructor.
+ *
+ * FileManager objects encapsulate the functionality of the file selector
+ * dialogs, as well as the full screen file manager application (though the
+ * latter is not yet implemented).
+ *
+ * @constructor
+ * @param {HTMLElement} dialogDom The DOM node containing the prototypical
+ * dialog UI.
+ */
+function VolumeManager() {
+ // The list of archives requested to mount. We will show contents once
+ // archive is mounted, but only for mounts from within this filebrowser tab.
+ this.requests_ = {};
+ this.mountedVolumes_ = {};
+
+ this.initMountPoints_();
+ chrome.fileBrowserPrivate.onMountCompleted.addListener(
+ this.onMountCompleted_.bind(this));
+ this.gDataStatus_ = VolumeManager.GDataStatus.UNMOUNTED;
+}
+
+VolumeManager.prototype.__proto__ = cr.EventTarget.prototype;
+
+VolumeManager.Error = {
+ /* Internal errors */
+ NOT_MOUNTED: 'not_mounted',
+ TIMEOUT: 'timeout',
+
+ /* System events */
+ UNKNOWN: 'error_unknown',
+ INTERNAL: 'error_internal',
+ UNKNOWN_FILESYSTEM: 'error_unknown_filesystem',
+ UNSUPPORTED_FILESYSTEM: 'error_unsuported_filesystem',
+ INVALID_ARCHIVE: 'error_invalid_archive',
+ LIBCROS_MISSING: 'error_libcros_missing',
+ AUTHENTICATION: 'error_authentication',
+ PATH_UNMOUNTED: 'error_path_unmounted'
+};
+
+VolumeManager.GDataStatus = {
+ UNMOUNTED: 'unmounted',
+ MOUNTING: 'mounting',
+ ERROR: 'error',
+ MOUNTED: 'mounted'
+};
+
+VolumeManager.getInstance = function() {
+ return VolumeManager.instance_ = VolumeManager.instance_ || new VolumeManager();
+};
+
+VolumeManager.prototype.setGDataStatus_ = function(newStatus) {
+ if (this.gDataStatus_ != newStatus) {
+ this.gDataStatus_ = newStatus;
+ cr.dispatchSimpleEvent(this, 'gdata-status-changed');
+ }
+};
+
+VolumeManager.prototype.getGDataStatus = function() {
+ return this.gDataStatus_;
+};
+
+VolumeManager.prototype.isMounted = function(mountPath) {
+ return mountPath in this.mountedVolumes_;
+};
+
+VolumeManager.prototype.initMountPoints_ = function() {
+ var mountedVolumes = {};
+ var self = this;
+ var index = 0;
+ var gDataMounted = false;
+ function step(mountPoints) {
+ if (index < mountPoints.length) {
+ var info = mountPoints[index];
+ if (info.mountType == 'gdata')
+ gDataMounted = true;
+ self.makeVolumeInfo_('/' + info.mountPath, info.mountCondition,
+ function(volume) {
+ mountedVolumes[volume.mountPath] = volume;
+ index++;
+ step(mountPoints);
+ });
+ } else {
+ self.mountedVolumes_ = mountedVolumes;
+ // Do not change ERROR status if gData is not mounted.
+ if (self.getGDataStatus() != VolumeManager.GDataStatus.ERROR &&
+ !gDataMounted) {
+ self.setGDataStatus_(gDataMounted ?
+ VolumeManager.GDataStatus.MOUNTED :
+ VolumeManager.GDataStatus.UNMOUNTED);
+ }
+ }
+ }
+
+ chrome.fileBrowserPrivate.getMountPoints(step);
+};
+
+/**
+ * Event handler called when some volume was mounted or unmouted.
+ */
+VolumeManager.prototype.onMountCompleted_ = function(event) {
+ if (event.eventType == 'mount') {
+ if (event.mountPath) {
+ var requestKey = this.makeRequestKey_('mount', event.mountType, event.sourcePath);
+ this.makeVolumeInfo_(event.mountPath, event.status, function(volume) {
+ this.mountedVolumes_[volume.mountPath] = volume;
+ this.finishRequest_(requestKey, event.status, event.mountPath);
+ this.notifyChange_();
+ }.bind(this));
+ } else {
+ console.log('No mount path');
+ this.finishRequest_(requestKey, event.status);
+ }
+ } else if (event.eventType == 'unmount') {
+ var mountPath = '/' + event.mountPath;
+ var status = event.status;
+ if (status == VolumeManager.Error.PATH_UNMOUNTED) {
+ console.log('Volume already unmounted: ', mountPath);
+ status = 'success';
+ }
+ this.finishRequest_(this.makeRequestKey_('mount', '', mountPath), status);
+
+ if (event.status == 'success') {
+ delete this.mountedVolumes_[mountPath];
+ this.notifyChange_();
+ }
+ }
+
+ if (event.mountType == 'gdata') {
+ if (event.status == 'success') {
+ if (event.eventType == 'mount')
+ this.setGDataStatus_(VolumeManager.GDataStatus.MOUNTED);
+ else if (event.eventType == 'unmount' && event.status == 'success')
+ this.setGDataStatus_(VolumeManager.GDataStatus.UMOUNTED);
+ }
+ }
+};
+
+VolumeManager.prototype.makeVolumeInfo_ = function(
+ mountPath, status, callback) {
+ chrome.fileBrowserPrivate.getVolumeMetadata(this.makeUrl_(mountPath),
+ function(metadata) {
+ callback({
+ mountPath: mountPath,
+ status: status,
+ readonly: !!metadata && metadata.isReadOnly
+ });
+ }.bind(this));
+};
+
+/**
+ * @param {string} requestType 'mount' | 'unmount'
+ * @param {string} mountType 'device' | 'file' | 'network' | 'gdata'.
+ * @param {string?} opt_sourcePath
+ */
+VolumeManager.prototype.makeRequestKey_ = function(requestType, mountType, opt_mountPath) {
+ return requestType + ':' + mountType + ':' + (opt_mountPath || '');
+};
+
+VolumeManager.prototype.mountGData = function(successCallback, errorCallback) {
+ if (this.getGDataStatus() == VolumeManager.GDataStatus.ERROR) {
+ this.setGDataStatus_(VolumeManager.GDataStatus.UNMOUNTED);
+ }
+ var self = this;
+ var timeout = setTimeout(function() {
+ if (self.getGDataStatus() == VolumeManager.GDataStatus.UNMOUNTED)
+ self.setGDataStatus_(VolumeManager.GDataStatus.MOUNTING);
+ timeout = null;
+ }, 500);
+ this.mount_('', 'gdata', function(mountPath) {
+ if (timeout !== null)
+ clearTimeout(timeout);
+ successCallback(mountPath);
+ }, function(error) {
+ if (self.getGDataStatus() != VolumeManager.GDataStatus.MOUNTED)
+ self.setGDataStatus_(VolumeManager.GDataStatus.ERROR);
+ if (timeout != null)
+ clearTimeout(timeout);
+ errorCallback(error);
+ });
+};
+
+VolumeManager.prototype.getMountCondition = function(mountPath) {
+ return this.getVolumeInfo_(mountPath).status;
+};
+
+VolumeManager.prototype.isReadOnly = function(mountPath) {
+ return this.getVolumeInfo_(mountPath).readonly;
+};
+
+VolumeManager.prototype.getVolumeInfo_ = function(mountPath) {
+ return this.mountedVolumes_[mountPath] || {};
+};
+
+/**
+ * Unmounts device.
+ * @param {Entry} entry The entry to unmount.
+ */
+VolumeManager.prototype.unmount = function(mountPath, successCallback, errorCallback) {
+ var volumeInfo = this.mountedVolumes_[mountPath];
+ if (!volumeInfo) {
+ errorCallback(VolumeManager.Error.NOT_NOUNTED);
+ return;
+ }
+
+ chrome.fileBrowserPrivate.removeMount(this.makeUrl_(mountPath));
+ this.startRequest_(this.makeRequestKey_('unmount', '', mountPath));
+};
+
+VolumeManager.prototype.mountArchive = function(fullPath, successCallback,
+ errorCallback) {
+ var requestKey = this.makeRequestKey_('mount', 'file');
+ if (requestKey in this.requests_) {
+ // Parallel requests are not supported. API doesn't provide a way
+ // to find request for specific response.
+ errorCallback('inprogress');
+ return;
+ }
+ this.mount_(this.makeUrl_(fullPath),
+ 'file', successCallback, errorCallback);
+};
+
+VolumeManager.prototype.makeUrl_ = function(path) {
+ return 'filesystem:' + chrome.extension.getURL('external' + path);
+};
+
+VolumeManager.prototype.mount_ = function(url, mountType,
+ successCallback, errorCallback) {
+ console.log('mount ', url, mountType);
+ chrome.fileBrowserPrivate.addMount(url, mountType, {},
+ function(sourcePath) {
+ var requestKey = this.makeRequestKey_('mount', mountType, sourcePath);
+ this.startRequest_(requestKey, successCallback, errorCallback);
+ }.bind(this));
+};
+
+VolumeManager.prototype.startRequest_ = function(key,
+ successCallback, errorCallback) {
+ console.log('Start request: ', key);
+ if (key in this.requests_) {
+ var request = this.requests_[key];
+ request.successCallbacks.push(successCallback);
+ request.errorCallbacks.push(errorCallback);
+ } else {
+ this.requests_[key] = {
+ successCallbacks: [successCallback],
+ errorCallbacks: [errorCallback],
+
+ timeout: setTimeout(this.onTimeout_.bind(this, key), 10000)
+ };
+ }
+};
+
+VolumeManager.prototype.onTimeout_ = function(key) {
+ this.invokeRequestCallbacks_(this.requests_[key],
+ VolumeManager.Error.TIMEOUT);
+ delete this.requests_[key];
+};
+
+VolumeManager.prototype.finishRequest_ = function(key, status, opt_mountPath) {
+ var request = this.requests_[key];
+ if (!request)
+ return;
+
+ clearTimeout(request.timeout);
+ this.invokeRequestCallbacks_(request, status, opt_mountPath);
+ delete this.requests_[key];
+}
+
+VolumeManager.prototype.invokeRequestCallbacks_= function(request, status,
+ opt_mountPath) {
+ function callEach(callbacks, self, args) {
+ for (var i = 0; i < callbacks.length; i++) {
+ callbacks[i].call(self, args);
+ }
+ }
+ if (status == 'success')
+ callEach(request.successCallbacks, this, [opt_mountPath]);
+ else
+ callEach(request.errorCallbacks, this, [status]);
+};
+
+VolumeManager.prototype.notifyChange_ = function() {
+ cr.dispatchSimpleEvent(this, 'change');
+};
+

Powered by Google App Engine
This is Rietveld 408576698