Refactor ExtensionActionContextMenuModel.

- Simplify constructor
- Rename to ExtensionContextMenuModel.*
- Remove views/extension_action_context_menu.*

BUG=none
TEST=none

Review URL: http://codereview.chromium.org/1107007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42271 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_action_context_menu_model.cc b/chrome/browser/extensions/extension_action_context_menu_model.cc
deleted file mode 100644
index fa49c4e..0000000
--- a/chrome/browser/extensions/extension_action_context_menu_model.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "chrome/browser/extensions/extension_action_context_menu_model.h"
-
-#include "app/l10n_util.h"
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/pref_service.h"
-#include "chrome/browser/profile.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_action.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/url_constants.h"
-#include "grit/generated_resources.h"
-
-enum MenuEntries {
-  NAME = 0,
-  CONFIGURE,
-  DISABLE,
-  UNINSTALL,
-  MANAGE,
-  INSPECT_POPUP
-};
-
-ExtensionActionContextMenuModel::ExtensionActionContextMenuModel(
-    Extension* extension, ExtensionAction* extension_action, PrefService* prefs,
-    MenuDelegate* delegate)
-  : ALLOW_THIS_IN_INITIALIZER_LIST(SimpleMenuModel(this)),
-    extension_(extension),
-    extension_action_(extension_action),
-    delegate_(delegate) {
-  AddItem(NAME, UTF8ToUTF16(extension->name()));
-  AddSeparator();
-  AddItemWithStringId(CONFIGURE, IDS_EXTENSIONS_OPTIONS);
-  AddItemWithStringId(DISABLE, IDS_EXTENSIONS_DISABLE);
-  AddItemWithStringId(UNINSTALL, IDS_EXTENSIONS_UNINSTALL);
-  AddSeparator();
-  AddItemWithStringId(MANAGE, IDS_MANAGE_EXTENSIONS);
-
-  if (extension_ && delegate_ && prefs &&
-      prefs->GetBoolean(prefs::kExtensionsUIDeveloperMode)) {
-    AddSeparator();
-    AddItemWithStringId(INSPECT_POPUP, IDS_EXTENSION_ACTION_INSPECT_POPUP);
-  }
-}
-
-ExtensionActionContextMenuModel::~ExtensionActionContextMenuModel() {
-}
-
-bool ExtensionActionContextMenuModel::IsCommandIdChecked(int command_id) const {
-  return false;
-}
-
-bool ExtensionActionContextMenuModel::IsCommandIdEnabled(int command_id) const {
-  if (command_id == CONFIGURE) {
-    return extension_->options_url().spec().length() > 0;
-  } else if (command_id == NAME) {
-    // The NAME links to the gallery page, which only makes sense if Google is
-    // hosting the extension. For other 3rd party extensions we don't have a
-    // homepage url, so we just disable this menu item on those cases, at least
-    // for now.
-    return extension_->update_url().DomainIs("google.com");
-  } else if (command_id == INSPECT_POPUP) {
-    if (!delegate_ || !extension_)
-      return false;
-    Browser* browser = BrowserList::GetLastActive();
-    if (!browser)
-      return false;
-    TabContents* contents = browser->GetSelectedTabContents();
-    if (!contents)
-      return false;
-
-    // Different tabs can have different popups set. We need to make sure we
-    // only enable the menu item if the current tab has a popup.
-    return (extension_action_->HasPopup(ExtensionTabUtil::GetTabId(contents)));
-  }
-  return true;
-}
-
-bool ExtensionActionContextMenuModel::GetAcceleratorForCommandId(
-    int command_id, menus::Accelerator* accelerator) {
-  return false;
-}
-
-void ExtensionActionContextMenuModel::ExecuteCommand(int command_id) {
-  // TODO(finnur): GetLastActive returns NULL in unit tests.
-  Browser* browser = BrowserList::GetLastActive();
-  Profile* profile = browser->profile();
-
-  switch (command_id) {
-    case NAME: {
-      GURL url(std::string(extension_urls::kGalleryBrowsePrefix) +
-               std::string("/detail/") + extension_->id());
-      browser->OpenURL(url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK);
-      break;
-    }
-    case CONFIGURE:
-      DCHECK(!extension_->options_url().is_empty());
-      profile->GetExtensionProcessManager()->OpenOptionsPage(extension_,
-                                                             browser);
-      break;
-    case DISABLE: {
-      ExtensionsService* extension_service = profile->GetExtensionsService();
-      extension_service->DisableExtension(extension_->id());
-      break;
-    }
-    case UNINSTALL: {
-      scoped_ptr<SkBitmap> uninstall_icon;
-      Extension::DecodeIcon(extension_, Extension::EXTENSION_ICON_LARGE,
-                            &uninstall_icon);
-
-      ExtensionInstallUI client(profile);
-      client.ConfirmUninstall(this, extension_, uninstall_icon.get());
-      break;
-    }
-    case MANAGE: {
-      browser->OpenURL(GURL(chrome::kChromeUIExtensionsURL), GURL(),
-                       SINGLETON_TAB, PageTransition::LINK);
-      break;
-    }
-    case INSPECT_POPUP: {
-      if (delegate_)
-        delegate_->ShowPopupForDevToolsWindow(extension_, extension_action_);
-      break;
-    }
-    default:
-     NOTREACHED() << "Unknown option";
-     break;
-  }
-}
-
-void ExtensionActionContextMenuModel::InstallUIProceed(bool create_app) {
-  DCHECK(!create_app);
-
-  // TODO(finnur): GetLastActive returns NULL in unit tests.
-  Browser* browser = BrowserList::GetLastActive();
-  std::string id = extension_->id();
-  browser->profile()->GetExtensionsService()->UninstallExtension(id, false);
-}
diff --git a/chrome/browser/extensions/extension_action_context_menu_model.h b/chrome/browser/extensions/extension_action_context_menu_model.h
deleted file mode 100644
index a35d269..0000000
--- a/chrome/browser/extensions/extension_action_context_menu_model.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2009 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.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_CONTEXT_MENU_MODEL_H_
-#define CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_CONTEXT_MENU_MODEL_H_
-
-#include "app/menus/simple_menu_model.h"
-#include "chrome/browser/extensions/extension_install_ui.h"
-
-class Extension;
-class ExtensionAction;
-class PrefService;
-
-// The menu model for the context menu for extension action icons (browser and
-// page actions).
-class ExtensionActionContextMenuModel
-    : public menus::SimpleMenuModel,
-      public menus::SimpleMenuModel::Delegate,
-      public ExtensionInstallUI::Delegate {
- public:
-  // Delegate to handle menu commands.
-  class MenuDelegate {
-   public:
-    // Called when the user selects the menu item which requests that the
-    // popup be shown and inspected.
-    virtual void ShowPopupForDevToolsWindow(Extension* extension,
-        ExtensionAction* extension_action) {
-    }
-  };
-
-  // |extension_action|, |prefs|, & |delegate| call all be NULL. If valid
-  // values are provided for all three, and prefs::kExtensionsUIDeveloperMode
-  // is enabled in the PrefService, a menu item will be shown for "Inspect
-  // Popup" which, when selected, will cause ShowPopupForDevToolsWindow() to be
-  // called on |delegate|.
-  ExtensionActionContextMenuModel(Extension* extension,
-                                  ExtensionAction* extension_action,
-                                  PrefService* prefs,
-                                  MenuDelegate* delegate);
-  ~ExtensionActionContextMenuModel();
-
-  // SimpleMenuModel behavior overrides.
-  virtual bool IsCommandIdChecked(int command_id) const;
-  virtual bool IsCommandIdEnabled(int command_id) const;
-  virtual bool GetAcceleratorForCommandId(int command_id,
-                                          menus::Accelerator* accelerator);
-  virtual void ExecuteCommand(int command_id);
-
-  // ExtensionInstallUI::Delegate overrides.
-  virtual void InstallUIProceed(bool create_app);
-  virtual void InstallUIAbort() {}
-
- private:
-  // The extension we are displaying the context menu for.
-  Extension* extension_;
-
-  // The extension action we are displaying the context menu for.
-  ExtensionAction* extension_action_;
-
-  // The delegate which handles the 'inspect popup' menu command.
-  MenuDelegate* delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExtensionActionContextMenuModel);
-};
-
-#endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_CONTEXT_MENU_MODEL_H_
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc
new file mode 100644
index 0000000..2c3be7d3
--- /dev/null
+++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2010 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.
+
+#include "chrome/browser/extensions/extension_context_menu_model.h"
+
+#include "app/l10n_util.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension_tabs_module.h"
+#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_action.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "grit/generated_resources.h"
+
+enum MenuEntries {
+  NAME = 0,
+  CONFIGURE,
+  DISABLE,
+  UNINSTALL,
+  MANAGE,
+  INSPECT_POPUP
+};
+
+ExtensionContextMenuModel::ExtensionContextMenuModel(
+    Extension* extension,
+    Browser* browser,
+    PopupDelegate* delegate)
+    : ALLOW_THIS_IN_INITIALIZER_LIST(SimpleMenuModel(this)),
+      extension_(extension),
+      browser_(browser),
+      profile_(browser->profile()),
+      delegate_(delegate) {
+  extension_action_ = extension->browser_action();
+  if (!extension_action_)
+    extension_action_ = extension->page_action();
+
+  InitCommonCommands();
+
+  if (profile_->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode) &&
+      delegate_) {
+    AddSeparator();
+    AddItemWithStringId(INSPECT_POPUP, IDS_EXTENSION_ACTION_INSPECT_POPUP);
+  }
+}
+
+ExtensionContextMenuModel::~ExtensionContextMenuModel() {
+}
+
+void ExtensionContextMenuModel::InitCommonCommands() {
+  AddItem(NAME, UTF8ToUTF16(extension_->name()));
+  AddSeparator();
+  AddItemWithStringId(CONFIGURE, IDS_EXTENSIONS_OPTIONS);
+  AddItemWithStringId(DISABLE, IDS_EXTENSIONS_DISABLE);
+  AddItemWithStringId(UNINSTALL, IDS_EXTENSIONS_UNINSTALL);
+  AddSeparator();
+  AddItemWithStringId(MANAGE, IDS_MANAGE_EXTENSIONS);
+}
+
+bool ExtensionContextMenuModel::IsCommandIdChecked(int command_id) const {
+  return false;
+}
+
+bool ExtensionContextMenuModel::IsCommandIdEnabled(int command_id) const {
+  if (command_id == CONFIGURE) {
+    return extension_->options_url().spec().length() > 0;
+  } else if (command_id == NAME) {
+    // The NAME links to the gallery page, which only makes sense if Google is
+    // hosting the extension. For other 3rd party extensions we don't have a
+    // homepage url, so we just disable this menu item on those cases, at least
+    // for now.
+    return extension_->update_url().DomainIs("google.com");
+  } else if (command_id == INSPECT_POPUP) {
+    TabContents* contents = browser_->GetSelectedTabContents();
+    if (!contents)
+      return false;
+
+    return extension_action_->HasPopup(ExtensionTabUtil::GetTabId(contents));
+  }
+  return true;
+}
+
+bool ExtensionContextMenuModel::GetAcceleratorForCommandId(
+    int command_id, menus::Accelerator* accelerator) {
+  return false;
+}
+
+void ExtensionContextMenuModel::ExecuteCommand(int command_id) {
+  switch (command_id) {
+    case NAME: {
+      GURL url(std::string(extension_urls::kGalleryBrowsePrefix) +
+               std::string("/detail/") + extension_->id());
+      browser_->OpenURL(url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK);
+      break;
+    }
+    case CONFIGURE:
+      DCHECK(!extension_->options_url().is_empty());
+      profile_->GetExtensionProcessManager()->OpenOptionsPage(extension_,
+                                                              browser_);
+      break;
+    case DISABLE: {
+      ExtensionsService* extension_service = profile_->GetExtensionsService();
+      extension_service->DisableExtension(extension_->id());
+      break;
+    }
+    case UNINSTALL: {
+      scoped_ptr<SkBitmap> uninstall_icon;
+      Extension::DecodeIcon(extension_, Extension::EXTENSION_ICON_LARGE,
+                            &uninstall_icon);
+
+      ExtensionInstallUI client(profile_);
+      client.ConfirmUninstall(this, extension_, uninstall_icon.get());
+      break;
+    }
+    case MANAGE: {
+      browser_->OpenURL(GURL(chrome::kChromeUIExtensionsURL), GURL(),
+                        SINGLETON_TAB, PageTransition::LINK);
+      break;
+    }
+    case INSPECT_POPUP: {
+      delegate_->InspectPopup(extension_action_);
+      break;
+    }
+    default:
+     NOTREACHED() << "Unknown option";
+     break;
+  }
+}
+
+void ExtensionContextMenuModel::InstallUIProceed(bool create_app) {
+  DCHECK(!create_app);
+
+  std::string id = extension_->id();
+  profile_->GetExtensionsService()->UninstallExtension(id, false);
+}
diff --git a/chrome/browser/extensions/extension_context_menu_model.h b/chrome/browser/extensions/extension_context_menu_model.h
new file mode 100644
index 0000000..21667ef
--- /dev/null
+++ b/chrome/browser/extensions/extension_context_menu_model.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_CONTEXT_MENU_MODEL_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_CONTEXT_MENU_MODEL_H_
+
+#include "app/menus/simple_menu_model.h"
+#include "chrome/browser/extensions/extension_install_ui.h"
+
+class Browser;
+class Extension;
+class ExtensionAction;
+class Profile;
+
+// The menu model for the context menu for extension action icons (browser and
+// page actions).
+class ExtensionContextMenuModel
+    : public menus::SimpleMenuModel,
+      public menus::SimpleMenuModel::Delegate,
+      public ExtensionInstallUI::Delegate {
+ public:
+  // Delegate to handle showing an ExtensionAction popup.
+  class PopupDelegate {
+   public:
+    // Called when the user selects the menu item which requests that the
+    // popup be shown and inspected.
+    virtual void InspectPopup(ExtensionAction* action) = 0;
+  };
+
+  // Creates a menu model for the given extension action. If
+  // prefs::kExtensionsUIDeveloperMode is enabled then a menu item
+  // will be shown for "Inspect Popup" which, when selected, will cause
+  // ShowPopupForDevToolsWindow() to be called on |delegate|.
+  ExtensionContextMenuModel(Extension* extension,
+                            Browser* browser,
+                            PopupDelegate* delegate);
+  virtual ~ExtensionContextMenuModel();
+
+  // SimpleMenuModel::Delegate overrides.
+  virtual bool IsCommandIdChecked(int command_id) const;
+  virtual bool IsCommandIdEnabled(int command_id) const;
+  virtual bool GetAcceleratorForCommandId(int command_id,
+                                          menus::Accelerator* accelerator);
+  virtual void ExecuteCommand(int command_id);
+
+  // ExtensionInstallUI::Delegate overrides.
+  virtual void InstallUIProceed(bool create_app);
+  virtual void InstallUIAbort() {}
+
+ private:
+  void InitCommonCommands();
+
+  // The extension we are displaying the menu for.
+  Extension* extension_;
+
+  // The extension action we are displaying the menu for (or NULL).
+  ExtensionAction* extension_action_;
+
+  Browser* browser_;
+
+  Profile* profile_;
+
+  // The delegate which handles the 'inspect popup' menu command (or NULL).
+  PopupDelegate* delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExtensionContextMenuModel);
+};
+
+#endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_CONTEXT_MENU_MODEL_H_
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
index 5ab13c67..16836bf 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
@@ -8,8 +8,8 @@
 
 #include "app/gfx/canvas_paint.h"
 #include "chrome/browser/browser.h"
-#include "chrome/browser/extensions/extension_action_context_menu_model.h"
 #include "chrome/browser/extensions/extension_browser_event_router.h"
+#include "chrome/browser/extensions/extension_context_menu_model.h"
 #include "chrome/browser/extensions/extensions_service.h"
 #include "chrome/browser/extensions/image_loading_tracker.h"
 #include "chrome/browser/gtk/cairo_cached_surface.h"
@@ -62,7 +62,8 @@
 }  // namespace
 
 class BrowserActionButton : public NotificationObserver,
-                            public ImageLoadingTracker::Observer {
+                            public ImageLoadingTracker::Observer,
+                            public ExtensionContextMenuModel::PopupDelegate {
  public:
   BrowserActionButton(BrowserActionsToolbarGtk* toolbar,
                       Extension* extension)
@@ -177,6 +178,12 @@
   }
 
  private:
+  // ExtensionContextMenuModel::PopupDelegate implementation.
+  virtual void InspectPopup(ExtensionAction* action) {
+    // TODO(estade): http://crbug.com/24477
+    NOTIMPLEMENTED();
+  }
+
   void SetImage(GdkPixbuf* image) {
     gtk_button_set_image(GTK_BUTTON(button_.get()),
         gtk_image_new_from_pixbuf(image));
@@ -188,18 +195,15 @@
     if (event->button.button != 3)
       return FALSE;
 
-    // TODO(rafaelw): support inspecting popups.
-    if (!action->context_menu_model_.get()) {
-      action->context_menu_model_.reset(
-          new ExtensionActionContextMenuModel(action->extension_,
-              action->extension_->browser_action(),
-              action->toolbar_->browser()->profile()->GetPrefs(), NULL));
-    }
-
+    action->context_menu_model_.reset(
+        new ExtensionContextMenuModel(
+            action->extension_,
+            action->toolbar_->browser(),
+            action));
     action->context_menu_.reset(
         new MenuGtk(NULL, action->context_menu_model_.get()));
-
     action->context_menu_->Popup(widget, event);
+
     return TRUE;
   }
 
@@ -275,7 +279,7 @@
 
   // The context menu view and model for this extension action.
   scoped_ptr<MenuGtk> context_menu_;
-  scoped_ptr<ExtensionActionContextMenuModel> context_menu_model_;
+  scoped_ptr<ExtensionContextMenuModel> context_menu_model_;
 
   friend class BrowserActionsToolbarGtk;
 };
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc
index 997d20d..b7b96d2 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_toolbar_gtk.cc
@@ -79,10 +79,7 @@
 
 BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window)
     : toolbar_(NULL),
-      location_bar_(new LocationBarViewGtk(browser->command_updater(),
-                                           browser->toolbar_model(),
-                                           this,
-                                           browser)),
+      location_bar_(new LocationBarViewGtk(this, browser)),
       model_(browser->toolbar_model()),
       page_menu_model_(this, browser),
       app_menu_model_(this, browser),
diff --git a/chrome/browser/gtk/location_bar_view_gtk.cc b/chrome/browser/gtk/location_bar_view_gtk.cc
index dabdf18..925f89c 100644
--- a/chrome/browser/gtk/location_bar_view_gtk.cc
+++ b/chrome/browser/gtk/location_bar_view_gtk.cc
@@ -23,7 +23,6 @@
 #include "chrome/browser/content_setting_bubble_model.h"
 #include "chrome/browser/content_setting_image_model.h"
 #include "chrome/browser/extensions/extension_accessibility_api_constants.h"
-#include "chrome/browser/extensions/extension_action_context_menu_model.h"
 #include "chrome/browser/extensions/extension_browser_event_router.h"
 #include "chrome/browser/extensions/extension_tabs_module.h"
 #include "chrome/browser/extensions/extensions_service.h"
@@ -138,8 +137,6 @@
 };
 
 LocationBarViewGtk::LocationBarViewGtk(
-    CommandUpdater* command_updater,
-    ToolbarModel* toolbar_model,
     const BubblePositioner* bubble_positioner,
     Browser* browser)
     : security_icon_event_box_(NULL),
@@ -155,8 +152,8 @@
       tab_to_search_hint_trailing_label_(NULL),
       type_to_search_hint_(NULL),
       profile_(NULL),
-      command_updater_(command_updater),
-      toolbar_model_(toolbar_model),
+      command_updater_(browser->command_updater()),
+      toolbar_model_(browser->toolbar_model()),
       browser_(browser),
       bubble_positioner_(bubble_positioner),
       disposition_(CURRENT_TAB),
@@ -1196,6 +1193,12 @@
   OnButtonPressed(widget(), &event);
 }
 
+void LocationBarViewGtk::PageActionViewGtk::InspectPopup(
+    ExtensionAction* action) {
+  // TODO(estade): http://crbug.com/24477
+  NOTIMPLEMENTED();
+}
+
 gboolean LocationBarViewGtk::PageActionViewGtk::OnButtonPressed(
     GtkWidget* sender,
     GdkEvent* event) {
@@ -1218,11 +1221,8 @@
     Extension* extension = profile_->GetExtensionsService()->GetExtensionById(
         page_action()->extension_id(), false);
 
-    // TODO(rafaelw): support inspecting popups.
-    if (!context_menu_model_.get())
-      context_menu_model_.reset(new ExtensionActionContextMenuModel(extension,
-          page_action_, profile_->GetPrefs(), NULL));
-
+    context_menu_model_.reset(
+        new ExtensionContextMenuModel(extension, owner_->browser_, this));
     context_menu_.reset(
         new MenuGtk(NULL, context_menu_model_.get()));
     context_menu_->Popup(sender, event);
diff --git a/chrome/browser/gtk/location_bar_view_gtk.h b/chrome/browser/gtk/location_bar_view_gtk.h
index 1da0e7a..2037a2e 100644
--- a/chrome/browser/gtk/location_bar_view_gtk.h
+++ b/chrome/browser/gtk/location_bar_view_gtk.h
@@ -15,6 +15,7 @@
 #include "base/scoped_vector.h"
 #include "chrome/browser/autocomplete/autocomplete_edit.h"
 #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
+#include "chrome/browser/extensions/extension_context_menu_model.h"
 #include "chrome/browser/extensions/image_loading_tracker.h"
 #include "chrome/browser/gtk/info_bubble_gtk.h"
 #include "chrome/browser/gtk/menu_gtk.h"
@@ -34,7 +35,6 @@
 class ContentSettingImageModel;
 class ContentSettingBubbleGtk;
 class ExtensionAction;
-class ExtensionActionContextMenuModel;
 class GtkThemeProvider;
 class Profile;
 class SkBitmap;
@@ -46,9 +46,7 @@
                            public LocationBarTesting,
                            public NotificationObserver {
  public:
-  LocationBarViewGtk(CommandUpdater* command_updater,
-                     ToolbarModel* toolbar_model,
-                     const BubblePositioner* bubble_positioner,
+  LocationBarViewGtk(const BubblePositioner* bubble_positioner,
                      Browser* browser_);
   virtual ~LocationBarViewGtk();
 
@@ -171,7 +169,8 @@
     DISALLOW_COPY_AND_ASSIGN(ContentSettingImageViewGtk);
   };
 
-  class PageActionViewGtk : public ImageLoadingTracker::Observer {
+  class PageActionViewGtk : public ImageLoadingTracker::Observer,
+                            public ExtensionContextMenuModel::PopupDelegate {
    public:
     PageActionViewGtk(
         LocationBarViewGtk* owner, Profile* profile,
@@ -199,6 +198,9 @@
     // Simulate left mouse click on the page action button.
     void TestActivatePageAction();
 
+    // Overridden from ExtensionContextMenuModel::PopupDelegate:
+    virtual void InspectPopup(ExtensionAction* action);
+
    private:
     static gboolean OnButtonPressedThunk(GtkWidget* sender,
                                          GdkEvent* event,
@@ -254,7 +256,7 @@
 
     // The context menu view and model for this extension action.
     scoped_ptr<MenuGtk> context_menu_;
-    scoped_ptr<ExtensionActionContextMenuModel> context_menu_model_;
+    scoped_ptr<ExtensionContextMenuModel> context_menu_model_;
 
     DISALLOW_COPY_AND_ASSIGN(PageActionViewGtk);
   };
diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc
index d56e4214..3998cd2 100644
--- a/chrome/browser/views/browser_actions_container.cc
+++ b/chrome/browser/views/browser_actions_container.cc
@@ -33,6 +33,7 @@
 #include "third_party/skia/include/effects/SkGradientShader.h"
 #include "views/controls/button/menu_button.h"
 #include "views/controls/button/text_button.h"
+#include "views/controls/menu/menu_2.h"
 #include "views/drag_utils.h"
 #include "views/window/window.h"
 
@@ -225,8 +226,11 @@
     // Make the menu appear below the button.
     point.Offset(0, height());
 
-    panel_->GetContextMenu()->Run(extension(), extension()->browser_action(),
-        panel_, panel_->profile()->GetPrefs(), point);
+    // Reconstructs the menu every time because the menu's contents are dynamic.
+    context_menu_contents_.reset(new ExtensionContextMenuModel(
+        extension(), panel_->browser(), panel_));
+    context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get()));
+    context_menu_menu_->RunContextMenuAt(point);
 
     SetButtonNotPushed();
     return false;
@@ -380,7 +384,6 @@
   if (model_)
     model_->RemoveObserver(this);
   StopShowFolderDropMenuTimer();
-  CloseMenus();
   HidePopup();
   DeleteBrowserActionViews();
 }
@@ -398,18 +401,12 @@
   return tab_contents->controller().session_id().id();
 }
 
-ExtensionActionContextMenu* BrowserActionsContainer::GetContextMenu() {
-  if (!context_menu_.get())
-    context_menu_.reset(new ExtensionActionContextMenu());
-  return context_menu_.get();
-}
-
 BrowserActionView* BrowserActionsContainer::GetBrowserActionView(
-    Extension* extension) {
+    ExtensionAction* action) {
   for (BrowserActionViews::iterator iter =
        browser_action_views_.begin(); iter != browser_action_views_.end();
        ++iter) {
-    if ((*iter)->button()->extension() == extension)
+    if ((*iter)->button()->browser_action() == action)
       return *iter;
   }
 
@@ -421,10 +418,7 @@
     browser_action_views_[i]->button()->UpdateState();
 }
 
-void BrowserActionsContainer::CloseMenus() {
-  if (context_menu_.get())
-    context_menu_->Cancel();
-  // Close the overflow menu if open.
+void BrowserActionsContainer::CloseOverflowMenu() {
   if (overflow_menu_)
     overflow_menu_->CancelMenu();
 }
@@ -881,8 +875,7 @@
            "exists.";
   }
 #endif
-
-  CloseMenus();
+  CloseOverflowMenu();
 
   if (!ShouldDisplayBrowserAction(extension))
     return;
@@ -923,7 +916,7 @@
 }
 
 void BrowserActionsContainer::BrowserActionRemoved(Extension* extension) {
-  CloseMenus();
+  CloseOverflowMenu();
 
   if (popup_ && popup_->host()->extension() == extension)
     HidePopup();
@@ -1082,9 +1075,9 @@
   overflow_menu_ = NULL;
 }
 
-void BrowserActionsContainer::ShowPopupForDevToolsWindow(Extension* extension,
-    ExtensionAction* extension_action) {
-  OnBrowserActionExecuted(GetBrowserActionView(extension)->button(),
+void BrowserActionsContainer::InspectPopup(
+    ExtensionAction* action) {
+  OnBrowserActionExecuted(GetBrowserActionView(action)->button(),
       true); // inspect_with_devtools
 }
 
diff --git a/chrome/browser/views/browser_actions_container.h b/chrome/browser/views/browser_actions_container.h
index bd25f897..6e38ab0b 100644
--- a/chrome/browser/views/browser_actions_container.h
+++ b/chrome/browser/views/browser_actions_container.h
@@ -11,12 +11,11 @@
 
 #include "app/slide_animation.h"
 #include "base/task.h"
-#include "chrome/browser/extensions/extension_action_context_menu_model.h"
+#include "chrome/browser/extensions/extension_context_menu_model.h"
 #include "chrome/browser/extensions/extension_toolbar_model.h"
 #include "chrome/browser/extensions/image_loading_tracker.h"
 #include "chrome/browser/views/browser_bubble.h"
 #include "chrome/browser/views/extensions/browser_action_overflow_menu_controller.h"
-#include "chrome/browser/views/extensions/extension_action_context_menu.h"
 #include "chrome/browser/views/extensions/extension_popup.h"
 #include "chrome/common/notification_observer.h"
 #include "chrome/common/notification_registrar.h"
@@ -35,6 +34,10 @@
 class PrefService;
 class Profile;
 
+namespace views {
+class Menu2;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // BrowserActionButton
 
@@ -116,6 +119,9 @@
   // The browser action shelf.
   BrowserActionsContainer* panel_;
 
+  scoped_ptr<ExtensionContextMenuModel> context_menu_contents_;
+  scoped_ptr<views::Menu2> context_menu_menu_;
+
   NotificationRegistrar registrar_;
 
   DISALLOW_COPY_AND_ASSIGN(BrowserActionButton);
@@ -233,7 +239,7 @@
     public AnimationDelegate,
     public ExtensionToolbarModel::Observer,
     public BrowserActionOverflowMenuController::Observer,
-    public ExtensionActionContextMenuModel::MenuDelegate,
+    public ExtensionContextMenuModel::PopupDelegate,
     public ExtensionPopup::Observer {
 
   friend class ShowFolderMenuTask;
@@ -255,10 +261,8 @@
   // Returns the profile this container is associated with.
   Profile* profile() const { return profile_; }
 
-  // Returns the context menu for Browser Actions. Constructs the menu object if
-  // not constructed yet. This menu is used for all browser actions (regardless
-  // of whether they are in the overflow menu or not).
-  ExtensionActionContextMenu* GetContextMenu();
+  // Returns the browser this container is associated with.
+  Browser* browser() const { return browser_; }
 
   // Returns the current tab's ID, or -1 if there is no current tab.
   int GetCurrentTabId() const;
@@ -269,7 +273,7 @@
   }
 
   // Retrieve the BrowserActionView for |extension|.
-  BrowserActionView* GetBrowserActionView(Extension* extension);
+  BrowserActionView* GetBrowserActionView(ExtensionAction* action);
 
   // Update the views to reflect the state of the browser action icons.
   void RefreshBrowserActionViews();
@@ -329,9 +333,8 @@
   virtual void NotifyMenuDeleted(
       BrowserActionOverflowMenuController* controller);
 
-  // Overridden from ExtensionActionContextMenuModel::MenuDelegate
-  virtual void ShowPopupForDevToolsWindow(Extension* extension,
-      ExtensionAction* extension_action);
+  // Overridden from ExtensionContextMenuModel::PopupDelegate
+  virtual void InspectPopup(ExtensionAction* action);
 
   // Overriden from ExtensionPopup::Delegate
   virtual void ExtensionPopupClosed(ExtensionPopup* popup);
@@ -366,8 +369,8 @@
   virtual void BrowserActionRemoved(Extension* extension);
   virtual void BrowserActionMoved(Extension* extension, int index);
 
-  // Closes the overflow and context menu if open.
-  void CloseMenus();
+  // Closes the overflow menu if open.
+  void CloseOverflowMenu();
 
   // Cancels the timer for showing the drop down menu.
   void StopShowFolderDropMenuTimer();
@@ -449,10 +452,6 @@
   // own lifetime so that it can stay alive during drag and drop operations.
   BrowserActionOverflowMenuController* overflow_menu_;
 
-  // The context menu that the overflow menu shows. Is NULL until the menu is
-  // shown for the first time.
-  scoped_ptr<ExtensionActionContextMenu> context_menu_;
-
   // The animation that happens when the container snaps to place.
   scoped_ptr<SlideAnimation> resize_animation_;
 
diff --git a/chrome/browser/views/extensions/browser_action_overflow_menu_controller.cc b/chrome/browser/views/extensions/browser_action_overflow_menu_controller.cc
index dbee697..6d6a740 100644
--- a/chrome/browser/views/extensions/browser_action_overflow_menu_controller.cc
+++ b/chrome/browser/views/extensions/browser_action_overflow_menu_controller.cc
@@ -7,12 +7,14 @@
 #include "app/gfx/canvas.h"
 #include "base/utf_string_conversions.h"
 #include "chrome/browser/browser_list.h"
+#include "chrome/browser/extensions/extension_context_menu_model.h"
 #include "chrome/browser/profile.h"
 #include "chrome/browser/tab_contents/tab_contents.h"
 #include "chrome/browser/views/browser_actions_container.h"
 #include "chrome/browser/views/extensions/browser_action_drag_data.h"
 #include "chrome/common/extensions/extension.h"
 #include "views/controls/menu/menu_item_view.h"
+#include "views/controls/menu/menu_2.h"
 
 BrowserActionOverflowMenuController::BrowserActionOverflowMenuController(
     BrowserActionsContainer* owner,
@@ -70,7 +72,9 @@
     menu_->RunMenuForDropAt(window, bounds, anchor);
   } else {
     menu_->RunMenuAt(window, menu_button_, bounds, anchor, false);
-    delete this;
+    // Give the context menu (if any) a chance to execute the user-selected
+    // command.
+    MessageLoop::current()->DeleteSoon(FROM_HERE, this);
   }
   return true;
 }
@@ -90,13 +94,13 @@
     int id,
     const gfx::Point& p,
     bool is_mouse_gesture) {
-  // This blocks until the user choses something or dismisses the menu.
-  owner_->GetContextMenu()->Run(
+  context_menu_contents_.reset(new ExtensionContextMenuModel(
       (*views_)[start_index_ + id - 1]->button()->extension(),
-      (*views_)[start_index_ + id - 1]->button()->extension()->browser_action(),
-      owner_,
-      owner_->profile()->GetPrefs(),
-      p);
+      owner_->browser(),
+      owner_));
+  context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get()));
+  // This blocks until the user choses something or dismisses the menu.
+  context_menu_menu_->RunContextMenuAt(p);
 
   // The user is done with the context menu, so we can close the underlying
   // menu.
diff --git a/chrome/browser/views/extensions/browser_action_overflow_menu_controller.h b/chrome/browser/views/extensions/browser_action_overflow_menu_controller.h
index e30db53..0efa964d 100644
--- a/chrome/browser/views/extensions/browser_action_overflow_menu_controller.h
+++ b/chrome/browser/views/extensions/browser_action_overflow_menu_controller.h
@@ -8,11 +8,17 @@
 #include <set>
 #include <vector>
 
+#include "base/scoped_ptr.h"
+#include "base/task.h"
 #include "views/controls/menu/menu_delegate.h"
 
 class BrowserActionsContainer;
 class BrowserActionView;
-class ExtensionActionContextMenu;
+class ExtensionContextMenuModel;
+
+namespace views {
+class Menu2;
+}
 
 // This class handles the overflow menu for browser actions (showing the menu,
 // drag and drop, etc). This class manages its own lifetime.
@@ -98,6 +104,12 @@
   // Whether this controller is being used for drop.
   bool for_drop_;
 
+  // The browser action context menu and model.
+  scoped_ptr<ExtensionContextMenuModel> context_menu_contents_;
+  scoped_ptr<views::Menu2> context_menu_menu_;
+
+  friend class DeleteTask<BrowserActionOverflowMenuController>;
+
   DISALLOW_COPY_AND_ASSIGN(BrowserActionOverflowMenuController);
 };
 
diff --git a/chrome/browser/views/extensions/extension_action_context_menu.cc b/chrome/browser/views/extensions/extension_action_context_menu.cc
deleted file mode 100644
index da7017d..0000000
--- a/chrome/browser/views/extensions/extension_action_context_menu.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "chrome/browser/views/extensions/extension_action_context_menu.h"
-
-#include "chrome/browser/browser.h"
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
-
-ExtensionActionContextMenu::ExtensionActionContextMenu()
-  : extension_(NULL) {
-}
-
-ExtensionActionContextMenu::~ExtensionActionContextMenu() {
-}
-
-void ExtensionActionContextMenu::Run(Extension* extension,
-    ExtensionAction* extension_action,
-    ExtensionActionContextMenuModel::MenuDelegate* delegate,
-    PrefService* prefs,
-    const gfx::Point& point) {
-  extension_ = extension;
-
-  context_menu_contents_.reset(
-      new ExtensionActionContextMenuModel(extension, extension_action, prefs,
-                                          delegate));
-  context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get()));
-  // This call blocks until the menu is dismissed or something is selected.
-  context_menu_menu_->RunContextMenuAt(point);
-}
-
-void ExtensionActionContextMenu::Cancel() {
-  if (context_menu_menu_.get())
-    context_menu_menu_->CancelMenu();
-}
diff --git a/chrome/browser/views/extensions/extension_action_context_menu.h b/chrome/browser/views/extensions/extension_action_context_menu.h
deleted file mode 100644
index 8aec10a..0000000
--- a/chrome/browser/views/extensions/extension_action_context_menu.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2009 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.
-
-#ifndef CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_ACTION_CONTEXT_MENU_H_
-#define CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_ACTION_CONTEXT_MENU_H_
-
-#include "views/controls/menu/menu_2.h"
-#include "chrome/browser/extensions/extension_install_ui.h"
-#include "chrome/browser/extensions/extension_action_context_menu_model.h"
-
-class Extension;
-class ExtensionAction;
-class PrefService;
-
-// Displays the context menu for extension action icons (browser/page actions).
-class ExtensionActionContextMenu {
- public:
-  ExtensionActionContextMenu();
-  ~ExtensionActionContextMenu();
-
-  // Display the context menu at a given point.
-  void Run(Extension* extension,
-           ExtensionAction* extension_action,
-           ExtensionActionContextMenuModel::MenuDelegate* delegate,
-           PrefService* prefs,
-           const gfx::Point& point);
-
-  // Closes the context menu if open.
-  void Cancel();
-
- private:
-  // The options menu.
-  scoped_ptr<ExtensionActionContextMenuModel> context_menu_contents_;
-  scoped_ptr<views::Menu2> context_menu_menu_;
-
-  // The extension we are showing the menu for.
-  Extension* extension_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExtensionActionContextMenu);
-};
-
-#endif  // CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_ACTION_CONTEXT_MENU_H_
diff --git a/chrome/browser/views/extensions/extension_installed_bubble.cc b/chrome/browser/views/extensions/extension_installed_bubble.cc
index 593165e..65fa333a 100644
--- a/chrome/browser/views/extensions/extension_installed_bubble.cc
+++ b/chrome/browser/views/extensions/extension_installed_bubble.cc
@@ -249,7 +249,8 @@
           &ExtensionInstalledBubble::ShowInternal), kAnimationWaitTime);
       return;
     }
-    reference_view = container->GetBrowserActionView(extension_);
+    reference_view = container->GetBrowserActionView(
+        extension_->browser_action());
     // If the view is not visible then it is in the chevron, so point the
     // install bubble to the chevron instead. If this is an incognito window,
     // both could be invisible.
diff --git a/chrome/browser/views/infobars/extension_infobar.cc b/chrome/browser/views/infobars/extension_infobar.cc
index 4fcaa87..d430320 100644
--- a/chrome/browser/views/infobars/extension_infobar.cc
+++ b/chrome/browser/views/infobars/extension_infobar.cc
@@ -7,14 +7,17 @@
 #include "app/gfx/canvas.h"
 #include "app/resource_bundle.h"
 #include "app/slide_animation.h"
-#include "chrome/browser/extensions/extension_action_context_menu_model.h"
+#include "chrome/browser/extensions/extension_context_menu_model.h"
 #include "chrome/browser/extensions/extension_infobar_delegate.h"
 #include "chrome/browser/extensions/extension_host.h"
+#include "chrome/browser/views/frame/browser_view.h"
 #include "chrome/common/extensions/extension.h"
+#include "chrome/common/platform_util.h"
 #include "grit/browser_resources.h"
 #include "grit/theme_resources.h"
 #include "views/controls/button/menu_button.h"
 #include "views/controls/menu/menu_2.h"
+#include "views/widget/widget.h"
 
 // The horizontal margin between the menu and the Extension (HTML) view.
 static const int kMenuHorizontalMargin = 1;
@@ -89,13 +92,13 @@
 }
 
 void ExtensionInfoBar::RunMenu(View* source, const gfx::Point& pt) {
-  if (!options_menu_contents_.get())
-    options_menu_contents_.reset(new ExtensionActionContextMenuModel(
-        delegate_->extension_host()->extension(),
-        // Do not include "Inspect Popup" in menu:
-        NULL,  // ExtensionAction
-        NULL,  // PrefService
-        NULL));  // ExtensionActionContextMenuModel::MenuDelegate
+  if (!options_menu_contents_.get()) {
+    Browser* browser = BrowserView::GetBrowserViewForNativeWindow(
+        platform_util::GetTopLevel(source->GetWidget()->GetNativeView()))->
+            browser();
+    options_menu_contents_.reset(new ExtensionContextMenuModel(
+        delegate_->extension_host()->extension(), browser, NULL));
+  }
 
   options_menu_menu_.reset(new views::Menu2(options_menu_contents_.get()));
   options_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPLEFT);
diff --git a/chrome/browser/views/infobars/extension_infobar.h b/chrome/browser/views/infobars/extension_infobar.h
index 0f0a64c..ed811d1 100644
--- a/chrome/browser/views/infobars/extension_infobar.h
+++ b/chrome/browser/views/infobars/extension_infobar.h
@@ -10,7 +10,7 @@
 #include "chrome/browser/views/extensions/extension_view.h"
 #include "views/controls/menu/view_menu_delegate.h"
 
-class ExtensionActionContextMenuModel;
+class ExtensionContextMenuModel;
 class ExtensionInfoBarDelegate;
 
 namespace views {
@@ -47,7 +47,7 @@
   ExtensionInfoBarDelegate* delegate_;
 
   // The dropdown menu for accessing the contextual extension actions.
-  scoped_ptr<ExtensionActionContextMenuModel> options_menu_contents_;
+  scoped_ptr<ExtensionContextMenuModel> options_menu_contents_;
   scoped_ptr<views::Menu2> options_menu_menu_;
   views::MenuButton* menu_;
 
diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc
index d657c061..31f61e47 100644
--- a/chrome/browser/views/location_bar_view.cc
+++ b/chrome/browser/views/location_bar_view.cc
@@ -28,8 +28,10 @@
 #include "chrome/browser/search_engines/template_url_model.h"
 #include "chrome/browser/view_ids.h"
 #include "chrome/browser/views/extensions/extension_popup.h"
+#include "chrome/browser/views/frame/browser_view.h"
 #include "chrome/browser/views/content_blocked_bubble_contents.h"
 #include "chrome/common/content_settings.h"
+#include "chrome/common/platform_util.h"
 #include "chrome/common/pref_names.h"
 #include "gfx/color_utils.h"
 #include "grit/generated_resources.h"
@@ -1543,14 +1545,12 @@
 
     Extension* extension = profile_->GetExtensionsService()->GetExtensionById(
         page_action()->extension_id(), false);
-
-    if (!context_menu_.get())
-      context_menu_.reset(new ExtensionActionContextMenu());
-    context_menu_->Run(extension,
-                       extension->page_action(),
-                       this,  // ExtensionActionContextMenuModel::Delegate
-                       profile_->GetPrefs(),
-                       point);
+    Browser* browser = BrowserView::GetBrowserViewForNativeWindow(
+        platform_util::GetTopLevel(GetWidget()->GetNativeView()))->browser();
+    context_menu_contents_.reset(new ExtensionContextMenuModel(
+        extension, browser, this));
+    context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get()));
+    context_menu_menu_->RunContextMenuAt(point);
     return;
   }
 
@@ -1632,8 +1632,8 @@
   SetVisible(visible);
 }
 
-void LocationBarView::PageActionImageView::ShowPopupForDevToolsWindow(
-    Extension* extension, ExtensionAction* extension_action) {
+void LocationBarView::PageActionImageView::InspectPopup(
+    ExtensionAction* action) {
   ExecuteAction(1,  // left-click
                 true);  // inspect_with_devtools
 }
diff --git a/chrome/browser/views/location_bar_view.h b/chrome/browser/views/location_bar_view.h
index d591e97..505492be 100644
--- a/chrome/browser/views/location_bar_view.h
+++ b/chrome/browser/views/location_bar_view.h
@@ -12,12 +12,12 @@
 #include "app/gfx/font.h"
 #include "base/task.h"
 #include "chrome/browser/autocomplete/autocomplete_edit.h"
+#include "chrome/browser/extensions/extension_context_menu_model.h"
 #include "chrome/browser/extensions/image_loading_tracker.h"
 #include "chrome/browser/location_bar.h"
 #include "chrome/browser/tab_contents/tab_contents.h"
 #include "chrome/browser/toolbar_model.h"
 #include "chrome/browser/views/browser_bubble.h"
-#include "chrome/browser/views/extensions/extension_action_context_menu.h"
 #include "chrome/browser/views/extensions/extension_popup.h"
 #include "chrome/browser/views/info_bubble.h"
 #include "chrome/common/content_settings_types.h"
@@ -26,6 +26,7 @@
 #include "gfx/rect.h"
 #include "views/controls/image_view.h"
 #include "views/controls/label.h"
+#include "views/controls/menu/menu_2.h"
 #include "views/controls/native/native_view_host.h"
 #include "views/painter.h"
 
@@ -35,6 +36,7 @@
 #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
 #endif
 
+class Browser;
 class BubblePositioner;
 class CommandUpdater;
 class ContentSettingImageModel;
@@ -102,7 +104,7 @@
   void Update(const TabContents* tab_for_state_restoring);
 
   void SetProfile(Profile* profile);
-  Profile* profile() { return profile_; }
+  Profile* profile() const { return profile_; }
 
   // Returns the current TabContents.
   TabContents* GetTabContents() const;
@@ -411,7 +413,7 @@
   // and notify the extension when the icon is clicked.
   class PageActionImageView : public LocationBarImageView,
       public ImageLoadingTracker::Observer,
-      public ExtensionActionContextMenuModel::MenuDelegate,
+      public ExtensionContextMenuModel::PopupDelegate,
       public ExtensionPopup::Observer {
    public:
     PageActionImageView(LocationBarView* owner,
@@ -439,9 +441,8 @@
     // Overridden from ImageLoadingTracker.
     virtual void OnImageLoaded(SkBitmap* image, size_t index);
 
-    // Overridden from ExtensionActionContextMenuModel::MenuDelegate
-    virtual void ShowPopupForDevToolsWindow(Extension* extension,
-        ExtensionAction* extension_action);
+    // Overridden from ExtensionContextMenuModelModel::Delegate
+    virtual void InspectPopup(ExtensionAction* action);
 
     // Overriden from ExtensionPopup::Observer
     virtual void ExtensionPopupClosed(ExtensionPopup* popup);
@@ -473,7 +474,8 @@
     PageActionMap page_action_icons_;
 
     // The context menu for this page action.
-    scoped_ptr<ExtensionActionContextMenu> context_menu_;
+    scoped_ptr<ExtensionContextMenuModel> context_menu_contents_;
+    scoped_ptr<views::Menu2> context_menu_menu_;
 
     // The object that is waiting for the image loading to complete
     // asynchronously.
@@ -572,6 +574,9 @@
   // Helper to show the first run info bubble.
   void ShowFirstRunBubbleInternal(bool use_OEM_bubble);
 
+  // Current browser. Not owned by us.
+  Browser* browser_;
+
   // Current profile. Not owned by us.
   Profile* profile_;
 
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index bb18a87..acbd591 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -912,8 +912,6 @@
         'browser/extensions/extension_accessibility_api.h',
         'browser/extensions/extension_accessibility_api_constants.cc',
         'browser/extensions/extension_accessibility_api_constants.h',
-        'browser/extensions/extension_action_context_menu_model.cc',
-        'browser/extensions/extension_action_context_menu_model.h',
         'browser/extensions/extension_bookmarks_module.cc',
         'browser/extensions/extension_bookmarks_module.h',
         'browser/extensions/extension_bookmarks_module_constants.cc',
@@ -924,6 +922,8 @@
         'browser/extensions/extension_browser_actions_api.h',
         'browser/extensions/extension_clipboard_api.cc',
         'browser/extensions/extension_clipboard_api.h',
+        'browser/extensions/extension_context_menu_model.cc',
+        'browser/extensions/extension_context_menu_model.h',
         'browser/extensions/extension_creator.cc',
         'browser/extensions/extension_creator.h',
         'browser/extensions/extension_disabled_infobar_delegate.cc',
@@ -2126,8 +2126,6 @@
         'browser/views/extensions/browser_action_drag_data.h',
         'browser/views/extensions/browser_action_overflow_menu_controller.cc',
         'browser/views/extensions/browser_action_overflow_menu_controller.h',
-        'browser/views/extensions/extension_action_context_menu.cc',
-        'browser/views/extensions/extension_action_context_menu.h',
         'browser/views/extensions/extension_install_prompt.cc',
         'browser/views/extensions/extension_installed_bubble.cc',
         'browser/views/extensions/extension_installed_bubble.h',
@@ -2734,8 +2732,6 @@
                 ['include', '^browser/views/extensions/browser_action_drag_data.h'],
                 ['include', '^browser/views/extensions/browser_action_overflow_menu_controller.cc'],
                 ['include', '^browser/views/extensions/browser_action_overflow_menu_controller.h'],
-                ['include', '^browser/views/extensions/extension_action_context_menu.cc'],
-                ['include', '^browser/views/extensions/extension_action_context_menu.h'],
                 ['include', '^browser/views/extensions/extension_install_prompt.cc'],
                 ['include', '^browser/views/extensions/extension_installed_bubble.cc'],
                 ['include', '^browser/views/extensions/extension_installed_bubble.h'],