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 |