Index: chrome/browser/extensions/webstore_standalone_installer.cc |
diff --git a/chrome/browser/extensions/webstore_standalone_installer.cc b/chrome/browser/extensions/webstore_standalone_installer.cc |
index 4f42f01b221312bc01654531b520157d9c2244e0..ca46c7512ccc94f7c0a199c388fc3a0baae58e68 100644 |
--- a/chrome/browser/extensions/webstore_standalone_installer.cc |
+++ b/chrome/browser/extensions/webstore_standalone_installer.cc |
@@ -31,6 +31,8 @@ const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse"; |
const char kInvalidManifestError[] = "Invalid manifest"; |
const char kUserCancelledError[] = "User cancelled install"; |
const char kExtensionIsBlacklisted[] = "Extension is blacklisted"; |
+const char kInstallInProgressError[] = "An install is already in progress"; |
+const char kLaunchInProgressError[] = "A launch is already in progress"; |
WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( |
const std::string& webstore_item_id, |
@@ -42,7 +44,8 @@ WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( |
install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), |
show_user_count_(true), |
average_rating_(0.0), |
- rating_count_(0) { |
+ rating_count_(0), |
+ install_registered_(false) { |
} |
void WebstoreStandaloneInstaller::BeginInstall() { |
@@ -56,6 +59,13 @@ void WebstoreStandaloneInstaller::BeginInstall() { |
return; |
} |
+ webstore_install::Result result = webstore_install::UNKNOWN_ERROR; |
+ std::string error; |
+ if (!EnsureUniqueInstall(&result, &error)) { |
+ CompleteInstall(result, error); |
+ return; |
+ } |
+ |
// Use the requesting page as the referrer both since that is more correct |
// (it is the page that caused this request to happen) and so that we can |
// track top sites that trigger inline install requests. |
@@ -79,13 +89,41 @@ void WebstoreStandaloneInstaller::AbortInstall() { |
// Abort any in-progress fetches. |
if (webstore_data_fetcher_) { |
webstore_data_fetcher_.reset(); |
+ DeregisterActiveInstall(); |
Release(); // Matches the AddRef in BeginInstall. |
} |
} |
+bool WebstoreStandaloneInstaller::EnsureUniqueInstall( |
+ webstore_install::Result* reason, |
+ std::string* error) { |
+ InstallTracker* tracker = InstallTracker::Get(profile_); |
+ DCHECK(tracker); |
+ |
+ const InstallTracker::InstallProgressData* existing_install_data = |
+ tracker->GetActiveInstall(id_); |
+ if (existing_install_data) { |
+ if (existing_install_data->is_ephemeral) { |
+ *reason = webstore_install::LAUNCH_IN_PROGRESS; |
+ *error = kLaunchInProgressError; |
+ } else { |
+ *reason = webstore_install::INSTALL_IN_PROGRESS; |
+ *error = kInstallInProgressError; |
+ } |
+ return false; |
+ } |
+ |
+ InstallTracker::InstallProgressData install_data(id_); |
+ InitInstallData(&install_data); |
+ tracker->AddActiveInstall(install_data); |
+ install_registered_ = true; |
+ return true; |
+} |
+ |
void WebstoreStandaloneInstaller::CompleteInstall( |
webstore_install::Result result, |
const std::string& error) { |
+ DeregisterActiveInstall(); |
if (!callback_.is_null()) |
callback_.Run(result == webstore_install::SUCCESS, error); |
Release(); // Matches the AddRef in BeginInstall. |
@@ -121,6 +159,11 @@ WebstoreStandaloneInstaller::GetLocalizedExtensionForDisplay() { |
return localized_extension_for_display_.get(); |
} |
+void WebstoreStandaloneInstaller::InitInstallData( |
+ InstallTracker::InstallProgressData* install_data) const { |
+ // Default implementation sets no properties. |
+} |
+ |
void WebstoreStandaloneInstaller::OnManifestParsed() { |
ProceedWithInstallPrompt(); |
} |
@@ -395,4 +438,13 @@ void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { |
webstore_data_fetcher_.reset(); |
} |
+void WebstoreStandaloneInstaller::DeregisterActiveInstall() { |
+ if (!install_registered_) |
+ return; |
+ |
+ InstallTracker* tracker = InstallTracker::Get(profile_); |
+ DCHECK(tracker); |
+ tracker->RemoveActiveInstall(id_); |
+} |
+ |
} // namespace extensions |