Chromium Code Reviews| Index: chrome/browser/extensions/api/webstore_private/webstore_private_api.cc |
| diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc |
| index a8ae144ba42618acfe2c6e54f8d09f1653be36bc..179e2ba2ad6bb7e2f43204cdd32259e7f247f6e6 100644 |
| --- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc |
| +++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc |
| @@ -86,8 +86,54 @@ scoped_ptr<WebstoreInstaller::Approval> PendingApprovals::PopApproval( |
| return scoped_ptr<WebstoreInstaller::Approval>(NULL); |
| } |
| +// Uniquely holds the profile and extension id of an install between the time we |
| +// prompt and complete the installs. |
| +struct PendingInstalls { |
|
koz (OOO until 15th September)
2013/05/20 23:57:12
Make this a class with |installs_| and related typ
calamity
2013/05/21 00:49:41
Done.
|
| + typedef std::pair<Profile*, std::string> ProfileAndExtensionId; |
| + typedef std::vector<ProfileAndExtensionId> InstallList; |
| + |
| + bool InsertInstall(Profile* profile, const std::string& id); |
| + void EraseInstall(Profile* profile, const std::string& id); |
| + InstallList::iterator FindInstall(Profile* profile, const std::string& id); |
| + |
| + InstallList installs_; |
| +}; |
| + |
| +// Returns true and inserts the profile/id pair if it is not present. Otherwise |
| +// returns false. |
| +bool PendingInstalls::InsertInstall(Profile* profile, const std::string& id) { |
| + if (FindInstall(profile, id) != installs_.end()) { |
|
koz (OOO until 15th September)
2013/05/20 23:57:12
nit: no curlies
calamity
2013/05/21 00:49:41
Done.
|
| + return false; |
| + } |
| + installs_.push_back(make_pair(profile, id)); |
| + return true; |
| +} |
| + |
| +// Removes the given profile/id pair. |
| +void PendingInstalls::EraseInstall(Profile* profile, const std::string& id) { |
| + InstallList::iterator it = FindInstall(profile, id); |
| + if (it != installs_.end()) { |
|
koz (OOO until 15th September)
2013/05/20 23:57:12
nit: no curlies
calamity
2013/05/21 00:49:41
Done.
|
| + installs_.erase(it); |
| + } |
| +} |
| + |
| +PendingInstalls::InstallList::iterator PendingInstalls::FindInstall( |
| + Profile* profile, |
| + const std::string& id) { |
| + for (size_t i = 0; i < installs_.size(); ++i) { |
| + ProfileAndExtensionId install = installs_[i]; |
| + if (install.second == id && |
| + profile->IsSameProfile(install.first)) { |
| + return (installs_.begin() + i); |
| + } |
| + } |
| + return installs_.end(); |
| +} |
| + |
| static base::LazyInstance<PendingApprovals> g_pending_approvals = |
| LAZY_INSTANCE_INITIALIZER; |
| +static base::LazyInstance<PendingInstalls> g_pending_installs = |
| + LAZY_INSTANCE_INITIALIZER; |
| const char kAppInstallBubbleKey[] = "appInstallBubble"; |
| const char kEnableLauncherKey[] = "enableLauncher"; |
| @@ -98,6 +144,7 @@ const char kLocalizedNameKey[] = "localizedName"; |
| const char kLoginKey[] = "login"; |
| const char kManifestKey[] = "manifest"; |
| +const char kAlreadyInstalledError[] = "This item is already installed"; |
| const char kCannotSpecifyIconDataAndUrlError[] = |
| "You cannot specify both icon data and an icon url"; |
| const char kInvalidIconUrlError[] = "Invalid icon url"; |
| @@ -223,6 +270,15 @@ bool BeginInstallWithManifestFunction::RunImpl() { |
| return false; |
| } |
| + ExtensionService* service = |
| + extensions::ExtensionSystem::Get(profile_)->extension_service(); |
| + if (service->GetInstalledExtension(id_) || |
| + !g_pending_installs.Get().InsertInstall(profile_, id_)) { |
| + SetResultCode(ALREADY_INSTALLED); |
| + error_ = kAlreadyInstalledError; |
| + return false; |
| + } |
| + |
| EXTENSION_FUNCTION_VALIDATE(details->GetString(kManifestKey, &manifest_)); |
| if (details->HasKey(kIconDataKey) && details->HasKey(kIconUrlKey)) { |
| @@ -307,6 +363,9 @@ void BeginInstallWithManifestFunction::SetResultCode(ResultCode code) { |
| case SIGNIN_FAILED: |
| SetResult(Value::CreateStringValue("signin_failed")); |
| break; |
| + case ALREADY_INSTALLED: |
| + SetResult(Value::CreateStringValue("already_installed")); |
| + break; |
| default: |
| CHECK(false); |
| } |
| @@ -532,6 +591,8 @@ void CompleteInstallFunction::OnExtensionInstallSuccess( |
| if (test_webstore_installer_delegate) |
| test_webstore_installer_delegate->OnExtensionInstallSuccess(id); |
| + g_pending_installs.Get().EraseInstall(profile_, id); |
| + |
| LOG(INFO) << "Install success, sending response"; |
| SendResponse(true); |
| @@ -551,6 +612,8 @@ void CompleteInstallFunction::OnExtensionInstallFailure( |
| id, error, reason); |
| } |
| + g_pending_installs.Get().EraseInstall(profile_, id); |
| + |
| error_ = error; |
| LOG(INFO) << "Install failed, sending response"; |
| SendResponse(false); |