Chromium Code Reviews| Index: chrome/browser/chromeos/app_mode/startup_app_launcher.cc |
| diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc |
| index 6f21c3ae4809d66203af7f34c9f494604ad781f7..eb7b0177f1f1f49f790342ad45afed0f57b67046 100644 |
| --- a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc |
| +++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc |
| @@ -19,12 +19,14 @@ |
| #include "chrome/browser/chromeos/ui/app_launch_view.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/extensions/extension_system.h" |
| +#include "chrome/browser/extensions/shell_window_registry.h" |
| #include "chrome/browser/extensions/webstore_startup_installer.h" |
| #include "chrome/browser/lifetime/application_lifetime.h" |
| #include "chrome/browser/policy/browser_policy_connector.h" |
| #include "chrome/browser/signin/token_service.h" |
| #include "chrome/browser/signin/token_service_factory.h" |
| #include "chrome/browser/ui/extensions/application_launch.h" |
| +#include "chrome/browser/ui/extensions/shell_window.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/extensions/extension.h" |
| @@ -37,6 +39,7 @@ |
| using content::BrowserThread; |
| using extensions::Extension; |
| using extensions::WebstoreStartupInstaller; |
| +using extensions::ShellWindowRegistry; |
| namespace chromeos { |
| @@ -53,13 +56,6 @@ const base::FilePath::CharType kOAuthFileName[] = |
| // Application install splash screen minimum show time in milliseconds. |
| const int kAppInstallSplashScreenMinTimeMS = 3000; |
| -// Initial delay that gives an app 30 seconds during which the main app window |
| -// must be created. If app fails to create the main window in this timeframe, |
| -// chrome will exit. |
| -// TODO(xiyuan): Find a nicer way to trace process lifetime management at |
| -// startup. This just fixes a race that happens on faster machines. |
| -const int kInitialEndKeepAliveDelayinSec = 30; |
| - |
| bool IsAppInstalled(Profile* profile, const std::string& app_id) { |
| return extensions::ExtensionSystem::Get(profile)->extension_service()-> |
| GetInstalledExtension(app_id); |
| @@ -67,6 +63,47 @@ bool IsAppInstalled(Profile* profile, const std::string& app_id) { |
| } // namespace |
| +//////////////////////////////////////////////////////////////////////////////// |
| +// StartupAppLauncher::AppWindowWatcher watches for a ShellWindow creation |
| +// for the given app id then runs the callback to notify its host. |
| + |
| +class StartupAppLauncher::AppWindowWatcher |
| + : public ShellWindowRegistry::Observer { |
| + public: |
| + AppWindowWatcher(Profile* profile, |
| + const std::string& app_id, |
| + const base::Closure& cb) |
| + : window_registry_(ShellWindowRegistry::Get(profile)), |
| + app_id_(app_id), |
| + cb_(cb) { |
| + if (window_registry_) |
| + window_registry_->AddObserver(this); |
| + } |
| + |
| + virtual ~AppWindowWatcher() { |
| + if (window_registry_) |
| + window_registry_->RemoveObserver(this); |
| + } |
| + |
| + private: |
| + // extensions::ShellWindowRegistry::Observer overrides: |
| + virtual void OnShellWindowAdded(ShellWindow* shell_window) OVERRIDE { |
| + if (shell_window->extension()->id() == app_id_) |
|
zel
2013/04/03 22:17:50
are you sure that extension() isn't NULL?
what if
|
| + cb_.Run(); |
| + } |
| + virtual void OnShellWindowIconChanged(ShellWindow* shell_window) OVERRIDE {} |
| + virtual void OnShellWindowRemoved(ShellWindow* shell_window) OVERRIDE {} |
| + |
| + ShellWindowRegistry* window_registry_; // Not owned. |
| + const std::string app_id_; |
| + base::Closure cb_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(AppWindowWatcher); |
| +}; |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| +// StartupAppLauncher |
| + |
| StartupAppLauncher::StartupAppLauncher(Profile* profile, |
| const std::string& app_id) |
| : profile_(profile), |
| @@ -221,11 +258,10 @@ void StartupAppLauncher::Cleanup() { |
| // the just launched app on success or should be ended on failure. |
| // Invoking it via a PostNonNestableTask because Cleanup() could be called |
| // before main message loop starts. |
| - BrowserThread::PostNonNestableDelayedTask( |
| + BrowserThread::PostNonNestableTask( |
| BrowserThread::UI, |
| FROM_HERE, |
| - base::Bind(&chrome::EndKeepAlive), |
| - base::TimeDelta::FromSeconds(kInitialEndKeepAliveDelayinSec)); |
| + base::Bind(&chrome::EndKeepAlive)); |
| delete this; |
| } |
| @@ -288,7 +324,13 @@ void StartupAppLauncher::Launch() { |
| extension, |
| extension_misc::LAUNCH_WINDOW, |
| NEW_WINDOW)); |
| - OnLaunchSuccess(); |
| + |
| + // Waits until app window is created to report OnLaunchSuccess. |
| + DCHECK(extension->is_platform_app()); |
| + app_window_watcher_.reset(new AppWindowWatcher( |
| + profile_, |
| + app_id_, |
| + base::Bind(&StartupAppLauncher::OnLaunchSuccess, AsWeakPtr()))); |
|
zel
2013/04/03 22:17:50
what happens if app never creates a window? are we
|
| } |
| void StartupAppLauncher::BeginInstall() { |