diff options
author | skerner@chromium.org <skerner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-31 13:42:28 +0000 |
---|---|---|
committer | skerner@chromium.org <skerner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-31 13:42:28 +0000 |
commit | 089bda66f423cfac13dcd22fd5c1f187524f12a5 (patch) | |
tree | 44fe5c4f470d57253409413cf6c63ff786612b78 /chrome/browser/download | |
parent | 02a1bc990c558ddb5085c6432866d971c5e71e9f (diff) | |
download | chromium_src-089bda66f423cfac13dcd22fd5c1f187524f12a5.zip chromium_src-089bda66f423cfac13dcd22fd5c1f187524f12a5.tar.gz chromium_src-089bda66f423cfac13dcd22fd5c1f187524f12a5.tar.bz2 |
Show that CRX unpacking is happening in the download shelf
BUG=80010
TEST=manual for now
Review URL: http://codereview.chromium.org/7047017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87302 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/download')
-rw-r--r-- | chrome/browser/download/download_item.cc | 73 | ||||
-rw-r--r-- | chrome/browser/download/download_item.h | 24 | ||||
-rw-r--r-- | chrome/browser/download/download_item_model.cc | 9 | ||||
-rw-r--r-- | chrome/browser/download/download_util.cc | 28 | ||||
-rw-r--r-- | chrome/browser/download/download_util.h | 14 |
5 files changed, 123 insertions, 25 deletions
diff --git a/chrome/browser/download/download_item.cc b/chrome/browser/download/download_item.cc index f2cc384..31fa520 100644 --- a/chrome/browser/download/download_item.cc +++ b/chrome/browser/download/download_item.cc @@ -22,6 +22,7 @@ #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/download/download_state_info.h" #include "chrome/browser/download/download_util.h" +#include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/history/download_history_info.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/prefs/pref_service.h" @@ -29,6 +30,7 @@ #include "chrome/common/extensions/extension.h" #include "chrome/common/pref_names.h" #include "content/browser/browser_thread.h" +#include "content/common/notification_source.h" #include "ui/base/l10n/l10n_util.h" // A DownloadItem normally goes through the following states: @@ -361,12 +363,8 @@ void DownloadItem::Completed() { UpdateObservers(); download_manager_->DownloadCompleted(id()); download_util::RecordDownloadCount(download_util::COMPLETED_COUNT); - - // Handle chrome extensions explicitly and skip the shell execute. if (is_extension_install()) { - download_util::OpenChromeExtension(download_manager_->profile(), - download_manager_, - *this); + // Extensions should already have been unpacked and opened. auto_opened_ = true; } else if (open_when_complete() || download_manager_->ShouldOpenFileBasedOnExtension( @@ -383,6 +381,57 @@ void DownloadItem::Completed() { } } +void DownloadItem::StartCrxInstall() { + DCHECK(is_extension_install()); + DCHECK(all_data_saved_); + + // We keep a scoped_refptr to the installer. This ensures that + // the installer continues to exist as long as we need to reference + // it. Our reference will be removed when installation completes, + // and NotificationType::CRX_INSTALLER_DONE fires. + scoped_refptr<CrxInstaller> crx_installer = + download_util::OpenChromeExtension( + download_manager_->profile(), + download_manager_, + *this); + + // We are only listening for events from the installer we started. + registrar_.Add(this, + NotificationType::CRX_INSTALLER_DONE, + Source<CrxInstaller>(crx_installer.get())); + + // The status text and percent complete indicator will change now + // that we are installing a CRX. Update observers so that they pick + // up the change. + UpdateObservers(); + + // At this point, we hold a reference to the installer and are + // listening for CRX_INSTALLER_DONE from that installer. + // If we are around when CRX_INSTALLER_DONE fires, Observe() will + // unreference |crx_installer_| and remove the listener from + // |registrar_|. If this download item is destroyed (user cancels, + // browser quits, etc) then |crx_installer_| goes out of scope, + // removing our reference. |registrar_|'s destructor will remove + // the listener for CRX_INSTALLER_DONE. +} + +// NotificationObserver implementation. +void DownloadItem::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::CRX_INSTALLER_DONE); + + // No need to listen for CRX_INSTALLER_DONE anymore. + registrar_.Remove(this, + NotificationType::CRX_INSTALLER_DONE, + source); + + auto_opened_ = true; + DCHECK(all_data_saved_); + + Completed(); +} + void DownloadItem::Interrupted(int64 size, int os_error) { if (!IsInProgress()) return; @@ -442,6 +491,13 @@ int64 DownloadItem::CurrentSpeed() const { } int DownloadItem::PercentComplete() const { + // We don't have an accurate way to estimate the time to unpack a CRX. + // The slowest part is re-encoding images, and time to do this depends on + // the contents of the image. If a CRX is being unpacked, indicate that + // we do not know how close to completion we are. + if (IsCrxInstallRuning()) + return -1; + return (total_bytes_ > 0) ? static_cast<int>(received_bytes_ * 100.0 / total_bytes_) : @@ -478,6 +534,7 @@ void DownloadItem::OnDownloadCompleting(DownloadFileManager* file_manager) { return; } + DCHECK(!is_extension_install()); Completed(); BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, @@ -494,6 +551,12 @@ void DownloadItem::OnDownloadRenamedToFinalName(const FilePath& full_path) { Rename(full_path); + if (is_extension_install()) { + StartCrxInstall(); + // Completed() will be called when the installer finishes. + return; + } + Completed(); } diff --git a/chrome/browser/download/download_item.h b/chrome/browser/download/download_item.h index ab04ddf..202ed23 100644 --- a/chrome/browser/download/download_item.h +++ b/chrome/browser/download/download_item.h @@ -27,8 +27,11 @@ #include "base/timer.h" #include "chrome/browser/download/download_process_handle.h" #include "chrome/browser/download/download_state_info.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" #include "googleurl/src/gurl.h" +class CrxInstaller; class DownloadFileManager; class DownloadManager; struct DownloadCreateInfo; @@ -39,7 +42,7 @@ struct DownloadHistoryInfo; // Destination tab's download view, may refer to a given DownloadItem. // // This is intended to be used only on the UI thread. -class DownloadItem { +class DownloadItem : public NotificationObserver { public: enum DownloadState { // Download is actively progressing. @@ -127,6 +130,11 @@ class DownloadItem { // Notifies our observers periodically. void UpdateObservers(); + // NotificationObserver implementation. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + // Returns true if it is OK to open this download. bool CanOpenDownload(); @@ -315,6 +323,13 @@ class DownloadItem { return state_info_.target_name != full_path_.BaseName(); } + // Is a CRX installer running on this download? + bool IsCrxInstallRuning() const { + return (is_extension_install() && + all_data_saved() && + state_ == IN_PROGRESS); + } + std::string DebugString(bool verbose) const; #ifdef UNIT_TEST @@ -336,6 +351,10 @@ class DownloadItem { void StartProgressTimer(); void StopProgressTimer(); + // Call to install this item as a CRX. Should only be called on + // items which are CRXes. Use is_extension_install() to check. + void StartCrxInstall(); + // State information used by the download manager. DownloadStateInfo state_info_; @@ -439,6 +458,9 @@ class DownloadItem { // only. bool open_enabled_; + // DownloadItem observes CRX installs it initiates. + NotificationRegistrar registrar_; + DISALLOW_COPY_AND_ASSIGN(DownloadItem); }; diff --git a/chrome/browser/download/download_item_model.cc b/chrome/browser/download/download_item_model.cc index 760d136..bbac94b 100644 --- a/chrome/browser/download/download_item_model.cc +++ b/chrome/browser/download/download_item_model.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -55,7 +55,12 @@ string16 DownloadItemModel::GetStatusText() { string16 status_text; switch (download_->state()) { case DownloadItem::IN_PROGRESS: - if (download_->open_when_complete()) { + if (download_->IsCrxInstallRuning()) { + // The download is a CRX (app, extension, theme, ...) and it is + // being unpacked and validated. + status_text = l10n_util::GetStringUTF16( + IDS_DOWNLOAD_STATUS_CRX_INSTALL_RUNNING); + } else if (download_->open_when_complete()) { if (simple_time.empty()) { status_text = l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_OPEN_WHEN_COMPLETE); diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc index ee2fe3a..70616ba 100644 --- a/chrome/browser/download/download_util.cc +++ b/chrome/browser/download/download_util.cc @@ -333,9 +333,10 @@ void GenerateSafeFileName(const std::string& mime_type, FilePath* file_name) { #endif } -void OpenChromeExtension(Profile* profile, - DownloadManager* download_manager, - const DownloadItem& download_item) { +scoped_refptr<CrxInstaller> OpenChromeExtension( + Profile* profile, + DownloadManager* download_manager, + const DownloadItem& download_item) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(download_item.is_extension_install()); @@ -355,18 +356,19 @@ void OpenChromeExtension(Profile* profile, download_item.mime_type())) { installer->InstallUserScript(download_item.full_path(), download_item.GetURL()); - return; + } else { + bool is_gallery_download = service->IsDownloadFromGallery( + download_item.GetURL(), download_item.referrer_url()); + installer->set_original_mime_type(download_item.original_mime_type()); + installer->set_apps_require_extension_mime_type(true); + installer->set_original_url(download_item.GetURL()); + installer->set_is_gallery_install(is_gallery_download); + installer->set_allow_silent_install(is_gallery_download); + installer->set_install_cause(extension_misc::INSTALL_CAUSE_USER_DOWNLOAD); + installer->InstallCrx(download_item.full_path()); } - bool is_gallery_download = service->IsDownloadFromGallery( - download_item.GetURL(), download_item.referrer_url()); - installer->set_original_mime_type(download_item.original_mime_type()); - installer->set_apps_require_extension_mime_type(true); - installer->set_original_url(download_item.GetURL()); - installer->set_is_gallery_install(is_gallery_download); - installer->set_allow_silent_install(is_gallery_download); - installer->set_install_cause(extension_misc::INSTALL_CAUSE_USER_DOWNLOAD); - installer->InstallCrx(download_item.full_path()); + return installer; } void RecordDownloadCount(DownloadCountTypes type) { diff --git a/chrome/browser/download/download_util.h b/chrome/browser/download/download_util.h index 3fedb5a..e89572e 100644 --- a/chrome/browser/download/download_util.h +++ b/chrome/browser/download/download_util.h @@ -12,6 +12,7 @@ #include "base/basictypes.h" #include "base/file_path.h" +#include "base/memory/ref_counted.h" #include "base/string16.h" #include "chrome/browser/download/download_process_handle.h" #include "ui/gfx/native_widget_types.h" @@ -21,6 +22,7 @@ #endif class BaseDownloadItemModel; +class CrxInstaller; class DictionaryValue; class DownloadItem; class DownloadManager; @@ -83,10 +85,14 @@ void GenerateFileName(const GURL& url, // full path to a file. void GenerateSafeFileName(const std::string& mime_type, FilePath* file_name); -// Opens downloaded Chrome extension file (*.crx). -void OpenChromeExtension(Profile* profile, - DownloadManager* download_manager, - const DownloadItem& download_item); +// Start installing a downloaded item item as a CRX (extension, theme, app, +// ...). The installer does work on the file thread, so the installation +// is not complete when this function returns. Returns the object managing +// the installation. +scoped_refptr<CrxInstaller> OpenChromeExtension( + Profile* profile, + DownloadManager* download_manager, + const DownloadItem& download_item); // Download progress animations ------------------------------------------------ |