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 |