summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-22 23:45:22 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-22 23:45:22 +0000
commitbad0b98ea106ce5fe58a6630e059e9aa58f9a8d0 (patch)
tree019df7184015e1bb6cb70f3410ccae018444852f
parent539f785c76060eb0373159e2d0cd91d113cbc4ae (diff)
downloadchromium_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.cc195
-rw-r--r--chrome/browser/chromeos/app_mode/startup_app_launcher.h15
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);
};