Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 = false; | |
| 501 if (registrar_.IsRegistered( | |
| 502 this, | |
| 503 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, | |
| 504 content::Source<ExtensionPrefs>(extension_prefs_))) { | |
| 505 registered = true; | |
|
Finnur
2014/08/20 12:06:16
This is a little confusing, given that you remove
Devlin
2014/08/20 15:31:22
Done.
| |
| 506 registrar_.Remove( | |
| 507 this, | |
| 508 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, | |
| 509 content::Source<ExtensionPrefs>(extension_prefs_)); | |
| 510 } | |
| 511 ExtensionActionAPI::SetBrowserActionVisibility( | |
| 512 extension_prefs_, extension->id(), visible); | |
| 513 if (registered) { | |
| 514 registrar_.Add(this, | |
| 515 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, | |
| 516 content::Source<ExtensionPrefs>(extension_prefs_)); | |
| 517 } | |
| 518 } | |
| 519 } | |
| 520 } | |
| 521 | |
| 522 void ExtensionToolbarModel::MaybeUpdateVisibilityPrefs() { | |
| 523 for (size_t i = 0u; i < toolbar_items_.size(); ++i) | |
| 524 MaybeUpdateVisibilityPref(toolbar_items_[i], i); | |
| 525 } | |
| 526 | |
| 453 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) { | 527 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) { |
| 454 int original_index = 0, i = 0; | 528 int original_index = 0, i = 0; |
| 455 for (ExtensionList::iterator iter = toolbar_items_.begin(); | 529 for (ExtensionList::iterator iter = toolbar_items_.begin(); |
| 456 iter != toolbar_items_.end(); | 530 iter != toolbar_items_.end(); |
| 457 ++iter, ++original_index) { | 531 ++iter, ++original_index) { |
| 458 if (util::IsIncognitoEnabled((*iter)->id(), profile_)) { | 532 if (util::IsIncognitoEnabled((*iter)->id(), profile_)) { |
| 459 if (incognito_index == i) | 533 if (incognito_index == i) |
| 460 break; | 534 break; |
| 461 ++i; | 535 ++i; |
| 462 } | 536 } |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 is_highlighting_ = false; | 667 is_highlighting_ = false; |
| 594 if (old_visible_icon_count_ != visible_icon_count_) { | 668 if (old_visible_icon_count_ != visible_icon_count_) { |
| 595 SetVisibleIconCount(old_visible_icon_count_); | 669 SetVisibleIconCount(old_visible_icon_count_); |
| 596 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); | 670 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); |
| 597 } | 671 } |
| 598 FOR_EACH_OBSERVER(Observer, observers_, ToolbarHighlightModeChanged(false)); | 672 FOR_EACH_OBSERVER(Observer, observers_, ToolbarHighlightModeChanged(false)); |
| 599 } | 673 } |
| 600 } | 674 } |
| 601 | 675 |
| 602 } // namespace extensions | 676 } // namespace extensions |
| OLD | NEW |