summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-10 22:21:18 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-10 22:21:18 +0000
commit2c4d75ca9211a2dd2d477d0c6cc17868d5ef15e6 (patch)
treece388a76263b960592fb75deae504db272bca17e /chrome
parent14141eaf80a9de9bc3a120ee7f9142b2d51dc564 (diff)
downloadchromium_src-2c4d75ca9211a2dd2d477d0c6cc17868d5ef15e6.zip
chromium_src-2c4d75ca9211a2dd2d477d0c6cc17868d5ef15e6.tar.gz
chromium_src-2c4d75ca9211a2dd2d477d0c6cc17868d5ef15e6.tar.bz2
app_list: Show disabled/terminated apps.
- Include disabled and terminated apps in AppsModelBuilder; - Update icon when apps are loaded/unloaded; - Run ExtensionEnableFlow when clicked on disabled/terminated app; BUG=157996 TEST=Verify disabled/terminated apps shows up in app launcher. R=sky@chromium.org,benwells@chromium.org Review URL: https://chromiumcodereview.appspot.com/11573026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176173 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/ui/app_list/app_list_controller_delegate.h11
-rw-r--r--chrome/browser/ui/app_list/apps_model_builder.cc38
-rw-r--r--chrome/browser/ui/app_list/apps_model_builder.h7
-rw-r--r--chrome/browser/ui/app_list/apps_model_builder_unittest.cc15
-rw-r--r--chrome/browser/ui/app_list/extension_app_item.cc193
-rw-r--r--chrome/browser/ui/app_list/extension_app_item.h43
-rw-r--r--chrome/browser/ui/ash/app_list/app_list_controller_ash.cc5
-rw-r--r--chrome/browser/ui/ash/app_list/app_list_controller_ash.h1
-rw-r--r--chrome/browser/ui/views/app_list/app_list_controller_win.cc14
9 files changed, 236 insertions, 91 deletions
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate.h b/chrome/browser/ui/app_list/app_list_controller_delegate.h
index dff9bbd..4fb8cf3 100644
--- a/chrome/browser/ui/app_list/app_list_controller_delegate.h
+++ b/chrome/browser/ui/app_list/app_list_controller_delegate.h
@@ -7,6 +7,8 @@
#include <string>
+#include "ui/gfx/native_widget_types.h"
+
class Profile;
// Interface to allow the view delegate to call out to whatever is controlling
@@ -25,15 +27,18 @@ class AppListControllerDelegate {
// Handle the view being activated or deactivated.
virtual void ViewActivationChanged(bool active);
+ // Get app list window.
+ virtual gfx::NativeWindow GetAppListWindow() = 0;
+
// Control of pinning apps.
virtual bool IsAppPinned(const std::string& extension_id);
virtual void PinApp(const std::string& extension_id);
virtual void UnpinApp(const std::string& extension_id);
virtual bool CanPin() = 0;
- // Be aware of the extension uninstalling flow.
- virtual void AboutToUninstallApp() {}
- virtual void UninstallAppCompleted() {}
+ // Be aware of the extension prompt (either uninstalling flow or enable flow).
+ virtual void OnShowExtensionPrompt() {}
+ virtual void OnCloseExtensionPrompt() {}
// Whether the controller supports showing the Create Shortcuts dialog.
virtual bool CanShowCreateShortcutsDialog() = 0;
diff --git a/chrome/browser/ui/app_list/apps_model_builder.cc b/chrome/browser/ui/app_list/apps_model_builder.cc
index b2416ad..30b3dbd 100644
--- a/chrome/browser/ui/app_list/apps_model_builder.cc
+++ b/chrome/browser/ui/app_list/apps_model_builder.cc
@@ -5,7 +5,6 @@
#include "chrome/browser/ui/app_list/apps_model_builder.h"
#include <algorithm>
-#include <vector>
#include "base/auto_reset.h"
#include "chrome/browser/extensions/extension_prefs.h"
@@ -22,8 +21,6 @@ using extensions::Extension;
namespace {
-typedef std::vector<ExtensionAppItem*> Apps;
-
bool AppPrecedes(const ExtensionAppItem* app1, const ExtensionAppItem* app2) {
const syncer::StringOrdinal& page1 = app1->GetPageOrdinal();
const syncer::StringOrdinal& page2 = app2->GetPageOrdinal();
@@ -77,6 +74,14 @@ void AppsModelBuilder::Build() {
HighlightApp();
}
+void AppsModelBuilder::AddApps(const ExtensionSet* extensions, Apps* apps) {
+ for (ExtensionSet::const_iterator app = extensions->begin();
+ app != extensions->end(); ++app) {
+ if ((*app)->ShouldDisplayInAppLauncher())
+ apps->push_back(new ExtensionAppItem(profile_, *app, controller_));
+ }
+}
+
void AppsModelBuilder::PopulateApps() {
ExtensionService* service =
extensions::ExtensionSystem::Get(profile_)->extension_service();
@@ -84,12 +89,9 @@ void AppsModelBuilder::PopulateApps() {
return;
Apps apps;
- const ExtensionSet* extensions = service->extensions();
- for (ExtensionSet::const_iterator app = extensions->begin();
- app != extensions->end(); ++app) {
- if ((*app)->ShouldDisplayInAppLauncher())
- apps.push_back(new ExtensionAppItem(profile_, *app, controller_));
- }
+ AddApps(service->extensions(), &apps);
+ AddApps(service->disabled_extensions(), &apps);
+ AddApps(service->terminated_extensions(), &apps);
if (apps.empty())
return;
@@ -188,20 +190,28 @@ void AppsModelBuilder::Observe(int type,
if (!extension->ShouldDisplayInAppLauncher())
return;
- if (FindApp(extension->id()) != -1)
+ const int existing_index = FindApp(extension->id());
+ if (existing_index != -1) {
+ GetAppAt(existing_index)->UpdateIcon();
return;
+ }
InsertApp(new ExtensionAppItem(profile_, extension, controller_));
HighlightApp();
break;
}
case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
- const Extension* extension =
- content::Details<extensions::UnloadedExtensionInfo>(
- details)->extension;
+ const content::Details<extensions::UnloadedExtensionInfo>& unload_info(
+ details);
+ const Extension* extension = unload_info->extension;
int index = FindApp(extension->id());
- if (index >= 0)
+ if (index < 0)
+ break;
+
+ if (unload_info->reason == extension_misc::UNLOAD_REASON_UNINSTALL)
model_->DeleteAt(index);
+ else
+ GetAppAt(index)->UpdateIcon();
break;
}
case chrome::NOTIFICATION_EXTENSION_LAUNCHER_REORDERED: {
diff --git a/chrome/browser/ui/app_list/apps_model_builder.h b/chrome/browser/ui/app_list/apps_model_builder.h
index 5c91583..e78afd5 100644
--- a/chrome/browser/ui/app_list/apps_model_builder.h
+++ b/chrome/browser/ui/app_list/apps_model_builder.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_APP_LIST_APPS_MODEL_BUILDER_H_
#include <string>
+#include <vector>
#include "base/gtest_prod_util.h"
#include "base/prefs/public/pref_change_registrar.h"
@@ -16,6 +17,7 @@
class AppListControllerDelegate;
class ExtensionAppItem;
+class ExtensionSet;
class Profile;
class AppsModelBuilder : public content::NotificationObserver,
@@ -30,6 +32,11 @@ class AppsModelBuilder : public content::NotificationObserver,
void Build();
private:
+ typedef std::vector<ExtensionAppItem*> Apps;
+
+ // Adds apps in |extensions| to |apps|.
+ void AddApps(const ExtensionSet* extensions, Apps* apps);
+
// Populates the model with apps.
void PopulateApps();
diff --git a/chrome/browser/ui/app_list/apps_model_builder_unittest.cc b/chrome/browser/ui/app_list/apps_model_builder_unittest.cc
index a3e6b2b..fb67902 100644
--- a/chrome/browser/ui/app_list/apps_model_builder_unittest.cc
+++ b/chrome/browser/ui/app_list/apps_model_builder_unittest.cc
@@ -76,7 +76,7 @@ TEST_F(AppsModelBuilderTest, DisableAndEnable) {
service_->DisableExtension(kHostedAppId,
extensions::Extension::DISABLE_NONE);
- EXPECT_EQ(std::string("Packaged App 1,Packaged App 2"),
+ EXPECT_EQ(std::string("Packaged App 1,Packaged App 2,Hosted App"),
GetModelContent(model.get()));
service_->EnableExtension(kHostedAppId);
@@ -84,6 +84,19 @@ TEST_F(AppsModelBuilderTest, DisableAndEnable) {
GetModelContent(model.get()));
}
+TEST_F(AppsModelBuilderTest, Uninstall) {
+ scoped_ptr<app_list::AppListModel::Apps> model(
+ new app_list::AppListModel::Apps);
+ AppsModelBuilder builder(profile_.get(), model.get(), NULL);
+ builder.Build();
+
+ service_->UninstallExtension(kPackagedApp2Id, false, NULL);
+ EXPECT_EQ(std::string("Packaged App 1,Hosted App"),
+ GetModelContent(model.get()));
+
+ loop_.RunUntilIdle();
+}
+
TEST_F(AppsModelBuilderTest, OrdinalPrefsChange) {
scoped_ptr<app_list::AppListModel::Apps> model(
new app_list::AppListModel::Apps);
diff --git a/chrome/browser/ui/app_list/extension_app_item.cc b/chrome/browser/ui/app_list/extension_app_item.cc
index fe6b13b..5e0e39f 100644
--- a/chrome/browser/ui/app_list/extension_app_item.cc
+++ b/chrome/browser/ui/app_list/extension_app_item.cc
@@ -6,6 +6,7 @@
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/context_menu_matcher.h"
+#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_sorting.h"
@@ -17,9 +18,11 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/extensions/extension_enable_flow.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_icon_set.h"
@@ -30,7 +33,9 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
-#include "ui/gfx/image/image.h"
+#include "ui/gfx/color_utils.h"
+#include "ui/gfx/image/canvas_image_source.h"
+#include "ui/gfx/image/image_skia_operations.h"
using extensions::Extension;
@@ -54,6 +59,10 @@ enum CommandId {
LAUNCH_TYPE_LAST,
};
+ExtensionService* GetExtensionService(Profile* profile) {
+ return extensions::ExtensionSystem::Get(profile)->extension_service();
+}
+
// ExtensionUninstaller decouples ExtensionAppItem from the extension uninstall
// flow. It shows extension uninstall dialog and wait for user to confirm or
// cancel the uninstall.
@@ -75,7 +84,7 @@ class ExtensionUninstaller : public ExtensionUninstallDialog::Delegate {
CleanUp();
return;
}
- controller_->AboutToUninstallApp();
+ controller_->OnShowExtensionPrompt();
dialog_.reset(ExtensionUninstallDialog::Create(NULL, this));
dialog_->ConfirmUninstall(extension);
}
@@ -83,20 +92,19 @@ class ExtensionUninstaller : public ExtensionUninstallDialog::Delegate {
private:
// Overridden from ExtensionUninstallDialog::Delegate:
virtual void ExtensionUninstallAccepted() OVERRIDE {
- ExtensionService* service =
- extensions::ExtensionSystem::Get(profile_)->extension_service();
- const Extension* extension = service->GetExtensionById(extension_id_, true);
+ ExtensionService* service = GetExtensionService(profile_);
+ const Extension* extension = service->GetInstalledExtension(extension_id_);
if (extension) {
service->UninstallExtension(extension_id_,
false, /* external_uninstall*/
NULL);
}
- controller_->UninstallAppCompleted();
+ controller_->OnCloseExtensionPrompt();
CleanUp();
}
virtual void ExtensionUninstallCanceled() OVERRIDE {
- controller_->UninstallAppCompleted();
+ controller_->OnCloseExtensionPrompt();
CleanUp();
}
@@ -112,32 +120,62 @@ class ExtensionUninstaller : public ExtensionUninstallDialog::Delegate {
DISALLOW_COPY_AND_ASSIGN(ExtensionUninstaller);
};
+class TabOverlayImageSource : public gfx::CanvasImageSource {
+ public:
+ TabOverlayImageSource(const gfx::ImageSkia& icon, const gfx::Size& size)
+ : gfx::CanvasImageSource(size, false),
+ icon_(icon) {
+ DCHECK_EQ(extension_misc::EXTENSION_ICON_SMALL, icon_.width());
+ DCHECK_EQ(extension_misc::EXTENSION_ICON_SMALL, icon_.height());
+ }
+ virtual ~TabOverlayImageSource() {}
+
+ private:
+ // gfx::CanvasImageSource overrides:
+ void Draw(gfx::Canvas* canvas) OVERRIDE {
+ using extension_misc::EXTENSION_ICON_SMALL;
+ using extension_misc::EXTENSION_ICON_MEDIUM;
+
+ const int kIconOffset = (EXTENSION_ICON_MEDIUM - EXTENSION_ICON_SMALL) / 2;
+
+ // The tab overlay is not vertically symmetric, to position the app in the
+ // middle of the overlay we need a slight adjustment.
+ const int kVerticalAdjust = 4;
+ canvas->DrawImageInt(
+ *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+ IDR_APP_LIST_TAB_OVERLAY),
+ 0, 0);
+ canvas->DrawImageInt(icon_, kIconOffset, kIconOffset + kVerticalAdjust);
+ }
+
+ gfx::ImageSkia icon_;
+
+ DISALLOW_COPY_AND_ASSIGN(TabOverlayImageSource);
+};
+
extensions::ExtensionPrefs::LaunchType GetExtensionLaunchType(
Profile* profile,
const Extension* extension) {
- return extensions::ExtensionSystem::Get(profile)->extension_service()->
- extension_prefs()->GetLaunchType(extension,
- extensions::ExtensionPrefs::LAUNCH_DEFAULT);
+ return GetExtensionService(profile)->extension_prefs()->
+ GetLaunchType(extension, extensions::ExtensionPrefs::LAUNCH_DEFAULT);
}
void SetExtensionLaunchType(
Profile* profile,
const std::string& extension_id,
extensions::ExtensionPrefs::LaunchType launch_type) {
- extensions::ExtensionSystem::Get(profile)->extension_service()->
- extension_prefs()->SetLaunchType(extension_id, launch_type);
+ GetExtensionService(profile)->extension_prefs()->SetLaunchType(extension_id,
+ launch_type);
}
bool IsExtensionEnabled(Profile* profile, const std::string& extension_id) {
- ExtensionService* service =
- extensions::ExtensionSystem::Get(profile)->extension_service();
+ ExtensionService* service = GetExtensionService(profile);
return service->IsExtensionEnabled(extension_id) &&
!service->GetTerminatedExtension(extension_id);
}
ExtensionSorting* GetExtensionSorting(Profile* profile) {
- return extensions::ExtensionSystem::Get(profile)->extension_service()->
- extension_prefs()->extension_sorting();
+ return GetExtensionService(profile)->extension_prefs()->extension_sorting();
}
bool MenuItemHasLauncherContext(const extensions::MenuItem* item) {
@@ -160,12 +198,6 @@ ExtensionAppItem::ExtensionAppItem(Profile* profile,
ExtensionAppItem::~ExtensionAppItem() {
}
-const Extension* ExtensionAppItem::GetExtension() const {
- const Extension* extension = extensions::ExtensionSystem::Get(profile_)->
- extension_service()->GetInstalledExtension(extension_id_);
- return extension;
-}
-
syncer::StringOrdinal ExtensionAppItem::GetPageOrdinal() const {
return GetExtensionSorting(profile_)->GetPageOrdinal(extension_id_);
}
@@ -215,6 +247,30 @@ void ExtensionAppItem::Move(const ExtensionAppItem* prev,
std::string());
}
+void ExtensionAppItem::UpdateIcon() {
+ gfx::ImageSkia icon = icon_->image_skia();
+
+ const bool enabled = IsExtensionEnabled(profile_, extension_id_);
+ if (!enabled) {
+ const color_utils::HSL shift = {-1, 0, 0.6};
+ icon = gfx::ImageSkiaOperations::CreateHSLShiftedImage(icon, shift);
+ }
+
+ if (HasOverlay()) {
+ const gfx::Size size(extension_misc::EXTENSION_ICON_MEDIUM,
+ extension_misc::EXTENSION_ICON_MEDIUM);
+ icon = gfx::ImageSkia(new TabOverlayImageSource(icon, size), size);
+ }
+
+ SetIcon(icon);
+}
+
+const Extension* ExtensionAppItem::GetExtension() const {
+ const Extension* extension = GetExtensionService(profile_)->
+ GetInstalledExtension(extension_id_);
+ return extension;
+}
+
void ExtensionAppItem::LoadImage(const Extension* extension) {
int icon_size = extension_misc::EXTENSION_ICON_MEDIUM;
if (HasOverlay())
@@ -226,7 +282,7 @@ void ExtensionAppItem::LoadImage(const Extension* extension) {
icon_size,
Extension::GetDefaultIcon(true),
this));
- SetIconWithOverlay(icon_->image_skia());
+ UpdateIcon();
}
bool ExtensionAppItem::HasOverlay() {
@@ -237,31 +293,6 @@ bool ExtensionAppItem::HasOverlay() {
#endif
}
-void ExtensionAppItem::SetIconWithOverlay(const gfx::ImageSkia& icon) {
- using extension_misc::EXTENSION_ICON_SMALL;
- using extension_misc::EXTENSION_ICON_MEDIUM;
-
- if (!HasOverlay()) {
- SetIcon(icon);
- return;
- }
-
- const int kIconOffset = (EXTENSION_ICON_MEDIUM - EXTENSION_ICON_SMALL) / 2;
-
- // The tab overlay is not vertically symmetric, to position the app in the
- // middle of the overlay we need a slight adjustment.
- const int kVerticalAdjust = 4;
- gfx::Canvas icon_canvas(gfx::Size(EXTENSION_ICON_MEDIUM,
- EXTENSION_ICON_MEDIUM),
- ui::SCALE_FACTOR_100P, false);
- icon_canvas.DrawImageInt(
- *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
- IDR_APP_LIST_TAB_OVERLAY),
- 0, 0);
- icon_canvas.DrawImageInt(icon, kIconOffset, kIconOffset + kVerticalAdjust);
- SetIcon(gfx::ImageSkia(icon_canvas.ExtractImageRep()));
-}
-
void ExtensionAppItem::ShowExtensionOptions() {
const Extension* extension = GetExtension();
if (!extension)
@@ -292,10 +323,61 @@ void ExtensionAppItem::StartExtensionUninstall() {
uninstaller->Run();
}
+bool ExtensionAppItem::RunExtensionEnableFlow() {
+ if (IsExtensionEnabled(profile_, extension_id_))
+ return false;
+
+ if (!extension_enable_flow_) {
+ controller_->OnShowExtensionPrompt();
+
+ extension_enable_flow_.reset(new ExtensionEnableFlow(
+ profile_, extension_id_, this));
+ extension_enable_flow_->Start();
+ }
+ return true;
+}
+
+void ExtensionAppItem::Launch(int event_flags) {
+ if (RunExtensionEnableFlow())
+ return;
+
+ const Extension* extension = GetExtension();
+ if (!extension)
+ return;
+
+ controller_->LaunchApp(profile_, extension->id(), event_flags);
+}
+
void ExtensionAppItem::OnExtensionIconImageChanged(
extensions::IconImage* image) {
DCHECK(icon_.get() == image);
- SetIconWithOverlay(icon_->image_skia());
+ UpdateIcon();
+}
+
+ExtensionInstallPrompt* ExtensionAppItem::CreateExtensionInstallPrompt() {
+ return new ExtensionInstallPrompt(profile_,
+ controller_->GetAppListWindow(),
+ this);
+}
+
+void ExtensionAppItem::ExtensionEnableFlowFinished() {
+ extension_enable_flow_.reset();
+ controller_->OnCloseExtensionPrompt();
+
+ // Automatically launch app after enabling.
+ Launch(ui::EF_NONE);
+}
+
+void ExtensionAppItem::ExtensionEnableFlowAborted(bool user_initiated) {
+ extension_enable_flow_.reset();
+ controller_->OnCloseExtensionPrompt();
+}
+
+content::WebContents* ExtensionAppItem::OpenURL(
+ const content::OpenURLParams& params) {
+ Browser* browser = chrome::FindOrCreateTabbedBrowser(
+ profile_, chrome::GetActiveDesktop());
+ return browser->OpenURL(params);
}
bool ExtensionAppItem::IsItemForCommandIdDynamic(int command_id) const {
@@ -402,19 +484,14 @@ void ExtensionAppItem::ExecuteCommand(int command_id) {
}
void ExtensionAppItem::Activate(int event_flags) {
- const Extension* extension = GetExtension();
- if (!extension)
+ if (RunExtensionEnableFlow())
return;
- controller_->ActivateApp(profile_, extension->id(), event_flags);
-}
-
-void ExtensionAppItem::Launch(int event_flags) {
const Extension* extension = GetExtension();
if (!extension)
return;
- controller_->LaunchApp(profile_, extension->id(), event_flags);
+ controller_->ActivateApp(profile_, extension->id(), event_flags);
}
ui::MenuModel* ExtensionAppItem::GetContextMenuModel() {
@@ -453,7 +530,9 @@ ui::MenuModel* ExtensionAppItem::GetContextMenuModel() {
extension_menu_items_->AppendExtensionItems(extension_id_, string16(),
&index);
- if (controller_->CanPin()) {
+ // TODO(xiyuan): Remove enabled check when launcher supports disabled
+ // and terminated apps.
+ if (controller_->CanPin() && IsExtensionEnabled(profile_, extension_id_)) {
context_menu_model_->AddSeparatorIfNecessary(ui::NORMAL_SEPARATOR);
context_menu_model_->AddItemWithStringId(
TOGGLE_PIN,
diff --git a/chrome/browser/ui/app_list/extension_app_item.h b/chrome/browser/ui/app_list/extension_app_item.h
index 5513076..00e7a8c 100644
--- a/chrome/browser/ui/app_list/extension_app_item.h
+++ b/chrome/browser/ui/app_list/extension_app_item.h
@@ -10,13 +10,14 @@
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/extensions/extension_icon_image.h"
#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
+#include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h"
+#include "content/public/browser/page_navigator.h"
#include "sync/api/string_ordinal.h"
#include "ui/base/models/simple_menu_model.h"
class AppListControllerDelegate;
-class ExtensionResource;
+class ExtensionEnableFlow;
class Profile;
-class SkBitmap;
namespace extensions {
class ContextMenuMatcher;
@@ -26,6 +27,8 @@ class Extension;
// ExtensionAppItem represents an extension app in app list.
class ExtensionAppItem : public ChromeAppListItem,
public extensions::IconImage::Observer,
+ public ExtensionEnableFlowDelegate,
+ public content::PageNavigator,
public ui::SimpleMenuModel::Delegate {
public:
ExtensionAppItem(Profile* profile,
@@ -33,10 +36,6 @@ class ExtensionAppItem : public ChromeAppListItem,
AppListControllerDelegate* controller);
virtual ~ExtensionAppItem();
- // Gets extension associated with this model. Returns NULL if extension
- // no longer exists.
- const extensions::Extension* GetExtension() const;
-
syncer::StringOrdinal GetPageOrdinal() const;
syncer::StringOrdinal GetAppLaunchOrdinal() const;
@@ -45,26 +44,48 @@ class ExtensionAppItem : public ChromeAppListItem,
// the beginning or at the end.
void Move(const ExtensionAppItem* prev, const ExtensionAppItem* next);
+ // Updates the app item's icon, if necessary adding an overlay and/or making
+ // it gray.
+ void UpdateIcon();
+
const std::string& extension_id() const { return extension_id_; }
private:
+ // Gets extension associated with this model. Returns NULL if extension
+ // no longer exists.
+ const extensions::Extension* GetExtension() const;
+
// Loads extension icon.
void LoadImage(const extensions::Extension* extension);
// Whether or not the app item has an overlay.
bool HasOverlay();
- // Sets the app item's icon, if necessary adding an overlay.
- void SetIconWithOverlay(const gfx::ImageSkia& icon);
-
void ShowExtensionOptions();
void ShowExtensionDetails();
void StartExtensionUninstall();
+ // Checks if extension is disabled and if enable flow should be started.
+ // Returns true if extension enable flow is started or there is already one
+ // running.
+ bool RunExtensionEnableFlow();
+
+ // Private equivalent to Activate(), without refocus for already-running apps.
+ void Launch(int event_flags);
+
// Overridden from extensions::IconImage::Observer:
virtual void OnExtensionIconImageChanged(
extensions::IconImage* image) OVERRIDE;
+ // Overridden from ExtensionEnableFlowDelegate:
+ virtual ExtensionInstallPrompt* CreateExtensionInstallPrompt() OVERRIDE;
+ virtual void ExtensionEnableFlowFinished() OVERRIDE;
+ virtual void ExtensionEnableFlowAborted(bool user_initiated) OVERRIDE;
+
+ // Overridden from content::PageNavigator:
+ virtual content::WebContents* OpenURL(
+ const content::OpenURLParams& params) OVERRIDE;
+
// Overridden from ui::SimpleMenuModel::Delegate:
virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE;
virtual string16 GetLabelForCommandId(int command_id) const OVERRIDE;
@@ -79,9 +100,6 @@ class ExtensionAppItem : public ChromeAppListItem,
virtual void Activate(int event_flags) OVERRIDE;
virtual ui::MenuModel* GetContextMenuModel() OVERRIDE;
- // Private equivalent to Activate(), without refocus for already-running apps.
- void Launch(int event_flags);
-
Profile* profile_;
const std::string extension_id_;
AppListControllerDelegate* controller_;
@@ -89,6 +107,7 @@ class ExtensionAppItem : public ChromeAppListItem,
scoped_ptr<extensions::IconImage> icon_;
scoped_ptr<ui::SimpleMenuModel> context_menu_model_;
scoped_ptr<extensions::ContextMenuMatcher> extension_menu_items_;
+ scoped_ptr<ExtensionEnableFlow> extension_enable_flow_;
DISALLOW_COPY_AND_ASSIGN(ExtensionAppItem);
};
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 fcbcc93..8cd3151 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
@@ -18,6 +18,11 @@ void AppListControllerDelegateAsh::DismissView() {
ash::Shell::GetInstance()->ToggleAppList(NULL);
}
+gfx::NativeWindow AppListControllerDelegateAsh::GetAppListWindow() {
+ DCHECK(ash::Shell::HasInstance());
+ return ash::Shell::GetInstance()->GetAppListWindow();
+}
+
bool AppListControllerDelegateAsh::IsAppPinned(
const std::string& extension_id) {
return ChromeLauncherController::instance()->IsAppPinned(extension_id);
diff --git a/chrome/browser/ui/ash/app_list/app_list_controller_ash.h b/chrome/browser/ui/ash/app_list/app_list_controller_ash.h
index d986a03d..c2449ea 100644
--- a/chrome/browser/ui/ash/app_list/app_list_controller_ash.h
+++ b/chrome/browser/ui/ash/app_list/app_list_controller_ash.h
@@ -17,6 +17,7 @@ class AppListControllerDelegateAsh : public AppListControllerDelegate {
private:
// AppListControllerDelegate overrides:
virtual void DismissView() OVERRIDE;
+ virtual gfx::NativeWindow GetAppListWindow() OVERRIDE;
virtual bool IsAppPinned(const std::string& extension_id) OVERRIDE;
virtual void PinApp(const std::string& extension_id) OVERRIDE;
virtual void UnpinApp(const std::string& extension_id) OVERRIDE;
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 1244d9e..0db9f0d 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
@@ -95,9 +95,10 @@ class AppListControllerDelegateWin : public AppListControllerDelegate {
virtual void DismissView() OVERRIDE;
virtual void ViewClosing() OVERRIDE;
virtual void ViewActivationChanged(bool active) OVERRIDE;
+ virtual gfx::NativeWindow GetAppListWindow() OVERRIDE;
virtual bool CanPin() OVERRIDE;
- virtual void AboutToUninstallApp() OVERRIDE;
- virtual void UninstallAppCompleted() OVERRIDE;
+ virtual void OnShowExtensionPrompt() OVERRIDE;
+ virtual void OnCloseExtensionPrompt() OVERRIDE;
virtual bool CanShowCreateShortcutsDialog() OVERRIDE;
virtual void ShowCreateShortcutsDialog(
Profile* profile,
@@ -187,15 +188,20 @@ void AppListControllerDelegateWin::ViewClosing() {
g_app_list_controller.Get().AppListClosing();
}
+gfx::NativeWindow AppListControllerDelegateWin::GetAppListWindow() {
+ app_list::AppListView* view = g_app_list_controller.Get().GetView();
+ return view ? view->GetWidget()->GetNativeWindow() : NULL;
+}
+
bool AppListControllerDelegateWin::CanPin() {
return false;
}
-void AppListControllerDelegateWin::AboutToUninstallApp() {
+void AppListControllerDelegateWin::OnShowExtensionPrompt() {
g_app_list_controller.Get().set_can_close(false);
}
-void AppListControllerDelegateWin::UninstallAppCompleted() {
+void AppListControllerDelegateWin::OnCloseExtensionPrompt() {
g_app_list_controller.Get().set_can_close(true);
}