Index: apps/launcher.cc |
diff --git a/apps/launcher.cc b/apps/launcher.cc |
index 8d31a0115c46e671d56a953aa194942a20f388df..e081eb185f131589133144d3a6fa50d822c4ea9e 100644 |
--- a/apps/launcher.cc |
+++ b/apps/launcher.cc |
@@ -63,8 +63,8 @@ namespace { |
const char kFallbackMimeType[] = "application/octet-stream"; |
-bool MakePathAbsolute(const base::FilePath& current_directory, |
- base::FilePath* file_path) { |
+bool DoMakePathAbsolute(const base::FilePath& current_directory, |
+ base::FilePath* file_path) { |
DCHECK(file_path); |
if (file_path->IsAbsolute()) |
return true; |
@@ -81,27 +81,11 @@ bool MakePathAbsolute(const base::FilePath& current_directory, |
return true; |
} |
-bool GetAbsolutePathFromCommandLine(const CommandLine& command_line, |
- const base::FilePath& current_directory, |
- base::FilePath* path) { |
- if (!command_line.GetArgs().size()) |
- return false; |
- |
- base::FilePath relative_path(command_line.GetArgs()[0]); |
- base::FilePath absolute_path(relative_path); |
- if (!MakePathAbsolute(current_directory, &absolute_path)) { |
- LOG(WARNING) << "Cannot make absolute path from " << relative_path.value(); |
- return false; |
- } |
- *path = absolute_path; |
- return true; |
-} |
- |
// Helper method to launch the platform app |extension| with no data. This |
// should be called in the fallback case, where it has been impossible to |
// load or obtain file launch data. |
void LaunchPlatformAppWithNoData(Profile* profile, const Extension* extension) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
AppEventRouter::DispatchOnLaunchedEvent(profile, extension); |
} |
@@ -119,7 +103,7 @@ class PlatformAppPathLauncher |
: profile_(profile), extension_(extension), file_path_(file_path) {} |
void Launch() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
if (file_path_.empty()) { |
LaunchPlatformAppWithNoData(profile_, extension_); |
return; |
@@ -147,11 +131,33 @@ class PlatformAppPathLauncher |
Launch(); |
} |
+ void LaunchWithRelativePath(const base::FilePath& current_directory) { |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, |
+ FROM_HERE, |
+ base::Bind(&PlatformAppPathLauncher::MakePathAbsolute, |
+ this, |
+ current_directory)); |
+ } |
+ |
private: |
friend class base::RefCountedThreadSafe<PlatformAppPathLauncher>; |
virtual ~PlatformAppPathLauncher() {} |
+ void MakePathAbsolute(const base::FilePath& current_directory) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
+ |
+ if (!DoMakePathAbsolute(current_directory, &file_path_)) { |
+ LOG(WARNING) << "Cannot make absolute path from " << file_path_.value(); |
+ file_path_ = base::FilePath(); |
+ } |
+ |
+ BrowserThread::PostTask(BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&PlatformAppPathLauncher::Launch, this)); |
+ } |
+ |
void OnFileValid() { |
#if defined(OS_CHROMEOS) |
if (drive::util::IsUnderDriveMountPoint(file_path_)) { |
@@ -171,7 +177,7 @@ class PlatformAppPathLauncher |
} |
void GetMimeTypeAndLaunch() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
// If the file doesn't exist, or is a directory, launch with no launch data. |
if (!base::PathExists(file_path_) || |
@@ -205,7 +211,7 @@ class PlatformAppPathLauncher |
#if defined(OS_CHROMEOS) |
void GetMimeTypeAndLaunchForDriveFile() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
drive::FileSystemInterface* file_system = |
drive::util::GetFileSystemByProfile(profile_); |
@@ -222,7 +228,7 @@ class PlatformAppPathLauncher |
void OnGotDriveFile(drive::FileError error, |
const base::FilePath& file_path, |
scoped_ptr<drive::ResourceEntry> entry) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
if (error != drive::FILE_ERROR_OK || |
!entry || entry->file_specific_info().is_hosted_document()) { |
@@ -310,9 +316,12 @@ class PlatformAppPathLauncher |
// The profile the app should be run in. |
Profile* profile_; |
// The extension providing the app. |
+ // TODO(benwells): Hold onto the extension ID instead of a pointer as it |
+ // is possible the extension will be unloaded while we're doing our thing. |
+ // See http://crbug.com/372270 for details. |
const Extension* extension_; |
// The path to be passed through to the app. |
- const base::FilePath file_path_; |
+ base::FilePath file_path_; |
// The ID of the file handler used to launch the app. |
std::string handler_id_; |
@@ -342,22 +351,20 @@ void LaunchPlatformAppWithCommandLine(Profile* profile, |
} |
} |
- base::FilePath path; |
- if (!GetAbsolutePathFromCommandLine(command_line, current_directory, &path)) { |
+ if (command_line.GetArgs().empty()) { |
LaunchPlatformAppWithNoData(profile, extension); |
return; |
} |
- // TODO(benwells): add a command-line argument to provide a handler ID. |
- LaunchPlatformAppWithPath(profile, extension, path); |
+ base::FilePath file_path(command_line.GetArgs()[0]); |
+ scoped_refptr<PlatformAppPathLauncher> launcher = |
+ new PlatformAppPathLauncher(profile, extension, file_path); |
+ launcher->LaunchWithRelativePath(current_directory); |
} |
void LaunchPlatformAppWithPath(Profile* profile, |
const Extension* extension, |
const base::FilePath& file_path) { |
- // launcher will be freed when nothing has a reference to it. The message |
- // queue will retain a reference for any outstanding task, so when the |
- // launcher has finished it will be freed. |
scoped_refptr<PlatformAppPathLauncher> launcher = |
new PlatformAppPathLauncher(profile, extension, file_path); |
launcher->Launch(); |