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 8c99fb8333774572a2ce66128fcb64dda14b7081..255f6c9ee20781e55b1fa9f1df7e6200eeb1abc8 100644 |
| --- a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc |
| +++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc |
| @@ -17,8 +17,9 @@ |
| #include "chrome/browser/chromeos/login/session/user_session_manager.h" |
| #include "chrome/browser/chromeos/login/users/user_manager.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| +#include "chrome/browser/extensions/install_tracker.h" |
| +#include "chrome/browser/extensions/install_tracker_factory.h" |
| #include "chrome/browser/extensions/updater/extension_updater.h" |
| -#include "chrome/browser/extensions/webstore_startup_installer.h" |
| #include "chrome/browser/lifetime/application_lifetime.h" |
| #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
| #include "chrome/browser/signin/signin_manager_factory.h" |
| @@ -46,7 +47,6 @@ |
| using content::BrowserThread; |
| using extensions::Extension; |
| -using extensions::WebstoreStartupInstaller; |
| namespace chromeos { |
| @@ -59,7 +59,7 @@ const char kOAuthClientSecret[] = "client_secret"; |
| const base::FilePath::CharType kOAuthFileName[] = |
| FILE_PATH_LITERAL("kiosk_auth"); |
| -const int kMaxInstallAttempt = 5; |
| +const int kMaxLaunchAttempt = 5; |
| } // namespace |
| @@ -72,13 +72,17 @@ StartupAppLauncher::StartupAppLauncher(Profile* profile, |
| diagnostic_mode_(diagnostic_mode), |
| delegate_(delegate), |
| network_ready_handled_(false), |
| - install_attempt_(0), |
| - ready_to_launch_(false) { |
| + launch_attempt_(0), |
| + ready_to_launch_(false), |
| + crx_ready_for_install_(true) { |
| DCHECK(profile_); |
| DCHECK(Extension::IdIsValid(app_id_)); |
| + KioskAppManager::Get()->AddObserver(this); |
| } |
| StartupAppLauncher::~StartupAppLauncher() { |
| + KioskAppManager::Get()->RemoveObserver(this); |
| + |
| // StartupAppLauncher can be deleted at anytime during the launch process |
| // through a user bailout shortcut. |
| ProfileOAuth2TokenServiceFactory::GetForProfile(profile_) |
| @@ -93,7 +97,33 @@ void StartupAppLauncher::ContinueWithNetworkReady() { |
| // Starts install if it is not started. |
| if (!network_ready_handled_) { |
| network_ready_handled_ = true; |
| - MaybeInstall(); |
| + base::FilePath crx_path; |
|
xiyuan
2014/07/08 21:50:59
The network might take sometime to be up and initi
jennyz
2014/07/12 00:03:20
Done.
|
| + std::string version; |
| + bool crx_cached = |
| + KioskAppManager::Get()->GetCachedCrx(app_id_, &crx_path, &version); |
| + bool installed = extensions::ExtensionSystem::Get(profile_) |
| + ->extension_service() |
| + ->GetInstalledExtension(app_id_); |
| + KioskAppManager* kiosk_app_manager = KioskAppManager::Get(); |
| + if (installed || crx_cached) { |
| + // If KioskAppManager is still checking update for |app_id_|, wait until |
| + // it completes. |
| + if (kiosk_app_manager->IsExtensionPendingForUpdateCheck(app_id_)) { |
| + crx_ready_for_install_ = false; |
| + return; |
| + } |
| + // If the app is installed or its crx file is cached, either check update |
| + // or install the app. |
| + MaybeInstall(); |
| + } else { |
| + // If the app is still being downloaded, wait until it completes. |
| + if (kiosk_app_manager->IsExtensionPendingForCache(app_id_)) { |
| + crx_ready_for_install_ = false; |
| + return; |
| + } |
| + LOG(ERROR) << "Failed to download the app: app_id=" << app_id_; |
| + OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_DOWNLOAD); |
| + } |
| } |
| } |
| @@ -152,8 +182,11 @@ void StartupAppLauncher::OnOAuthFileLoaded(KioskOAuthParams* auth_params) { |
| void StartupAppLauncher::RestartLauncher() { |
| // If the installer is still running in the background, we don't need to |
| // restart the launch process. We will just wait until it completes and |
| - // lunches the kiosk app. |
| - if (installer_ != NULL) { |
| + // launches the kiosk app. |
| + if (extensions::ExtensionSystem::Get(profile_) |
| + ->extension_service() |
| + ->pending_extension_manager() |
| + ->IsIdPending(app_id_)) { |
| LOG(WARNING) << "Installer still running"; |
| return; |
| } |
| @@ -166,17 +199,26 @@ void StartupAppLauncher::MaybeInitializeNetwork() { |
| const Extension* extension = extensions::ExtensionSystem::Get(profile_)-> |
| extension_service()->GetInstalledExtension(app_id_); |
| - const bool requires_network = !extension || |
| - !extensions::OfflineEnabledInfo::IsOfflineEnabled(extension); |
| + base::FilePath crx_path; |
| + std::string version; |
| + bool crx_cached = |
| + KioskAppManager::Get()->GetCachedCrx(app_id_, &crx_path, &version); |
| + const bool requires_network = |
| + (!extension && !crx_cached) || |
| + (extension && |
| + !extensions::OfflineEnabledInfo::IsOfflineEnabled(extension)); |
| if (requires_network) { |
| delegate_->InitializeNetwork(); |
| return; |
| } |
| - // Offline enabled app attempts update if network is ready. Otherwise, |
| - // go directly to launch. |
| - if (delegate_->IsNetworkReady()) |
| + // Install the extension if it is not installed yet, or update the extension |
| + // if it is already installed and the network is ready; otherwise, launch the |
| + // offline enabled app. |
| + if (!extension) |
| + MaybeInstall(); |
| + else if (delegate_->IsNetworkReady()) |
| ContinueWithNetworkReady(); |
| else |
| OnReadyToLaunch(); |
| @@ -228,6 +270,75 @@ void StartupAppLauncher::OnRefreshTokensLoaded() { |
| MaybeInitializeNetwork(); |
| } |
| +void StartupAppLauncher::OnFinishCrxInstall(const std::string& extension_id, |
| + bool success) { |
| + DCHECK(extension_id == app_id_); |
|
xiyuan
2014/07/08 21:50:59
nit: Remove the DCHECK since "if" below handles th
jennyz
2014/07/12 00:03:21
Done.
|
| + if (extension_id != app_id_) |
| + return; |
| + |
| + extensions::InstallTracker* tracker = |
| + extensions::InstallTrackerFactory::GetForProfile(profile_); |
| + tracker->RemoveObserver(this); |
| + if (delegate_->IsShowingNetworkConfigScreen()) { |
| + LOG(WARNING) << "Showing network config screen"; |
| + return; |
| + } |
| + |
| + if (success) { |
| + // Check if the app is offline enabled. |
| + const Extension* extension = extensions::ExtensionSystem::Get(profile_) |
| + ->extension_service() |
| + ->GetInstalledExtension(extension_id); |
| + DCHECK(extension); |
| + const bool offline_enabled = |
| + extensions::OfflineEnabledInfo::IsOfflineEnabled(extension); |
| + if (offline_enabled || delegate_->IsNetworkReady()) { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(&StartupAppLauncher::OnReadyToLaunch, AsWeakPtr())); |
| + } else { |
| + ++launch_attempt_; |
| + if (launch_attempt_ < kMaxLaunchAttempt) { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(&StartupAppLauncher::MaybeInitializeNetwork, |
| + AsWeakPtr())); |
| + return; |
| + } |
| + OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_LAUNCH); |
| + } |
| + return; |
| + } |
| + |
| + LOG(ERROR) << "Failed to install the kiosk application app_id: " |
| + << extension_id; |
| + OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); |
| +} |
| + |
| +void StartupAppLauncher::OnKioskAppDataChanged(const std::string& app_id) { |
| + OnKioskAppDataLoadStatusChanged(app_id); |
| +} |
| + |
| +void StartupAppLauncher::OnKioskAppDataLoadFailure(const std::string& app_id) { |
| + OnKioskAppDataLoadStatusChanged(app_id); |
| +} |
| + |
| +void StartupAppLauncher::OnKioskAppDataLoadStatusChanged( |
| + const std::string& app_id) { |
| + if (app_id != app_id_) |
| + return; |
| + |
| + if (!crx_ready_for_install_ && |
| + !KioskAppManager::Get()->IsExtensionPendingForCache(app_id_) && |
| + !KioskAppManager::Get()->IsExtensionPendingForUpdateCheck(app_id_)) { |
| + crx_ready_for_install_ = true; |
| + network_ready_handled_ = false; |
| + ContinueWithNetworkReady(); |
| + } |
| +} |
| + |
| void StartupAppLauncher::LaunchApp() { |
| if (!ready_to_launch_) { |
| NOTREACHED(); |
| @@ -278,6 +389,11 @@ void StartupAppLauncher::MaybeInstall() { |
| ExtensionService* extension_service = |
| extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| + // The extension with be installed by external loader only when it is not |
| + // installed yet, so the extension loader will not skip the installation |
| + // due to the version comparison logic. |
| + // TODO(jennyz): If the extension is installed, but crx is updated to a newer |
| + // version, should we reinstall it again? |
| if (!extension_service->GetInstalledExtension(app_id_)) { |
| BeginInstall(); |
| return; |
| @@ -297,47 +413,21 @@ void StartupAppLauncher::OnUpdateCheckFinished() { |
| } |
| void StartupAppLauncher::BeginInstall() { |
| - installer_ = new WebstoreStartupInstaller( |
| - app_id_, |
| - profile_, |
| - false, |
| - base::Bind(&StartupAppLauncher::InstallCallback, AsWeakPtr())); |
| - installer_->BeginInstall(); |
| -} |
| - |
| -void StartupAppLauncher::InstallCallback(bool success, |
| - const std::string& error) { |
| - installer_ = NULL; |
| - if (delegate_->IsShowingNetworkConfigScreen()) { |
| - LOG(WARNING) << "Showing network config screen"; |
| - return; |
| - } |
| - |
| - if (success) { |
| - // Finish initialization after the callback returns. |
| - // So that the app finishes its installation. |
| - BrowserThread::PostTask( |
| - BrowserThread::UI, |
| - FROM_HERE, |
| - base::Bind(&StartupAppLauncher::OnReadyToLaunch, |
| - AsWeakPtr())); |
| + KioskAppManager::Get()->InstallKioskApp(app_id_); |
| + |
| + if (extensions::ExtensionSystem::Get(profile_) |
| + ->extension_service() |
| + ->pending_extension_manager() |
| + ->IsIdPending(app_id_)) { |
| + // Observe the crx installation events. |
| + extensions::InstallTracker* tracker = |
| + extensions::InstallTrackerFactory::GetForProfile(profile_); |
| + tracker->AddObserver(this); |
| return; |
| } |
| - LOG(ERROR) << "App install failed: " << error |
| - << ", for attempt " << install_attempt_; |
| - |
| - ++install_attempt_; |
| - if (install_attempt_ < kMaxInstallAttempt) { |
| - BrowserThread::PostTask( |
| - BrowserThread::UI, |
| - FROM_HERE, |
| - base::Bind(&StartupAppLauncher::MaybeInitializeNetwork, |
| - AsWeakPtr())); |
| - return; |
| - } |
| - |
| - OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); |
| + // The extension is skipped for installation due to some error. |
| + OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_LAUNCH); |
| } |
| void StartupAppLauncher::OnReadyToLaunch() { |