Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / file_manager / open_util.cc
index 45d107d..b16ffc8 100644 (file)
 #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"
@@ -38,9 +30,6 @@
 #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 {
@@ -48,7 +37,9 @@ namespace util {
 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(
@@ -56,23 +47,10 @@ void ShowWarningMessageBox(Profile* profile, const base::FilePath& file_path) {
       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,
@@ -88,7 +66,7 @@ void ExecuteFileTaskForUrl(Profile* profile,
       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.
@@ -97,39 +75,30 @@ void ExecuteFileTaskForUrl(Profile* profile,
 // "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);
@@ -159,16 +128,19 @@ bool OpenFile(Profile* profile, const base::FilePath& file_path) {
 // 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);
+    }
   }
 }
 
@@ -191,6 +163,13 @@ void CheckIfDirectoryExists(
     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,
@@ -199,48 +178,67 @@ void CheckIfDirectoryExists(
                  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