#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/file_manager/app_id.h"
-#include "chrome/browser/chromeos/file_manager/file_browser_handlers.h"
#include "chrome/browser/chromeos/file_manager/file_tasks.h"
#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
#include "chrome/browser/chromeos/file_manager/mime_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/chromeos/file_manager/url_util.h"
-#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/simple_message_box.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/storage_partition.h"
#include "content/public/browser/user_metrics.h"
-#include "extensions/browser/extension_system.h"
#include "google_apis/drive/task_util.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "webkit/browser/fileapi/file_system_url.h"
using content::BrowserThread;
-using extensions::Extension;
-using extensions::app_file_handler_util::FindFileHandlersForFiles;
-using extensions::app_file_handler_util::PathAndMimeTypeSet;
using fileapi::FileSystemURL;
namespace file_manager {
namespace {
// Shows a warning message box saying that the file could not be opened.
-void ShowWarningMessageBox(Profile* profile, const base::FilePath& file_path) {
+void ShowWarningMessageBox(Profile* profile,
+ const base::FilePath& file_path,
+ int message_id) {
Browser* browser = chrome::FindTabbedBrowser(
profile, false, chrome::HOST_DESKTOP_TYPE_ASH);
chrome::ShowMessageBox(
l10n_util::GetStringFUTF16(
IDS_FILE_BROWSER_ERROR_VIEWING_FILE_TITLE,
base::UTF8ToUTF16(file_path.BaseName().AsUTF8Unsafe())),
- l10n_util::GetStringUTF16(IDS_FILE_BROWSER_ERROR_VIEWING_FILE),
+ l10n_util::GetStringUTF16(message_id),
chrome::MESSAGE_BOX_TYPE_WARNING);
}
-// Grants file system access to the file manager.
-bool GrantFileSystemAccessToFileBrowser(Profile* profile) {
- // The file manager always runs in the site for its extension id, so that
- // is the site for which file access permissions should be granted.
- fileapi::ExternalFileSystemBackend* backend =
- GetFileSystemContextForExtensionId(
- profile, kFileManagerAppId)->external_backend();
- if (!backend)
- return false;
- backend->GrantFullAccessToExtension(kFileManagerAppId);
- return true;
-}
-
// Executes the |task| for the file specified by |url|.
void ExecuteFileTaskForUrl(Profile* profile,
const file_tasks::TaskDescriptor& task,
file_tasks::FileTaskFinishedCallback());
}
-// Opens the file manager for the specified |file_path|. Used to implement
+// Opens the file manager for the specified |url|. Used to implement
// internal handlers of special action IDs:
//
// "open" - Open the file manager for the given folder.
// "select" - Open the file manager for the given file. The folder containing
// the file will be opened with the file selected.
void OpenFileManagerWithInternalActionId(Profile* profile,
- const base::FilePath& file_path,
+ const GURL& url,
const std::string& action_id) {
DCHECK(action_id == "auto-open" ||
action_id == "open" ||
action_id == "select");
-
content::RecordAction(base::UserMetricsAction("ShowFileBrowserFullTab"));
- GURL url;
- if (!ConvertAbsoluteFilePathToFileSystemUrl(
- profile, file_path, kFileManagerAppId, &url))
- return;
-
file_tasks::TaskDescriptor task(kFileManagerAppId,
file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER,
action_id);
ExecuteFileTaskForUrl(profile, task, url);
}
-// Opens the file specified by |file_path| by finding and executing a file
+// Opens the file specified by |url| by finding and executing a file
// task for the file. Returns false if failed to open the file (i.e. no file
// task is found).
-bool OpenFile(Profile* profile, const base::FilePath& file_path) {
- GURL url;
- if (!ConvertAbsoluteFilePathToFileSystemUrl(
- profile, file_path, kFileManagerAppId, &url))
- return false;
-
+// TODO(fukino): curbug.com/352250. Currently |path| is used only for retrieving
+// file extension, but we might want to sniff file contents and infer mime type.
+bool OpenFile(Profile* profile, const base::FilePath& path, const GURL& url) {
// The file is opened per the file extension, hence extension-less files
// cannot be opened properly.
- std::string mime_type = GetMimeTypeForPath(file_path);
+ std::string mime_type = GetMimeTypeForPath(path);
extensions::app_file_handler_util::PathAndMimeTypeSet path_mime_set;
- path_mime_set.insert(std::make_pair(file_path, mime_type));
+ path_mime_set.insert(std::make_pair(path, mime_type));
std::vector<GURL> file_urls;
file_urls.push_back(url);
// Used to implement OpenItem().
void ContinueOpenItem(Profile* profile,
const base::FilePath& file_path,
+ const GURL& url,
base::File::Error error) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (error == base::File::FILE_OK) {
- // A directory exists at |file_path|. Open it with the file manager.
- OpenFileManagerWithInternalActionId(profile, file_path, "open");
+ // A directory exists at |url|. Open it with the file manager.
+ OpenFileManagerWithInternalActionId(profile, url, "open");
} else {
- // |file_path| should be a file. Open it.
- if (!OpenFile(profile, file_path))
- ShowWarningMessageBox(profile, file_path);
+ // |url| should be a file. Open it.
+ if (!OpenFile(profile, file_path, url)) {
+ ShowWarningMessageBox(profile, file_path,
+ IDS_FILE_BROWSER_ERROR_VIEWING_FILE);
+ }
}
}
const fileapi::FileSystemOperationRunner::StatusCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // Check the existence of directory using file system API implementation on
+ // behalf of the file manager app. We need to grant access beforehand.
+ fileapi::ExternalFileSystemBackend* backend =
+ file_system_context->external_backend();
+ DCHECK(backend);
+ backend->GrantFullAccessToExtension(kFileManagerAppId);
+
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&CheckIfDirectoryExistsOnIOThread,
google_apis::CreateRelayCallback(callback)));
}
+// Converts the |given_path| passed from external callers to the form that the
+// file manager can correctly handle. It first migrates old Drive/Download
+// folder path to the new formats, and then converts path to filesystem URL.
+//
+// When conversion fails, it shows a warning dialog UI and returns false.
+bool ConvertPath(Profile* profile,
+ const base::FilePath& given_path,
+ base::FilePath* path,
+ GURL* url) {
+ // The path may have been stored in preferences in old versions.
+ // We need migration here.
+ // TODO(kinaba): crbug.com/313539 remove it in the future.
+ if (!util::MigratePathFromOldFormat(profile, given_path, path))
+ *path = given_path;
+
+ if (!ConvertAbsoluteFilePathToFileSystemUrl(
+ profile, *path, kFileManagerAppId, url)) {
+ ShowWarningMessageBox(profile, *path,
+ IDS_FILE_BROWSER_ERROR_UNRESOLVABLE_FILE);
+ return false;
+ }
+ return true;
+}
+
} // namespace
void OpenRemovableDrive(Profile* profile, const base::FilePath& file_path) {
- OpenFileManagerWithInternalActionId(profile, file_path, "auto-open");
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ base::FilePath converted_path;
+ GURL url;
+ if (!ConvertPath(profile, file_path, &converted_path, &url))
+ return;
+
+ OpenFileManagerWithInternalActionId(profile, url, "auto-open");
}
void OpenItem(Profile* profile, const base::FilePath& file_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // The path may have been stored in preferences in old versions.
- // We need migration here.
- // TODO(kinaba): crbug.com/313539 remove it in the future.
- base::FilePath path;
- if (!util::MigratePathFromOldFormat(profile, file_path, &path))
- path = file_path;
-
+ base::FilePath converted_path;
GURL url;
- if (!ConvertAbsoluteFilePathToFileSystemUrl(
- profile, path, kFileManagerAppId, &url) ||
- !GrantFileSystemAccessToFileBrowser(profile)) {
- ShowWarningMessageBox(profile, path);
+ if (!ConvertPath(profile, file_path, &converted_path, &url))
return;
- }
-
- scoped_refptr<fileapi::FileSystemContext> file_system_context =
- GetFileSystemContextForExtensionId(
- profile, kFileManagerAppId);
- CheckIfDirectoryExists(file_system_context, url,
- base::Bind(&ContinueOpenItem, profile, path));
+ CheckIfDirectoryExists(
+ GetFileSystemContextForExtensionId(profile, kFileManagerAppId),
+ url,
+ base::Bind(&ContinueOpenItem, profile, converted_path, url));
}
void ShowItemInFolder(Profile* profile, const base::FilePath& file_path) {
- // The path may have been stored in preferences in old versions.
- // We need migration here.
- // TODO(kinaba): crbug.com/313539 remove it in the future.
- base::FilePath path;
- if (!util::MigratePathFromOldFormat(profile, file_path, &path))
- path = file_path;
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ base::FilePath converted_path;
+ GURL url;
+ if (!ConvertPath(profile, file_path, &converted_path, &url))
+ return;
// This action changes the selection so we do not reuse existing tabs.
- OpenFileManagerWithInternalActionId(profile, path, "select");
+ OpenFileManagerWithInternalActionId(profile, url, "select");
}
} // namespace util