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( | |
187 profile_, extension_, extensions::SOURCE_UNKNOWN); | |
benwells
2014/10/28 21:22:47
Why is this unknown? I think we should plumb throu
cylee1
2014/10/29 16:39:59
This function is called only for the failure case
cylee1
2014/10/29 17:23:49
Changed to SOURCE_FILE_HANDLER anyway since it's o
| |
194 } | 188 } |
195 | 189 |
196 void OnMimeTypesCollected(scoped_ptr<std::vector<std::string> > mime_types) { | 190 void OnMimeTypesCollected(scoped_ptr<std::vector<std::string> > mime_types) { |
197 DCHECK(file_paths_.size() == mime_types->size()); | 191 DCHECK(file_paths_.size() == mime_types->size()); |
198 | 192 |
199 // If fetching a mime type failed, then use a fallback one. | 193 // If fetching a mime type failed, then use a fallback one. |
200 for (size_t i = 0; i < mime_types->size(); ++i) { | 194 for (size_t i = 0; i < mime_types->size(); ++i) { |
201 const std::string mime_type = | 195 const std::string mime_type = |
202 !(*mime_types)[i].empty() ? (*mime_types)[i] : kFallbackMimeType; | 196 !(*mime_types)[i].empty() ? (*mime_types)[i] : kFallbackMimeType; |
203 mime_types_.push_back(mime_type); | 197 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_; | 297 extensions::app_file_handler_util::MimeTypeCollector collector_; |
304 | 298 |
305 DISALLOW_COPY_AND_ASSIGN(PlatformAppPathLauncher); | 299 DISALLOW_COPY_AND_ASSIGN(PlatformAppPathLauncher); |
306 }; | 300 }; |
307 | 301 |
308 } // namespace | 302 } // namespace |
309 | 303 |
310 void LaunchPlatformAppWithCommandLine(Profile* profile, | 304 void LaunchPlatformAppWithCommandLine(Profile* profile, |
311 const Extension* extension, | 305 const Extension* extension, |
312 const CommandLine& command_line, | 306 const CommandLine& command_line, |
313 const base::FilePath& current_directory) { | 307 const base::FilePath& current_directory, |
308 extensions::AppLaunchSource source) { | |
314 // An app with "kiosk_only" should not be installed and launched | 309 // 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 | 310 // outside of ChromeOS kiosk mode in the first place. This is a defensive |
316 // check in case this scenario does occur. | 311 // check in case this scenario does occur. |
317 if (extensions::KioskModeInfo::IsKioskOnly(extension)) { | 312 if (extensions::KioskModeInfo::IsKioskOnly(extension)) { |
318 bool in_kiosk_mode = false; | 313 bool in_kiosk_mode = false; |
319 #if defined(OS_CHROMEOS) | 314 #if defined(OS_CHROMEOS) |
320 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); | 315 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); |
321 in_kiosk_mode = user_manager && user_manager->IsLoggedInAsKioskApp(); | 316 in_kiosk_mode = user_manager && user_manager->IsLoggedInAsKioskApp(); |
322 #endif | 317 #endif |
323 if (!in_kiosk_mode) { | 318 if (!in_kiosk_mode) { |
(...skipping 10 matching lines...) Expand all Loading... | |
334 #else | 329 #else |
335 base::CommandLine::StringType about_blank_url(url::kAboutBlankURL); | 330 base::CommandLine::StringType about_blank_url(url::kAboutBlankURL); |
336 #endif | 331 #endif |
337 CommandLine::StringVector args = command_line.GetArgs(); | 332 CommandLine::StringVector args = command_line.GetArgs(); |
338 // Browser tests will add about:blank to the command line. This should | 333 // 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 | 334 // 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 | 335 // has write access will result in a file 'about' being created, which |
341 // causes problems on the bots. | 336 // causes problems on the bots. |
342 if (args.empty() || (command_line.HasSwitch(switches::kTestType) && | 337 if (args.empty() || (command_line.HasSwitch(switches::kTestType) && |
343 args[0] == about_blank_url)) { | 338 args[0] == about_blank_url)) { |
344 LaunchPlatformAppWithNoData(profile, extension); | 339 AppRuntimeEventRouter::DispatchOnLaunchedEvent(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, |
358 const Extension* extension, | |
359 extensions::AppLaunchSource source) { | |
363 LaunchPlatformAppWithCommandLine(profile, | 360 LaunchPlatformAppWithCommandLine(profile, |
364 extension, | 361 extension, |
365 CommandLine(CommandLine::NO_PROGRAM), | 362 CommandLine(CommandLine::NO_PROGRAM), |
366 base::FilePath()); | 363 base::FilePath(), |
364 source); | |
367 } | 365 } |
368 | 366 |
369 void LaunchPlatformAppWithFileHandler( | 367 void LaunchPlatformAppWithFileHandler( |
370 Profile* profile, | 368 Profile* profile, |
371 const Extension* extension, | 369 const Extension* extension, |
372 const std::string& handler_id, | 370 const std::string& handler_id, |
373 const std::vector<base::FilePath>& file_paths) { | 371 const std::vector<base::FilePath>& file_paths) { |
374 scoped_refptr<PlatformAppPathLauncher> launcher = | 372 scoped_refptr<PlatformAppPathLauncher> launcher = |
375 new PlatformAppPathLauncher(profile, extension, file_paths); | 373 new PlatformAppPathLauncher(profile, extension, file_paths); |
376 launcher->LaunchWithHandler(handler_id); | 374 launcher->LaunchWithHandler(handler_id); |
377 } | 375 } |
378 | 376 |
379 void RestartPlatformApp(Profile* profile, const Extension* extension) { | 377 void RestartPlatformApp(Profile* profile, const Extension* extension) { |
380 EventRouter* event_router = EventRouter::Get(profile); | 378 EventRouter* event_router = EventRouter::Get(profile); |
381 bool listening_to_restart = event_router-> | 379 bool listening_to_restart = event_router-> |
382 ExtensionHasEventListener(extension->id(), | 380 ExtensionHasEventListener(extension->id(), |
383 app_runtime::OnRestarted::kEventName); | 381 app_runtime::OnRestarted::kEventName); |
384 | 382 |
385 if (listening_to_restart) { | 383 if (listening_to_restart) { |
386 AppRuntimeEventRouter::DispatchOnRestartedEvent(profile, extension); | 384 AppRuntimeEventRouter::DispatchOnRestartedEvent(profile, extension); |
387 return; | 385 return; |
388 } | 386 } |
389 | |
benwells
2014/10/28 21:22:47
Nit: keep the empty line here.
cylee1
2014/10/29 16:39:59
Done.
| |
390 extensions::ExtensionPrefs* extension_prefs = | 387 extensions::ExtensionPrefs* extension_prefs = |
391 extensions::ExtensionPrefs::Get(profile); | 388 extensions::ExtensionPrefs::Get(profile); |
392 bool had_windows = extension_prefs->IsActive(extension->id()); | 389 bool had_windows = extension_prefs->IsActive(extension->id()); |
393 extension_prefs->SetIsActive(extension->id(), false); | 390 extension_prefs->SetIsActive(extension->id(), false); |
394 bool listening_to_launch = event_router-> | 391 bool listening_to_launch = event_router-> |
395 ExtensionHasEventListener(extension->id(), | 392 ExtensionHasEventListener(extension->id(), |
396 app_runtime::OnLaunched::kEventName); | 393 app_runtime::OnLaunched::kEventName); |
397 | 394 |
398 if (listening_to_launch && had_windows) | 395 if (listening_to_launch && had_windows) { |
399 LaunchPlatformAppWithNoData(profile, extension); | 396 AppRuntimeEventRouter::DispatchOnLaunchedEvent( |
397 profile, extension, extensions::SOURCE_RESTART); | |
398 } | |
400 } | 399 } |
401 | 400 |
402 void LaunchPlatformAppWithUrl(Profile* profile, | 401 void LaunchPlatformAppWithUrl(Profile* profile, |
403 const Extension* extension, | 402 const Extension* extension, |
404 const std::string& handler_id, | 403 const std::string& handler_id, |
405 const GURL& url, | 404 const GURL& url, |
406 const GURL& referrer_url) { | 405 const GURL& referrer_url) { |
407 AppRuntimeEventRouter::DispatchOnLaunchedEventWithUrl( | 406 AppRuntimeEventRouter::DispatchOnLaunchedEventWithUrl( |
408 profile, extension, handler_id, url, referrer_url); | 407 profile, extension, handler_id, url, referrer_url); |
409 } | 408 } |
410 | 409 |
411 } // namespace apps | 410 } // namespace apps |
OLD | NEW |