Chromium Code Reviews| 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 "chrome/browser/chromeos/app_mode/startup_app_launcher.h" | 5 #include "chrome/browser/chromeos/app_mode/startup_app_launcher.h" |
| 6 | 6 |
| 7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/json/json_file_value_serializer.h" | 10 #include "base/json/json_file_value_serializer.h" |
| 11 #include "base/path_service.h" | 11 #include "base/path_service.h" |
| 12 #include "base/prefs/pref_service.h" | 12 #include "base/prefs/pref_service.h" |
| 13 #include "base/time.h" | 13 #include "base/time.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
| 16 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" | 16 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" |
| 17 #include "chrome/browser/chromeos/app_mode/kiosk_app_update_service.h" | 17 #include "chrome/browser/chromeos/app_mode/kiosk_app_update_service.h" |
| 18 #include "chrome/browser/chromeos/login/user_manager.h" | 18 #include "chrome/browser/chromeos/login/user_manager.h" |
| 19 #include "chrome/browser/chromeos/ui/app_launch_view.h" | 19 #include "chrome/browser/chromeos/ui/app_launch_view.h" |
| 20 #include "chrome/browser/extensions/extension_service.h" | 20 #include "chrome/browser/extensions/extension_service.h" |
| 21 #include "chrome/browser/extensions/extension_system.h" | 21 #include "chrome/browser/extensions/extension_system.h" |
| 22 #include "chrome/browser/extensions/shell_window_registry.h" | |
| 22 #include "chrome/browser/extensions/webstore_startup_installer.h" | 23 #include "chrome/browser/extensions/webstore_startup_installer.h" |
| 23 #include "chrome/browser/lifetime/application_lifetime.h" | 24 #include "chrome/browser/lifetime/application_lifetime.h" |
| 24 #include "chrome/browser/policy/browser_policy_connector.h" | 25 #include "chrome/browser/policy/browser_policy_connector.h" |
| 25 #include "chrome/browser/signin/token_service.h" | 26 #include "chrome/browser/signin/token_service.h" |
| 26 #include "chrome/browser/signin/token_service_factory.h" | 27 #include "chrome/browser/signin/token_service_factory.h" |
| 27 #include "chrome/browser/ui/extensions/application_launch.h" | 28 #include "chrome/browser/ui/extensions/application_launch.h" |
| 29 #include "chrome/browser/ui/extensions/shell_window.h" | |
| 28 #include "chrome/common/chrome_paths.h" | 30 #include "chrome/common/chrome_paths.h" |
| 29 #include "chrome/common/chrome_switches.h" | 31 #include "chrome/common/chrome_switches.h" |
| 30 #include "chrome/common/extensions/extension.h" | 32 #include "chrome/common/extensions/extension.h" |
| 31 #include "chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h" | 33 #include "chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h" |
| 32 #include "chrome/common/pref_names.h" | 34 #include "chrome/common/pref_names.h" |
| 33 #include "content/public/browser/browser_thread.h" | 35 #include "content/public/browser/browser_thread.h" |
| 34 #include "google_apis/gaia/gaia_auth_consumer.h" | 36 #include "google_apis/gaia/gaia_auth_consumer.h" |
| 35 #include "google_apis/gaia/gaia_constants.h" | 37 #include "google_apis/gaia/gaia_constants.h" |
| 36 | 38 |
| 37 using content::BrowserThread; | 39 using content::BrowserThread; |
| 38 using extensions::Extension; | 40 using extensions::Extension; |
| 39 using extensions::WebstoreStartupInstaller; | 41 using extensions::WebstoreStartupInstaller; |
| 42 using extensions::ShellWindowRegistry; | |
| 40 | 43 |
| 41 namespace chromeos { | 44 namespace chromeos { |
| 42 | 45 |
| 43 namespace { | 46 namespace { |
| 44 | 47 |
| 45 | 48 |
| 46 const char kOAuthRefreshToken[] = "refresh_token"; | 49 const char kOAuthRefreshToken[] = "refresh_token"; |
| 47 const char kOAuthClientId[] = "client_id"; | 50 const char kOAuthClientId[] = "client_id"; |
| 48 const char kOAuthClientSecret[] = "client_secret"; | 51 const char kOAuthClientSecret[] = "client_secret"; |
| 49 | 52 |
| 50 const base::FilePath::CharType kOAuthFileName[] = | 53 const base::FilePath::CharType kOAuthFileName[] = |
| 51 FILE_PATH_LITERAL("kiosk_auth"); | 54 FILE_PATH_LITERAL("kiosk_auth"); |
| 52 | 55 |
| 53 // Application install splash screen minimum show time in milliseconds. | 56 // Application install splash screen minimum show time in milliseconds. |
| 54 const int kAppInstallSplashScreenMinTimeMS = 3000; | 57 const int kAppInstallSplashScreenMinTimeMS = 3000; |
| 55 | 58 |
| 56 // Initial delay that gives an app 30 seconds during which the main app window | |
| 57 // must be created. If app fails to create the main window in this timeframe, | |
| 58 // chrome will exit. | |
| 59 // TODO(xiyuan): Find a nicer way to trace process lifetime management at | |
| 60 // startup. This just fixes a race that happens on faster machines. | |
| 61 const int kInitialEndKeepAliveDelayinSec = 30; | |
| 62 | |
| 63 bool IsAppInstalled(Profile* profile, const std::string& app_id) { | 59 bool IsAppInstalled(Profile* profile, const std::string& app_id) { |
| 64 return extensions::ExtensionSystem::Get(profile)->extension_service()-> | 60 return extensions::ExtensionSystem::Get(profile)->extension_service()-> |
| 65 GetInstalledExtension(app_id); | 61 GetInstalledExtension(app_id); |
| 66 } | 62 } |
| 67 | 63 |
| 68 } // namespace | 64 } // namespace |
| 69 | 65 |
| 66 //////////////////////////////////////////////////////////////////////////////// | |
| 67 // StartupAppLauncher::AppWindowWatcher watches for a ShellWindow creation | |
| 68 // for the given app id then runs the callback to notify its host. | |
| 69 | |
| 70 class StartupAppLauncher::AppWindowWatcher | |
| 71 : public ShellWindowRegistry::Observer { | |
| 72 public: | |
| 73 AppWindowWatcher(Profile* profile, | |
| 74 const std::string& app_id, | |
| 75 const base::Closure& cb) | |
| 76 : window_registry_(ShellWindowRegistry::Get(profile)), | |
| 77 app_id_(app_id), | |
| 78 cb_(cb) { | |
| 79 if (window_registry_) | |
| 80 window_registry_->AddObserver(this); | |
| 81 } | |
| 82 | |
| 83 virtual ~AppWindowWatcher() { | |
| 84 if (window_registry_) | |
| 85 window_registry_->RemoveObserver(this); | |
| 86 } | |
| 87 | |
| 88 private: | |
| 89 // extensions::ShellWindowRegistry::Observer overrides: | |
| 90 virtual void OnShellWindowAdded(ShellWindow* shell_window) OVERRIDE { | |
| 91 if (shell_window->extension()->id() == app_id_) | |
|
zel
2013/04/03 22:17:50
are you sure that extension() isn't NULL?
what if
| |
| 92 cb_.Run(); | |
| 93 } | |
| 94 virtual void OnShellWindowIconChanged(ShellWindow* shell_window) OVERRIDE {} | |
| 95 virtual void OnShellWindowRemoved(ShellWindow* shell_window) OVERRIDE {} | |
| 96 | |
| 97 ShellWindowRegistry* window_registry_; // Not owned. | |
| 98 const std::string app_id_; | |
| 99 base::Closure cb_; | |
| 100 | |
| 101 DISALLOW_COPY_AND_ASSIGN(AppWindowWatcher); | |
| 102 }; | |
| 103 | |
| 104 //////////////////////////////////////////////////////////////////////////////// | |
| 105 // StartupAppLauncher | |
| 106 | |
| 70 StartupAppLauncher::StartupAppLauncher(Profile* profile, | 107 StartupAppLauncher::StartupAppLauncher(Profile* profile, |
| 71 const std::string& app_id) | 108 const std::string& app_id) |
| 72 : profile_(profile), | 109 : profile_(profile), |
| 73 app_id_(app_id), | 110 app_id_(app_id), |
| 74 launch_splash_start_time_(0) { | 111 launch_splash_start_time_(0) { |
| 75 DCHECK(profile_); | 112 DCHECK(profile_); |
| 76 DCHECK(Extension::IdIsValid(app_id_)); | 113 DCHECK(Extension::IdIsValid(app_id_)); |
| 77 DCHECK(ash::Shell::HasInstance()); | 114 DCHECK(ash::Shell::HasInstance()); |
| 78 ash::Shell::GetInstance()->AddPreTargetHandler(this); | 115 ash::Shell::GetInstance()->AddPreTargetHandler(this); |
| 79 } | 116 } |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 214 } | 251 } |
| 215 } | 252 } |
| 216 | 253 |
| 217 void StartupAppLauncher::Cleanup() { | 254 void StartupAppLauncher::Cleanup() { |
| 218 chromeos::CloseAppLaunchSplashScreen(); | 255 chromeos::CloseAppLaunchSplashScreen(); |
| 219 | 256 |
| 220 // Ends OpenAsh() keep alive since the session should either be bound with | 257 // Ends OpenAsh() keep alive since the session should either be bound with |
| 221 // the just launched app on success or should be ended on failure. | 258 // the just launched app on success or should be ended on failure. |
| 222 // Invoking it via a PostNonNestableTask because Cleanup() could be called | 259 // Invoking it via a PostNonNestableTask because Cleanup() could be called |
| 223 // before main message loop starts. | 260 // before main message loop starts. |
| 224 BrowserThread::PostNonNestableDelayedTask( | 261 BrowserThread::PostNonNestableTask( |
| 225 BrowserThread::UI, | 262 BrowserThread::UI, |
| 226 FROM_HERE, | 263 FROM_HERE, |
| 227 base::Bind(&chrome::EndKeepAlive), | 264 base::Bind(&chrome::EndKeepAlive)); |
| 228 base::TimeDelta::FromSeconds(kInitialEndKeepAliveDelayinSec)); | |
| 229 | 265 |
| 230 delete this; | 266 delete this; |
| 231 } | 267 } |
| 232 | 268 |
| 233 void StartupAppLauncher::OnLaunchSuccess() { | 269 void StartupAppLauncher::OnLaunchSuccess() { |
| 234 const int64 time_taken_ms = (base::TimeTicks::Now() - | 270 const int64 time_taken_ms = (base::TimeTicks::Now() - |
| 235 base::TimeTicks::FromInternalValue(launch_splash_start_time_)). | 271 base::TimeTicks::FromInternalValue(launch_splash_start_time_)). |
| 236 InMilliseconds(); | 272 InMilliseconds(); |
| 237 | 273 |
| 238 // Enforce that we show app install splash screen for some minimum amount | 274 // Enforce that we show app install splash screen for some minimum amount |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 if (!g_browser_process->browser_policy_connector()->IsEnterpriseManaged()) { | 317 if (!g_browser_process->browser_policy_connector()->IsEnterpriseManaged()) { |
| 282 PrefService* local_state = g_browser_process->local_state(); | 318 PrefService* local_state = g_browser_process->local_state(); |
| 283 local_state->SetBoolean(prefs::kRebootAfterUpdate, true); | 319 local_state->SetBoolean(prefs::kRebootAfterUpdate, true); |
| 284 } | 320 } |
| 285 | 321 |
| 286 // Always open the app in a window. | 322 // Always open the app in a window. |
| 287 chrome::OpenApplication(chrome::AppLaunchParams(profile_, | 323 chrome::OpenApplication(chrome::AppLaunchParams(profile_, |
| 288 extension, | 324 extension, |
| 289 extension_misc::LAUNCH_WINDOW, | 325 extension_misc::LAUNCH_WINDOW, |
| 290 NEW_WINDOW)); | 326 NEW_WINDOW)); |
| 291 OnLaunchSuccess(); | 327 |
| 328 // Waits until app window is created to report OnLaunchSuccess. | |
| 329 DCHECK(extension->is_platform_app()); | |
| 330 app_window_watcher_.reset(new AppWindowWatcher( | |
| 331 profile_, | |
| 332 app_id_, | |
| 333 base::Bind(&StartupAppLauncher::OnLaunchSuccess, AsWeakPtr()))); | |
|
zel
2013/04/03 22:17:50
what happens if app never creates a window? are we
| |
| 292 } | 334 } |
| 293 | 335 |
| 294 void StartupAppLauncher::BeginInstall() { | 336 void StartupAppLauncher::BeginInstall() { |
| 295 DVLOG(1) << "BeginInstall... connection = " | 337 DVLOG(1) << "BeginInstall... connection = " |
| 296 << net::NetworkChangeNotifier::GetConnectionType(); | 338 << net::NetworkChangeNotifier::GetConnectionType(); |
| 297 | 339 |
| 298 chromeos::UpdateAppLaunchSplashScreenState( | 340 chromeos::UpdateAppLaunchSplashScreenState( |
| 299 chromeos::APP_LAUNCH_STATE_INSTALLING_APPLICATION); | 341 chromeos::APP_LAUNCH_STATE_INSTALLING_APPLICATION); |
| 300 | 342 |
| 301 if (IsAppInstalled(profile_, app_id_)) { | 343 if (IsAppInstalled(profile_, app_id_)) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 if (event->key_code() != ui::VKEY_S || | 402 if (event->key_code() != ui::VKEY_S || |
| 361 !(event->flags() & ui::EF_CONTROL_DOWN) || | 403 !(event->flags() & ui::EF_CONTROL_DOWN) || |
| 362 !(event->flags() & ui::EF_ALT_DOWN)) { | 404 !(event->flags() & ui::EF_ALT_DOWN)) { |
| 363 return; | 405 return; |
| 364 } | 406 } |
| 365 | 407 |
| 366 OnLaunchFailure(KioskAppLaunchError::USER_CANCEL); | 408 OnLaunchFailure(KioskAppLaunchError::USER_CANCEL); |
| 367 } | 409 } |
| 368 | 410 |
| 369 } // namespace chromeos | 411 } // namespace chromeos |
| OLD | NEW |