| 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;
|
| + 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_);
|
| + 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(
|
| + 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);
|
|
|
| - ++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);
|
|
|
| - OnLaunchFailure(KioskAppLaunchError::UNABLE_TO_INSTALL);
|
| + return installer;
|
| }
|
|
|
| void StartupAppLauncher::OnReadyToLaunch() {
|
|
|