summaryrefslogtreecommitdiffstats
path: root/chrome/browser/download
diff options
context:
space:
mode:
authorskerner@chromium.org <skerner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-31 13:42:28 +0000
committerskerner@chromium.org <skerner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-31 13:42:28 +0000
commit089bda66f423cfac13dcd22fd5c1f187524f12a5 (patch)
tree44fe5c4f470d57253409413cf6c63ff786612b78 /chrome/browser/download
parent02a1bc990c558ddb5085c6432866d971c5e71e9f (diff)
downloadchromium_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.cc73
-rw-r--r--chrome/browser/download/download_item.h24
-rw-r--r--chrome/browser/download/download_item_model.cc9
-rw-r--r--chrome/browser/download/download_util.cc28
-rw-r--r--chrome/browser/download/download_util.h14
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 ------------------------------------------------