diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-22 23:45:22 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-22 23:45:22 +0000 |
commit | bad0b98ea106ce5fe58a6630e059e9aa58f9a8d0 (patch) | |
tree | 019df7184015e1bb6cb70f3410ccae018444852f | |
parent | 539f785c76060eb0373159e2d0cd91d113cbc4ae (diff) | |
download | chromium_src-bad0b98ea106ce5fe58a6630e059e9aa58f9a8d0.zip chromium_src-bad0b98ea106ce5fe58a6630e059e9aa58f9a8d0.tar.gz chromium_src-bad0b98ea106ce5fe58a6630e059e9aa58f9a8d0.tar.bz2 |
Merge 244632 "kiosk: Do update check during launch."
The missed two files from last merge in r246082.
> kiosk: Do update check during launch.
>
> - Check app update during launching;
> - Update cached app data when app is installed/updated;
>
> BUG=330713
> R=tengs@chromium.org
>
> Review URL: https://codereview.chromium.org/137343003
TBR=xiyuan@chromium.org
Review URL: https://codereview.chromium.org/140323016
git-svn-id: svn://svn.chromium.org/chrome/branches/1750/src@246448 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/chromeos/app_mode/startup_app_launcher.cc | 195 | ||||
-rw-r--r-- | chrome/browser/chromeos/app_mode/startup_app_launcher.h | 15 |
2 files changed, 188 insertions, 22 deletions
diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc index 1339567..8561504 100644 --- a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc +++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc @@ -16,6 +16,8 @@ #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_system.h" +#include "chrome/browser/extensions/updater/manifest_fetch_data.h" +#include "chrome/browser/extensions/updater/safe_manifest_parser.h" #include "chrome/browser/extensions/webstore_startup_installer.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/signin/profile_oauth2_token_service.h" @@ -23,12 +25,20 @@ #include "chrome/browser/ui/extensions/application_launch.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/chrome_version_info.h" +#include "chrome/common/extensions/manifest_url_handler.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "extensions/common/extension.h" #include "extensions/common/manifest_handlers/kiosk_mode_info.h" #include "google_apis/gaia/gaia_auth_consumer.h" #include "google_apis/gaia/gaia_constants.h" +#include "net/base/load_flags.h" +#include "net/url_request/url_fetcher.h" +#include "net/url_request/url_fetcher_delegate.h" +#include "net/url_request/url_request_context_getter.h" +#include "net/url_request/url_request_status.h" +#include "url/gurl.h" using content::BrowserThread; using extensions::Extension; @@ -45,13 +55,123 @@ const char kOAuthClientSecret[] = "client_secret"; const base::FilePath::CharType kOAuthFileName[] = FILE_PATH_LITERAL("kiosk_auth"); -bool IsAppInstalled(Profile* profile, const std::string& app_id) { - return extensions::ExtensionSystem::Get(profile)->extension_service()-> - GetInstalledExtension(app_id); -} - } // namespace +class StartupAppLauncher::AppUpdateChecker + : public base::SupportsWeakPtr<AppUpdateChecker>, + public net::URLFetcherDelegate { + public: + explicit AppUpdateChecker(StartupAppLauncher* launcher) + : launcher_(launcher), + profile_(launcher->profile_), + app_id_(launcher->app_id_) {} + virtual ~AppUpdateChecker() {} + + void Start() { + const Extension* app = GetInstalledApp(); + if (!app) { + launcher_->OnUpdateCheckNotInstalled(); + return; + } + + GURL update_url = extensions::ManifestURL::GetUpdateURL(app); + if (update_url.is_empty()) + update_url = extension_urls::GetWebstoreUpdateUrl(); + if (!update_url.is_valid()) { + launcher_->OnUpdateCheckNoUpdate(); + return; + } + + manifest_fetch_data_.reset( + new extensions::ManifestFetchData(update_url, 0)); + manifest_fetch_data_->AddExtension( + app_id_, app->version()->GetString(), NULL, "", ""); + + manifest_fetcher_.reset(net::URLFetcher::Create( + manifest_fetch_data_->full_url(), net::URLFetcher::GET, this)); + manifest_fetcher_->SetRequestContext(profile_->GetRequestContext()); + manifest_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | + net::LOAD_DO_NOT_SAVE_COOKIES | + net::LOAD_DISABLE_CACHE); + manifest_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); + manifest_fetcher_->Start(); + } + + private: + const Extension* GetInstalledApp() { + ExtensionService* extension_service = + extensions::ExtensionSystem::Get(profile_)->extension_service(); + return extension_service->GetInstalledExtension(app_id_); + } + + void HandleManifestResults(const extensions::ManifestFetchData& fetch_data, + const UpdateManifest::Results* results) { + if (!results || results->list.empty()) { + launcher_->OnUpdateCheckNoUpdate(); + return; + } + + DCHECK_EQ(1u, results->list.size()); + + const UpdateManifest::Result& update = results->list[0]; + + if (update.browser_min_version.length() > 0) { + Version browser_version; + chrome::VersionInfo version_info; + if (version_info.is_valid()) + browser_version = Version(version_info.Version()); + + Version browser_min_version(update.browser_min_version); + if (browser_version.IsValid() && + browser_min_version.IsValid() && + browser_min_version.CompareTo(browser_version) > 0) { + launcher_->OnUpdateCheckNoUpdate(); + return; + } + } + + const Version& existing_version = *GetInstalledApp()->version(); + Version update_version(update.version); + if (existing_version.IsValid() && + update_version.IsValid() && + update_version.CompareTo(existing_version) <= 0) { + launcher_->OnUpdateCheckNoUpdate(); + return; + } + + launcher_->OnUpdateCheckUpdateAvailable(); + } + + // net::URLFetcherDelegate implementation. + virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE { + DCHECK_EQ(source, manifest_fetcher_.get()); + + if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS || + source->GetResponseCode() != 200) { + launcher_->OnUpdateCheckNoUpdate(); + return; + } + + std::string data; + source->GetResponseAsString(&data); + scoped_refptr<extensions::SafeManifestParser> safe_parser( + new extensions::SafeManifestParser( + data, + manifest_fetch_data_.release(), + base::Bind(&AppUpdateChecker::HandleManifestResults, + AsWeakPtr()))); + safe_parser->Start(); + } + + StartupAppLauncher* launcher_; + Profile* profile_; + const std::string app_id_; + + scoped_ptr<extensions::ManifestFetchData> manifest_fetch_data_; + scoped_ptr<net::URLFetcher> manifest_fetcher_; + + DISALLOW_COPY_AND_ASSIGN(AppUpdateChecker); +}; StartupAppLauncher::StartupAppLauncher(Profile* profile, const std::string& app_id, @@ -80,7 +200,7 @@ void StartupAppLauncher::ContinueWithNetworkReady() { // Starts install if it is not started. if (!install_attempted_) { install_attempted_ = true; - BeginInstall(); + MaybeInstall(); } } @@ -183,17 +303,6 @@ void StartupAppLauncher::OnRefreshTokensLoaded() { InitializeNetwork(); } -void StartupAppLauncher::OnLaunchSuccess() { - delegate_->OnLaunchSucceeded(); -} - -void StartupAppLauncher::OnLaunchFailure(KioskAppLaunchError::Error error) { - LOG(ERROR) << "App launch failed, error: " << error; - DCHECK_NE(KioskAppLaunchError::NONE, error); - - delegate_->OnLaunchFailed(error); -} - void StartupAppLauncher::LaunchApp() { if (!ready_to_launch_) { NOTREACHED(); @@ -225,14 +334,44 @@ void StartupAppLauncher::LaunchApp() { OnLaunchSuccess(); } -void StartupAppLauncher::BeginInstall() { +void StartupAppLauncher::OnLaunchSuccess() { + delegate_->OnLaunchSucceeded(); +} + +void StartupAppLauncher::OnLaunchFailure(KioskAppLaunchError::Error error) { + LOG(ERROR) << "App launch failed, error: " << error; + DCHECK_NE(KioskAppLaunchError::NONE, error); + + delegate_->OnLaunchFailed(error); +} + +void StartupAppLauncher::MaybeInstall() { delegate_->OnInstallingApp(); - if (IsAppInstalled(profile_, app_id_)) { - OnReadyToLaunch(); - return; - } + update_checker_.reset(new AppUpdateChecker(this)); + update_checker_->Start(); +} + +void StartupAppLauncher::OnUpdateCheckNotInstalled() { + BeginInstall(); +} +void StartupAppLauncher::OnUpdateCheckUpdateAvailable() { + // Uninstall to force a re-install. + // TODO(xiyuan): Find a better way. Either download CRX and install it + // directly or integrate with ExtensionUpdater in someway. + ExtensionService* extension_service = + extensions::ExtensionSystem::Get(profile_)->extension_service(); + extension_service->UninstallExtension(app_id_, false, NULL); + + OnUpdateCheckNotInstalled(); +} + +void StartupAppLauncher::OnUpdateCheckNoUpdate() { + OnReadyToLaunch(); +} + +void StartupAppLauncher::BeginInstall() { installer_ = new WebstoreStartupInstaller( app_id_, profile_, @@ -252,6 +391,13 @@ void StartupAppLauncher::InstallCallback(bool success, FROM_HERE, base::Bind(&StartupAppLauncher::OnReadyToLaunch, AsWeakPtr())); + + // Schedule app data update after installation. + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&StartupAppLauncher::UpdateAppData, + AsWeakPtr())); return; } @@ -264,4 +410,9 @@ void StartupAppLauncher::OnReadyToLaunch() { delegate_->OnReadyToLaunch(); } +void StartupAppLauncher::UpdateAppData() { + KioskAppManager::Get()->ClearAppData(app_id_); + KioskAppManager::Get()->UpdateAppDataFromProfile(app_id_, profile_, NULL); +} + } // namespace chromeos diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher.h b/chrome/browser/chromeos/app_mode/startup_app_launcher.h index 43f7cbf..72a4597 100644 --- a/chrome/browser/chromeos/app_mode/startup_app_launcher.h +++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.h @@ -74,12 +74,25 @@ class StartupAppLauncher std::string client_secret; }; + // A class to check if the app has an update. It invokes BeginInstall + // if the app is not installed or not up-to-date. Otherwise, it invokes + // OnReadyToLaunch. + class AppUpdateChecker; + void OnLaunchSuccess(); void OnLaunchFailure(KioskAppLaunchError::Error error); + void MaybeInstall(); + + // Callbacks from AppUpdateChecker + void OnUpdateCheckNotInstalled(); + void OnUpdateCheckUpdateAvailable(); + void OnUpdateCheckNoUpdate(); + void BeginInstall(); void InstallCallback(bool success, const std::string& error); void OnReadyToLaunch(); + void UpdateAppData(); void InitializeTokenService(); void InitializeNetwork(); @@ -101,6 +114,8 @@ class StartupAppLauncher scoped_refptr<extensions::WebstoreStandaloneInstaller> installer_; KioskOAuthParams auth_params_; + scoped_ptr<AppUpdateChecker> update_checker_; + DISALLOW_COPY_AND_ASSIGN(StartupAppLauncher); }; |