Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4158)

Unified Diff: chrome/browser/extensions/api/webstore_private/webstore_private_api.cc

Issue 389613006: Prevent duplicate concurrent installs of the same extension (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed update of webstore_result Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 ed224121f0d8b55f293f3558542bdd04d869458f..71017ee4fbff864cfc7a1732381bd2e43a17fdeb 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/chrome_notification_types.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/webstore_installer.h"
#include "chrome/browser/gpu/gpu_feature_checker.h"
#include "chrome/browser/profiles/profile_manager.h"
@@ -116,65 +117,8 @@ scoped_ptr<WebstoreInstaller::Approval> PendingApprovals::PopApproval(
return scoped_ptr<WebstoreInstaller::Approval>();
}
-// Uniquely holds the profile and extension id of an install between the time we
-// prompt and complete the installs.
-class PendingInstalls {
- public:
- PendingInstalls();
- ~PendingInstalls();
-
- bool InsertInstall(Profile* profile, const std::string& id);
- void EraseInstall(Profile* profile, const std::string& id);
- bool ContainsInstall(Profile* profile, const std::string& id);
- private:
- typedef std::pair<Profile*, std::string> ProfileAndExtensionId;
- typedef std::vector<ProfileAndExtensionId> InstallList;
-
- InstallList::iterator FindInstall(Profile* profile, const std::string& id);
-
- InstallList installs_;
-
- DISALLOW_COPY_AND_ASSIGN(PendingInstalls);
-};
-
-PendingInstalls::PendingInstalls() {}
-PendingInstalls::~PendingInstalls() {}
-
-// 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())
- 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())
- installs_.erase(it);
-}
-
-bool PendingInstalls::ContainsInstall(Profile* profile, const std::string& id) {
- return FindInstall(profile, id) != installs_.end();
-}
-
-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;
// A preference set by the web store to indicate login information for
// purchased apps.
@@ -326,12 +270,16 @@ bool WebstorePrivateBeginInstallWithManifest3Function::RunAsync() {
*params_->details.icon_data : std::string();
Profile* profile = GetProfile();
+ InstallTracker* tracker = InstallTracker::Get(profile);
+ DCHECK(tracker);
if (util::IsExtensionInstalledPermanently(params_->details.id, profile) ||
- !g_pending_installs.Get().InsertInstall(profile, params_->details.id)) {
+ tracker->GetActiveInstall(params_->details.id)) {
SetResultCode(ALREADY_INSTALLED);
error_ = kAlreadyInstalledError;
return false;
}
+ ActiveInstallData install_data(params_->details.id);
+ scoped_active_install_.reset(new ScopedActiveInstall(tracker, install_data));
net::URLRequestContextGetter* context_getter = NULL;
if (!icon_url.is_empty())
@@ -450,7 +398,6 @@ void WebstorePrivateBeginInstallWithManifest3Function::OnWebstoreParseFailure(
CHECK(false);
}
error_ = error_message;
- g_pending_installs.Get().EraseInstall(GetProfile(), id);
SendResponse(false);
// Matches the AddRef in RunAsync().
@@ -463,7 +410,6 @@ void WebstorePrivateBeginInstallWithManifest3Function::SigninFailed(
SetResultCode(SIGNIN_FAILED);
error_ = error.ToString();
- g_pending_installs.Get().EraseInstall(GetProfile(), params_->details.id);
SendResponse(false);
// Matches the AddRef in RunAsync().
@@ -514,6 +460,9 @@ void WebstorePrivateBeginInstallWithManifest3Function::InstallUIProceed() {
approval->authuser = authuser_;
g_pending_approvals.Get().PushApproval(approval.Pass());
+ DCHECK(scoped_active_install_.get());
+ scoped_active_install_->CancelDeregister();
+
SetResultCode(ERROR_NONE);
SendResponse(true);
@@ -531,7 +480,6 @@ void WebstorePrivateBeginInstallWithManifest3Function::InstallUIAbort(
bool user_initiated) {
error_ = kUserCancelledError;
SetResultCode(USER_CANCELLED);
- g_pending_installs.Get().EraseInstall(GetProfile(), params_->details.id);
SendResponse(false);
// The web store install histograms are a subset of the install histograms.
@@ -576,6 +524,9 @@ bool WebstorePrivateCompleteInstallFunction::RunAsync() {
return false;
}
+ scoped_active_install_.reset(new ScopedActiveInstall(
+ InstallTracker::Get(GetProfile()), params->expected_id));
+
AppListService* app_list_service =
AppListService::Get(GetCurrentBrowser()->host_desktop_type());
@@ -646,7 +597,6 @@ void WebstorePrivateCompleteInstallFunction::OnExtensionInstallFailure(
error_ = error;
VLOG(1) << "Install failed, sending response";
- g_pending_installs.Get().EraseInstall(GetProfile(), id);
SendResponse(false);
RecordWebstoreExtensionInstallResult(false);
@@ -661,7 +611,6 @@ void WebstorePrivateCompleteInstallFunction::OnInstallSuccess(
test_webstore_installer_delegate->OnExtensionInstallSuccess(id);
VLOG(1) << "Install success, sending response";
- g_pending_installs.Get().EraseInstall(GetProfile(), id);
SendResponse(true);
}
@@ -856,13 +805,6 @@ bool WebstorePrivateLaunchEphemeralAppFunction::RunAsync() {
LaunchEphemeralApp::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params);
- // If a full install is in progress, do not install ephemerally.
- if (g_pending_installs.Get().ContainsInstall(GetProfile(), params->id)) {
- SetResult(LaunchEphemeralAppResult::RESULT_INSTALL_IN_PROGRESS,
- "An install is already in progress");
- return false;
- }
-
AddRef(); // Balanced in OnLaunchComplete()
scoped_refptr<EphemeralAppLauncher> launcher =
@@ -919,6 +861,12 @@ void WebstorePrivateLaunchEphemeralAppFunction::OnLaunchComplete(
case webstore_install::LAUNCH_UNSUPPORTED_EXTENSION_TYPE:
api_result = LaunchEphemeralAppResult::RESULT_UNSUPPORTED_EXTENSION_TYPE;
break;
+ case webstore_install::INSTALL_IN_PROGRESS:
+ api_result = LaunchEphemeralAppResult::RESULT_INSTALL_IN_PROGRESS;
+ break;
+ case webstore_install::LAUNCH_IN_PROGRESS:
+ api_result = LaunchEphemeralAppResult::RESULT_LAUNCH_IN_PROGRESS;
+ break;
default:
NOTREACHED();
break;
« no previous file with comments | « chrome/browser/extensions/api/webstore_private/webstore_private_api.h ('k') | chrome/browser/extensions/install_tracker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698