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