Commit 3fd9004c authored by tbarzic@chromium.org's avatar tbarzic@chromium.org

Revert Revert 94812 - Formatting feature initial commit for ChromeOS Tree

Previously reviewed and landed.

Reverting to make merging next patch into M14 easier.

Added formatting API for browser extension as well as event routing. 
Created a complete UI for formatting.

This code depends on the following changes to libcros:
http://gerrit.chromium.org/gerrit/#change,4446

BUG=chromium-os:4541, chromium-os:17071
TEST=Try to format removable media.


Review URL: http://codereview.chromium.org/7471024

TBR=sidor@chromium.org
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=95909
Review URL: http://codereview.chromium.org/7628011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96493 0039d316-1c4b-4281-b951-d872f2087c98
parent 9af656c0
......@@ -9066,6 +9066,10 @@ Keep your key file in a safe place. You will need it to create new versions of y
Are you sure you want to delete $1 items?
</message>
<message name="IDS_FILE_BROWSER_FORMATTING_WARNING" desc="Displayed when you attempt to format device.">
Formatting the removable media is going to erase all data. Do you wish to continue?
</message>
<message name="IDS_FILE_BROWSER_SELECT_FOLDER_TITLE" desc="Select folder title.">
Select a folder to open
</message>
......@@ -12276,6 +12280,26 @@ Keep your key file in a safe place. You will need it to create new versions of y
Sorry, the external storage device is not supported on your Chromebook at this time.
</message>
<!-- Formatting device notifications -->
<message name="IDS_FORMATTING_OF_DEVICE_PENDING_TITLE" desc="Text of notification message which is shown when formatting process of some device is pending">
Formatting pending
</message>
<message name="IDS_FORMATTING_OF_DEVICE_FINISHED_TITLE" desc="Text of notification message which is shown when formatting process finshes">
Formatting finished
</message>
<message name="IDS_FORMATTING_OF_DEVICE_PENDING_MESSAGE" desc="Text of notification message which is shown when formatting process of some device is pending">
The formatting process can take a couple of seconds. Please wait.
</message>
<message name="IDS_FORMATTING_STARTED_FAILURE_MESSAGE" desc="Text of notification message which is shown when formatting process can not be started.">
Could not start the formatting process.
</message>
<message name="IDS_FORMATTING_FINISHED_SUCCESS_MESSAGE" desc="Text of notification message which is shown when formatting finishes without any errors.">
Formatting finished successfully!
</message>
<message name="IDS_FORMATTING_FINISHED_FAILURE_MESSAGE" desc="Text of notification message which is shown when there are some errors while formatting.">
Aw, Snap! There've been some errors while formatting...
</message>
<!-- Network state strings for ChromeOS -->
<message name="IDS_CHROMEOS_NETWORK_STATE_UNKNOWN" desc="Network state in about:network: UNKNOWN">
Unknown
......
......@@ -132,6 +132,10 @@ void MockMountLibrary::SetupDefaultReplies() {
.Times(AnyNumber());
EXPECT_CALL(*this, UnmountPath(_))
.Times(AnyNumber());
EXPECT_CALL(*this, FormatUnmountedDevice(_))
.Times(AnyNumber());
EXPECT_CALL(*this, FormatMountedDevice(_))
.Times(AnyNumber());
EXPECT_CALL(*this, UnmountDeviceRecursive(_, _, _))
.Times(AnyNumber());
}
......
......@@ -31,6 +31,8 @@ class MockMountLibrary : public MountLibrary {
MOCK_METHOD3(MountPath, void(const char*, MountType,
const MountPathOptions&));
MOCK_METHOD1(UnmountPath, void(const char*));
MOCK_METHOD1(FormatUnmountedDevice, void(const char*));
MOCK_METHOD1(FormatMountedDevice, void(const char*));
MOCK_METHOD3(UnmountDeviceRecursive, void(const char*,
MountLibrary::UnmountDeviceRecursiveCallbackType, void*));
......
......@@ -5,6 +5,7 @@
#include "chrome/browser/chromeos/cros/mount_library.h"
#include <set>
#include <vector>
#include "base/message_loop.h"
#include "base/string_util.h"
......@@ -143,6 +144,63 @@ class MountLibraryImpl : public MountLibrary {
this);
}
virtual void FormatUnmountedDevice(const char* file_path) OVERRIDE {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!CrosLibrary::Get()->EnsureLoaded()) {
OnFormatDevice(file_path,
false,
MOUNT_METHOD_ERROR_LOCAL,
kLibraryNotLoaded);
return;
}
for (MountLibrary::DiskMap::iterator it = disks_.begin();
it != disks_.end(); ++it) {
if (it->second->file_path().compare(file_path) == 0 &&
!it->second->mount_path().empty()) {
OnFormatDevice(file_path,
false,
MOUNT_METHOD_ERROR_LOCAL,
"Device is still mounted.");
return;
}
}
FormatDevice(file_path,
"vfat", // currently format in vfat by default
&MountLibraryImpl::FormatDeviceCallback,
this);
}
virtual void FormatMountedDevice(const char* mount_path) OVERRIDE {
DCHECK(mount_path);
Disk* disk = NULL;
for (MountLibrary::DiskMap::iterator it = disks_.begin();
it != disks_.end(); ++it) {
if (it->second->mount_path().compare(mount_path) == 0) {
disk = it->second;
break;
}
}
if (!disk) {
OnFormatDevice(disk->device_path().c_str(),
false,
MOUNT_METHOD_ERROR_LOCAL,
"Device with this mount path not found.");
return;
}
if (formatting_pending_.find(disk->device_path()) !=
formatting_pending_.end()) {
OnFormatDevice(disk->device_path().c_str(),
false,
MOUNT_METHOD_ERROR_LOCAL,
"Formatting is already pending.");
return;
}
// Formatting process continues, after unmounting.
formatting_pending_[disk->device_path()] = disk->file_path();
UnmountPath(disk->mount_path().c_str());
}
virtual void UnmountDeviceRecursive(const char* device_path,
UnmountDeviceRecursiveCallbackType callback, void* user_data)
OVERRIDE {
......@@ -237,6 +295,17 @@ class MountLibraryImpl : public MountLibrary {
self->OnUnmountPath(mount_path, error, error_message);
}
// Callback for FormatRemovableDevice method.
static void FormatDeviceCallback(void* object,
const char* device_path,
bool success,
MountMethodErrorType error,
const char* error_message) {
DCHECK(object);
MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
self->OnFormatDevice(device_path, success, error, error_message);
}
// Callback for UnmountDeviceRecursive.
static void UnmountDeviceRecursiveCallback(void* object,
const char* mount_path,
......@@ -254,7 +323,7 @@ class MountLibraryImpl : public MountLibrary {
cb_data->success = false;
} else if (error == MOUNT_METHOD_ERROR_NONE) {
LOG(INFO) << mount_path << " unmounted.";
}
}
// This is safe as long as all callbacks are called on the same thread as
// UnmountDeviceRecursive.
......@@ -351,16 +420,21 @@ class MountLibraryImpl : public MountLibrary {
mount_points_it->second.mount_type));
std::string path(mount_points_it->second.source_path);
mount_points_.erase(mount_points_it);
DiskMap::iterator iter = disks_.find(path);
if (iter == disks_.end()) {
// disk might have been removed by now?
// disk might have been removed by now.
return;
}
Disk* disk = iter->second;
DCHECK(disk);
disk->clear_mount_path();
FireDiskStatusUpdate(MOUNT_DISK_UNMOUNTED, disk);
// Check if there is a formatting scheduled
PathMap::iterator it = formatting_pending_.find(disk->device_path());
if (it != formatting_pending_.end()) {
const std::string file_path = it->second;
formatting_pending_.erase(it);
FormatUnmountedDevice(file_path.c_str());
}
} else {
LOG(WARNING) << "Unmount request failed for device "
<< mount_path << ", with error: "
......@@ -368,6 +442,23 @@ class MountLibraryImpl : public MountLibrary {
}
}
void OnFormatDevice(const char* device_path,
bool success,
MountMethodErrorType error,
const char* error_message) {
DCHECK(device_path);
if (error == MOUNT_METHOD_ERROR_NONE && device_path && success) {
FireDeviceStatusUpdate(MOUNT_FORMATTING_STARTED, device_path);
} else {
FireDeviceStatusUpdate(MOUNT_FORMATTING_STARTED,
std::string("!") + device_path);
LOG(WARNING) << "Format request failed for device "
<< device_path << ", with error: "
<< (error_message ? error_message : "Unknown");
}
}
void OnGetDiskProperties(const char* device_path,
const DiskInfo* disk1,
MountMethodErrorType error,
......@@ -523,6 +614,10 @@ class MountLibraryImpl : public MountLibrary {
type = MOUNT_DEVICE_SCANNED;
break;
}
case FORMATTING_FINISHED: {
type = MOUNT_FORMATTING_FINISHED;
break;
}
default: {
return;
}
......@@ -574,6 +669,10 @@ class MountLibraryImpl : public MountLibrary {
MountLibrary::DiskMap disks_;
MountLibrary::MountPointMap mount_points_;
// Set of devices that are supposed to be formated, but are currently waiting
// to be unmounted. When device is in this map, the formatting process HAVEN'T
// started yet.
PathMap formatting_pending_;
DISALLOW_COPY_AND_ASSIGN(MountLibraryImpl);
};
......@@ -594,6 +693,8 @@ class MountLibraryStubImpl : public MountLibrary {
virtual void MountPath(const char* source_path, MountType type,
const MountPathOptions& options) OVERRIDE {}
virtual void UnmountPath(const char* mount_path) OVERRIDE {}
virtual void FormatUnmountedDevice(const char* device_path) OVERRIDE {}
virtual void FormatMountedDevice(const char* mount_path) OVERRIDE {}
virtual void UnmountDeviceRecursive(const char* device_path,
UnmountDeviceRecursiveCallbackType callback, void* user_data)
OVERRIDE {}
......
......@@ -24,7 +24,9 @@ typedef enum MountLibraryEventType {
MOUNT_DISK_UNMOUNTED,
MOUNT_DEVICE_ADDED,
MOUNT_DEVICE_REMOVED,
MOUNT_DEVICE_SCANNED
MOUNT_DEVICE_SCANNED,
MOUNT_FORMATTING_STARTED,
MOUNT_FORMATTING_FINISHED
} MountLibraryEventType;
// This class handles the interaction with the ChromeOS mount library APIs.
......@@ -100,6 +102,7 @@ class MountLibrary {
bool on_boot_device_;
};
typedef std::map<std::string, Disk*> DiskMap;
typedef std::map<std::string, std::string> PathMap;
struct MountPointInfo {
std::string source_path;
......@@ -144,6 +147,14 @@ class MountLibrary {
// |path| is device's mount path.
virtual void UnmountPath(const char* path) = 0;
// Formats device given its file path.
// Example: file_path: /dev/sdb1
virtual void FormatUnmountedDevice(const char* file_path) = 0;
// Formats Device given its mount path. Unmount's the device
// Example: mount_path: /media/VOLUME_LABEL
virtual void FormatMountedDevice(const char* mount_path) = 0;
// Unmounts device_poath and all of its known children.
virtual void UnmountDeviceRecursive(const char* device_path,
UnmountDeviceRecursiveCallbackType callback, void* user_data) = 0;
......
......@@ -27,6 +27,11 @@ class SystemNotification;
// found.
class ExtensionFileBrowserEventRouter
: public chromeos::MountLibrary::Observer {
friend void HideFileBrowserNotificationExternally(
const std::string& category, const std::string& system_path,
ExtensionFileBrowserEventRouter* that);
public:
explicit ExtensionFileBrowserEventRouter(Profile* profile);
virtual ~ExtensionFileBrowserEventRouter();
......@@ -87,13 +92,17 @@ class ExtensionFileBrowserEventRouter
// USB mount event handlers.
void OnDiskAdded(const chromeos::MountLibrary::Disk* disk);
void OnDiskRemoved(const chromeos::MountLibrary::Disk* disk);
void OnDiskMounted(const chromeos::MountLibrary::Disk* disk);
void OnDiskUnmounted(const chromeos::MountLibrary::Disk* disk);
void OnDeviceAdded(const std::string& device_path);
void OnDeviceRemoved(const std::string& device_path);
void OnDeviceScanned(const std::string& device_path);
void OnFormattingStarted(const std::string& device_path);
void OnFormattingFinished(const std::string& device_path);
// Finds first notifications corresponding to the same device. Ensures that
// we don't pop up multiple notifications for the same device.
NotificationMap::iterator FindNotificationForPath(const std::string& path);
NotificationMap::iterator FindNotificationForId(const std::string& path);
// Process file watch notifications.
void HandleFileWatchNotification(const FilePath& path,
......@@ -119,10 +128,13 @@ class ExtensionFileBrowserEventRouter
bool small);
// Show/hide desktop notifications.
void ShowDeviceNotification(const std::string& system_path,
int icon_resource_id,
const string16& message);
void HideDeviceNotification(const std::string& system_path);
void ShowFileBrowserNotification(const std::string& category,
const std::string& system_path,
int icon_resource_id,
const string16& title,
const string16& message);
void HideFileBrowserNotification(const std::string& category,
const std::string& system_path);
scoped_refptr<FileWatcherDelegate> delegate_;
MountPointMap mounted_devices_;
......
......@@ -639,7 +639,6 @@ class ExecuteTasksFileSystemCallbackDispatcher
}
virtual void DidFail(base::PlatformFileError error_code) OVERRIDE {
LOG(WARNING) << "Local file system cant be resolved";
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(function_,
......@@ -1212,12 +1211,11 @@ bool RemoveMountFunction::RunImpl() {
std::string mount_path;
if (!args_->GetString(0, &mount_path)) {
return false;
return false;
}
UrlList file_paths;
file_paths.push_back(GURL(mount_path));
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(this,
......@@ -1235,7 +1233,6 @@ void RemoveMountFunction::GetLocalPathsResponseOnUIThread(
SendResponse(false);
return;
}
#ifdef OS_CHROMEOS
chromeos::CrosLibrary::Get()->GetMountLibrary()->UnmountPath(
files[0].value().c_str());
......@@ -1257,7 +1254,7 @@ bool GetMountPointsFunction::RunImpl() {
base::ListValue *mounts = new base::ListValue();
result_.reset(mounts);
#ifdef OS_CHROMEOS
#ifdef OS_CHROMEOS
chromeos::MountLibrary *mount_lib =
chromeos::CrosLibrary::Get()->GetMountLibrary();
chromeos::MountLibrary::MountPointMap mount_points =
......@@ -1270,6 +1267,33 @@ bool GetMountPointsFunction::RunImpl() {
mounts->Append(MountPointToValue(profile_, it->second));
}
#endif
SendResponse(true);
return true;
}
FormatDeviceFunction::FormatDeviceFunction() {
}
FormatDeviceFunction::~FormatDeviceFunction() {
}
bool FormatDeviceFunction::RunImpl() {
if (args_->GetSize() != 1) {
return false;
}
std::string volume_mount_path;
if (!args_->GetString(0, &volume_mount_path)) {
NOTREACHED();
return false;
}
#ifdef OS_CHROMEOS
chromeos::CrosLibrary::Get()->GetMountLibrary()->FormatMountedDevice(
volume_mount_path.c_str());
#endif
SendResponse(true);
return true;
}
......@@ -1427,6 +1451,8 @@ bool FileDialogStringsFunction::RunImpl() {
SET_STRING(IDS_FILE_BROWSER, CONFIRM_DELETE_ONE);
SET_STRING(IDS_FILE_BROWSER, CONFIRM_DELETE_SOME);
SET_STRING(IDS_FILE_BROWSER, FORMATTING_WARNING);
SET_STRING(IDS_FILE_BROWSER, SELECT_FOLDER_TITLE);
SET_STRING(IDS_FILE_BROWSER, SELECT_OPEN_FILE_TITLE);
SET_STRING(IDS_FILE_BROWSER, SELECT_OPEN_MULTI_FILE_TITLE);
......
......@@ -277,6 +277,21 @@ class GetMountPointsFunction
DECLARE_EXTENSION_FUNCTION_NAME("fileBrowserPrivate.getMountPoints");
};
// Formats Device given its mount path.
class FormatDeviceFunction
: public SyncExtensionFunction {
public:
FormatDeviceFunction();
protected:
virtual ~FormatDeviceFunction();
virtual bool RunImpl() OVERRIDE;
private:
DECLARE_EXTENSION_FUNCTION_NAME("fileBrowserPrivate.formatDevice");
};
// Retrieves devices meta-data. Expects volume's device path as an argument.
class GetVolumeMetadataFunction
: public SyncExtensionFunction {
......
......@@ -369,6 +369,7 @@ void FactoryRegistry::ResetFunctions() {
RegisterFunction<AddMountFunction>();
RegisterFunction<RemoveMountFunction>();
RegisterFunction<GetMountPointsFunction>();
RegisterFunction<FormatDeviceFunction>();
RegisterFunction<ViewFilesFunction>();
// Mediaplayer
......
......@@ -6467,6 +6467,17 @@
]
}
]
},
{
"name": "formatDevice",
"description": "Formats a mounted device",
"parameters": [
{
"name": "mountPath",
"type": "string",
"description": "Device's mount path."
}
]
}
],
"events": [
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment