OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/macros.h" | 5 #include "base/macros.h" |
6 #include "base/memory/ref_counted.h" | 6 #include "base/memory/ref_counted.h" |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" | 8 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
| 9 #include "chrome/browser/extensions/extension_action_manager.h" |
9 #include "chrome/browser/extensions/extension_service.h" | 10 #include "chrome/browser/extensions/extension_service.h" |
10 #include "chrome/browser/extensions/extension_service_test_base.h" | 11 #include "chrome/browser/extensions/extension_service_test_base.h" |
11 #include "chrome/browser/extensions/extension_toolbar_model.h" | 12 #include "chrome/browser/extensions/extension_toolbar_model.h" |
12 #include "chrome/browser/extensions/extension_toolbar_model_factory.h" | 13 #include "chrome/browser/extensions/extension_toolbar_model_factory.h" |
13 #include "chrome/browser/extensions/test_extension_system.h" | 14 #include "chrome/browser/extensions/test_extension_system.h" |
14 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
| 16 #include "chrome/browser/sessions/session_tab_helper.h" |
15 #include "chrome/common/extensions/api/extension_action/action_info.h" | 17 #include "chrome/common/extensions/api/extension_action/action_info.h" |
16 #include "components/crx_file/id_util.h" | 18 #include "components/crx_file/id_util.h" |
| 19 #include "content/public/test/web_contents_tester.h" |
17 #include "extensions/browser/extension_prefs.h" | 20 #include "extensions/browser/extension_prefs.h" |
18 #include "extensions/browser/extension_registry.h" | 21 #include "extensions/browser/extension_registry.h" |
19 #include "extensions/browser/extension_system.h" | 22 #include "extensions/browser/extension_system.h" |
20 #include "extensions/common/extension.h" | 23 #include "extensions/common/extension.h" |
21 #include "extensions/common/extension_builder.h" | 24 #include "extensions/common/extension_builder.h" |
22 #include "extensions/common/feature_switch.h" | 25 #include "extensions/common/feature_switch.h" |
23 #include "extensions/common/manifest_constants.h" | 26 #include "extensions/common/manifest_constants.h" |
24 #include "extensions/common/value_builder.h" | 27 #include "extensions/common/value_builder.h" |
25 | 28 |
26 namespace extensions { | 29 namespace extensions { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 class ExtensionToolbarModelTestObserver | 84 class ExtensionToolbarModelTestObserver |
82 : public ExtensionToolbarModel::Observer { | 85 : public ExtensionToolbarModel::Observer { |
83 public: | 86 public: |
84 explicit ExtensionToolbarModelTestObserver(ExtensionToolbarModel* model); | 87 explicit ExtensionToolbarModelTestObserver(ExtensionToolbarModel* model); |
85 ~ExtensionToolbarModelTestObserver() override; | 88 ~ExtensionToolbarModelTestObserver() override; |
86 | 89 |
87 size_t inserted_count() const { return inserted_count_; } | 90 size_t inserted_count() const { return inserted_count_; } |
88 size_t removed_count() const { return removed_count_; } | 91 size_t removed_count() const { return removed_count_; } |
89 size_t moved_count() const { return moved_count_; } | 92 size_t moved_count() const { return moved_count_; } |
90 int highlight_mode_count() const { return highlight_mode_count_; } | 93 int highlight_mode_count() const { return highlight_mode_count_; } |
| 94 size_t reorder_count() const { return reorder_count_; } |
91 | 95 |
92 private: | 96 private: |
93 // ExtensionToolbarModel::Observer: | 97 // ExtensionToolbarModel::Observer: |
94 void ToolbarExtensionAdded(const Extension* extension, int index) override { | 98 void ToolbarExtensionAdded(const Extension* extension, int index) override { |
95 ++inserted_count_; | 99 ++inserted_count_; |
96 } | 100 } |
97 | 101 |
98 void ToolbarExtensionRemoved(const Extension* extension) override { | 102 void ToolbarExtensionRemoved(const Extension* extension) override { |
99 ++removed_count_; | 103 ++removed_count_; |
100 } | 104 } |
101 | 105 |
102 void ToolbarExtensionMoved(const Extension* extension, int index) override { | 106 void ToolbarExtensionMoved(const Extension* extension, int index) override { |
103 ++moved_count_; | 107 ++moved_count_; |
104 } | 108 } |
105 | 109 |
106 void ToolbarExtensionUpdated(const Extension* extension) override {} | 110 void ToolbarExtensionUpdated(const Extension* extension) override {} |
107 | 111 |
108 bool ShowExtensionActionPopup(const Extension* extension, | 112 bool ShowExtensionActionPopup(const Extension* extension, |
109 bool grant_active_tab) override { | 113 bool grant_active_tab) override { |
110 return false; | 114 return false; |
111 } | 115 } |
112 | 116 |
113 void ToolbarVisibleCountChanged() override {} | 117 void ToolbarVisibleCountChanged() override {} |
114 | 118 |
115 void ToolbarHighlightModeChanged(bool is_highlighting) override { | 119 void ToolbarHighlightModeChanged(bool is_highlighting) override { |
116 // Add one if highlighting, subtract one if not. | 120 // Add one if highlighting, subtract one if not. |
117 highlight_mode_count_ += is_highlighting ? 1 : -1; | 121 highlight_mode_count_ += is_highlighting ? 1 : -1; |
118 } | 122 } |
119 | 123 |
| 124 void ToolbarReorderNecessary(content::WebContents* web_contents) override { |
| 125 ++reorder_count_; |
| 126 } |
| 127 |
120 Browser* GetBrowser() override { return NULL; } | 128 Browser* GetBrowser() override { return NULL; } |
121 | 129 |
122 ExtensionToolbarModel* model_; | 130 ExtensionToolbarModel* model_; |
123 | 131 |
124 size_t inserted_count_; | 132 size_t inserted_count_; |
125 size_t removed_count_; | 133 size_t removed_count_; |
126 size_t moved_count_; | 134 size_t moved_count_; |
127 // Int because it could become negative (if something goes wrong). | 135 // Int because it could become negative (if something goes wrong). |
128 int highlight_mode_count_; | 136 int highlight_mode_count_; |
| 137 size_t reorder_count_; |
129 }; | 138 }; |
130 | 139 |
131 ExtensionToolbarModelTestObserver::ExtensionToolbarModelTestObserver( | 140 ExtensionToolbarModelTestObserver::ExtensionToolbarModelTestObserver( |
132 ExtensionToolbarModel* model) : model_(model), | 141 ExtensionToolbarModel* model) : model_(model), |
133 inserted_count_(0u), | 142 inserted_count_(0u), |
134 removed_count_(0u), | 143 removed_count_(0u), |
135 moved_count_(0u), | 144 moved_count_(0u), |
136 highlight_mode_count_(0) { | 145 highlight_mode_count_(0), |
| 146 reorder_count_(0u) { |
137 model_->AddObserver(this); | 147 model_->AddObserver(this); |
138 } | 148 } |
139 | 149 |
140 ExtensionToolbarModelTestObserver::~ExtensionToolbarModelTestObserver() { | 150 ExtensionToolbarModelTestObserver::~ExtensionToolbarModelTestObserver() { |
141 model_->RemoveObserver(this); | 151 model_->RemoveObserver(this); |
142 } | 152 } |
143 | 153 |
144 } // namespace | 154 } // namespace |
145 | 155 |
146 class ExtensionToolbarModelUnitTest : public ExtensionServiceTestBase { | 156 class ExtensionToolbarModelUnitTest : public ExtensionServiceTestBase { |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 // Resetting B to be visible should make the order C A B, with no overflow. | 921 // Resetting B to be visible should make the order C A B, with no overflow. |
912 ExtensionActionAPI::SetBrowserActionVisibility( | 922 ExtensionActionAPI::SetBrowserActionVisibility( |
913 prefs, extension_b->id(), true); | 923 prefs, extension_b->id(), true); |
914 EXPECT_EQ(3u, num_toolbar_items()); | 924 EXPECT_EQ(3u, num_toolbar_items()); |
915 EXPECT_EQ(-1, toolbar_model()->GetVisibleIconCount()); // -1 = 'all' | 925 EXPECT_EQ(-1, toolbar_model()->GetVisibleIconCount()); // -1 = 'all' |
916 EXPECT_EQ(extension_c, GetExtensionAtIndex(0u)); | 926 EXPECT_EQ(extension_c, GetExtensionAtIndex(0u)); |
917 EXPECT_EQ(extension_a, GetExtensionAtIndex(1u)); | 927 EXPECT_EQ(extension_a, GetExtensionAtIndex(1u)); |
918 EXPECT_EQ(extension_b, GetExtensionAtIndex(2u)); | 928 EXPECT_EQ(extension_b, GetExtensionAtIndex(2u)); |
919 } | 929 } |
920 | 930 |
| 931 // Test that toolbar actions can pop themselves out of overflow if they want |
| 932 // to act on a given web contents. |
| 933 TEST_F(ExtensionToolbarModelUnitTest, ToolbarActionsPopOutToAct) { |
| 934 // Extensions popping themselves out to act is part of the toolbar redesign, |
| 935 // and hidden behind a flag. |
| 936 FeatureSwitch::ScopedOverride enable_redesign( |
| 937 FeatureSwitch::extension_action_redesign(), true); |
| 938 Init(); |
| 939 |
| 940 ASSERT_TRUE(AddActionExtensions()); |
| 941 |
| 942 // We should start in the order of "browser action" "page action" "no action" |
| 943 // and have all extensions visible. |
| 944 EXPECT_EQ(3u, num_toolbar_items()); |
| 945 EXPECT_EQ(-1, toolbar_model()->GetVisibleIconCount()); // -1 = 'all'. |
| 946 EXPECT_EQ(browser_action(), GetExtensionAtIndex(0u)); |
| 947 EXPECT_EQ(page_action(), GetExtensionAtIndex(1u)); |
| 948 EXPECT_EQ(no_action(), GetExtensionAtIndex(2u)); |
| 949 |
| 950 // Shrink the model to only show one action, and move the page action to the |
| 951 // end. |
| 952 toolbar_model()->SetVisibleIconCount(1); |
| 953 toolbar_model()->MoveExtensionIcon(page_action()->id(), 2u); |
| 954 |
| 955 // Quickly verify that the move/visible count worked. |
| 956 EXPECT_EQ(1, toolbar_model()->GetVisibleIconCount()); |
| 957 EXPECT_EQ(browser_action(), GetExtensionAtIndex(0u)); |
| 958 EXPECT_EQ(no_action(), GetExtensionAtIndex(1u)); |
| 959 EXPECT_EQ(page_action(), GetExtensionAtIndex(2u)); |
| 960 |
| 961 // Create two test web contents, and a session tab helper for each. We need |
| 962 // a session tab helper, since we rely on tab ids. |
| 963 content::WebContents* web_contents = |
| 964 content::WebContentsTester::CreateTestWebContents(profile(), NULL); |
| 965 ASSERT_TRUE(web_contents); |
| 966 SessionTabHelper::CreateForWebContents(web_contents); |
| 967 content::WebContents* second_web_contents = |
| 968 content::WebContentsTester::CreateTestWebContents(profile(), NULL); |
| 969 ASSERT_TRUE(second_web_contents); |
| 970 SessionTabHelper::CreateForWebContents(second_web_contents); |
| 971 |
| 972 // Find the tab ids, ensure that the two web contents have different ids, and |
| 973 // verify that neither is -1 (invalid). |
| 974 int tab_id = SessionTabHelper::IdForTab(web_contents); |
| 975 int second_tab_id = SessionTabHelper::IdForTab(second_web_contents); |
| 976 EXPECT_NE(tab_id, second_tab_id); |
| 977 EXPECT_NE(-1, second_tab_id); |
| 978 EXPECT_NE(-1, tab_id); |
| 979 |
| 980 // First, check the model order for the first tab. Since we haven't changed |
| 981 // anything (i.e., no extensions want to act), this should be the same as we |
| 982 // left it: "browser action", "no action", "page action", with only one |
| 983 // visible. |
| 984 ExtensionList tab_order = toolbar_model()->GetItemOrderForTab(web_contents); |
| 985 ASSERT_EQ(3u, tab_order.size()); |
| 986 EXPECT_EQ(browser_action(), tab_order[0]); |
| 987 EXPECT_EQ(no_action(), tab_order[1]); |
| 988 EXPECT_EQ(page_action(), tab_order[2]); |
| 989 EXPECT_EQ(1, toolbar_model()->GetVisibleIconCountForTab(web_contents)); |
| 990 // And we should have no notifications to reorder the toolbar. |
| 991 EXPECT_EQ(0u, observer()->reorder_count()); |
| 992 |
| 993 // Make "page action" want to act by making it's page action visible on the |
| 994 // first tab, and notify the API of the change. |
| 995 ExtensionActionManager* action_manager = |
| 996 ExtensionActionManager::Get(profile()); |
| 997 ExtensionAction* action = action_manager->GetExtensionAction(*page_action()); |
| 998 ASSERT_TRUE(action); |
| 999 action->SetIsVisible(tab_id, true); |
| 1000 ExtensionActionAPI* extension_action_api = ExtensionActionAPI::Get(profile()); |
| 1001 extension_action_api->NotifyChange(action, web_contents, profile()); |
| 1002 |
| 1003 // This should result in "page action" being popped out of the overflow menu. |
| 1004 // This has two visible effects: |
| 1005 // - page action should move to the second index (the one right after the last |
| 1006 // originally-visible). |
| 1007 // - The visible count should increase by one (so page action is visible). |
| 1008 tab_order = toolbar_model()->GetItemOrderForTab(web_contents); |
| 1009 ASSERT_EQ(3u, tab_order.size()); |
| 1010 EXPECT_EQ(browser_action(), tab_order[0]); |
| 1011 EXPECT_EQ(page_action(), tab_order[1]); |
| 1012 EXPECT_EQ(no_action(), tab_order[2]); |
| 1013 EXPECT_EQ(2, toolbar_model()->GetVisibleIconCountForTab(web_contents)); |
| 1014 // We should also have been told to reorder the toolbar. |
| 1015 EXPECT_EQ(1u, observer()->reorder_count()); |
| 1016 |
| 1017 // This should not have any effect on the second tab, which should still have |
| 1018 // the original order and visible count. |
| 1019 tab_order = toolbar_model()->GetItemOrderForTab(second_web_contents); |
| 1020 ASSERT_EQ(3u, tab_order.size()); |
| 1021 EXPECT_EQ(browser_action(), tab_order[0]); |
| 1022 EXPECT_EQ(no_action(), tab_order[1]); |
| 1023 EXPECT_EQ(page_action(), tab_order[2]); |
| 1024 EXPECT_EQ(1, toolbar_model()->GetVisibleIconCountForTab(second_web_contents)); |
| 1025 |
| 1026 // Now, set the action to be hidden again, and notify of the change. |
| 1027 action->SetIsVisible(tab_id, false); |
| 1028 extension_action_api->NotifyChange(action, web_contents, profile()); |
| 1029 // The order and visible count should return to normal (the page action should |
| 1030 // move back to its original index in overflow). So, order should be "browser |
| 1031 // action", "no action", "page action". |
| 1032 tab_order = toolbar_model()->GetItemOrderForTab(web_contents); |
| 1033 ASSERT_EQ(3u, tab_order.size()); |
| 1034 EXPECT_EQ(browser_action(), tab_order[0]); |
| 1035 EXPECT_EQ(no_action(), tab_order[1]); |
| 1036 EXPECT_EQ(page_action(), tab_order[2]); |
| 1037 EXPECT_EQ(1, toolbar_model()->GetVisibleIconCountForTab(web_contents)); |
| 1038 // This should also result in a reorder. |
| 1039 EXPECT_EQ(2u, observer()->reorder_count()); |
| 1040 |
| 1041 // Move page action to the first index (so it's naturally visible), and make |
| 1042 // it want to act. |
| 1043 toolbar_model()->MoveExtensionIcon(page_action()->id(), 0u); |
| 1044 action->SetIsVisible(tab_id, true); |
| 1045 extension_action_api->NotifyChange(action, web_contents, profile()); |
| 1046 // Since the action is already visible, this should have no effect - the order |
| 1047 // and visible count should remain unchanged. Order is "page action", "browser |
| 1048 // action", "no action". |
| 1049 tab_order = toolbar_model()->GetItemOrderForTab(web_contents); |
| 1050 ASSERT_EQ(3u, tab_order.size()); |
| 1051 EXPECT_EQ(page_action(), tab_order[0]); |
| 1052 EXPECT_EQ(browser_action(), tab_order[1]); |
| 1053 EXPECT_EQ(no_action(), tab_order[2]); |
| 1054 EXPECT_EQ(1, toolbar_model()->GetVisibleIconCountForTab(web_contents)); |
| 1055 |
| 1056 // We should still be able to increase the size of the model, and to move the |
| 1057 // page action. |
| 1058 toolbar_model()->SetVisibleIconCount(2); |
| 1059 toolbar_model()->MoveExtensionIcon(page_action()->id(), 1u); |
| 1060 tab_order = toolbar_model()->GetItemOrderForTab(web_contents); |
| 1061 ASSERT_EQ(3u, tab_order.size()); |
| 1062 EXPECT_EQ(browser_action(), tab_order[0]); |
| 1063 EXPECT_EQ(page_action(), tab_order[1]); |
| 1064 EXPECT_EQ(no_action(), tab_order[2]); |
| 1065 EXPECT_EQ(2, toolbar_model()->GetVisibleIconCountForTab(web_contents)); |
| 1066 |
| 1067 // Neither of the above operations should have precipitated a reorder. |
| 1068 EXPECT_EQ(2u, observer()->reorder_count()); |
| 1069 |
| 1070 // If we moved the page action, the move should remain in effect even after |
| 1071 // the action no longer wants to act. |
| 1072 action->SetIsVisible(tab_id, false); |
| 1073 extension_action_api->NotifyChange(action, web_contents, profile()); |
| 1074 tab_order = toolbar_model()->GetItemOrderForTab(web_contents); |
| 1075 ASSERT_EQ(3u, tab_order.size()); |
| 1076 EXPECT_EQ(browser_action(), tab_order[0]); |
| 1077 EXPECT_EQ(page_action(), tab_order[1]); |
| 1078 EXPECT_EQ(no_action(), tab_order[2]); |
| 1079 EXPECT_EQ(2, toolbar_model()->GetVisibleIconCountForTab(web_contents)); |
| 1080 // The above change should *not* require a reorder, because the extension is |
| 1081 // in a new, visible spot and doesn't need to change its position. |
| 1082 EXPECT_EQ(2u, observer()->reorder_count()); |
| 1083 } |
| 1084 |
921 } // namespace extensions | 1085 } // namespace extensions |
OLD | NEW |