summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/api/webstore_private/webstore_private_api.cc14
-rw-r--r--chrome/browser/extensions/api/webstore_private/webstore_private_api.h3
-rw-r--r--chrome/browser/ui/app_list/app_list_util.h5
-rw-r--r--chrome/browser/ui/app_list/app_list_view_delegate.cc6
-rw-r--r--chrome/browser/ui/app_list/app_list_view_delegate.h4
-rw-r--r--chrome/browser/ui/app_list/apps_model_builder.cc8
-rw-r--r--chrome/browser/ui/app_list/apps_model_builder.h4
-rw-r--r--chrome/browser/ui/app_list/extension_app_item.cc5
-rw-r--r--chrome/browser/ui/ash/app_list/app_list_controller_ash.cc6
-rw-r--r--chrome/browser/ui/cocoa/app_list/app_list_controller_cocoa.mm6
-rw-r--r--chrome/browser/ui/views/app_list/app_list_controller_win.cc24
-rw-r--r--ui/app_list/app_list_item_model.cc25
-rw-r--r--ui/app_list/app_list_item_model.h8
-rw-r--r--ui/app_list/app_list_item_model_observer.h6
-rw-r--r--ui/app_list/views/app_list_item_view.cc35
-rw-r--r--ui/app_list/views/app_list_item_view.h2
-rw-r--r--ui/app_list/views/app_list_main_view.cc2
17 files changed, 158 insertions, 5 deletions
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 f76efd3..e218bbe 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -468,9 +468,11 @@ void CompleteInstallFunction::OnGetAppLauncherEnabled(
bool app_launcher_enabled) {
if (app_launcher_enabled) {
std::string name;
- DCHECK(approval_->parsed_manifest->GetString(extension_manifest_keys::kName,
- &name));
#if defined(ENABLE_APP_LIST)
+ if (!approval_->parsed_manifest->GetString(extension_manifest_keys::kName,
+ &name)) {
+ NOTREACHED();
+ }
// Tell the app list about the install that we just started.
chrome::NotifyAppListOfBeginExtensionInstall(
profile(), id, name, approval_->installing_icon);
@@ -513,6 +515,14 @@ void CompleteInstallFunction::OnExtensionInstallFailure(
Release();
}
+void CompleteInstallFunction::OnExtensionDownloadProgress(
+ const std::string& id,
+ content::DownloadItem* item) {
+#if defined(ENABLE_APP_LIST)
+ chrome::NotifyAppListOfDownloadProgress(profile(), id,
+ item->PercentComplete());
+#endif
+}
bool GetBrowserLoginFunction::RunImpl() {
SetResult(CreateLoginResult(profile_->GetOriginalProfile()));
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.h b/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
index 2d5ed9c..3fbedc9 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
@@ -164,6 +164,9 @@ class CompleteInstallFunction
const std::string& id,
const std::string& error,
WebstoreInstaller::FailureReason reason) OVERRIDE;
+ virtual void OnExtensionDownloadProgress(
+ const std::string& id,
+ content::DownloadItem* item) OVERRIDE;
protected:
virtual ~CompleteInstallFunction();
diff --git a/chrome/browser/ui/app_list/app_list_util.h b/chrome/browser/ui/app_list/app_list_util.h
index 5cbada4..bdd17a6 100644
--- a/chrome/browser/ui/app_list/app_list_util.h
+++ b/chrome/browser/ui/app_list/app_list_util.h
@@ -50,6 +50,11 @@ void NotifyAppListOfBeginExtensionInstall(
const std::string& extension_name,
const gfx::ImageSkia& installing_icon);
+void NotifyAppListOfDownloadProgress(
+ Profile* profile,
+ const std::string& extension_id,
+ int percent_downloaded);
+
} // namespace chrome
#endif // CHROME_BROWSER_UI_APP_LIST_APP_LIST_UTIL_H_
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc
index c0a7955..15d294e 100644
--- a/chrome/browser/ui/app_list/app_list_view_delegate.cc
+++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
@@ -63,6 +63,12 @@ void AppListViewDelegate::OnBeginExtensionInstall(
installing_icon);
}
+void AppListViewDelegate::OnDownloadProgress(
+ const std::string& extension_id,
+ int percent_downloaded) {
+ apps_builder_->OnDownloadProgress(extension_id, percent_downloaded);
+}
+
void AppListViewDelegate::ActivateAppListItem(
app_list::AppListItemModel* item,
int event_flags) {
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.h b/chrome/browser/ui/app_list/app_list_view_delegate.h
index 457a7d9..4bd04b4 100644
--- a/chrome/browser/ui/app_list/app_list_view_delegate.h
+++ b/chrome/browser/ui/app_list/app_list_view_delegate.h
@@ -36,6 +36,10 @@ class AppListViewDelegate : public app_list::AppListViewDelegate {
const std::string& extension_name,
const gfx::ImageSkia& installing_icon);
+ // Called when the download of an extension makes progress.
+ void OnDownloadProgress(const std::string& extension_id,
+ int percent_downloaded);
+
private:
// Overridden from app_list::AppListViewDelegate:
virtual void SetModel(app_list::AppListModel* model) OVERRIDE;
diff --git a/chrome/browser/ui/app_list/apps_model_builder.cc b/chrome/browser/ui/app_list/apps_model_builder.cc
index 399d4c5..8af3d3e 100644
--- a/chrome/browser/ui/app_list/apps_model_builder.cc
+++ b/chrome/browser/ui/app_list/apps_model_builder.cc
@@ -88,6 +88,14 @@ void AppsModelBuilder::OnBeginExtensionInstall(
HighlightApp();
}
+void AppsModelBuilder::OnDownloadProgress(const std::string& extension_id,
+ int percent_downloaded) {
+ int i = FindApp(extension_id);
+ if (i == -1)
+ return;
+ GetAppAt(i)->SetPercentDownloaded(percent_downloaded);
+}
+
void AppsModelBuilder::AddApps(const ExtensionSet* extensions, Apps* apps) {
for (ExtensionSet::const_iterator app = extensions->begin();
app != extensions->end(); ++app) {
diff --git a/chrome/browser/ui/app_list/apps_model_builder.h b/chrome/browser/ui/app_list/apps_model_builder.h
index f369d30..305bd941 100644
--- a/chrome/browser/ui/app_list/apps_model_builder.h
+++ b/chrome/browser/ui/app_list/apps_model_builder.h
@@ -40,6 +40,10 @@ class AppsModelBuilder : public content::NotificationObserver,
const std::string& extension_name,
const gfx::ImageSkia& installing_icon);
+ // Called when progress is made on an extension's download.
+ void OnDownloadProgress(const std::string& extension_id,
+ int percent_downloaded);
+
private:
typedef std::vector<ExtensionAppItem*> Apps;
diff --git a/chrome/browser/ui/app_list/extension_app_item.cc b/chrome/browser/ui/app_list/extension_app_item.cc
index 56281dc..feae3f6 100644
--- a/chrome/browser/ui/app_list/extension_app_item.cc
+++ b/chrome/browser/ui/app_list/extension_app_item.cc
@@ -208,8 +208,9 @@ bool ExtensionAppItem::HasOverlay() const {
void ExtensionAppItem::Reload() {
const Extension* extension = GetExtension();
- // If the extension isn't there, show the 'extension is installing' UI.
- if (!extension) {
+ bool is_installing = !extension;
+ SetIsInstalling(is_installing);
+ if (is_installing) {
SetTitle(extension_name_);
UpdateIcon();
return;
diff --git a/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc b/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc
index ce6f119..55fb595 100644
--- a/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc
+++ b/chrome/browser/ui/ash/app_list/app_list_controller_ash.cc
@@ -91,4 +91,10 @@ void NotifyAppListOfBeginExtensionInstall(
const gfx::ImageSkia& installing_icon) {
}
+void NotifyAppListOfDownloadProgress(
+ Profile* profile,
+ const std::string& extension_id,
+ int percent_downloaded) {
+}
+
} // namespace chrome
diff --git a/chrome/browser/ui/cocoa/app_list/app_list_controller_cocoa.mm b/chrome/browser/ui/cocoa/app_list/app_list_controller_cocoa.mm
index 61dd01e..3580de6 100644
--- a/chrome/browser/ui/cocoa/app_list/app_list_controller_cocoa.mm
+++ b/chrome/browser/ui/cocoa/app_list/app_list_controller_cocoa.mm
@@ -87,4 +87,10 @@ void NotifyAppListOfBeginExtensionInstall(
const gfx::ImageSkia& installing_icon) {
}
+void NotifyAppListOfDownloadProgress(
+ Profile* profile,
+ const std::string& extension_id,
+ int percent_downloaded) {
+}
+
} // namespace chrome
diff --git a/chrome/browser/ui/views/app_list/app_list_controller_win.cc b/chrome/browser/ui/views/app_list/app_list_controller_win.cc
index 70df366..5fe7960 100644
--- a/chrome/browser/ui/views/app_list/app_list_controller_win.cc
+++ b/chrome/browser/ui/views/app_list/app_list_controller_win.cc
@@ -191,6 +191,9 @@ class AppListController : public ProfileInfoCacheObserver {
const std::string& extension_id,
const std::string& extension_name,
const gfx::ImageSkia& installing_icon);
+ void OnDownloadProgress(Profile* profile,
+ const std::string& extension_id,
+ int percent_downloaded);
private:
// Loads a profile asynchronously and calls OnProfileLoaded() when done.
@@ -547,6 +550,18 @@ void AppListController::OnBeginExtensionInstall(
installing_icon);
}
+void AppListController::OnDownloadProgress(Profile* profile,
+ const std::string& extension_id,
+ int percent_downloaded) {
+ // We only have a model for the current profile, so ignore events about
+ // others.
+ // TODO(koz): We should keep a model for each profile so we can record
+ // information like this.
+ if (profile != profile_)
+ return;
+ view_delegate_->OnDownloadProgress(extension_id, percent_downloaded);
+}
+
// Attempts to find the bounds of the Windows taskbar. Returns true on success.
// |rect| is in screen coordinates. If the taskbar is in autohide mode and is
// not visible, |rect| will be outside the current monitor's bounds, except for
@@ -860,6 +875,15 @@ void NotifyAppListOfBeginExtensionInstall(
extension_name,
installing_icon);
}
+
+void NotifyAppListOfDownloadProgress(
+ Profile* profile,
+ const std::string& extension_id,
+ int percent_downloaded) {
+ g_app_list_controller.Get().OnDownloadProgress(profile, extension_id,
+ percent_downloaded);
+}
+
#endif // !defined(USE_ASH)
} // namespace chrome
diff --git a/ui/app_list/app_list_item_model.cc b/ui/app_list/app_list_item_model.cc
index c3a74bf..c9a2831 100644
--- a/ui/app_list/app_list_item_model.cc
+++ b/ui/app_list/app_list_item_model.cc
@@ -9,7 +9,10 @@
namespace app_list {
-AppListItemModel::AppListItemModel() : highlighted_(false) {
+AppListItemModel::AppListItemModel()
+ : highlighted_(false),
+ is_installing_(false),
+ percent_downloaded_(-1) {
}
AppListItemModel::~AppListItemModel() {
@@ -38,6 +41,26 @@ void AppListItemModel::SetHighlighted(bool highlighted) {
ItemHighlightedChanged());
}
+void AppListItemModel::SetIsInstalling(bool is_installing) {
+ if (is_installing_ == is_installing)
+ return;
+
+ is_installing_ = is_installing;
+ FOR_EACH_OBSERVER(AppListItemModelObserver,
+ observers_,
+ ItemIsInstallingChanged());
+}
+
+void AppListItemModel::SetPercentDownloaded(int percent_downloaded) {
+ if (percent_downloaded_ == percent_downloaded)
+ return;
+
+ percent_downloaded_ = percent_downloaded;
+ FOR_EACH_OBSERVER(AppListItemModelObserver,
+ observers_,
+ ItemPercentDownloadedChanged());
+}
+
void AppListItemModel::AddObserver(AppListItemModelObserver* observer) {
observers_.AddObserver(observer);
}
diff --git a/ui/app_list/app_list_item_model.h b/ui/app_list/app_list_item_model.h
index ca382de..2960931 100644
--- a/ui/app_list/app_list_item_model.h
+++ b/ui/app_list/app_list_item_model.h
@@ -36,6 +36,12 @@ class APP_LIST_EXPORT AppListItemModel {
void SetHighlighted(bool highlighted);
bool highlighted() const { return highlighted_; }
+ void SetIsInstalling(bool is_installing);
+ bool is_installing() const { return is_installing_; }
+
+ void SetPercentDownloaded(int percent_downloaded);
+ int percent_downloaded() const { return percent_downloaded_; }
+
void AddObserver(AppListItemModelObserver* observer);
void RemoveObserver(AppListItemModelObserver* observer);
@@ -47,6 +53,8 @@ class APP_LIST_EXPORT AppListItemModel {
gfx::ImageSkia icon_;
std::string title_;
bool highlighted_;
+ bool is_installing_;
+ int percent_downloaded_;
ObserverList<AppListItemModelObserver> observers_;
diff --git a/ui/app_list/app_list_item_model_observer.h b/ui/app_list/app_list_item_model_observer.h
index 0e5f99d..80abb39 100644
--- a/ui/app_list/app_list_item_model_observer.h
+++ b/ui/app_list/app_list_item_model_observer.h
@@ -20,6 +20,12 @@ class APP_LIST_EXPORT AppListItemModelObserver {
// Invoked after item's highlighted state is changed.
virtual void ItemHighlightedChanged() = 0;
+ // Invoked after item begins or finishes installing.
+ virtual void ItemIsInstallingChanged() = 0;
+
+ // Invoked after item's download percentage changes.
+ virtual void ItemPercentDownloadedChanged() = 0;
+
protected:
virtual ~AppListItemModelObserver() {}
};
diff --git a/ui/app_list/views/app_list_item_view.cc b/ui/app_list/views/app_list_item_view.cc
index e481cb4..4793a99 100644
--- a/ui/app_list/views/app_list_item_view.cc
+++ b/ui/app_list/views/app_list_item_view.cc
@@ -31,6 +31,9 @@ namespace {
const int kTopBottomPadding = 10;
const int kTopPadding = 20;
const int kIconTitleSpacing = 7;
+const int kProgressBarHorizontalPadding = 8;
+const int kProgressBarVerticalPadding = 4;
+const int kProgressBarHeight = 4;
const SkColor kTitleColor = SkColorSetRGB(0x5A, 0x5A, 0x5A);
const SkColor kTitleHoverColor = SkColorSetRGB(0x3C, 0x3C, 0x3C);
@@ -38,6 +41,9 @@ const SkColor kTitleHoverColor = SkColorSetRGB(0x3C, 0x3C, 0x3C);
const SkColor kHoverAndPushedColor = SkColorSetARGB(0x19, 0, 0, 0);
const SkColor kSelectedColor = SkColorSetARGB(0x0D, 0, 0, 0);
const SkColor kHighlightedColor = kHoverAndPushedColor;
+const SkColor kDownloadProgressBackgroundColor =
+ SkColorSetRGB(0x90, 0x90, 0x90);
+const SkColor kDownloadProgressColor = SkColorSetRGB(0x20, 0xAA, 0x20);
const int kLeftRightPaddingChars = 1;
@@ -168,6 +174,16 @@ void AppListItemView::ItemHighlightedChanged() {
SchedulePaint();
}
+void AppListItemView::ItemIsInstallingChanged() {
+ if (model_->is_installing())
+ apps_grid_view_->EnsureViewVisible(this);
+ SchedulePaint();
+}
+
+void AppListItemView::ItemPercentDownloadedChanged() {
+ SchedulePaint();
+}
+
std::string AppListItemView::GetClassName() const {
return kViewClassName;
}
@@ -210,6 +226,25 @@ void AppListItemView::OnPaint(gfx::Canvas* canvas) {
} else if (apps_grid_view_->IsSelectedView(this)) {
canvas->FillRect(rect, kSelectedColor);
}
+
+ if (model_->is_installing()) {
+ gfx::Rect progress_bar_background(
+ rect.x() + kProgressBarHorizontalPadding,
+ rect.bottom() - kProgressBarVerticalPadding - kProgressBarHeight,
+ rect.width() - 2 * kProgressBarHorizontalPadding,
+ kProgressBarHeight);
+ canvas->FillRect(progress_bar_background, kDownloadProgressBackgroundColor);
+
+ if (model_->percent_downloaded() != -1) {
+ float percent = model_->percent_downloaded() / 100.0;
+ gfx::Rect progress_bar(
+ progress_bar_background.x(),
+ progress_bar_background.y(),
+ progress_bar_background.width() * percent,
+ progress_bar_background.height());
+ canvas->FillRect(progress_bar, kDownloadProgressColor);
+ }
+ }
}
void AppListItemView::GetAccessibleState(ui::AccessibleViewState* state) {
diff --git a/ui/app_list/views/app_list_item_view.h b/ui/app_list/views/app_list_item_view.h
index 7cabc5f..a037de2 100644
--- a/ui/app_list/views/app_list_item_view.h
+++ b/ui/app_list/views/app_list_item_view.h
@@ -64,6 +64,8 @@ class APP_LIST_EXPORT AppListItemView : public views::CustomButton,
virtual void ItemIconChanged() OVERRIDE;
virtual void ItemTitleChanged() OVERRIDE;
virtual void ItemHighlightedChanged() OVERRIDE;
+ virtual void ItemIsInstallingChanged() OVERRIDE;
+ virtual void ItemPercentDownloadedChanged() OVERRIDE;
// views::View overrides:
virtual std::string GetClassName() const OVERRIDE;
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc
index f73f428..bfadf21 100644
--- a/ui/app_list/views/app_list_main_view.cc
+++ b/ui/app_list/views/app_list_main_view.cc
@@ -60,6 +60,8 @@ class AppListMainView::IconLoader : public AppListItemModelObserver {
}
virtual void ItemTitleChanged() OVERRIDE {}
virtual void ItemHighlightedChanged() OVERRIDE {}
+ virtual void ItemIsInstallingChanged() OVERRIDE {};
+ virtual void ItemPercentDownloadedChanged() OVERRIDE {};
AppListMainView* owner_;
AppListItemModel* item_;