extension_context_menu_model_unittest.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_context_menu_model.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/extensions/extension_service_test_base.h"
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/extensions/menu_manager.h"
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/extensions/menu_manager_factory.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/common/extensions/api/context_menus.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/test_browser_window.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/test_management_policy.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension_builder.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/value_builder.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionContextMenuModelTest : public ExtensionServiceTestBase {
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) public:
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ExtensionContextMenuModelTest();
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Build an extension to pass to the menu constructor.  It needs an
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // ExtensionAction.
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_refptr<Extension> BuildExtension();
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Creates an extension menu item for |extension| with the given |context|
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // and adds it to |manager|. Refreshes |model| to show new item.
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void AddContextItemAndRefreshModel(MenuManager* manager,
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                     Extension* extension,
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                     MenuItem::Context context,
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                     ExtensionContextMenuModel* model);
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Reinitializes the given |model|.
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void RefreshMenu(ExtensionContextMenuModel* model);
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Returns the number of extension menu items that show up in |model|.
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  int CountExtensionItems(ExtensionContextMenuModel* model);
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) private:
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  int cur_id_;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ExtensionContextMenuModelTest::ExtensionContextMenuModelTest() : cur_id_(0) {
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)scoped_refptr<Extension> ExtensionContextMenuModelTest::BuildExtension() {
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return ExtensionBuilder()
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      .SetManifest(DictionaryBuilder()
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                       .Set("name", "Page Action Extension")
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                       .Set("version", "1")
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                       .Set("manifest_version", 2)
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                       .Set("page_action",
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                            DictionaryBuilder().Set("default_title", "Hello")))
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      .Build();
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ExtensionContextMenuModelTest::AddContextItemAndRefreshModel(
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MenuManager* manager,
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Extension* extension,
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MenuItem::Context context,
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ExtensionContextMenuModel* model) {
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  MenuItem::Type type = MenuItem::NORMAL;
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  MenuItem::ContextList contexts(context);
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const MenuItem::ExtensionKey key(extension->id());
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  MenuItem::Id id(false, key);
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  id.uid = ++cur_id_;
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  manager->AddContextItem(extension,
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                          new MenuItem(id,
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                       "test",
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                       false,  // checked
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                       true,   // enabled
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                       type,
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                       contexts));
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RefreshMenu(model);
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ExtensionContextMenuModelTest::RefreshMenu(
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ExtensionContextMenuModel* model) {
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  model->InitMenu(model->GetExtension());
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)int ExtensionContextMenuModelTest::CountExtensionItems(
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ExtensionContextMenuModel* model) {
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return model->extension_items_count_;
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace {
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that applicable menu items are disabled when a ManagementPolicy
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// prohibits them.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionContextMenuModelTest, PolicyDisablesItems) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeEmptyExtensionService();
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_refptr<Extension> extension = BuildExtension();
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(extension.get());
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service_->AddExtension(extension.get());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a Browser for the ExtensionContextMenuModel to use.
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Browser::CreateParams params(profile_.get(), chrome::GetActiveDesktop());
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBrowserWindow test_window;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.window = &test_window;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser browser(params);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ExtensionContextMenuModel> menu(
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new ExtensionContextMenuModel(extension.get(), &browser));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions::ExtensionSystem* system =
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extensions::ExtensionSystem::Get(profile_.get());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  system->management_policy()->UnregisterAllProviders();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Actions should be enabled.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::UNINSTALL));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions::TestManagementPolicyProvider policy_provider(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  system->management_policy()->RegisterProvider(&policy_provider);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the actions are disabled.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(menu->IsCommandIdEnabled(ExtensionContextMenuModel::UNINSTALL));
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't leave |policy_provider| dangling.
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  system->management_policy()->UnregisterAllProviders();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ExtensionContextMenuModelTest, ExtensionItemTest) {
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  InitializeEmptyExtensionService();
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_refptr<Extension> extension = BuildExtension();
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_TRUE(extension.get());
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  service_->AddExtension(extension.get());
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Create a Browser for the ExtensionContextMenuModel to use.
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Browser::CreateParams params(profile_.get(), chrome::GetActiveDesktop());
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestBrowserWindow test_window;
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  params.window = &test_window;
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Browser browser(params);
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Create a MenuManager for adding context items.
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  MenuManager* manager = static_cast<MenuManager*>(
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      (MenuManagerFactory::GetInstance()->SetTestingFactoryAndUse(
1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          profile_.get(),
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          &MenuManagerFactory::BuildServiceInstanceForTesting)));
1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_TRUE(manager);
1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_refptr<ExtensionContextMenuModel> menu(
1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new ExtensionContextMenuModel(extension.get(), &browser));
1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // There should be no extension items yet.
1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(0, CountExtensionItems(menu));
1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Add a browser action menu item for |extension| to |manager|.
1566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  AddContextItemAndRefreshModel(
1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      manager, extension.get(), MenuItem::BROWSER_ACTION, menu);
1586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Since |extension| has a page action, the browser action menu item should
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // not be present.
1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(0, CountExtensionItems(menu));
1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Add a page action menu item and reset the context menu.
1646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  AddContextItemAndRefreshModel(
1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      manager, extension.get(), MenuItem::PAGE_ACTION, menu);
1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // The page action item should be present because |extension| has a page
1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // action.
1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(1, CountExtensionItems(menu));
1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Create more page action items to test top level menu item limitations.
1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (int i = 0; i < api::context_menus::ACTION_MENU_TOP_LEVEL_LIMIT; ++i)
1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    AddContextItemAndRefreshModel(
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        manager, extension.get(), MenuItem::PAGE_ACTION, menu);
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // The menu should only have a limited number of extension items, since they
1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // are all top level items, and we limit the number of top level extension
1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // items.
1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(api::context_menus::ACTION_MENU_TOP_LEVEL_LIMIT,
1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            CountExtensionItems(menu));
1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  AddContextItemAndRefreshModel(
1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      manager, extension.get(), MenuItem::PAGE_ACTION, menu);
1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Adding another top level item should not increase the count.
1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(api::context_menus::ACTION_MENU_TOP_LEVEL_LIMIT,
1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            CountExtensionItems(menu));
1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
192