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() { |