Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Side by Side Diff: chrome/browser/extensions/extension_toolbar_model.cc

Issue 476873002: Make hiding an extension action cause it to go to the overflow menu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/extensions/extension_toolbar_model.h" 5 #include "chrome/browser/extensions/extension_toolbar_model.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/message_loop/message_loop.h"
9 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
10 #include "base/metrics/histogram_base.h" 11 #include "base/metrics/histogram_base.h"
11 #include "base/prefs/pref_service.h" 12 #include "base/prefs/pref_service.h"
12 #include "chrome/browser/chrome_notification_types.h" 13 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 14 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
14 #include "chrome/browser/extensions/extension_action_manager.h" 15 #include "chrome/browser/extensions/extension_action_manager.h"
15 #include "chrome/browser/extensions/extension_tab_util.h" 16 #include "chrome/browser/extensions/extension_tab_util.h"
16 #include "chrome/browser/extensions/extension_toolbar_model_factory.h" 17 #include "chrome/browser/extensions/extension_toolbar_model_factory.h"
17 #include "chrome/browser/extensions/extension_util.h" 18 #include "chrome/browser/extensions/extension_util.h"
18 #include "chrome/browser/extensions/tab_helper.h" 19 #include "chrome/browser/extensions/tab_helper.h"
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 if (!inserted) { 109 if (!inserted) {
109 DCHECK_EQ(index, static_cast<int>(toolbar_items_.size())); 110 DCHECK_EQ(index, static_cast<int>(toolbar_items_.size()));
110 index = toolbar_items_.size(); 111 index = toolbar_items_.size();
111 112
112 toolbar_items_.push_back(make_scoped_refptr(extension)); 113 toolbar_items_.push_back(make_scoped_refptr(extension));
113 last_known_positions_.push_back(extension->id()); 114 last_known_positions_.push_back(extension->id());
114 } 115 }
115 116
116 FOR_EACH_OBSERVER( 117 FOR_EACH_OBSERVER(
117 Observer, observers_, ToolbarExtensionMoved(extension, index)); 118 Observer, observers_, ToolbarExtensionMoved(extension, index));
118 119 MaybeUpdateVisibilityPref(extension, index);
119 UpdatePrefs(); 120 UpdatePrefs();
120 } 121 }
121 122
122 ExtensionAction::ShowAction ExtensionToolbarModel::ExecuteBrowserAction( 123 ExtensionAction::ShowAction ExtensionToolbarModel::ExecuteBrowserAction(
123 const Extension* extension, 124 const Extension* extension,
124 Browser* browser, 125 Browser* browser,
125 GURL* popup_url_out, 126 GURL* popup_url_out,
126 bool should_grant) { 127 bool should_grant) {
127 content::WebContents* web_contents = NULL; 128 content::WebContents* web_contents = NULL;
128 int tab_id = 0; 129 int tab_id = 0;
(...skipping 20 matching lines...) Expand all
149 } 150 }
150 151
151 ExtensionActionAPI::BrowserActionExecuted( 152 ExtensionActionAPI::BrowserActionExecuted(
152 browser->profile(), *browser_action, web_contents); 153 browser->profile(), *browser_action, web_contents);
153 return ExtensionAction::ACTION_NONE; 154 return ExtensionAction::ACTION_NONE;
154 } 155 }
155 156
156 void ExtensionToolbarModel::SetVisibleIconCount(int count) { 157 void ExtensionToolbarModel::SetVisibleIconCount(int count) {
157 visible_icon_count_ = 158 visible_icon_count_ =
158 count == static_cast<int>(toolbar_items_.size()) ? -1 : count; 159 count == static_cast<int>(toolbar_items_.size()) ? -1 : count;
160
159 // Only set the prefs if we're not in highlight mode. Highlight mode is 161 // Only set the prefs if we're not in highlight mode. Highlight mode is
160 // designed to be a transitory state, and should not persist across browser 162 // designed to be a transitory state, and should not persist across browser
161 // restarts (though it may be re-entered). 163 // restarts (though it may be re-entered).
162 if (!is_highlighting_) 164 if (!is_highlighting_) {
165 // Additionally, if we are using the new toolbar, any icons which are in the
166 // overflow menu are considered "hidden". But it so happens that the times
167 // we are likely to call SetVisibleIconCount() are also those when we are
168 // in flux. So wait for things to cool down before setting the prefs.
169 base::MessageLoop::current()->PostTask(
170 FROM_HERE,
171 base::Bind(&ExtensionToolbarModel::MaybeUpdateVisibilityPrefs,
172 weak_ptr_factory_.GetWeakPtr()));
163 prefs_->SetInteger(pref_names::kToolbarSize, visible_icon_count_); 173 prefs_->SetInteger(pref_names::kToolbarSize, visible_icon_count_);
174 }
164 } 175 }
165 176
166 void ExtensionToolbarModel::OnExtensionLoaded( 177 void ExtensionToolbarModel::OnExtensionLoaded(
167 content::BrowserContext* browser_context, 178 content::BrowserContext* browser_context,
168 const Extension* extension) { 179 const Extension* extension) {
169 // We don't want to add the same extension twice. It may have already been 180 // We don't want to add the same extension twice. It may have already been
170 // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user 181 // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user
171 // hides the browser action and then disables and enables the extension. 182 // hides the browser action and then disables and enables the extension.
172 for (size_t i = 0; i < toolbar_items_.size(); i++) { 183 for (size_t i = 0; i < toolbar_items_.size(); i++) {
173 if (toolbar_items_[i].get() == extension) 184 if (toolbar_items_[i].get() == extension)
(...skipping 23 matching lines...) Expand all
197 if (pos != last_known_positions_.end()) { 208 if (pos != last_known_positions_.end()) {
198 last_known_positions_.erase(pos); 209 last_known_positions_.erase(pos);
199 UpdatePrefs(); 210 UpdatePrefs();
200 } 211 }
201 } 212 }
202 213
203 void ExtensionToolbarModel::Observe( 214 void ExtensionToolbarModel::Observe(
204 int type, 215 int type,
205 const content::NotificationSource& source, 216 const content::NotificationSource& source,
206 const content::NotificationDetails& details) { 217 const content::NotificationDetails& details) {
207 DCHECK_EQ( 218 DCHECK_EQ(NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, type);
208 extensions::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
209 type);
210 const Extension* extension = 219 const Extension* extension =
211 ExtensionRegistry::Get(profile_)->GetExtensionById( 220 ExtensionRegistry::Get(profile_)->GetExtensionById(
212 *content::Details<const std::string>(details).ptr(), 221 *content::Details<const std::string>(details).ptr(),
213 ExtensionRegistry::EVERYTHING); 222 ExtensionRegistry::EVERYTHING);
214 if (ExtensionActionAPI::GetBrowserActionVisibility(extension_prefs_, 223
215 extension->id())) 224 bool visible = ExtensionActionAPI::GetBrowserActionVisibility(
216 AddExtension(extension); 225 extension_prefs_, extension->id());
217 else 226 // Hiding works differently with the new and old toolbars.
218 RemoveExtension(extension); 227 if (include_all_extensions_) {
228 int new_size = 0;
229 int new_index = 0;
230 if (visible) {
231 // If this action used to be hidden, we can't possible be showing all.
232 DCHECK_NE(-1, visible_icon_count_);
233 // Grow the bar by one and move the extension to the end of the visibles.
234 new_size = visible_icon_count_ + 1;
235 new_index = new_size - 1;
236 } else {
237 // If we're hiding one, we must be showing at least one.
238 DCHECK_NE(visible_icon_count_, 0);
239 // Shrink the bar by one and move the extension to the beginning of the
240 // overflow menu.
241 new_size = visible_icon_count_ == -1 ?
242 toolbar_items_.size() - 1 : visible_icon_count_ - 1;
243 new_index = new_size;
244 }
245 SetVisibleIconCount(new_size);
246 MoveExtensionIcon(extension, new_index);
247 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged());
248 } else { // Don't include all extensions.
249 if (visible)
250 AddExtension(extension);
251 else
252 RemoveExtension(extension);
253 }
219 } 254 }
220 255
221 void ExtensionToolbarModel::OnReady() { 256 void ExtensionToolbarModel::OnReady() {
222 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_); 257 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
223 InitializeExtensionList(registry->enabled_extensions()); 258 InitializeExtensionList(registry->enabled_extensions());
224 // Wait until the extension system is ready before observing any further 259 // Wait until the extension system is ready before observing any further
225 // changes so that the toolbar buttons can be shown in their stable ordering 260 // changes so that the toolbar buttons can be shown in their stable ordering
226 // taken from prefs. 261 // taken from prefs.
227 extension_registry_observer_.Add(registry); 262 extension_registry_observer_.Add(registry);
228 registrar_.Add( 263 registrar_.Add(
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 toolbar_items_.push_back(make_scoped_refptr(extension)); 327 toolbar_items_.push_back(make_scoped_refptr(extension));
293 } 328 }
294 } else { 329 } else {
295 // This is a never before seen extension, that was added to the end. Make 330 // This is a never before seen extension, that was added to the end. Make
296 // sure to reflect that. (|new_index| was set above.) 331 // sure to reflect that. (|new_index| was set above.)
297 toolbar_items_.push_back(make_scoped_refptr(extension)); 332 toolbar_items_.push_back(make_scoped_refptr(extension));
298 last_known_positions_.push_back(extension->id()); 333 last_known_positions_.push_back(extension->id());
299 UpdatePrefs(); 334 UpdatePrefs();
300 } 335 }
301 336
337 MaybeUpdateVisibilityPref(extension, new_index);
338
302 // If we're currently highlighting, then even though we add a browser action 339 // If we're currently highlighting, then even though we add a browser action
303 // to the full list (|toolbar_items_|, there won't be another *visible* 340 // to the full list (|toolbar_items_|, there won't be another *visible*
304 // browser action, which was what the observers care about. 341 // browser action, which was what the observers care about.
305 if (!is_highlighting_) { 342 if (!is_highlighting_) {
306 FOR_EACH_OBSERVER( 343 FOR_EACH_OBSERVER(
307 Observer, observers_, ToolbarExtensionAdded(extension, new_index)); 344 Observer, observers_, ToolbarExtensionAdded(extension, new_index));
308 } 345 }
309 } 346 }
310 347
311 void ExtensionToolbarModel::RemoveExtension(const Extension* extension) { 348 void ExtensionToolbarModel::RemoveExtension(const Extension* extension) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 // 1. Create a vector of extensions sorted by their pref values. This vector may 380 // 1. Create a vector of extensions sorted by their pref values. This vector may
344 // have holes. 381 // have holes.
345 // 2. Create a vector of extensions that did not have a pref value. 382 // 2. Create a vector of extensions that did not have a pref value.
346 // 3. Remove holes from the sorted vector and append the unsorted vector. 383 // 3. Remove holes from the sorted vector and append the unsorted vector.
347 void ExtensionToolbarModel::InitializeExtensionList( 384 void ExtensionToolbarModel::InitializeExtensionList(
348 const ExtensionSet& extensions) { 385 const ExtensionSet& extensions) {
349 last_known_positions_ = extension_prefs_->GetToolbarOrder(); 386 last_known_positions_ = extension_prefs_->GetToolbarOrder();
350 Populate(last_known_positions_, extensions); 387 Populate(last_known_positions_, extensions);
351 388
352 extensions_initialized_ = true; 389 extensions_initialized_ = true;
390 MaybeUpdateVisibilityPrefs();
353 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); 391 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged());
354 } 392 }
355 393
356 void ExtensionToolbarModel::Populate(const ExtensionIdList& positions, 394 void ExtensionToolbarModel::Populate(const ExtensionIdList& positions,
357 const ExtensionSet& extensions) { 395 const ExtensionSet& extensions) {
358 // Items that have explicit positions. 396 // Items that have explicit positions.
359 ExtensionList sorted; 397 ExtensionList sorted;
360 sorted.resize(positions.size(), NULL); 398 sorted.resize(positions.size(), NULL);
361 // The items that don't have explicit positions. 399 // The items that don't have explicit positions.
362 ExtensionList unsorted; 400 ExtensionList unsorted;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 void ExtensionToolbarModel::UpdatePrefs() { 481 void ExtensionToolbarModel::UpdatePrefs() {
444 if (!extension_prefs_) 482 if (!extension_prefs_)
445 return; 483 return;
446 484
447 // Don't observe change caused by self. 485 // Don't observe change caused by self.
448 pref_change_registrar_.Remove(pref_names::kToolbar); 486 pref_change_registrar_.Remove(pref_names::kToolbar);
449 extension_prefs_->SetToolbarOrder(last_known_positions_); 487 extension_prefs_->SetToolbarOrder(last_known_positions_);
450 pref_change_registrar_.Add(pref_names::kToolbar, pref_change_callback_); 488 pref_change_registrar_.Add(pref_names::kToolbar, pref_change_callback_);
451 } 489 }
452 490
491 void ExtensionToolbarModel::MaybeUpdateVisibilityPref(
492 const Extension* extension, int index) {
493 // We only update the visibility pref for hidden/not hidden based on the
494 // overflow menu with the new toolbar design.
495 if (include_all_extensions_) {
496 bool visible = index < visible_icon_count_ || visible_icon_count_ == -1;
497 if (visible != ExtensionActionAPI::GetBrowserActionVisibility(
498 extension_prefs_, extension->id())) {
499 // Don't observe changes caused by ourselves.
500 bool registered = !registrar_.IsEmpty();
501 registrar_.RemoveAll(); // Cheat since we only have one notification.
Finnur 2014/08/19 10:18:04 Seems like you aren't saving much with this. Why n
Devlin 2014/08/19 16:54:39 sigh... probably for the best. But typing NOTIFIC
Finnur 2014/08/20 12:06:16 That's why they invented the clipboard! ;)
Devlin 2014/08/20 15:31:22 :P
502 ExtensionActionAPI::SetBrowserActionVisibility(
503 extension_prefs_, extension->id(), visible);
504 if (registered) {
505 registrar_.Add(this,
506 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
507 content::Source<ExtensionPrefs>(extension_prefs_));
508 }
509 }
510 }
511 }
512
513 void ExtensionToolbarModel::MaybeUpdateVisibilityPrefs() {
514 for (size_t i = 0u; i < toolbar_items_.size(); ++i)
515 MaybeUpdateVisibilityPref(toolbar_items_[i], i);
516 }
517
453 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) { 518 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) {
454 int original_index = 0, i = 0; 519 int original_index = 0, i = 0;
455 for (ExtensionList::iterator iter = toolbar_items_.begin(); 520 for (ExtensionList::iterator iter = toolbar_items_.begin();
456 iter != toolbar_items_.end(); 521 iter != toolbar_items_.end();
457 ++iter, ++original_index) { 522 ++iter, ++original_index) {
458 if (util::IsIncognitoEnabled((*iter)->id(), profile_)) { 523 if (util::IsIncognitoEnabled((*iter)->id(), profile_)) {
459 if (incognito_index == i) 524 if (incognito_index == i)
460 break; 525 break;
461 ++i; 526 ++i;
462 } 527 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 is_highlighting_ = false; 658 is_highlighting_ = false;
594 if (old_visible_icon_count_ != visible_icon_count_) { 659 if (old_visible_icon_count_ != visible_icon_count_) {
595 SetVisibleIconCount(old_visible_icon_count_); 660 SetVisibleIconCount(old_visible_icon_count_);
596 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); 661 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged());
597 } 662 }
598 FOR_EACH_OBSERVER(Observer, observers_, ToolbarHighlightModeChanged(false)); 663 FOR_EACH_OBSERVER(Observer, observers_, ToolbarHighlightModeChanged(false));
599 } 664 }
600 } 665 }
601 666
602 } // namespace extensions 667 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698