blob: 3dc28d3c0102785965e4ae95b8296b989dc06c23 [file] [log] [blame]
// Copyright 2016 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.
/**
* Represents each volume, such as "drive", "download directory", each "USB
* flush storage", or "mounted zip archive" etc.
*
* @constructor
* @implements {VolumeInfo}
* @struct
*
* @param {VolumeManagerCommon.VolumeType} volumeType The type of the volume.
* @param {string} volumeId ID of the volume.
* @param {FileSystem} fileSystem The file system object for this volume.
* @param {(string|undefined)} error The error if an error is found.
* @param {(string|undefined)} deviceType The type of device
* ('usb'|'sd'|'optical'|'mobile'|'unknown') (as defined in
* chromeos/disks/disk_mount_manager.cc). Can be undefined.
* @param {(string|undefined)} devicePath Identifier of the device that the
* volume belongs to. Can be undefined.
* @param {boolean} isReadOnly True if the volume is read only.
* @param {boolean} isReadOnlyRemovableDevice True if the volume is read only
* removable device.
* @param {!{displayName:string, isCurrentProfile:boolean}} profile Profile
* information.
* @param {string} label Label of the volume.
* @param {(string|undefined)} providerId Id of the provider for this volume.
* Undefined for non-FSP volumes.
* @param {boolean} hasMedia When true the volume has been identified
* as containing media such as photos or videos.
* @param {boolean} configurable When true, then the volume can be configured.
* @param {boolean} watchable When true, then the volume can be watched.
* @param {VolumeManagerCommon.Source} source Source of the volume's data.
* @param {VolumeManagerCommon.FileSystemType} diskFileSystemType File system
* type indentifier.
* @param {!chrome.fileManagerPrivate.IconSet} iconSet Set of icons for this
* volume.
*/
function VolumeInfoImpl(
volumeType, volumeId, fileSystem, error, deviceType, devicePath, isReadOnly,
isReadOnlyRemovableDevice, profile, label, providerId, hasMedia,
configurable, watchable, source, diskFileSystemType, iconSet) {
this.volumeType_ = volumeType;
this.volumeId_ = volumeId;
this.fileSystem_ = fileSystem;
this.label_ = label;
this.displayRoot_ = null;
this.teamDriveDisplayRoot_ = null;
/**
* @type {FilesAppEntry} an entry to be used as prefix of this volume on
* breadcrumbs, e.g. "My Files > Downloads", "My Files" is a prefixEntry
* on "Downloads" VolumeInfo.
*/
this.prefixEntry_ = null;
/** @type {Object<!FakeEntry>} */
this.fakeEntries_ = {};
/** @type {Promise<!DirectoryEntry>} */
this.displayRootPromise_ = null;
if (volumeType === VolumeManagerCommon.VolumeType.DRIVE) {
this.fakeEntries_[VolumeManagerCommon.RootType.DRIVE_OFFLINE] =
new FakeEntry(
str('DRIVE_OFFLINE_COLLECTION_LABEL'),
VolumeManagerCommon.RootType.DRIVE_OFFLINE);
this.fakeEntries_[VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME] =
new FakeEntry(
str('DRIVE_SHARED_WITH_ME_COLLECTION_LABEL'),
VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME);
}
// Note: This represents if the mounting of the volume is successfully done
// or not. (If error is empty string, the mount is successfully done).
// TODO(hidehiko): Rename to make this more understandable.
this.error_ = error;
this.deviceType_ = deviceType;
this.devicePath_ = devicePath;
this.isReadOnly_ = isReadOnly;
this.isReadOnlyRemovableDevice_ = isReadOnlyRemovableDevice;
this.profile_ = Object.freeze(profile);
this.providerId_ = providerId;
this.hasMedia_ = hasMedia;
this.configurable_ = configurable;
this.watchable_ = watchable;
this.source_ = source;
this.diskFileSystemType_ = diskFileSystemType;
this.iconSet_ = iconSet;
}
VolumeInfoImpl.prototype = /** @struct */ {
/**
* @return {VolumeManagerCommon.VolumeType} Volume type.
*/
get volumeType() {
return this.volumeType_;
},
/**
* @return {string} Volume ID.
*/
get volumeId() {
return this.volumeId_;
},
/**
* @return {FileSystem} File system object.
*/
get fileSystem() {
return this.fileSystem_;
},
/**
* @return {DirectoryEntry} Display root path. It is null before finishing to
* resolve the entry.
*/
get displayRoot() {
return this.displayRoot_;
},
/**
* @return {DirectoryEntry} The display root path of Team Drives directory.
* It is null before finishing to resolve the entry. Valid only for Drive
* volume.
*/
get teamDriveDisplayRoot() {
return this.teamDriveDisplayRoot_;
},
/**
* @return {Object<!FakeEntry>} Fake entries.
*/
get fakeEntries() {
return this.fakeEntries_;
},
/**
* @return {(string|undefined)} Error identifier.
*/
get error() {
return this.error_;
},
/**
* @return {(string|undefined)} Device type identifier.
*/
get deviceType() {
return this.deviceType_;
},
/**
* @return {(string|undefined)} Device identifier.
*/
get devicePath() {
return this.devicePath_;
},
/**
* @return {boolean} Whether read only or not.
*/
get isReadOnly() {
return this.isReadOnly_;
},
/**
* @return {boolean} Whether the device is read-only removable device or not.
*/
get isReadOnlyRemovableDevice() {
return this.isReadOnlyRemovableDevice_;
},
/**
* @return {!{displayName:string, isCurrentProfile:boolean}} Profile data.
*/
get profile() {
return this.profile_;
},
/**
* @return {string} Label for the volume.
*/
get label() {
return this.label_;
},
/**
* @return {(string|undefined)} Id of a provider for this volume.
*/
get providerId() {
return this.providerId_;
},
/**
* @return {boolean} True if the volume contains media.
*/
get hasMedia() {
return this.hasMedia_;
},
/**
* @return {boolean} True if the volume is configurable.
*/
get configurable() {
return this.configurable_;
},
/**
* @return {boolean} True if the volume is watchable.
*/
get watchable() {
return this.watchable_;
},
/**
* @return {VolumeManagerCommon.Source} Source of the volume's data.
*/
get source() {
return this.source_;
},
/**
* @return {VolumeManagerCommon.FileSystemType} File system type identifier.
*/
get diskFileSystemType() {
return this.diskFileSystemType_;
},
/**
* @return {chrome.fileManagerPrivate.IconSet} Set of icons for this volume.
*/
get iconSet() {
return this.iconSet_;
},
/**
* @type {FilesAppEntry} an entry to be used as prefix of this volume on
* breadcrumbs, e.g. "My Files > Downloads", "My Files" is a prefixEntry
* on "Downloads" VolumeInfo.
*/
get prefixEntry() {
return this.prefixEntry_;
},
set prefixEntry(entry) {
this.prefixEntry_ = entry;
},
};
/**
* Returns a promise to the entry for the given URL
* @param {string} url The filesystem URL
* @return {!Promise<Entry>}
*/
VolumeInfoImpl.resolveFileSystemUrl_ = function(url) {
return new Promise(window.webkitResolveLocalFileSystemURL.bind(null, url));
};
/**
* Sets |teamDriveDisplayRoot_| if team drives are enabled.
*
* The return value will resolve once this operation is complete.
* @return {!Promise<void>}
*/
VolumeInfoImpl.prototype.resolveTeamDrivesRoot_ = function() {
return VolumeInfoImpl
.resolveFileSystemUrl_(
this.fileSystem_.root.toURL() +
VolumeManagerCommon.TEAM_DRIVES_DIRECTORY_NAME)
.then(
teamDrivesRoot => {
this.teamDriveDisplayRoot_ = teamDrivesRoot;
},
error => {
if (error.name != 'NotFoundError') {
throw error;
}
});
};
/**
* @override
*/
VolumeInfoImpl.prototype.resolveDisplayRoot = function(opt_onSuccess,
opt_onFailure) {
if (!this.displayRootPromise_) {
// TODO(mtomasz): Do not add VolumeInfo which failed to resolve root, and
// remove this if logic. Call opt_onSuccess() always, instead.
if (this.volumeType !== VolumeManagerCommon.VolumeType.DRIVE) {
if (this.fileSystem_)
this.displayRootPromise_ = /** @type {Promise<!DirectoryEntry>} */ (
Promise.resolve(this.fileSystem_.root));
else
this.displayRootPromise_ = /** @type {Promise<!DirectoryEntry>} */ (
Promise.reject(this.error));
} else {
// For Drive, we need to resolve.
var displayRootURL = this.fileSystem_.root.toURL() + 'root';
this.displayRootPromise_ =
Promise
.all([
VolumeInfoImpl.resolveFileSystemUrl_(displayRootURL),
this.resolveTeamDrivesRoot_()
])
.then(([root]) => {
return root;
});
}
// Store the obtained displayRoot.
this.displayRootPromise_.then(function(displayRoot) {
this.displayRoot_ = displayRoot;
}.bind(this));
}
if (opt_onSuccess)
this.displayRootPromise_.then(opt_onSuccess, opt_onFailure);
return this.displayRootPromise_;
};