| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "apps/launcher.h" | 5 #include "apps/launcher.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 return true; | 78 return true; |
| 79 } | 79 } |
| 80 | 80 |
| 81 if (!current_directory.IsAbsolute()) | 81 if (!current_directory.IsAbsolute()) |
| 82 return false; | 82 return false; |
| 83 | 83 |
| 84 *file_path = current_directory.Append(*file_path); | 84 *file_path = current_directory.Append(*file_path); |
| 85 return true; | 85 return true; |
| 86 } | 86 } |
| 87 | 87 |
| 88 // Helper method to launch the platform app |extension| with no data. This | |
| 89 // should be called in the fallback case, where it has been impossible to | |
| 90 // load or obtain file launch data. | |
| 91 void LaunchPlatformAppWithNoData(Profile* profile, const Extension* extension) { | |
| 92 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 93 AppRuntimeEventRouter::DispatchOnLaunchedEvent(profile, extension); | |
| 94 } | |
| 95 | |
| 96 // Class to handle launching of platform apps to open specific paths. | 88 // Class to handle launching of platform apps to open specific paths. |
| 97 // An instance of this class is created for each launch. The lifetime of these | 89 // An instance of this class is created for each launch. The lifetime of these |
| 98 // instances is managed by reference counted pointers. As long as an instance | 90 // instances is managed by reference counted pointers. As long as an instance |
| 99 // has outstanding tasks on a message queue it will be retained; once all | 91 // has outstanding tasks on a message queue it will be retained; once all |
| 100 // outstanding tasks are completed it will be deleted. | 92 // outstanding tasks are completed it will be deleted. |
| 101 class PlatformAppPathLauncher | 93 class PlatformAppPathLauncher |
| 102 : public base::RefCountedThreadSafe<PlatformAppPathLauncher> { | 94 : public base::RefCountedThreadSafe<PlatformAppPathLauncher> { |
| 103 public: | 95 public: |
| 104 PlatformAppPathLauncher(Profile* profile, | 96 PlatformAppPathLauncher(Profile* profile, |
| 105 const Extension* extension, | 97 const Extension* extension, |
| 106 const std::vector<base::FilePath>& file_paths) | 98 const std::vector<base::FilePath>& file_paths) |
| 107 : profile_(profile), | 99 : profile_(profile), |
| 108 extension_(extension), | 100 extension_(extension), |
| 109 file_paths_(file_paths), | 101 file_paths_(file_paths), |
| 110 collector_(profile) {} | 102 collector_(profile) {} |
| 111 | 103 |
| 112 PlatformAppPathLauncher(Profile* profile, | 104 PlatformAppPathLauncher(Profile* profile, |
| 113 const Extension* extension, | 105 const Extension* extension, |
| 114 const base::FilePath& file_path) | 106 const base::FilePath& file_path) |
| 115 : profile_(profile), extension_(extension), collector_(profile) { | 107 : profile_(profile), extension_(extension), collector_(profile) { |
| 116 if (!file_path.empty()) | 108 if (!file_path.empty()) |
| 117 file_paths_.push_back(file_path); | 109 file_paths_.push_back(file_path); |
| 118 } | 110 } |
| 119 | 111 |
| 120 void Launch() { | 112 void Launch() { |
| 121 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 113 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 122 if (file_paths_.empty()) { | 114 if (file_paths_.empty()) { |
| 123 LaunchPlatformAppWithNoData(profile_, extension_); | 115 LaunchWithNoLaunchData(); |
| 124 return; | 116 return; |
| 125 } | 117 } |
| 126 | 118 |
| 127 for (size_t i = 0; i < file_paths_.size(); ++i) { | 119 for (size_t i = 0; i < file_paths_.size(); ++i) { |
| 128 DCHECK(file_paths_[i].IsAbsolute()); | 120 DCHECK(file_paths_[i].IsAbsolute()); |
| 129 } | 121 } |
| 130 | 122 |
| 131 if (HasFileSystemWritePermission(extension_)) { | 123 if (HasFileSystemWritePermission(extension_)) { |
| 132 PrepareFilesForWritableApp( | 124 PrepareFilesForWritableApp( |
| 133 file_paths_, | 125 file_paths_, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 file_paths_, | 178 file_paths_, |
| 187 base::Bind(&PlatformAppPathLauncher::OnMimeTypesCollected, this)); | 179 base::Bind(&PlatformAppPathLauncher::OnMimeTypesCollected, this)); |
| 188 } | 180 } |
| 189 | 181 |
| 190 void OnFilesInvalid(const base::FilePath& /* error_path */) { | 182 void OnFilesInvalid(const base::FilePath& /* error_path */) { |
| 191 LaunchWithNoLaunchData(); | 183 LaunchWithNoLaunchData(); |
| 192 } | 184 } |
| 193 | 185 |
| 194 void LaunchWithNoLaunchData() { | 186 void LaunchWithNoLaunchData() { |
| 195 // This method is required as an entry point on the UI thread. | 187 // This method is required as an entry point on the UI thread. |
| 196 LaunchPlatformAppWithNoData(profile_, extension_); | 188 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 189 AppRuntimeEventRouter::DispatchOnLaunchedEvent( |
| 190 profile_, extension_, extensions::SOURCE_FILE_HANDLER); |
| 197 } | 191 } |
| 198 | 192 |
| 199 void OnMimeTypesCollected(scoped_ptr<std::vector<std::string> > mime_types) { | 193 void OnMimeTypesCollected(scoped_ptr<std::vector<std::string> > mime_types) { |
| 200 DCHECK(file_paths_.size() == mime_types->size()); | 194 DCHECK(file_paths_.size() == mime_types->size()); |
| 201 | 195 |
| 202 // If fetching a mime type failed, then use a fallback one. | 196 // If fetching a mime type failed, then use a fallback one. |
| 203 for (size_t i = 0; i < mime_types->size(); ++i) { | 197 for (size_t i = 0; i < mime_types->size(); ++i) { |
| 204 const std::string mime_type = | 198 const std::string mime_type = |
| 205 !(*mime_types)[i].empty() ? (*mime_types)[i] : kFallbackMimeType; | 199 !(*mime_types)[i].empty() ? (*mime_types)[i] : kFallbackMimeType; |
| 206 mime_types_.push_back(mime_type); | 200 mime_types_.push_back(mime_type); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 extensions::app_file_handler_util::MimeTypeCollector collector_; | 300 extensions::app_file_handler_util::MimeTypeCollector collector_; |
| 307 | 301 |
| 308 DISALLOW_COPY_AND_ASSIGN(PlatformAppPathLauncher); | 302 DISALLOW_COPY_AND_ASSIGN(PlatformAppPathLauncher); |
| 309 }; | 303 }; |
| 310 | 304 |
| 311 } // namespace | 305 } // namespace |
| 312 | 306 |
| 313 void LaunchPlatformAppWithCommandLine(Profile* profile, | 307 void LaunchPlatformAppWithCommandLine(Profile* profile, |
| 314 const Extension* extension, | 308 const Extension* extension, |
| 315 const base::CommandLine& command_line, | 309 const base::CommandLine& command_line, |
| 316 const base::FilePath& current_directory) { | 310 const base::FilePath& current_directory, |
| 311 extensions::AppLaunchSource source) { |
| 317 // An app with "kiosk_only" should not be installed and launched | 312 // An app with "kiosk_only" should not be installed and launched |
| 318 // outside of ChromeOS kiosk mode in the first place. This is a defensive | 313 // outside of ChromeOS kiosk mode in the first place. This is a defensive |
| 319 // check in case this scenario does occur. | 314 // check in case this scenario does occur. |
| 320 if (extensions::KioskModeInfo::IsKioskOnly(extension)) { | 315 if (extensions::KioskModeInfo::IsKioskOnly(extension)) { |
| 321 bool in_kiosk_mode = false; | 316 bool in_kiosk_mode = false; |
| 322 #if defined(OS_CHROMEOS) | 317 #if defined(OS_CHROMEOS) |
| 323 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); | 318 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); |
| 324 in_kiosk_mode = user_manager && user_manager->IsLoggedInAsKioskApp(); | 319 in_kiosk_mode = user_manager && user_manager->IsLoggedInAsKioskApp(); |
| 325 #endif | 320 #endif |
| 326 if (!in_kiosk_mode) { | 321 if (!in_kiosk_mode) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 337 #else | 332 #else |
| 338 base::CommandLine::StringType about_blank_url(url::kAboutBlankURL); | 333 base::CommandLine::StringType about_blank_url(url::kAboutBlankURL); |
| 339 #endif | 334 #endif |
| 340 base::CommandLine::StringVector args = command_line.GetArgs(); | 335 base::CommandLine::StringVector args = command_line.GetArgs(); |
| 341 // Browser tests will add about:blank to the command line. This should | 336 // Browser tests will add about:blank to the command line. This should |
| 342 // never be interpreted as a file to open, as doing so with an app that | 337 // never be interpreted as a file to open, as doing so with an app that |
| 343 // has write access will result in a file 'about' being created, which | 338 // has write access will result in a file 'about' being created, which |
| 344 // causes problems on the bots. | 339 // causes problems on the bots. |
| 345 if (args.empty() || (command_line.HasSwitch(switches::kTestType) && | 340 if (args.empty() || (command_line.HasSwitch(switches::kTestType) && |
| 346 args[0] == about_blank_url)) { | 341 args[0] == about_blank_url)) { |
| 347 LaunchPlatformAppWithNoData(profile, extension); | 342 AppRuntimeEventRouter::DispatchOnLaunchedEvent(profile, extension, source); |
| 348 return; | 343 return; |
| 349 } | 344 } |
| 350 | 345 |
| 351 base::FilePath file_path(command_line.GetArgs()[0]); | 346 base::FilePath file_path(command_line.GetArgs()[0]); |
| 352 scoped_refptr<PlatformAppPathLauncher> launcher = | 347 scoped_refptr<PlatformAppPathLauncher> launcher = |
| 353 new PlatformAppPathLauncher(profile, extension, file_path); | 348 new PlatformAppPathLauncher(profile, extension, file_path); |
| 354 launcher->LaunchWithRelativePath(current_directory); | 349 launcher->LaunchWithRelativePath(current_directory); |
| 355 } | 350 } |
| 356 | 351 |
| 357 void LaunchPlatformAppWithPath(Profile* profile, | 352 void LaunchPlatformAppWithPath(Profile* profile, |
| 358 const Extension* extension, | 353 const Extension* extension, |
| 359 const base::FilePath& file_path) { | 354 const base::FilePath& file_path) { |
| 360 scoped_refptr<PlatformAppPathLauncher> launcher = | 355 scoped_refptr<PlatformAppPathLauncher> launcher = |
| 361 new PlatformAppPathLauncher(profile, extension, file_path); | 356 new PlatformAppPathLauncher(profile, extension, file_path); |
| 362 launcher->Launch(); | 357 launcher->Launch(); |
| 363 } | 358 } |
| 364 | 359 |
| 365 void LaunchPlatformApp(Profile* profile, const Extension* extension) { | 360 void LaunchPlatformApp(Profile* profile, |
| 366 LaunchPlatformAppWithCommandLine(profile, | 361 const Extension* extension, |
| 367 extension, | 362 extensions::AppLaunchSource source) { |
| 368 base::CommandLine( | 363 LaunchPlatformAppWithCommandLine( |
| 369 base::CommandLine::NO_PROGRAM), | 364 profile, |
| 370 base::FilePath()); | 365 extension, |
| 366 base::CommandLine(base::CommandLine::NO_PROGRAM), |
| 367 base::FilePath(), |
| 368 source); |
| 371 } | 369 } |
| 372 | 370 |
| 373 void LaunchPlatformAppWithFileHandler( | 371 void LaunchPlatformAppWithFileHandler( |
| 374 Profile* profile, | 372 Profile* profile, |
| 375 const Extension* extension, | 373 const Extension* extension, |
| 376 const std::string& handler_id, | 374 const std::string& handler_id, |
| 377 const std::vector<base::FilePath>& file_paths) { | 375 const std::vector<base::FilePath>& file_paths) { |
| 378 scoped_refptr<PlatformAppPathLauncher> launcher = | 376 scoped_refptr<PlatformAppPathLauncher> launcher = |
| 379 new PlatformAppPathLauncher(profile, extension, file_paths); | 377 new PlatformAppPathLauncher(profile, extension, file_paths); |
| 380 launcher->LaunchWithHandler(handler_id); | 378 launcher->LaunchWithHandler(handler_id); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 392 } | 390 } |
| 393 | 391 |
| 394 extensions::ExtensionPrefs* extension_prefs = | 392 extensions::ExtensionPrefs* extension_prefs = |
| 395 extensions::ExtensionPrefs::Get(profile); | 393 extensions::ExtensionPrefs::Get(profile); |
| 396 bool had_windows = extension_prefs->IsActive(extension->id()); | 394 bool had_windows = extension_prefs->IsActive(extension->id()); |
| 397 extension_prefs->SetIsActive(extension->id(), false); | 395 extension_prefs->SetIsActive(extension->id(), false); |
| 398 bool listening_to_launch = event_router-> | 396 bool listening_to_launch = event_router-> |
| 399 ExtensionHasEventListener(extension->id(), | 397 ExtensionHasEventListener(extension->id(), |
| 400 app_runtime::OnLaunched::kEventName); | 398 app_runtime::OnLaunched::kEventName); |
| 401 | 399 |
| 402 if (listening_to_launch && had_windows) | 400 if (listening_to_launch && had_windows) { |
| 403 LaunchPlatformAppWithNoData(profile, extension); | 401 AppRuntimeEventRouter::DispatchOnLaunchedEvent( |
| 402 profile, extension, extensions::SOURCE_RESTART); |
| 403 } |
| 404 } | 404 } |
| 405 | 405 |
| 406 void LaunchPlatformAppWithUrl(Profile* profile, | 406 void LaunchPlatformAppWithUrl(Profile* profile, |
| 407 const Extension* extension, | 407 const Extension* extension, |
| 408 const std::string& handler_id, | 408 const std::string& handler_id, |
| 409 const GURL& url, | 409 const GURL& url, |
| 410 const GURL& referrer_url) { | 410 const GURL& referrer_url) { |
| 411 AppRuntimeEventRouter::DispatchOnLaunchedEventWithUrl( | 411 AppRuntimeEventRouter::DispatchOnLaunchedEventWithUrl( |
| 412 profile, extension, handler_id, url, referrer_url); | 412 profile, extension, handler_id, url, referrer_url); |
| 413 } | 413 } |
| 414 | 414 |
| 415 } // namespace apps | 415 } // namespace apps |
| OLD | NEW |