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 f40fab5834698adc2d9124ab77f2871c02963cfb..0b14b818ffc3c8e46e2cd0aa02779a4dff78d513 100644 |
| --- a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc |
| +++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc |
| @@ -15,9 +15,11 @@ |
| #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" |
| #include "chrome/browser/chromeos/app_mode/kiosk_diagnosis_runner.h" |
| #include "chrome/browser/chromeos/login/users/user_manager.h" |
| +#include "chrome/browser/extensions/crx_installer.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" |
| @@ -45,7 +47,6 @@ |
| using content::BrowserThread; |
| using extensions::Extension; |
| -using extensions::WebstoreStartupInstaller; |
| namespace chromeos { |
| @@ -58,7 +59,8 @@ const char kOAuthClientSecret[] = "client_secret"; |
| const base::FilePath::CharType kOAuthFileName[] = |
| FILE_PATH_LITERAL("kiosk_auth"); |
| -const int kMaxInstallAttempt = 5; |
| +const int kMaxDownloadAttempt = 5; |
| +const int kMaxLaunchAttempt = 5; |
| } // namespace |
| @@ -71,13 +73,20 @@ StartupAppLauncher::StartupAppLauncher(Profile* profile, |
| diagnostic_mode_(diagnostic_mode), |
| delegate_(delegate), |
| network_ready_handled_(false), |
| - install_attempt_(0), |
| - ready_to_launch_(false) { |
| + download_attempt_(0), |
| + launch_attempt_(0), |
| + ready_to_launch_(false), |
| + update_check_pending_(false), |
| + crx_cache_pending_(false) { |
| 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_) |
| @@ -92,7 +101,33 @@ void StartupAppLauncher::ContinueWithNetworkReady() { |
| // Starts install if it is not started. |
| if (!network_ready_handled_) { |
| network_ready_handled_ = true; |
| - MaybeInstall(); |
| + base::FilePath crx_path; |
| + 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_)) { |
| + update_check_pending_ = true; |
| + 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_cache_pending_ = true; |
| + return; |
| + } |
| + LOG(ERROR) << "Failed to download the app: app_id=" << app_id_; |
| + OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_DOWNLOAD); |
| + } |
| } |
| } |
| @@ -151,8 +186,8 @@ 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 (crx_installer_ != NULL) { |
| LOG(WARNING) << "Installer still running"; |
| return; |
| } |
| @@ -165,17 +200,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(); |
| @@ -227,6 +271,81 @@ void StartupAppLauncher::OnRefreshTokensLoaded() { |
| MaybeInitializeNetwork(); |
| } |
| +void StartupAppLauncher::OnFinishCrxInstall(const std::string& extension_id, |
| + bool success) { |
| + DCHECK(extension_id == app_id_); |
| + if (extension_id != app_id_) |
| + return; |
| + |
| + extensions::InstallTracker* tracker = |
| + extensions::InstallTrackerFactory::GetForProfile(profile_); |
| + tracker->RemoveObserver(this); |
| + crx_installer_ = NULL; |
| + 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_cache_pending_ && |
| + !KioskAppManager::Get()->IsExtensionPendingForCache(app_id_)) { |
| + crx_cache_pending_ = false; |
| + network_ready_handled_ = false; |
| + ContinueWithNetworkReady(); |
| + } else if (update_check_pending_ && |
| + !KioskAppManager::Get()->IsExtensionPendingForUpdateCheck( |
| + app_id_)) { |
| + update_check_pending_ = false; |
|
xiyuan
2014/05/29 19:49:01
We probably could consolidate |crx_cache_pending_|
jennyz
2014/07/07 21:11:12
Done.
|
| + network_ready_handled_ = false; |
| + ContinueWithNetworkReady(); |
| + } |
| +} |
| + |
| void StartupAppLauncher::LaunchApp() { |
| if (!ready_to_launch_) { |
| NOTREACHED(); |
| @@ -296,47 +415,42 @@ void StartupAppLauncher::OnUpdateCheckFinished() { |
| } |
| void StartupAppLauncher::BeginInstall() { |
| - installer_ = new WebstoreStartupInstaller( |
| - app_id_, |
| - profile_, |
| - false, |
| - base::Bind(&StartupAppLauncher::InstallCallback, AsWeakPtr())); |
| - installer_->BeginInstall(); |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(!crx_installer_.get()); |
| + |
| + base::FilePath crx_path; |
| + std::string version; |
| + KioskAppManager::Get()->GetCachedCrx(app_id_, &crx_path, &version); |
| + base::Version crx_version(version); |
| + |
| + crx_installer_ = CreateCrxInstaller(profile_); |
|
xiyuan
2014/05/29 19:49:01
Sorry that I did not mention this earlier. We shou
jennyz
2014/07/07 21:11:12
Removed CrxInstaller from StartupAppLauncher, used
|
| + crx_installer_->set_expected_id(app_id_); |
| + crx_installer_->set_expected_version(crx_version); |
| + crx_installer_->set_is_gallery_install(true); |
| + crx_installer_->set_allow_silent_install(true); |
| + |
| + crx_installer_->InstallCrx(crx_path); |
| } |
| -void StartupAppLauncher::InstallCallback(bool success, |
| - const std::string& error) { |
| - installer_ = NULL; |
| - if (delegate_->IsShowingNetworkConfigScreen()) { |
| - LOG(WARNING) << "Showing network config screen"; |
| - return; |
| - } |
| +scoped_refptr<extensions::CrxInstaller> StartupAppLauncher::CreateCrxInstaller( |
|
xiyuan
2014/05/29 19:49:01
Consider merge this into BeginInstall.
jennyz
2014/07/07 21:11:12
This function has been removed.
|
| + Profile* profile) { |
| + ExtensionService* service = |
| + extensions::ExtensionSystem::Get(profile)->extension_service(); |
| + CHECK(service); |
| - 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())); |
| - return; |
| - } |
| + scoped_refptr<extensions::CrxInstaller> installer( |
| + extensions::CrxInstaller::CreateSilent(service)); |
| - LOG(ERROR) << "App install failed: " << error |
| - << ", for attempt " << install_attempt_; |
| + installer->set_error_on_unsupported_requirements(true); |
| + installer->set_delete_source(false); |
| + installer->set_install_cause(extension_misc::INSTALL_CAUSE_USER_DOWNLOAD); |
|
xiyuan
2014/05/29 19:49:01
How about use INSTALL_CAUSE_EXTERNAL_FILE? INSTALL
jennyz
2014/07/07 21:11:12
Function has been removed.
|
| - ++install_attempt_; |
| - if (install_attempt_ < kMaxInstallAttempt) { |
| - BrowserThread::PostTask( |
| - BrowserThread::UI, |
| - FROM_HERE, |
| - base::Bind(&StartupAppLauncher::MaybeInitializeNetwork, |
| - AsWeakPtr())); |
| - return; |
| - } |
| + // Observe the crx installation events. |
| + extensions::InstallTracker* tracker = |
| + extensions::InstallTrackerFactory::GetForProfile(profile_); |
| + tracker->AddObserver(this); |
|
xiyuan
2014/05/29 19:49:01
This should be moved out of CreateCrxInstaller.
jennyz
2014/07/07 21:11:12
Done.
|
| - OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL); |
| + return installer; |
| } |
| void StartupAppLauncher::OnReadyToLaunch() { |