Skip to content

Commit

Permalink
Cleanup MIME handling in launcher.cc.
Browse files Browse the repository at this point in the history
This is the final patch in the MIME cleanup efforts in order to enable provided
file systems work with file handlers.

TEST=unit_test: *FileHandlersMimeUtilTest*
BUG=379036
R=benwells@chromium.org, kinaba@chromium.org

Review URL: https://codereview.chromium.org/364793003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281218 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
mtomasz@chromium.org committed Jul 3, 2014
1 parent 97df3be commit fb6de88
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 165 deletions.
2 changes: 1 addition & 1 deletion apps/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ include_rules = [
# Temporary allowed includes.
# TODO(benwells): remove these (http://crbug.com/159366)
"+chrome/browser/chrome_notification_types.h",
"+chrome/browser/chromeos/file_manager/filesystem_api_util.h",
"+chrome/browser/chromeos/login/users/user_manager.h",
"+chrome/browser/lifetime/application_lifetime.h",
"+chrome/browser/profiles",
Expand All @@ -30,6 +29,7 @@ include_rules = [
# Pieces of the extensions system that need to move to src/extensions.
# See http://crbug.com/162530 for details.
"+chrome/browser/extensions/api/file_handlers/app_file_handler_util.h",
"+chrome/browser/extensions/api/file_handlers/mime_util.h",
"+chrome/browser/extensions/api/file_system/file_system_api.h",
"+chrome/browser/extensions/chrome_extension_web_contents_observer.h",
"+chrome/browser/extensions/suggest_permission_util.h",
Expand Down
132 changes: 24 additions & 108 deletions apps/launcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
#include "chrome/browser/extensions/api/file_handlers/mime_util.h"
#include "chrome/browser/extensions/api/file_system/file_system_api.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
Expand All @@ -32,13 +33,10 @@
#include "extensions/common/extension_messages.h"
#include "extensions/common/manifest_handlers/kiosk_mode_info.h"
#include "net/base/filename_util.h"
#include "net/base/mime_sniffer.h"
#include "net/base/mime_util.h"
#include "net/base/net_util.h"
#include "url/gurl.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/file_manager/filesystem_api_util.h"
#include "chrome/browser/chromeos/login/users/user_manager.h"
#endif

Expand Down Expand Up @@ -101,12 +99,15 @@ class PlatformAppPathLauncher
PlatformAppPathLauncher(Profile* profile,
const Extension* extension,
const std::vector<base::FilePath>& file_paths)
: profile_(profile), extension_(extension), file_paths_(file_paths) {}
: profile_(profile),
extension_(extension),
file_paths_(file_paths),
collector_(profile) {}

PlatformAppPathLauncher(Profile* profile,
const Extension* extension,
const base::FilePath& file_path)
: profile_(profile), extension_(extension) {
: profile_(profile), extension_(extension), collector_(profile) {
if (!file_path.empty())
file_paths_.push_back(file_path);
}
Expand All @@ -127,12 +128,12 @@ class PlatformAppPathLauncher
file_paths_,
profile_,
false,
base::Bind(&PlatformAppPathLauncher::OnFileValid, this),
base::Bind(&PlatformAppPathLauncher::OnFileInvalid, this));
base::Bind(&PlatformAppPathLauncher::OnFilesValid, this),
base::Bind(&PlatformAppPathLauncher::OnFilesInvalid, this));
return;
}

OnFileValid();
OnFilesValid();
}

void LaunchWithHandler(const std::string& handler_id) {
Expand Down Expand Up @@ -175,116 +176,30 @@ class PlatformAppPathLauncher
base::Bind(&PlatformAppPathLauncher::Launch, this));
}

void OnFileValid() {
mime_types_.resize(file_paths_.size());
#if defined(OS_CHROMEOS)
GetNextNonNativeMimeType();
#else
BrowserThread::PostTask(
BrowserThread::FILE,
FROM_HERE,
base::Bind(&PlatformAppPathLauncher::GetMimeTypesAndLaunch, this));
#endif
void OnFilesValid() {
collector_.CollectForLocalPaths(
file_paths_,
base::Bind(&PlatformAppPathLauncher::OnMimeTypesCollected, this));
}

void OnFileInvalid(const base::FilePath& /* error_path */) {
void OnFilesInvalid(const base::FilePath& /* error_path */) {
LaunchWithNoLaunchData();
}

#if defined(OS_CHROMEOS)
void GetNextNonNativeMimeType() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);

bool any_native_files = false;
for (size_t i = 0; i < mime_types_.size(); ++i) {
if (!mime_types_[i].empty())
continue;
const base::FilePath& file_path = file_paths_[i];
if (file_manager::util::IsUnderNonNativeLocalPath(profile_, file_path)) {
file_manager::util::GetNonNativeLocalPathMimeType(
profile_,
file_path,
base::Bind(&PlatformAppPathLauncher::OnGotMimeType, this, i));
return;
}
any_native_files = true;
}

// If there are any native files, we need to call GetMimeTypesAndLaunch to
// obtain mime types for the files.
if (any_native_files) {
BrowserThread::PostTask(
BrowserThread::FILE,
FROM_HERE,
base::Bind(&PlatformAppPathLauncher::GetMimeTypesAndLaunch, this));
return;
}

// Otherwise, we can call LaunchWithMimeTypes directly.
LaunchWithMimeTypes();
}

void OnGotMimeType(size_t index, bool success, const std::string& mime_type) {
if (!success) {
LaunchWithNoLaunchData();
return;
}
mime_types_[index] = mime_type.empty() ? kFallbackMimeType : mime_type;
GetNextNonNativeMimeType();
}
#endif

void GetMimeTypesAndLaunch() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);

for (size_t i = 0; i < mime_types_.size(); ++i) {
if (!this->mime_types_[i].empty())
continue;
const base::FilePath& file_path = file_paths_[i];

// If the file doesn't exist, or is a directory, launch with no launch
// data.
if (!base::PathExists(file_path) || base::DirectoryExists(file_path)) {
LOG(WARNING) << "No file exists with path " << file_path.value();
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&PlatformAppPathLauncher::LaunchWithNoLaunchData, this));
return;
}

std::string mime_type;
if (!net::GetMimeTypeFromFile(file_path, &mime_type)) {
// If MIME type of the file can't be determined by its path,
// try to sniff it by its content.
std::vector<char> content(net::kMaxBytesToSniff);
int bytes_read = base::ReadFile(file_path, &content[0], content.size());
if (bytes_read >= 0) {
net::SniffMimeType(&content[0],
bytes_read,
net::FilePathToFileURL(file_path),
std::string(), // type_hint (passes no hint)
&mime_type);
}
if (mime_type.empty())
mime_type = kFallbackMimeType;
}
mime_types_[i] = mime_type;
}

BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&PlatformAppPathLauncher::LaunchWithMimeTypes, this));
}

void LaunchWithNoLaunchData() {
// This method is required as an entry point on the UI thread.
LaunchPlatformAppWithNoData(profile_, extension_);
}

void LaunchWithMimeTypes() {
DCHECK(file_paths_.size() == mime_types_.size());
void OnMimeTypesCollected(scoped_ptr<std::vector<std::string> > mime_types) {
DCHECK(file_paths_.size() == mime_types->size());

// If fetching a mime type failed, then use a fallback one.
for (size_t i = 0; i < mime_types->size(); ++i) {
const std::string mime_type =
!(*mime_types)[i].empty() ? (*mime_types)[i] : kFallbackMimeType;
mime_types_.push_back(mime_type);
}

// Find file handler from the platform app for the file being opened.
const extensions::FileHandlerInfo* handler = NULL;
Expand Down Expand Up @@ -383,6 +298,7 @@ class PlatformAppPathLauncher
std::vector<std::string> mime_types_;
// The ID of the file handler used to launch the app.
std::string handler_id_;
extensions::app_file_handler_util::MimeTypeCollector collector_;

DISALLOW_COPY_AND_ASSIGN(PlatformAppPathLauncher);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
#include "chrome/browser/chromeos/file_manager/mime_util.h"
#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
#include "chrome/browser/extensions/api/file_handlers/mime_util.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/filename_util.h"
Expand Down Expand Up @@ -150,7 +150,7 @@ bool FileBrowserPrivateGetFileTasksFunction::RunAsync() {
local_paths_.push_back(file_system_url.path());
}

collector_.reset(new file_manager::util::MimeTypeCollector(GetProfile()));
collector_.reset(new app_file_handler_util::MimeTypeCollector(GetProfile()));
collector_->CollectForLocalPaths(
local_paths_,
base::Bind(&FileBrowserPrivateGetFileTasksFunction::OnMimeTypesCollected,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ namespace base {
class FilePath;
} // namespace base

namespace file_manager {
namespace util {
class MimeTypeCollector;
} // namespace util
} // namespace file_manager

namespace extensions {

namespace app_file_handler_util {
class MimeTypeCollector;
} // namespace app_file_handler_util

// Implements the chrome.fileBrowserPrivate.executeTask method.
class FileBrowserPrivateExecuteTaskFunction
: public LoggedAsyncExtensionFunction {
Expand Down Expand Up @@ -66,7 +64,7 @@ class FileBrowserPrivateGetFileTasksFunction
scoped_ptr<app_file_handler_util::PathAndMimeTypeSet> path_mime_set,
scoped_ptr<std::vector<GURL> > file_urls);

scoped_ptr<file_manager::util::MimeTypeCollector> collector_;
scoped_ptr<app_file_handler_util::MimeTypeCollector> collector_;
std::vector<GURL> file_urls_;
std::vector<base::FilePath> local_paths_;
};
Expand Down
4 changes: 2 additions & 2 deletions chrome/browser/chromeos/file_manager/open_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
#include "chrome/browser/chromeos/file_manager/app_id.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/mime_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
Expand Down Expand Up @@ -131,7 +131,7 @@ void OpenFile(Profile* profile,
const base::FilePath& path,
const GURL& url,
const base::Callback<void(bool)>& callback) {
GetMimeTypeForLocalPath(
extensions::app_file_handler_util::GetMimeTypeForLocalPath(
profile,
path,
base::Bind(&OpenFileWithMimeType, profile, path, url, callback));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/file_manager/mime_util.h"
#include "chrome/browser/extensions/api/file_handlers/mime_util.h"

#include "base/file_util.h"
#include "base/files/file_path.h"
#include "chrome/browser/chromeos/file_manager/filesystem_api_util.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/filename_util.h"
#include "net/base/mime_sniffer.h"
#include "net/base/mime_util.h"
#include "webkit/browser/fileapi/file_system_url.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/file_manager/filesystem_api_util.h"
#endif

using content::BrowserThread;

namespace file_manager {
namespace util {
namespace extensions {
namespace app_file_handler_util {
namespace {

// Detects MIME type by reading initial bytes from the file. If found, then
Expand All @@ -36,6 +40,7 @@ void SniffMimeType(const base::FilePath& local_path, std::string* result) {
}
}

#if defined(OS_CHROMEOS)
// Called when fetching MIME type for a non-native local path is completed.
// If |success| is false, then tries to guess the MIME type by looking at the
// file name.
Expand All @@ -53,6 +58,7 @@ void OnGetMimeTypeForNonNativeLocalPathCompleted(
net::GetMimeTypeFromFile(local_path, &mime_type_from_extension);
callback.Run(mime_type_from_extension);
}
#endif

// Called when sniffing for MIME type in the native local file is completed.
void OnSniffMimeTypeForNativeLocalPathCompleted(
Expand All @@ -67,32 +73,35 @@ void GetMimeTypeForLocalPath(
Profile* profile,
const base::FilePath& local_path,
const base::Callback<void(const std::string&)>& callback) {
if (IsUnderNonNativeLocalPath(profile, local_path)) {
#if defined(OS_CHROMEOS)
if (file_manager::util::IsUnderNonNativeLocalPath(profile, local_path)) {
// For non-native files, try to get the MIME type from metadata. If not
// available, then try to guess from the extension. Never sniff (because
// it can be very slow).
GetNonNativeLocalPathMimeType(
file_manager::util::GetNonNativeLocalPathMimeType(
profile,
local_path,
base::Bind(&OnGetMimeTypeForNonNativeLocalPathCompleted,
local_path,
callback));
return;
}
#endif

// For native local files, try to guess the mime from the extension. If
// not availble, then try to sniff if.
std::string mime_type_from_extension;
if (net::GetMimeTypeFromFile(local_path, &mime_type_from_extension)) {
callback.Run(mime_type_from_extension);
} else {
// For native local files, try to guess the mime from the extension. If
// not availble, then try to sniff if.
std::string mime_type_from_extension;
if (net::GetMimeTypeFromFile(local_path, &mime_type_from_extension)) {
callback.Run(mime_type_from_extension);
} else {
scoped_ptr<std::string> sniffed_mime_type(new std::string);
std::string* sniffed_mime_type_ptr = sniffed_mime_type.get();
BrowserThread::PostBlockingPoolTaskAndReply(
FROM_HERE,
base::Bind(&SniffMimeType, local_path, sniffed_mime_type_ptr),
base::Bind(&OnSniffMimeTypeForNativeLocalPathCompleted,
base::Passed(&sniffed_mime_type),
callback));
}
scoped_ptr<std::string> sniffed_mime_type(new std::string);
std::string* sniffed_mime_type_ptr = sniffed_mime_type.get();
BrowserThread::PostBlockingPoolTaskAndReply(
FROM_HERE,
base::Bind(&SniffMimeType, local_path, sniffed_mime_type_ptr),
base::Bind(&OnSniffMimeTypeForNativeLocalPathCompleted,
base::Passed(&sniffed_mime_type),
callback));
}
}

Expand Down Expand Up @@ -154,5 +163,5 @@ void MimeTypeCollector::OnMimeTypeCollected(size_t index,
}
}

} // namespace util
} // namespace file_manager
} // namespace app_file_handler_util
} // namespace extensions
Loading

0 comments on commit fb6de88

Please sign in to comment.