diff options
author | sidor@chromium.org <sidor@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-13 04:38:25 +0000 |
---|---|---|
committer | sidor@chromium.org <sidor@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-13 04:38:25 +0000 |
commit | 0e55c84770b95a2f2c80fc9edaaf81bbf4e691ad (patch) | |
tree | 918aab7662202f229a93652277e2c4d539369f4e | |
parent | 0edd1aaf8bdfa4c137945bdc2bbff9014160da01 (diff) | |
download | chromium_src-0e55c84770b95a2f2c80fc9edaaf81bbf4e691ad.zip chromium_src-0e55c84770b95a2f2c80fc9edaaf81bbf4e691ad.tar.gz chromium_src-0e55c84770b95a2f2c80fc9edaaf81bbf4e691ad.tar.bz2 |
Adding a format device button to UI.
Additionally local path translation is now supported by filebrowser extension in formatting routine.
BUG=chromium-os:4541, chromium-os:17071
TEST=Try to format removable device
Review URL: http://codereview.chromium.org/7583041
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96682 0039d316-1c4b-4281-b951-d872f2087c98
8 files changed, 178 insertions, 60 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 89ec2d5..bc48cad 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -8956,6 +8956,9 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_FILE_BROWSER_UNMOUNT_ARCHIVE" desc="Title of the action for unmounting the archive file."> Close archive </message> + <message name="IDS_FILE_BROWSER_FORMAT_DEVICE" desc="Title of the action for formatting removable device."> + Format device + </message> <message name="IDS_FILE_BROWSER_CONFIRM_OVERWRITE_FILE" desc="Asks the user if they are sure they want to overwrite an existing file with another one."> A file named "$1" already exists. Do you want to replace it? diff --git a/chrome/browser/chromeos/cros/mount_library.cc b/chrome/browser/chromeos/cros/mount_library.cc index 6b32eb2..77a06a2c 100644 --- a/chrome/browser/chromeos/cros/mount_library.cc +++ b/chrome/browser/chromeos/cros/mount_library.cc @@ -180,9 +180,8 @@ class MountLibraryImpl : public MountLibrary { break; } } - if (!disk) { - OnFormatDevice(disk->device_path().c_str(), + OnFormatDevice(mount_path, false, MOUNT_METHOD_ERROR_LOCAL, "Device with this mount path not found."); @@ -190,7 +189,7 @@ class MountLibraryImpl : public MountLibrary { } if (formatting_pending_.find(disk->device_path()) != formatting_pending_.end()) { - OnFormatDevice(disk->device_path().c_str(), + OnFormatDevice(mount_path, false, MOUNT_METHOD_ERROR_LOCAL, "Formatting is already pending."); @@ -297,12 +296,18 @@ class MountLibraryImpl : public MountLibrary { // Callback for FormatRemovableDevice method. static void FormatDeviceCallback(void* object, - const char* device_path, + const char* file_path, bool success, MountMethodErrorType error, const char* error_message) { DCHECK(object); MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); + const char* device_path = self->FilePathToDevicePath(file_path); + if (!device_path) { + LOG(ERROR) << "Error while handling disks metadata. Cannot find " + << "device that is being formatted."; + return; + } self->OnFormatDevice(device_path, success, error, error_message); } @@ -615,6 +620,14 @@ class MountLibraryImpl : public MountLibrary { break; } case FORMATTING_FINISHED: { + // FORMATTING_FINISHED actually returns file path instead of device + // path. + device_path = FilePathToDevicePath(device_path); + if (!device_path) { + LOG(ERROR) << "Error while handling disks metadata. Cannot find " + << "device that is being formatted."; + return; + } type = MOUNT_FORMATTING_FINISHED; break; } @@ -658,6 +671,15 @@ class MountLibraryImpl : public MountLibrary { mount_info)); } + const char* FilePathToDevicePath(const char* file_path) { + for (MountLibrary::DiskMap::iterator it = disks_.begin(); + it != disks_.end(); ++it) { + if (it->second->file_path().compare(file_path) == 0) + return it->second->device_path().c_str(); + } + return NULL; + } + // Mount event change observers. ObserverList<Observer> observers_; diff --git a/chrome/browser/extensions/extension_file_browser_private_api.cc b/chrome/browser/extensions/extension_file_browser_private_api.cc index 29d3d7d..7856eb9 100644 --- a/chrome/browser/extensions/extension_file_browser_private_api.cc +++ b/chrome/browser/extensions/extension_file_browser_private_api.cc @@ -650,7 +650,6 @@ class ExecuteTasksFileSystemCallbackDispatcher // handler (target) extension and its renderer process. bool SetupFileAccessPermissions(const GURL& origin_file_url, GURL* target_file_url, FilePath* file_path, bool* is_directory) { - if (!extension_.get()) return false; @@ -1283,19 +1282,38 @@ bool FormatDeviceFunction::RunImpl() { return false; } - std::string volume_mount_path; - if (!args_->GetString(0, &volume_mount_path)) { + std::string volume_file_url; + if (!args_->GetString(0, &volume_file_url)) { NOTREACHED(); return false; } + UrlList file_paths; + file_paths.push_back(GURL(volume_file_url)); + + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + NewRunnableMethod(this, + &FormatDeviceFunction::GetLocalPathsOnFileThread, + file_paths, reinterpret_cast<void*>(NULL))); + return true; +} + +void FormatDeviceFunction::GetLocalPathsResponseOnUIThread( + const FilePathList& files, void* context) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + if (files.size() != 1) { + SendResponse(false); + return; + } + #ifdef OS_CHROMEOS chromeos::CrosLibrary::Get()->GetMountLibrary()->FormatMountedDevice( - volume_mount_path.c_str()); + files[0].value().c_str()); #endif SendResponse(true); - return true; } GetVolumeMetadataFunction::GetVolumeMetadataFunction() { @@ -1325,8 +1343,13 @@ bool GetVolumeMetadataFunction::RunImpl() { chromeos::MountLibrary::Disk* volume = volume_it->second; DictionaryValue* volume_info = new DictionaryValue(); result_.reset(volume_info); + // Localising mount path. + FilePath relative_mount_path; + FileManagerUtil::ConvertFileToRelativeFileSystemPath(profile_, + FilePath(volume->mount_path()), &relative_mount_path); + volume_info->SetString("devicePath", volume->device_path()); - volume_info->SetString("mountPath", volume->mount_path()); + volume_info->SetString("mountPath", relative_mount_path.value()); volume_info->SetString("systemPath", volume->system_path()); volume_info->SetString("filePath", volume->file_path()); volume_info->SetString("deviceLabel", volume->device_label()); @@ -1405,6 +1428,7 @@ bool FileDialogStringsFunction::RunImpl() { SET_STRING(IDS_FILE_BROWSER, ARCHIVE_MOUNT_FAILED); SET_STRING(IDS_FILE_BROWSER, MOUNT_ARCHIVE); SET_STRING(IDS_FILE_BROWSER, UNMOUNT_ARCHIVE); + SET_STRING(IDS_FILE_BROWSER, FORMAT_DEVICE); SET_STRING(IDS_FILE_BROWSER, CONFIRM_OVERWRITE_FILE); SET_STRING(IDS_FILE_BROWSER, FILE_ALREADY_EXISTS); @@ -1469,29 +1493,29 @@ bool FileDialogStringsFunction::RunImpl() { SET_STRING(IDS_FILE_BROWSER, PLAYBACK_ERROR); // MP3 metadata extractor plugin - SET_STRING(IDS_FILE_BROWSER, ID3_ALBUM); // TALB - SET_STRING(IDS_FILE_BROWSER, ID3_BPM); // TBPM - SET_STRING(IDS_FILE_BROWSER, ID3_COMPOSER); // TCOM - SET_STRING(IDS_FILE_BROWSER, ID3_COPYRIGHT_MESSAGE); // TCOP - SET_STRING(IDS_FILE_BROWSER, ID3_DATE); // TDAT - SET_STRING(IDS_FILE_BROWSER, ID3_PLAYLIST_DELAY); // TDLY - SET_STRING(IDS_FILE_BROWSER, ID3_ENCODED_BY); // TENC - SET_STRING(IDS_FILE_BROWSER, ID3_LYRICIST); // TEXT - SET_STRING(IDS_FILE_BROWSER, ID3_FILE_TYPE); // TFLT - SET_STRING(IDS_FILE_BROWSER, ID3_TIME); // TIME - SET_STRING(IDS_FILE_BROWSER, ID3_TITLE); // TIT2 - SET_STRING(IDS_FILE_BROWSER, ID3_LENGTH); // TLEN - SET_STRING(IDS_FILE_BROWSER, ID3_FILE_OWNER); // TOWN - SET_STRING(IDS_FILE_BROWSER, ID3_LEAD_PERFORMER); // TPE1 - SET_STRING(IDS_FILE_BROWSER, ID3_BAND); // TPE2 - SET_STRING(IDS_FILE_BROWSER, ID3_TRACK_NUMBER); // TRCK - SET_STRING(IDS_FILE_BROWSER, ID3_YEAR); // TYER - SET_STRING(IDS_FILE_BROWSER, ID3_COPYRIGHT); // WCOP - SET_STRING(IDS_FILE_BROWSER, ID3_OFFICIAL_AUDIO_FILE_WEBPAGE); // WOAF - SET_STRING(IDS_FILE_BROWSER, ID3_OFFICIAL_ARTIST); // WOAR - SET_STRING(IDS_FILE_BROWSER, ID3_OFFICIAL_AUDIO_SOURCE_WEBPAGE); // WOAS - SET_STRING(IDS_FILE_BROWSER, ID3_PUBLISHERS_OFFICIAL_WEBPAGE); // WPUB - SET_STRING(IDS_FILE_BROWSER, ID3_USER_DEFINED_URL_LINK_FRAME); // WXXX + SET_STRING(IDS_FILE_BROWSER, ID3_ALBUM); // TALB + SET_STRING(IDS_FILE_BROWSER, ID3_BPM); // TBPM + SET_STRING(IDS_FILE_BROWSER, ID3_COMPOSER); // TCOM + SET_STRING(IDS_FILE_BROWSER, ID3_COPYRIGHT_MESSAGE); // TCOP + SET_STRING(IDS_FILE_BROWSER, ID3_DATE); // TDAT + SET_STRING(IDS_FILE_BROWSER, ID3_PLAYLIST_DELAY); // TDLY + SET_STRING(IDS_FILE_BROWSER, ID3_ENCODED_BY); // TENC + SET_STRING(IDS_FILE_BROWSER, ID3_LYRICIST); // TEXT + SET_STRING(IDS_FILE_BROWSER, ID3_FILE_TYPE); // TFLT + SET_STRING(IDS_FILE_BROWSER, ID3_TIME); // TIME + SET_STRING(IDS_FILE_BROWSER, ID3_TITLE); // TIT2 + SET_STRING(IDS_FILE_BROWSER, ID3_LENGTH); // TLEN + SET_STRING(IDS_FILE_BROWSER, ID3_FILE_OWNER); // TOWN + SET_STRING(IDS_FILE_BROWSER, ID3_LEAD_PERFORMER); // TPE1 + SET_STRING(IDS_FILE_BROWSER, ID3_BAND); // TPE2 + SET_STRING(IDS_FILE_BROWSER, ID3_TRACK_NUMBER); // TRCK + SET_STRING(IDS_FILE_BROWSER, ID3_YEAR); // TYER + SET_STRING(IDS_FILE_BROWSER, ID3_COPYRIGHT); // WCOP + SET_STRING(IDS_FILE_BROWSER, ID3_OFFICIAL_AUDIO_FILE_WEBPAGE); // WOAF + SET_STRING(IDS_FILE_BROWSER, ID3_OFFICIAL_ARTIST); // WOAR + SET_STRING(IDS_FILE_BROWSER, ID3_OFFICIAL_AUDIO_SOURCE_WEBPAGE); // WOAS + SET_STRING(IDS_FILE_BROWSER, ID3_PUBLISHERS_OFFICIAL_WEBPAGE); // WPUB + SET_STRING(IDS_FILE_BROWSER, ID3_USER_DEFINED_URL_LINK_FRAME); // WXXX SET_STRING(IDS_FILEBROWSER, ENQUEUE); #undef SET_STRING diff --git a/chrome/browser/extensions/extension_file_browser_private_api.h b/chrome/browser/extensions/extension_file_browser_private_api.h index 83a3767..7c7716d 100644 --- a/chrome/browser/extensions/extension_file_browser_private_api.h +++ b/chrome/browser/extensions/extension_file_browser_private_api.h @@ -134,8 +134,8 @@ class FileBrowserFunction void* context); // Callback with converted local paths. - virtual void GetLocalPathsResponseOnUIThread( - const FilePathList& files, void* context) {} + virtual void GetLocalPathsResponseOnUIThread(const FilePathList& files, + void* context) {} // Figure out the tab_id of the hosting tab. int32 GetTabId() const; @@ -174,8 +174,8 @@ class ViewFilesFunction virtual bool RunImpl() OVERRIDE; // FileBrowserFunction overrides. - virtual void GetLocalPathsResponseOnUIThread( - const FilePathList& files, void* context) OVERRIDE; + virtual void GetLocalPathsResponseOnUIThread(const FilePathList& files, + void* context) OVERRIDE; private: DECLARE_EXTENSION_FUNCTION_NAME("fileBrowserPrivate.viewFiles"); @@ -194,8 +194,8 @@ class SelectFilesFunction virtual bool RunImpl() OVERRIDE; // FileBrowserFunction overrides. - virtual void GetLocalPathsResponseOnUIThread( - const FilePathList& files, void* context) OVERRIDE; + virtual void GetLocalPathsResponseOnUIThread(const FilePathList& files, + void* context) OVERRIDE; private: DECLARE_EXTENSION_FUNCTION_NAME("fileBrowserPrivate.selectFiles"); @@ -229,8 +229,8 @@ class AddMountFunction virtual bool RunImpl() OVERRIDE; // FileBrowserFunction overrides. - virtual void GetLocalPathsResponseOnUIThread( - const FilePathList& files, void* context) OVERRIDE; + virtual void GetLocalPathsResponseOnUIThread(const FilePathList& files, + void* context) OVERRIDE; private: struct MountParamaters { @@ -257,7 +257,7 @@ class RemoveMountFunction // FileBrowserFunction overrides. virtual bool RunImpl() OVERRIDE; virtual void GetLocalPathsResponseOnUIThread(const FilePathList& files, - void* context) OVERRIDE; + void* context) OVERRIDE; private: DECLARE_EXTENSION_FUNCTION_NAME("fileBrowserPrivate.removeMount"); @@ -279,15 +279,19 @@ class GetMountPointsFunction // Formats Device given its mount path. class FormatDeviceFunction - : public SyncExtensionFunction { - public: - FormatDeviceFunction(); + : public FileBrowserFunction { + public: + FormatDeviceFunction(); protected: virtual ~FormatDeviceFunction(); virtual bool RunImpl() OVERRIDE; +// FileBrowserFunction overrides. + virtual void GetLocalPathsResponseOnUIThread(const FilePathList& files, + void* context) OVERRIDE; + private: DECLARE_EXTENSION_FUNCTION_NAME("fileBrowserPrivate.formatDevice"); }; diff --git a/chrome/browser/extensions/extension_file_browser_private_apitest.cc b/chrome/browser/extensions/extension_file_browser_private_apitest.cc index f381104..9ceda8c 100644 --- a/chrome/browser/extensions/extension_file_browser_private_apitest.cc +++ b/chrome/browser/extensions/extension_file_browser_private_apitest.cc @@ -49,7 +49,7 @@ class ExtensionFileBrowserPrivateApiTest : public ExtensionApiTest { std::pair<std::string, chromeos::MountLibrary::Disk*>( "device_path1", new chromeos::MountLibrary::Disk("device_path1", - "mount_path1", + "/media/removable/mount_path1", "system_path1", "file_path1", "device_label1", @@ -65,7 +65,7 @@ class ExtensionFileBrowserPrivateApiTest : public ExtensionApiTest { std::pair<std::string, chromeos::MountLibrary::Disk*>( "device_path2", new chromeos::MountLibrary::Disk("device_path2", - "mount_path2", + "/media/removable/mount_path2", "system_path2", "file_path2", "device_label2", @@ -81,7 +81,7 @@ class ExtensionFileBrowserPrivateApiTest : public ExtensionApiTest { std::pair<std::string, chromeos::MountLibrary::Disk*>( "device_path3", new chromeos::MountLibrary::Disk("device_path3", - "mount_path3", + "/media/removable/mount_path3", "system_path3", "file_path3", "device_label3", diff --git a/chrome/browser/resources/file_manager/js/file_manager.js b/chrome/browser/resources/file_manager/js/file_manager.js index 17b9939..f63753f 100644 --- a/chrome/browser/resources/file_manager/js/file_manager.js +++ b/chrome/browser/resources/file_manager/js/file_manager.js @@ -1516,6 +1516,7 @@ FileManager.prototype = { if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) { // Since unmount task cannot be defined in terms of file patterns, // we manually include it here, if all selected items are mount points. + this.taskButtons_.innerHTML = ''; chrome.fileBrowserPrivate.getFileTasks( selection.urls, this.onTasksFound_.bind(this, @@ -1594,8 +1595,6 @@ FileManager.prototype = { title: '' }); } - - this.taskButtons_.innerHTML = ''; for (var i = 0; i < tasksList.length; i++) { var task = tasksList[i]; @@ -1631,20 +1630,79 @@ FileManager.prototype = { task.title = str('UNMOUNT_ARCHIVE'); } } + this.renderTaskButton_(task); + } + // This needs to be done in sparate function, as check requires + // asynchronous function calls. + this.maybeRenderFormattingTask_(); + }; + + FileManager.prototype.renderTaskButton_ = function(task) { + var button = this.document_.createElement('button'); + button.addEventListener('click', this.onTaskButtonClicked_.bind(this)); + button.className = 'task-button'; + button.task = task; + + var img = this.document_.createElement('img'); + img.src = task.iconUrl; - var button = this.document_.createElement('button'); - button.addEventListener('click', this.onTaskButtonClicked_.bind(this)); - button.className = 'task-button'; - button.task = task; + button.appendChild(img); + button.appendChild(this.document_.createTextNode(task.title)); + + this.taskButtons_.appendChild(button); + }; + + /** + * Checks whether formatting task should be displayed and if the answer is + * affirmative renders it. Includes asynchronous calls, so it's splitted into + * three parts. + */ + FileManager.prototype.maybeRenderFormattingTask_ = function() { + // Not to make unnecesary getMountPoints() call we doublecheck if there is + // only one selected entry. + if (this.selection.entries.length != 1) + return; + var self = this; + function onMountPointsFound(mountPoints) { + self.mountPoints_ = mountPoints; - var img = this.document_.createElement('img'); - img.src = task.iconUrl; + function normalize(x) { + if (x[0] == '/') + return x.slice(1); + else + return x; + } - button.appendChild(img); - button.appendChild(this.document_.createTextNode(task.title)); + function onVolumeMetadataFound(volumeMetadata) { + if (volumeMetadata.deviceType == "flash") { + if (self.selection.entries.length != 1 || + normalize(self.selection.entries[0].fullPath) != + normalize(volumeMetadata.mountPath)) { + return; + } + var task = { + taskId: self.getExtensionId_() + '|format-device', + iconUrl: chrome.extension.getURL('images/filetype_generic.png'), + title: str('FORMAT_DEVICE') + }; + self.renderTaskButton_(task); + } + } - this.taskButtons_.appendChild(button); + if (self.selection.entries.length != 1) + return; + var selectedPath = self.selection.entries[0].fullPath; + for (var i = 0; i < mountPoints.length; i++) { + if (mountPoints[i].mountType == "device" && + normalize(mountPoints[i].mountPath) == normalize(selectedPath)) { + chrome.fileBrowserPrivate.getVolumeMetadata(mountPoints[i].sourceUrl, + onVolumeMetadataFound); + return; + } + } } + + chrome.fileBrowserPrivate.getMountPoints(onMountPointsFound); }; FileManager.prototype.getExtensionId_ = function() { @@ -1720,6 +1778,10 @@ FileManager.prototype = { for (var index = 0; index < urls.length; ++index) { chrome.fileBrowserPrivate.removeMount(urls[index]); } + } else if (id == 'format-device') { + this.confirm.show(str('FORMATTING_WARNING'), function() { + chrome.fileBrowserPrivate.formatDevice(urls[0]); + }); } }; diff --git a/chrome/browser/resources/file_manager/js/mock_chrome.js b/chrome/browser/resources/file_manager/js/mock_chrome.js index 453041d..70bb972 100644 --- a/chrome/browser/resources/file_manager/js/mock_chrome.js +++ b/chrome/browser/resources/file_manager/js/mock_chrome.js @@ -221,6 +221,7 @@ chrome.fileBrowserPrivate = { MOUNT_ARCHIVE: 'Open archive', UNMOUNT_ARCHIVE: 'Close archive', + FORMAT_DEVICE: 'Format device', CONFIRM_OVERWRITE_FILE: 'A file named "$1" already exists. Do you want to replace it?', FILE_ALREADY_EXISTS: 'The file named "$1" already exists. Please choose a different name.', diff --git a/chrome/test/data/extensions/api_test/filebrowser_mount/test.html b/chrome/test/data/extensions/api_test/filebrowser_mount/test.html index f3cdb90..387bc7e 100644 --- a/chrome/test/data/extensions/api_test/filebrowser_mount/test.html +++ b/chrome/test/data/extensions/api_test/filebrowser_mount/test.html @@ -2,7 +2,7 @@ // These have to be sync'd with extension_file_browser_private_apitest.cc var expectedVolume1 = { devicePath: 'device_path1', - mountPath: 'mount_path1', + mountPath: 'removable/mount_path1', systemPath: 'system_path1', filePath: 'file_path1', deviceLabel: 'device_label1', @@ -18,6 +18,7 @@ var expectedVolume1 = { var expectedVolume2 = { devicePath: 'device_path2', mountPath: 'mount_path2', + mountPath: 'removable/mount_path2', systemPath: 'system_path2', filePath: 'file_path2', deviceLabel: 'device_label2', @@ -33,6 +34,7 @@ var expectedVolume2 = { var expectedVolume3 = { devicePath: 'device_path3', mountPath: 'mount_path3', + mountPath: 'removable/mount_path3', systemPath: 'system_path3', filePath: 'file_path3', deviceLabel: 'device_label3', |