X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fchrome%2Fbrowser%2Fresources%2Ffile_manager%2Fbackground%2Fjs%2Fvolume_manager.js;h=67eaffefe1fe3c2ddd300f0e92af39d5a1d89e5f;hb=ff3e2503a20db9193d323c1d19c38c68004dec4a;hp=e55c9e7c84ce95b0e2d50b3cf5b0f541286bd330;hpb=7338fba38ba696536d1cc9d389afd716a6ab2fe6;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/chrome/browser/resources/file_manager/background/js/volume_manager.js b/src/chrome/browser/resources/file_manager/background/js/volume_manager.js index e55c9e7..67eaffe 100644 --- a/src/chrome/browser/resources/file_manager/background/js/volume_manager.js +++ b/src/chrome/browser/resources/file_manager/background/js/volume_manager.js @@ -9,7 +9,6 @@ * flush storage", or "mounted zip archive" etc. * * @param {util.VolumeType} volumeType The type of the volume. - * @param {string} mountPath Where the volume is mounted. * @param {string} volumeId ID of the volume. * @param {DirectoryEntry} root The root directory entry of this volume. * @param {string} error The error if an error is found. @@ -23,7 +22,6 @@ */ function VolumeInfo( volumeType, - mountPath, volumeId, root, error, @@ -32,7 +30,6 @@ function VolumeInfo( profile) { this.volumeType_ = volumeType; // TODO(hidehiko): This should include FileSystem instance. - this.mountPath_ = mountPath; this.volumeId_ = volumeId; this.root_ = root; this.displayRoot_ = null; @@ -41,23 +38,21 @@ function VolumeInfo( this.displayRootPromise_ = null; if (volumeType === util.VolumeType.DRIVE) { - this.fakeEntries[RootType.DRIVE_OFFLINE] = { - fullPath: RootDirectory.DRIVE_OFFLINE, + // TODO(mtomasz): Convert fake entries to DirectoryProvider. + this.fakeEntries_[RootType.DRIVE_OFFLINE] = { isDirectory: true, rootType: RootType.DRIVE_OFFLINE, - toURL: function() { return 'fake-entry://' + this.fullPath; } + toURL: function() { return 'fake-entry://drive_offline' } }; - this.fakeEntries[RootType.DRIVE_SHARED_WITH_ME] = { - fullPath: RootDirectory.DRIVE_SHARED_WITH_ME, + this.fakeEntries_[RootType.DRIVE_SHARED_WITH_ME] = { isDirectory: true, rootType: RootType.DRIVE_SHARED_WITH_ME, - toURL: function() { return 'fake-entry://' + this.fullPath; } + toURL: function() { return 'fake-entry://drive_shared_with_me'; } }; - this.fakeEntries[RootType.DRIVE_RECENT] = { - fullPath: RootDirectory.DRIVE_RECENT, + this.fakeEntries_[RootType.DRIVE_RECENT] = { isDirectory: true, rootType: RootType.DRIVE_RECENT, - toURL: function() { return 'fake-entry://' + this.fullPath; } + toURL: function() { return 'fake-entry://drive_recent'; } }; } @@ -80,12 +75,6 @@ VolumeInfo.prototype = { return this.volumeType_; }, /** - * @return {string} Mount path. - */ - get mountPath() { - return this.mountPath_; - }, - /** * @return {string} Volume id. */ get volumeId() { @@ -179,6 +168,7 @@ volumeManagerUtil.validateError = function(error) { /** * Returns the root entry of a volume mounted at mountPath. + * TODO(mtomasz): Migrate to volumeId, once requestFileSystem can handle it. * * @param {string} mountPath The mounted path of the volume. * @param {function(DirectoryEntry)} successCallback Called when the root entry @@ -232,7 +222,6 @@ volumeManagerUtil.createVolumeInfo = function(volumeMetadata, callback) { } callback(new VolumeInfo( volumeMetadata.volumeType, - volumeMetadata.mountPath, volumeMetadata.volumeId, entry, volumeMetadata.mountCondition, @@ -245,7 +234,6 @@ volumeManagerUtil.createVolumeInfo = function(volumeMetadata, callback) { volumeMetadata.mountPath + ', ' + fileError.name); callback(new VolumeInfo( volumeMetadata.volumeType, - volumeMetadata.mountPath, volumeMetadata.volumeId, null, // Root entry is not found. volumeMetadata.mountCondition, @@ -270,7 +258,7 @@ volumeManagerUtil.volumeListOrder_ = [ ]; /** - * Orders two volumes by volumeType and mountPath. + * Orders two volumes by volumeType and volumeId. * * The volumes at first are compared by volume type in the order of * volumeListOrder_. Then they are compared by volume ID. @@ -371,16 +359,26 @@ VolumeInfoList.prototype.findIndex = function(volumeId) { }; /** - * Searches the information of the volume that contains an item pointed by the - * path. - * @param {string} path Path pointing an entry on a volume. + * Searches the information of the volume that contains the passed entry. + * @param {Entry|Object} entry Entry on the volume to be foudn. * @return {VolumeInfo} The volume's information, or null if not found. */ -VolumeInfoList.prototype.findByPath = function(path) { +VolumeInfoList.prototype.findByEntry = function(entry) { + // TODO(mtomasz): Switch to comparing file systems once possible. for (var i = 0; i < this.length; i++) { - var mountPath = this.item(i).mountPath; - if (path === mountPath || path.indexOf(mountPath + '/') === 0) - return this.item(i); + var volumeInfo = this.item(i); + if (!volumeInfo.root) + continue; + if (util.isSameEntry(entry, volumeInfo.root) || + entry.toURL().indexOf(volumeInfo.root.toURL() + '/') === 0) { + return volumeInfo; + } + // Additionally, check fake entries. + for (var key in volumeInfo.fakeEntries_) { + var fakeEntry = volumeInfo.fakeEntries_[key]; + if (util.isSameEntry(fakeEntry, entry)) + return volumeInfo; + } } return null; }; @@ -533,6 +531,7 @@ VolumeManager.prototype.initialize_ = function(callback) { */ VolumeManager.prototype.onMountCompleted_ = function(event) { if (event.eventType === 'mount') { + // TODO(mtomasz): Migrate to volumeId once possible. if (event.volumeMetadata.mountPath) { var requestKey = this.makeRequestKey_( 'mount', @@ -544,7 +543,7 @@ VolumeManager.prototype.onMountCompleted_ = function(event) { event.volumeMetadata, function(volumeInfo) { this.volumeInfoList.add(volumeInfo); - this.finishRequest_(requestKey, event.status, volumeInfo.mountPath); + this.finishRequest_(requestKey, event.status, volumeInfo); if (volumeInfo.volumeType === util.VolumeType.DRIVE) { // Update the network connection status, because until the @@ -559,23 +558,21 @@ VolumeManager.prototype.onMountCompleted_ = function(event) { this.finishRequest_(requestKey, event.status); } } else if (event.eventType === 'unmount') { - var mountPath = event.volumeMetadata.mountPath; + var volumeId = event.volumeMetadata.volumeId; var status = event.status; if (status === util.VolumeError.PATH_UNMOUNTED) { - console.warn('Volume already unmounted: ', mountPath); + console.warn('Volume already unmounted: ', volumeId); status = 'success'; } - var requestKey = this.makeRequestKey_('unmount', mountPath); + var requestKey = this.makeRequestKey_('unmount', volumeId); var requested = requestKey in this.requests_; var volumeInfoIndex = - this.volumeInfoList.findIndex(event.volumeMetadata.volumeId); - var volumeInfo = volumeInfoIndex != -1 ? + this.volumeInfoList.findIndex(volumeId); + var volumeInfo = volumeInfoIndex !== -1 ? this.volumeInfoList.item(volumeInfoIndex) : null; if (event.status === 'success' && !requested && volumeInfo) { - console.warn('Mounted volume without a request: ', mountPath); + console.warn('Mounted volume without a request: ', volumeId); var e = new Event('externally-unmounted'); - // TODO(mtomasz): The mountPath field is deprecated. Remove it. - e.mountPath = mountPath; e.volumeInfo = volumeInfo; this.dispatchEvent(e); } @@ -590,25 +587,25 @@ VolumeManager.prototype.onMountCompleted_ = function(event) { * Creates string to match mount events with requests. * @param {string} requestType 'mount' | 'unmount'. TODO(hidehiko): Replace by * enum. - * @param {string} path Source path provided by API for mount request, or - * mount path for unmount request. + * @param {string} argument Argument describing the request, eg. source file + * path of the archive to be mounted, or a volumeId for unmounting. * @return {string} Key for |this.requests_|. * @private */ -VolumeManager.prototype.makeRequestKey_ = function(requestType, path) { - return requestType + ':' + path; +VolumeManager.prototype.makeRequestKey_ = function(requestType, argument) { + return requestType + ':' + argument; }; /** * @param {string} fileUrl File url to the archive file. - * @param {function(string)} successCallback Success callback. + * @param {function(VolumeInfo)} successCallback Success callback. * @param {function(util.VolumeError)} errorCallback Error callback. */ VolumeManager.prototype.mountArchive = function( fileUrl, successCallback, errorCallback) { chrome.fileBrowserPrivate.addMount(fileUrl, function(sourcePath) { console.info( - 'Mount request: url=' + fileUrl + '; sourceUrl=' + sourcePath); + 'Mount request: url=' + fileUrl + '; sourcePath=' + sourcePath); var requestKey = this.makeRequestKey_('mount', sourcePath); this.startRequest_(requestKey, successCallback, errorCallback); }.bind(this)); @@ -617,54 +614,24 @@ VolumeManager.prototype.mountArchive = function( /** * Unmounts volume. * @param {!VolumeInfo} volumeInfo Volume to be unmounted. - * @param {function(string)} successCallback Success callback. + * @param {function()} successCallback Success callback. * @param {function(util.VolumeError)} errorCallback Error callback. */ VolumeManager.prototype.unmount = function(volumeInfo, successCallback, errorCallback) { - chrome.fileBrowserPrivate.removeMount( - util.makeFilesystemUrl(volumeInfo.mountPath)); - var requestKey = this.makeRequestKey_('unmount', volumeInfo.mountPath); + chrome.fileBrowserPrivate.removeMount(volumeInfo.volumeId); + var requestKey = this.makeRequestKey_('unmount', volumeInfo.volumeId); this.startRequest_(requestKey, successCallback, errorCallback); }; /** - * Resolves the absolute path to its entry. Shouldn't be used outside of the - * Files app's initialization. - * @param {string} path The path to be resolved. - * @param {function(Entry)} successCallback Called with the resolved entry on - * success. - * @param {function(FileError)} errorCallback Called on error. + * Obtains a volume info containing the passed entry. + * @param {Entry|Object} entry Entry on the volume to be returned. Can be fake. + * @return {VolumeInfo} The VolumeInfo instance or null if not found. */ -VolumeManager.prototype.resolveAbsolutePath = function( - path, successCallback, errorCallback) { - // Make sure the path is in the mounted volume. - var volumeInfo = this.getVolumeInfo(path); - if (!volumeInfo || !volumeInfo.root) { - errorCallback(util.createDOMError(util.FileError.NOT_FOUND_ERR)); - return; - } - - webkitResolveLocalFileSystemURL( - util.makeFilesystemUrl(path), successCallback, errorCallback); -}; - -/** - * Obtains the information of the volume that containing an entry pointed by the - * specified path. - * TODO(hirono): Stop to use path to get a volume info. - * - * @param {string|Entry} target Path or Entry pointing anywhere on a volume. - * @return {VolumeInfo} The data about the volume. - */ -VolumeManager.prototype.getVolumeInfo = function(target) { - if (typeof target === 'string') - return this.volumeInfoList.findByPath(target); - else if (util.isFakeEntry(target)) - return this.getCurrentProfileVolumeInfo(util.VolumeType.DRIVE); - else - return this.volumeInfoList.findByPath(target.fullPath); +VolumeManager.prototype.getVolumeInfo = function(entry) { + return this.volumeInfoList.findByEntry(entry); }; /** @@ -699,34 +666,33 @@ VolumeManager.prototype.getLocationInfo = function(entry) { true /* fake entries are read only. */); } - // TODO(mtomasz): Find by Entry instead. - var volumeInfo = this.volumeInfoList.findByPath(entry.fullPath); + var volumeInfo = this.volumeInfoList.findByEntry(entry); if (!volumeInfo) return null; - var rootPath; var rootType; var isReadOnly; + var isRootEntry; if (volumeInfo.volumeType === util.VolumeType.DRIVE) { - // If the volume is drive, root path can be either mountPath + '/root' or - // mountPath + '/other'. - if ((entry.fullPath + '/').indexOf(volumeInfo.mountPath + '/root/') === 0) { - rootPath = volumeInfo.mountPath + '/root'; + // For Drive, the roots are /root and /other, instead of /. + // TODO(mtomasz): Simplify once switching to filesystem per volume. + if (entry.toURL() === volumeInfo.root.toURL() + '/root' || + entry.toURL().indexOf(volumeInfo.root.toURL() + '/root/') === 0) { rootType = RootType.DRIVE; - isReadOnly = volumeInfo.isReadOnly || - this.getDriveConnectionState().type === - util.DriveConnectionType.OFFLINE; - } else if ((entry.fullPath + '/').indexOf( - volumeInfo.mountPath + '/other/') === 0) { - rootPath = volumeInfo.mountPath + '/other'; + isReadOnly = volumeInfo.isReadOnly; + isRootEntry = entry.toURL() === volumeInfo.root.toURL() + '/root'; + } else if (entry.toURL() === volumeInfo.root.toURL() + '/other' || + entry.toURL().indexOf(volumeInfo.root.toURL() + '/other/') === 0) { rootType = RootType.DRIVE_OTHER; isReadOnly = true; + isRootEntry = entry.toURL() === volumeInfo.root.toURL() + '/other'; } else { - throw new Error(entry.fullPath + ' is an invalid drive path.'); + // Accessing Drive files outside of /drive/root and /drive/other is not + // allowed, but can happen. Therefore returning null. + return null; } } else { // Otherwise, root path is same with a mount path of the volume. - rootPath = volumeInfo.mountPath; switch (volumeInfo.volumeType) { case util.VolumeType.DOWNLOADS: rootType = RootType.DOWNLOADS; @@ -741,20 +707,20 @@ VolumeManager.prototype.getLocationInfo = function(entry) { rootType = RootType.CLOUD_DEVICE; break; default: + // Programming error, throw an exception. throw new Error('Invalid volume type: ' + volumeInfo.volumeType); } isReadOnly = volumeInfo.isReadOnly; + isRootEntry = util.isSameEntry(entry, volumeInfo.root); } - var isRootEntry = (entry.fullPath.substr(0, rootPath.length) || '/') === - entry.fullPath; return new EntryLocation(volumeInfo, rootType, isRootEntry, isReadOnly); }; /** * @param {string} key Key produced by |makeRequestKey_|. - * @param {function(string)} successCallback To be called when request finishes - * successfully. + * @param {function(VolumeInfo)} successCallback To be called when request + * finishes successfully. * @param {function(util.VolumeError)} errorCallback To be called when * request fails. * @private @@ -790,16 +756,16 @@ VolumeManager.prototype.onTimeout_ = function(key) { /** * @param {string} key Key produced by |makeRequestKey_|. * @param {util.VolumeError|'success'} status Status received from the API. - * @param {string=} opt_mountPath Mount path. + * @param {VolumeInfo=} opt_volumeInfo Volume info of the mounted volume. * @private */ -VolumeManager.prototype.finishRequest_ = function(key, status, opt_mountPath) { +VolumeManager.prototype.finishRequest_ = function(key, status, opt_volumeInfo) { var request = this.requests_[key]; if (!request) return; clearTimeout(request.timeout); - this.invokeRequestCallbacks_(request, status, opt_mountPath); + this.invokeRequestCallbacks_(request, status, opt_volumeInfo); delete this.requests_[key]; }; @@ -807,18 +773,18 @@ VolumeManager.prototype.finishRequest_ = function(key, status, opt_mountPath) { * @param {Object} request Structure created in |startRequest_|. * @param {util.VolumeError|string} status If status === 'success' * success callbacks are called. - * @param {string=} opt_mountPath Mount path. Required if success. + * @param {VolumeInfo=} opt_volumeInfo Volume info of the mounted volume. * @private */ -VolumeManager.prototype.invokeRequestCallbacks_ = function(request, status, - opt_mountPath) { +VolumeManager.prototype.invokeRequestCallbacks_ = function( + request, status, opt_volumeInfo) { var callEach = function(callbacks, self, args) { for (var i = 0; i < callbacks.length; i++) { callbacks[i].apply(self, args); } }; if (status === 'success') { - callEach(request.successCallbacks, this, [opt_mountPath]); + callEach(request.successCallbacks, this, [opt_volumeInfo]); } else { volumeManagerUtil.validateError(status); callEach(request.errorCallbacks, this, [status]);