Index: chrome/browser/extensions/external_install_ui.cc |
diff --git a/chrome/browser/extensions/external_install_ui.cc b/chrome/browser/extensions/external_install_ui.cc |
index 7d4936b3d21229d3f784ce9c8769633b9ac4947d..a071228dc0f6ab82934798a5d4029e81511fb4ed 100644 |
--- a/chrome/browser/extensions/external_install_ui.cc |
+++ b/chrome/browser/extensions/external_install_ui.cc |
@@ -19,6 +19,8 @@ |
#include "chrome/browser/extensions/extension_install_ui.h" |
#include "chrome/browser/extensions/extension_service.h" |
#include "chrome/browser/extensions/extension_uninstall_dialog.h" |
+#include "chrome/browser/extensions/webstore_data_fetcher.h" |
+#include "chrome/browser/extensions/webstore_data_fetcher_delegate.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/browser_finder.h" |
@@ -56,11 +58,10 @@ static const int kMenuCommandId = IDC_EXTERNAL_EXTENSION_ALERT; |
class ExternalInstallGlobalError; |
-// TODO(mpcomplete): Get rid of the refcounting on this class, or document |
-// why it's necessary. Will do after refactoring to merge back with |
-// ExtensionDisabledDialogDelegate. |
+// This class is refcounted to stay alive while we try and pull webstore data. |
class ExternalInstallDialogDelegate |
: public ExtensionInstallPrompt::Delegate, |
+ public WebstoreDataFetcherDelegate, |
public base::RefCountedThreadSafe<ExternalInstallDialogDelegate> { |
public: |
ExternalInstallDialogDelegate(Browser* browser, |
@@ -80,12 +81,27 @@ class ExternalInstallDialogDelegate |
virtual void InstallUIProceed() OVERRIDE; |
virtual void InstallUIAbort(bool user_initiated) OVERRIDE; |
+ // WebstoreDataFetcherDelegate: |
+ virtual void OnWebstoreRequestFailure() OVERRIDE; |
+ virtual void OnWebstoreResponseParseSuccess( |
+ scoped_ptr<base::DictionaryValue> webstore_data) OVERRIDE; |
+ virtual void OnWebstoreResponseParseFailure( |
+ const std::string& error) OVERRIDE; |
+ |
+ // Show the install dialog to the user. |
+ void ShowInstallUI(); |
+ |
// The UI for showing the install dialog when enabling. |
scoped_ptr<ExtensionInstallPrompt> install_ui_; |
+ scoped_ptr<ExtensionInstallPrompt::Prompt> prompt_; |
Browser* browser_; |
base::WeakPtr<ExtensionService> service_weak_; |
- const std::string extension_id_; |
+ scoped_ptr<WebstoreDataFetcher> webstore_data_fetcher_; |
+ std::string extension_id_; |
+ bool use_global_error_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ExternalInstallDialogDelegate); |
}; |
// Only shows a menu item, no bubble. Clicking the menu item shows |
@@ -97,8 +113,6 @@ class ExternalInstallMenuAlert : public GlobalErrorWithStandardBubble, |
const Extension* extension); |
virtual ~ExternalInstallMenuAlert(); |
- const Extension* extension() const { return extension_; } |
- |
// GlobalError implementation. |
virtual Severity GetSeverity() OVERRIDE; |
virtual bool HasMenuItem() OVERRIDE; |
@@ -123,6 +137,9 @@ class ExternalInstallMenuAlert : public GlobalErrorWithStandardBubble, |
ExtensionService* service_; |
const Extension* extension_; |
content::NotificationRegistrar registrar_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(ExternalInstallMenuAlert); |
}; |
// Shows a menu item and a global error bubble, replacing the install dialog. |
@@ -151,6 +168,9 @@ class ExternalInstallGlobalError : public ExternalInstallMenuAlert { |
// manually). |
ExternalInstallDialogDelegate* delegate_; |
const ExtensionInstallPrompt::Prompt* prompt_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(ExternalInstallGlobalError); |
}; |
static void CreateExternalInstallGlobalError( |
@@ -196,41 +216,100 @@ ExternalInstallDialogDelegate::ExternalInstallDialogDelegate( |
bool use_global_error) |
: browser_(browser), |
service_weak_(service->AsWeakPtr()), |
- extension_id_(extension->id()) { |
+ extension_id_(extension->id()), |
+ use_global_error_(use_global_error) { |
AddRef(); // Balanced in Proceed or Abort. |
+ prompt_.reset(new ExtensionInstallPrompt::Prompt( |
+ ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT)); |
+ |
+ // If we don't have a browser, we can't go to the webstore to fetch data. |
+ // This should only happen in tests. |
+ if (!browser) { |
+ ShowInstallUI(); |
+ return; |
+ } |
+ |
+ webstore_data_fetcher_.reset(new WebstoreDataFetcher( |
+ this, |
+ browser->profile()->GetRequestContext(), |
+ GURL::EmptyGURL(), |
+ extension->id())); |
+ webstore_data_fetcher_->Start(); |
+} |
+ |
+void ExternalInstallDialogDelegate::OnWebstoreRequestFailure() { |
+ ShowInstallUI(); |
+} |
+ |
+void ExternalInstallDialogDelegate::OnWebstoreResponseParseSuccess( |
+ scoped_ptr<base::DictionaryValue> webstore_data) { |
+ std::string localized_user_count; |
+ double average_rating; |
+ int rating_count; |
+ if (!webstore_data->GetString(kUsersKey, &localized_user_count) || |
+ !webstore_data->GetDouble(kAverageRatingKey, &average_rating) || |
+ !webstore_data->GetInteger(kRatingCountKey, &rating_count)) { |
+ // If we don't get a valid webstore response, short circuit, and continue |
+ // to show a prompt without webstore data. |
+ ShowInstallUI(); |
+ return; |
+ } |
+ |
+ bool show_user_count = true; |
+ webstore_data->GetBoolean(kShowUserCountKey, &show_user_count); |
+ |
+ prompt_->SetWebstoreData(localized_user_count, |
+ show_user_count, |
+ average_rating, |
+ rating_count); |
+ |
+ ShowInstallUI(); |
+} |
+ |
+void ExternalInstallDialogDelegate::OnWebstoreResponseParseFailure( |
+ const std::string& error) { |
+ ShowInstallUI(); |
+} |
+ |
+void ExternalInstallDialogDelegate::ShowInstallUI() { |
+ const Extension* extension = NULL; |
+ if (!service_weak_.get() || |
+ !(extension = service_weak_->GetInstalledExtension(extension_id_))) { |
+ return; |
+ } |
install_ui_.reset( |
- ExtensionInstallUI::CreateInstallPromptWithBrowser(browser)); |
+ ExtensionInstallUI::CreateInstallPromptWithBrowser(browser_)); |
const ExtensionInstallPrompt::ShowDialogCallback callback = |
- use_global_error ? |
- base::Bind(&CreateExternalInstallGlobalError, |
- service_weak_, extension_id_) : |
- ExtensionInstallPrompt::GetDefaultShowDialogCallback(); |
- install_ui_->ConfirmExternalInstall(this, extension, callback); |
+ use_global_error_ ? |
+ base::Bind(&CreateExternalInstallGlobalError, |
+ service_weak_, |
+ extension_id_) : |
+ ExtensionInstallPrompt::GetDefaultShowDialogCallback(); |
+ |
+ install_ui_->ConfirmExternalInstall(this, extension, callback, *prompt_); |
} |
ExternalInstallDialogDelegate::~ExternalInstallDialogDelegate() { |
} |
void ExternalInstallDialogDelegate::InstallUIProceed() { |
- if (!service_weak_.get()) |
- return; |
- const Extension* extension = |
- service_weak_->GetInstalledExtension(extension_id_); |
- if (!extension) |
+ const Extension* extension = NULL; |
+ if (!service_weak_.get() || |
+ !(extension = service_weak_->GetInstalledExtension(extension_id_))) { |
return; |
+ } |
service_weak_->GrantPermissionsAndEnableExtension(extension); |
Release(); |
} |
void ExternalInstallDialogDelegate::InstallUIAbort(bool user_initiated) { |
- if (!service_weak_.get()) |
- return; |
- const Extension* extension = |
- service_weak_->GetInstalledExtension(extension_id_); |
- if (!extension) |
+ const Extension* extension = NULL; |
+ if (!service_weak_.get() || |
+ !(extension = service_weak_->GetInstalledExtension(extension_id_))) { |
return; |
+ } |
service_weak_->UninstallExtension(extension_id_, false, NULL); |
Release(); |
} |