| Index: chrome/browser/extensions/webstore_installer.cc
|
| diff --git a/chrome/browser/extensions/webstore_installer.cc b/chrome/browser/extensions/webstore_installer.cc
|
| index 0bafe1c1fd3ee2cbba1f852db8d61cef1c5182f6..db6ebb8ed1338c890854f8e11c9d94cf23a06385 100644
|
| --- a/chrome/browser/extensions/webstore_installer.cc
|
| +++ b/chrome/browser/extensions/webstore_installer.cc
|
| @@ -14,6 +14,7 @@
|
| #include "base/string_number_conversions.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/browser/browser_process.h"
|
| +#include "chrome/browser/download/chrome_download_manager_delegate.h"
|
| #include "chrome/browser/download/download_prefs.h"
|
| #include "chrome/browser/download/download_util.h"
|
| #include "chrome/browser/extensions/crx_installer.h"
|
| @@ -31,11 +32,14 @@
|
| #include "content/public/browser/navigation_controller.h"
|
| #include "content/public/browser/navigation_entry.h"
|
| #include "content/public/browser/notification_details.h"
|
| +#include "content/public/browser/notification_service.h"
|
| #include "content/public/browser/notification_source.h"
|
| #include "googleurl/src/gurl.h"
|
| #include "net/base/escape.h"
|
|
|
| using content::BrowserThread;
|
| +using content::DownloadId;
|
| +using content::DownloadItem;
|
| using content::NavigationController;
|
|
|
| namespace {
|
| @@ -43,7 +47,10 @@ namespace {
|
| const char kInvalidIdError[] = "Invalid id";
|
| const char kNoBrowserError[] = "No browser found";
|
| const char kDownloadDirectoryError[] = "Could not create download directory";
|
| -
|
| +const char kDownloadCanceledError[] = "Download canceled";
|
| +const char kInstallCanceledError[] = "Install canceled";
|
| +const char kDownloadInterruptedError[] = "Download interrupted";
|
| +const char kInvalidDownloadError[] = "Download was not a CRX";
|
| const char kInlineInstallSource[] = "inline";
|
| const char kDefaultInstallSource[] = "";
|
|
|
| @@ -60,9 +67,8 @@ GURL GetWebstoreInstallURL(
|
| }
|
| std::vector<std::string> params;
|
| params.push_back("id=" + extension_id);
|
| - if (!install_source.empty()) {
|
| + if (!install_source.empty())
|
| params.push_back("installsource=" + install_source);
|
| - }
|
| params.push_back("lang=" + g_browser_process->GetApplicationLocale());
|
| params.push_back("uc");
|
| std::string url_string = extension_urls::GetWebstoreUpdateUrl(true).spec();
|
| @@ -120,17 +126,25 @@ WebstoreInstaller::WebstoreInstaller(Profile* profile,
|
| delegate_(delegate),
|
| controller_(controller),
|
| id_(id),
|
| + download_item_(NULL),
|
| flags_(flags) {
|
| download_url_ = GetWebstoreInstallURL(id, flags & FLAG_INLINE_INSTALL ?
|
| kInlineInstallSource : kDefaultInstallSource);
|
|
|
| + registrar_.Add(this, chrome::NOTIFICATION_CRX_INSTALLER_DONE,
|
| + content::NotificationService::AllSources());
|
| registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
|
| content::Source<Profile>(profile));
|
| registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR,
|
| content::Source<CrxInstaller>(NULL));
|
| }
|
|
|
| -WebstoreInstaller::~WebstoreInstaller() {}
|
| +WebstoreInstaller::~WebstoreInstaller() {
|
| + if (download_item_) {
|
| + download_item_->RemoveObserver(this);
|
| + download_item_ = NULL;
|
| + }
|
| +}
|
|
|
| void WebstoreInstaller::Start() {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| @@ -155,6 +169,18 @@ void WebstoreInstaller::Observe(int type,
|
| const content::NotificationSource& source,
|
| const content::NotificationDetails& details) {
|
| switch (type) {
|
| + case chrome::NOTIFICATION_CRX_INSTALLER_DONE: {
|
| + const Extension* extension =
|
| + content::Details<const Extension>(details).ptr();
|
| + CrxInstaller* installer = content::Source<CrxInstaller>(source).ptr();
|
| + if (extension == NULL && download_item_ != NULL &&
|
| + installer->download_url() == download_item_->GetURL() &&
|
| + installer->profile()->IsSameProfile(profile_)) {
|
| + ReportFailure(kInstallCanceledError);
|
| + }
|
| + break;
|
| + }
|
| +
|
| case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
|
| CHECK(profile_->IsSameProfile(content::Source<Profile>(source).ptr()));
|
| const Extension* extension =
|
| @@ -188,6 +214,48 @@ void WebstoreInstaller::SetDownloadDirectoryForTests(FilePath* directory) {
|
| g_download_directory_for_tests = directory;
|
| }
|
|
|
| +void WebstoreInstaller::OnDownloadStarted(DownloadId id, net::Error error) {
|
| + if (error != net::OK) {
|
| + ReportFailure(net::ErrorToString(error));
|
| + return;
|
| + }
|
| +
|
| + CHECK(id.IsValid());
|
| +
|
| + content::DownloadManager* download_manager = profile_->GetDownloadManager();
|
| + download_item_ = download_manager->GetActiveDownloadItem(id.local());
|
| + download_item_->AddObserver(this);
|
| +}
|
| +
|
| +void WebstoreInstaller::OnDownloadUpdated(DownloadItem* download) {
|
| + CHECK_EQ(download_item_, download);
|
| +
|
| + switch (download->GetState()) {
|
| + case DownloadItem::CANCELLED:
|
| + ReportFailure(kDownloadCanceledError);
|
| + break;
|
| + case DownloadItem::INTERRUPTED:
|
| + ReportFailure(kDownloadInterruptedError);
|
| + break;
|
| + case DownloadItem::REMOVING:
|
| + download_item_->RemoveObserver(this);
|
| + download_item_ = NULL;
|
| + break;
|
| + case DownloadItem::COMPLETE:
|
| + // Wait for other notifications if the download is really an extension.
|
| + if (!ChromeDownloadManagerDelegate::IsExtensionDownload(download))
|
| + ReportFailure(kInvalidDownloadError);
|
| + break;
|
| + default:
|
| + // Continue listening if the download is not in one of the above states.
|
| + break;
|
| + }
|
| +}
|
| +
|
| +void WebstoreInstaller::OnDownloadOpened(DownloadItem* download) {
|
| + CHECK_EQ(download_item_, download);
|
| +}
|
| +
|
| void WebstoreInstaller::StartDownload(const FilePath& file) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
|
|
| @@ -216,19 +284,23 @@ void WebstoreInstaller::StartDownload(const FilePath& file) {
|
| profile_->GetDownloadManager()->DownloadUrl(
|
| download_url_, referrer, "",
|
| false, -1, save_info, controller_->GetWebContents(),
|
| - content::DownloadManager::OnStartedCallback());
|
| + base::Bind(&WebstoreInstaller::OnDownloadStarted, this));
|
| }
|
|
|
| void WebstoreInstaller::ReportFailure(const std::string& error) {
|
| - if (delegate_)
|
| + if (delegate_) {
|
| delegate_->OnExtensionInstallFailure(id_, error);
|
| + delegate_ = NULL;
|
| + }
|
|
|
| Release(); // Balanced in Start().
|
| }
|
|
|
| void WebstoreInstaller::ReportSuccess() {
|
| - if (delegate_)
|
| + if (delegate_) {
|
| delegate_->OnExtensionInstallSuccess(id_);
|
| + delegate_ = NULL;
|
| + }
|
|
|
| Release(); // Balanced in Start().
|
| }
|
|
|