| 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/ui/toolbar/toolbar_actions_model.h" | 5 #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "chrome/browser/ui/toolbar/toolbar_actions_model_factory.h" | 29 #include "chrome/browser/ui/toolbar/toolbar_actions_model_factory.h" |
| 30 #include "components/prefs/pref_service.h" | 30 #include "components/prefs/pref_service.h" |
| 31 #include "content/public/browser/notification_details.h" | 31 #include "content/public/browser/notification_details.h" |
| 32 #include "content/public/browser/notification_source.h" | 32 #include "content/public/browser/notification_source.h" |
| 33 #include "content/public/browser/web_contents.h" | 33 #include "content/public/browser/web_contents.h" |
| 34 #include "extensions/browser/extension_registry.h" | 34 #include "extensions/browser/extension_registry.h" |
| 35 #include "extensions/browser/extension_system.h" | 35 #include "extensions/browser/extension_system.h" |
| 36 #include "extensions/browser/extension_util.h" | 36 #include "extensions/browser/extension_util.h" |
| 37 #include "extensions/browser/pref_names.h" | 37 #include "extensions/browser/pref_names.h" |
| 38 #include "extensions/common/extension_set.h" | 38 #include "extensions/common/extension_set.h" |
| 39 #include "extensions/common/feature_switch.h" | |
| 40 #include "extensions/common/manifest_constants.h" | 39 #include "extensions/common/manifest_constants.h" |
| 41 #include "extensions/common/one_shot_event.h" | 40 #include "extensions/common/one_shot_event.h" |
| 42 | 41 |
| 43 ToolbarActionsModel::ToolbarActionsModel( | 42 ToolbarActionsModel::ToolbarActionsModel( |
| 44 Profile* profile, | 43 Profile* profile, |
| 45 extensions::ExtensionPrefs* extension_prefs) | 44 extensions::ExtensionPrefs* extension_prefs) |
| 46 : profile_(profile), | 45 : profile_(profile), |
| 47 extension_prefs_(extension_prefs), | 46 extension_prefs_(extension_prefs), |
| 48 prefs_(profile_->GetPrefs()), | 47 prefs_(profile_->GetPrefs()), |
| 49 extension_action_api_(extensions::ExtensionActionAPI::Get(profile_)), | 48 extension_action_api_(extensions::ExtensionActionAPI::Get(profile_)), |
| 50 extension_registry_(extensions::ExtensionRegistry::Get(profile_)), | 49 extension_registry_(extensions::ExtensionRegistry::Get(profile_)), |
| 51 extension_action_manager_( | 50 extension_action_manager_( |
| 52 extensions::ExtensionActionManager::Get(profile_)), | 51 extensions::ExtensionActionManager::Get(profile_)), |
| 53 component_actions_factory_( | 52 component_actions_factory_( |
| 54 base::MakeUnique<ComponentToolbarActionsFactory>(profile_)), | 53 base::MakeUnique<ComponentToolbarActionsFactory>(profile_)), |
| 55 actions_initialized_(false), | 54 actions_initialized_(false), |
| 56 use_redesign_( | |
| 57 extensions::FeatureSwitch::extension_action_redesign()->IsEnabled()), | |
| 58 highlight_type_(HIGHLIGHT_NONE), | 55 highlight_type_(HIGHLIGHT_NONE), |
| 59 has_active_bubble_(false), | 56 has_active_bubble_(false), |
| 60 extension_action_observer_(this), | 57 extension_action_observer_(this), |
| 61 extension_registry_observer_(this), | 58 extension_registry_observer_(this), |
| 62 weak_ptr_factory_(this) { | 59 weak_ptr_factory_(this) { |
| 63 extensions::ExtensionSystem::Get(profile_)->ready().Post( | 60 extensions::ExtensionSystem::Get(profile_)->ready().Post( |
| 64 FROM_HERE, base::Bind(&ToolbarActionsModel::OnReady, | 61 FROM_HERE, base::Bind(&ToolbarActionsModel::OnReady, |
| 65 weak_ptr_factory_.GetWeakPtr())); | 62 weak_ptr_factory_.GetWeakPtr())); |
| 66 visible_icon_count_ = | 63 visible_icon_count_ = |
| 67 prefs_->GetInteger(extensions::pref_names::kToolbarSize); | 64 prefs_->GetInteger(extensions::pref_names::kToolbarSize); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 const extensions::Extension* extension = GetExtensionById(item.id); | 181 const extensions::Extension* extension = GetExtensionById(item.id); |
| 185 DCHECK(extension); | 182 DCHECK(extension); |
| 186 | 183 |
| 187 // Create and add an ExtensionActionViewController for the extension. | 184 // Create and add an ExtensionActionViewController for the extension. |
| 188 result = base::MakeUnique<ExtensionActionViewController>( | 185 result = base::MakeUnique<ExtensionActionViewController>( |
| 189 extension, browser, | 186 extension, browser, |
| 190 extension_action_manager_->GetExtensionAction(*extension), bar); | 187 extension_action_manager_->GetExtensionAction(*extension), bar); |
| 191 break; | 188 break; |
| 192 } | 189 } |
| 193 case COMPONENT_ACTION: { | 190 case COMPONENT_ACTION: { |
| 194 DCHECK(use_redesign_); | |
| 195 result = component_actions_factory_->GetComponentToolbarActionForId( | 191 result = component_actions_factory_->GetComponentToolbarActionForId( |
| 196 item.id, browser, bar); | 192 item.id, browser, bar); |
| 197 break; | 193 break; |
| 198 } | 194 } |
| 199 case UNKNOWN_ACTION: | 195 case UNKNOWN_ACTION: |
| 200 NOTREACHED(); // Should never have an UNKNOWN_ACTION in toolbar_items. | 196 NOTREACHED(); // Should never have an UNKNOWN_ACTION in toolbar_items. |
| 201 break; | 197 break; |
| 202 } | 198 } |
| 203 return result; | 199 return result; |
| 204 } | 200 } |
| 205 | 201 |
| 206 void ToolbarActionsModel::OnExtensionActionVisibilityChanged( | |
| 207 const std::string& extension_id, | |
| 208 bool is_now_visible) { | |
| 209 if (use_redesign_) | |
| 210 return; | |
| 211 const extensions::Extension* extension = GetExtensionById(extension_id); | |
| 212 if (is_now_visible) | |
| 213 AddExtension(extension); | |
| 214 else | |
| 215 RemoveExtension(extension); | |
| 216 } | |
| 217 | |
| 218 void ToolbarActionsModel::OnExtensionLoaded( | 202 void ToolbarActionsModel::OnExtensionLoaded( |
| 219 content::BrowserContext* browser_context, | 203 content::BrowserContext* browser_context, |
| 220 const extensions::Extension* extension) { | 204 const extensions::Extension* extension) { |
| 221 // We don't want to add the same extension twice. It may have already been | 205 // We don't want to add the same extension twice. It may have already been |
| 222 // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user | 206 // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user |
| 223 // hides the browser action and then disables and enables the extension. | 207 // hides the browser action and then disables and enables the extension. |
| 224 if (!HasItem(ToolbarItem(extension->id(), EXTENSION_ACTION))) | 208 if (!HasItem(ToolbarItem(extension->id(), EXTENSION_ACTION))) |
| 225 AddExtension(extension); | 209 AddExtension(extension); |
| 226 } | 210 } |
| 227 | 211 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 // Wait until the extension system is ready before observing any further | 248 // Wait until the extension system is ready before observing any further |
| 265 // changes so that the toolbar buttons can be shown in their stable ordering | 249 // changes so that the toolbar buttons can be shown in their stable ordering |
| 266 // taken from prefs. | 250 // taken from prefs. |
| 267 extension_registry_observer_.Add(extension_registry_); | 251 extension_registry_observer_.Add(extension_registry_); |
| 268 extension_action_observer_.Add(extension_action_api_); | 252 extension_action_observer_.Add(extension_action_api_); |
| 269 | 253 |
| 270 actions_initialized_ = true; | 254 actions_initialized_ = true; |
| 271 for (Observer& observer : observers_) | 255 for (Observer& observer : observers_) |
| 272 observer.OnToolbarModelInitialized(); | 256 observer.OnToolbarModelInitialized(); |
| 273 | 257 |
| 274 if (use_redesign_) { | 258 component_actions_factory_->UnloadMigratedExtensions( |
| 275 component_actions_factory_->UnloadMigratedExtensions( | 259 extensions::ExtensionSystem::Get(profile_)->extension_service(), |
| 276 extensions::ExtensionSystem::Get(profile_)->extension_service(), | 260 extension_registry_); |
| 277 extension_registry_); | |
| 278 } | |
| 279 } | 261 } |
| 280 | 262 |
| 281 size_t ToolbarActionsModel::FindNewPositionFromLastKnownGood( | 263 size_t ToolbarActionsModel::FindNewPositionFromLastKnownGood( |
| 282 const ToolbarItem& action) { | 264 const ToolbarItem& action) { |
| 283 // See if we have last known good position for this action. | 265 // See if we have last known good position for this action. |
| 284 size_t new_index = 0; | 266 size_t new_index = 0; |
| 285 // Loop through the ID list of known positions, to count the number of | 267 // Loop through the ID list of known positions, to count the number of |
| 286 // visible action icons preceding |action|'s id. | 268 // visible action icons preceding |action|'s id. |
| 287 for (const std::string& last_pos_id : last_known_positions_) { | 269 for (const std::string& last_pos_id : last_known_positions_) { |
| 288 if (last_pos_id == action.id) | 270 if (last_pos_id == action.id) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 301 return toolbar_items_.size(); | 283 return toolbar_items_.size(); |
| 302 } | 284 } |
| 303 | 285 |
| 304 bool ToolbarActionsModel::ShouldAddExtension( | 286 bool ToolbarActionsModel::ShouldAddExtension( |
| 305 const extensions::Extension* extension) { | 287 const extensions::Extension* extension) { |
| 306 // In incognito mode, don't add any extensions that aren't incognito-enabled. | 288 // In incognito mode, don't add any extensions that aren't incognito-enabled. |
| 307 if (profile_->IsOffTheRecord() && | 289 if (profile_->IsOffTheRecord() && |
| 308 !extensions::util::IsIncognitoEnabled(extension->id(), profile_)) | 290 !extensions::util::IsIncognitoEnabled(extension->id(), profile_)) |
| 309 return false; | 291 return false; |
| 310 | 292 |
| 311 if (use_redesign_) { | 293 // In this case, we don't care about the browser action visibility, because |
| 312 // In this case, we don't care about the browser action visibility, because | 294 // we want to show each extension regardless. |
| 313 // we want to show each extension regardless. | 295 return extension_action_manager_->GetExtensionAction(*extension) != nullptr; |
| 314 return extension_action_manager_->GetExtensionAction(*extension) != nullptr; | |
| 315 } | |
| 316 | |
| 317 return extension_action_manager_->GetBrowserAction(*extension) && | |
| 318 extension_action_api_->GetBrowserActionVisibility(extension->id()); | |
| 319 } | 296 } |
| 320 | 297 |
| 321 void ToolbarActionsModel::AddExtension(const extensions::Extension* extension) { | 298 void ToolbarActionsModel::AddExtension(const extensions::Extension* extension) { |
| 322 if (!ShouldAddExtension(extension)) | 299 if (!ShouldAddExtension(extension)) |
| 323 return; | 300 return; |
| 324 | 301 |
| 325 AddItem(ToolbarItem(extension->id(), EXTENSION_ACTION)); | 302 AddItem(ToolbarItem(extension->id(), EXTENSION_ACTION)); |
| 326 } | 303 } |
| 327 | 304 |
| 328 void ToolbarActionsModel::AddItem(const ToolbarItem& item) { | 305 void ToolbarActionsModel::AddItem(const ToolbarItem& item) { |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 if (!toolbar_items_.empty()) { | 578 if (!toolbar_items_.empty()) { |
| 602 // Visible count can be -1, meaning: 'show all'. Since UMA converts negative | 579 // Visible count can be -1, meaning: 'show all'. Since UMA converts negative |
| 603 // values to 0, this would be counted as 'show none' unless we convert it to | 580 // values to 0, this would be counted as 'show none' unless we convert it to |
| 604 // max. | 581 // max. |
| 605 UMA_HISTOGRAM_COUNTS_100( | 582 UMA_HISTOGRAM_COUNTS_100( |
| 606 "ExtensionToolbarModel.BrowserActionsVisible", | 583 "ExtensionToolbarModel.BrowserActionsVisible", |
| 607 visible_icon_count_ == -1 | 584 visible_icon_count_ == -1 |
| 608 ? base::HistogramBase::kSampleType_MAX | 585 ? base::HistogramBase::kSampleType_MAX |
| 609 : visible_icon_count_ - component_actions_count); | 586 : visible_icon_count_ - component_actions_count); |
| 610 | 587 |
| 611 if (use_redesign_) { | 588 UMA_HISTOGRAM_COUNTS_100("Toolbar.ActionsModel.ToolbarActionsVisible", |
| 612 // The only time this will useful and possibly vary from | 589 visible_icon_count_ == -1 |
| 613 // BrowserActionsVisible is when the redesign has been enabled. | 590 ? base::HistogramBase::kSampleType_MAX |
| 614 UMA_HISTOGRAM_COUNTS_100("Toolbar.ActionsModel.ToolbarActionsVisible", | 591 : visible_icon_count_); |
| 615 visible_icon_count_ == -1 | |
| 616 ? base::HistogramBase::kSampleType_MAX | |
| 617 : visible_icon_count_); | |
| 618 } | |
| 619 } | 592 } |
| 620 } | 593 } |
| 621 | 594 |
| 622 bool ToolbarActionsModel::HasItem(const ToolbarItem& item) const { | 595 bool ToolbarActionsModel::HasItem(const ToolbarItem& item) const { |
| 623 return base::ContainsValue(toolbar_items_, item); | 596 return base::ContainsValue(toolbar_items_, item); |
| 624 } | 597 } |
| 625 | 598 |
| 626 bool ToolbarActionsModel::HasComponentAction( | 599 bool ToolbarActionsModel::HasComponentAction( |
| 627 const std::string& action_id) const { | 600 const std::string& action_id) const { |
| 628 DCHECK(use_redesign_); | |
| 629 return HasItem(ToolbarItem(action_id, COMPONENT_ACTION)); | 601 return HasItem(ToolbarItem(action_id, COMPONENT_ACTION)); |
| 630 } | 602 } |
| 631 | 603 |
| 632 void ToolbarActionsModel::AddComponentAction(const std::string& action_id) { | 604 void ToolbarActionsModel::AddComponentAction(const std::string& action_id) { |
| 633 DCHECK(use_redesign_); | |
| 634 if (!actions_initialized_) { | 605 if (!actions_initialized_) { |
| 635 component_actions_factory_->OnAddComponentActionBeforeInit(action_id); | 606 component_actions_factory_->OnAddComponentActionBeforeInit(action_id); |
| 636 return; | 607 return; |
| 637 } | 608 } |
| 638 | 609 |
| 639 ToolbarItem component_item(action_id, COMPONENT_ACTION); | 610 ToolbarItem component_item(action_id, COMPONENT_ACTION); |
| 640 DCHECK(!HasItem(component_item)); | 611 DCHECK(!HasItem(component_item)); |
| 641 AddItem(component_item); | 612 AddItem(component_item); |
| 642 } | 613 } |
| 643 | 614 |
| 644 void ToolbarActionsModel::RemoveComponentAction(const std::string& action_id) { | 615 void ToolbarActionsModel::RemoveComponentAction(const std::string& action_id) { |
| 645 DCHECK(use_redesign_); | |
| 646 if (!actions_initialized_) { | 616 if (!actions_initialized_) { |
| 647 component_actions_factory_->OnRemoveComponentActionBeforeInit(action_id); | 617 component_actions_factory_->OnRemoveComponentActionBeforeInit(action_id); |
| 648 return; | 618 return; |
| 649 } | 619 } |
| 650 // If the action was visible and there are overflowed actions, we reduce the | 620 // If the action was visible and there are overflowed actions, we reduce the |
| 651 // visible count so that we don't pop out a previously-hidden action. | 621 // visible count so that we don't pop out a previously-hidden action. |
| 652 if (IsActionVisible(action_id) && !all_icons_visible()) | 622 if (IsActionVisible(action_id) && !all_icons_visible()) |
| 653 SetVisibleIconCount(visible_icon_count() - 1); | 623 SetVisibleIconCount(visible_icon_count() - 1); |
| 654 | 624 |
| 655 ToolbarItem component_item(action_id, COMPONENT_ACTION); | 625 ToolbarItem component_item(action_id, COMPONENT_ACTION); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 // Don't observe change caused by self. | 678 // Don't observe change caused by self. |
| 709 pref_change_registrar_.Remove(extensions::pref_names::kToolbar); | 679 pref_change_registrar_.Remove(extensions::pref_names::kToolbar); |
| 710 extension_prefs_->SetToolbarOrder(last_known_positions_); | 680 extension_prefs_->SetToolbarOrder(last_known_positions_); |
| 711 pref_change_registrar_.Add(extensions::pref_names::kToolbar, | 681 pref_change_registrar_.Add(extensions::pref_names::kToolbar, |
| 712 pref_change_callback_); | 682 pref_change_callback_); |
| 713 } | 683 } |
| 714 | 684 |
| 715 void ToolbarActionsModel::SetActionVisibility(const std::string& action_id, | 685 void ToolbarActionsModel::SetActionVisibility(const std::string& action_id, |
| 716 bool is_now_visible) { | 686 bool is_now_visible) { |
| 717 // Hiding works differently with the new and old toolbars. | 687 // Hiding works differently with the new and old toolbars. |
| 718 if (use_redesign_) { | 688 DCHECK(HasItem(ToolbarItem(action_id, EXTENSION_ACTION))); |
| 719 DCHECK(HasItem(ToolbarItem(action_id, EXTENSION_ACTION))); | |
| 720 | 689 |
| 721 int new_size = 0; | 690 int new_size = 0; |
| 722 int new_index = 0; | 691 int new_index = 0; |
| 723 if (is_now_visible) { | 692 if (is_now_visible) { |
| 724 // If this action used to be hidden, we can't possibly be showing all. | 693 // If this action used to be hidden, we can't possibly be showing all. |
| 725 DCHECK_LT(visible_icon_count(), toolbar_items_.size()); | 694 DCHECK_LT(visible_icon_count(), toolbar_items_.size()); |
| 726 // Grow the bar by one and move the action to the end of the visibles. | 695 // Grow the bar by one and move the action to the end of the visibles. |
| 727 new_size = visible_icon_count() + 1; | 696 new_size = visible_icon_count() + 1; |
| 728 new_index = new_size - 1; | 697 new_index = new_size - 1; |
| 729 } else { | 698 } else { |
| 730 // If we're hiding one, we must be showing at least one. | 699 // If we're hiding one, we must be showing at least one. |
| 731 DCHECK_GE(visible_icon_count(), 0u); | 700 DCHECK_GE(visible_icon_count(), 0u); |
| 732 // Shrink the bar by one and move the action to the beginning of the | 701 // Shrink the bar by one and move the action to the beginning of the |
| 733 // overflow menu. | 702 // overflow menu. |
| 734 new_size = visible_icon_count() - 1; | 703 new_size = visible_icon_count() - 1; |
| 735 new_index = new_size; | 704 new_index = new_size; |
| 736 } | |
| 737 SetVisibleIconCount(new_size); | |
| 738 MoveActionIcon(action_id, new_index); | |
| 739 } else { // Legacy toolbar; hiding removes it from the toolbar. | |
| 740 if (!profile_->IsOffTheRecord()) { | |
| 741 extension_action_api_->SetBrowserActionVisibility(action_id, | |
| 742 is_now_visible); | |
| 743 } else { | |
| 744 OnExtensionActionVisibilityChanged(action_id, is_now_visible); | |
| 745 } | |
| 746 } | 705 } |
| 706 SetVisibleIconCount(new_size); |
| 707 MoveActionIcon(action_id, new_index); |
| 747 } | 708 } |
| 748 | 709 |
| 749 void ToolbarActionsModel::OnActionToolbarPrefChange() { | 710 void ToolbarActionsModel::OnActionToolbarPrefChange() { |
| 750 // If extensions are not ready, defer to later Populate() call. | 711 // If extensions are not ready, defer to later Populate() call. |
| 751 if (!actions_initialized_) | 712 if (!actions_initialized_) |
| 752 return; | 713 return; |
| 753 | 714 |
| 754 // Recalculate |last_known_positions_| to be |pref_positions| followed by | 715 // Recalculate |last_known_positions_| to be |pref_positions| followed by |
| 755 // ones that are only in |last_known_positions_|. | 716 // ones that are only in |last_known_positions_|. |
| 756 std::vector<std::string> pref_positions = extension_prefs_->GetToolbarOrder(); | 717 std::vector<std::string> pref_positions = extension_prefs_->GetToolbarOrder(); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 return extension_registry_->enabled_extensions().GetByID(id); | 822 return extension_registry_->enabled_extensions().GetByID(id); |
| 862 } | 823 } |
| 863 | 824 |
| 864 bool ToolbarActionsModel::IsActionVisible(const std::string& action_id) const { | 825 bool ToolbarActionsModel::IsActionVisible(const std::string& action_id) const { |
| 865 size_t index = 0u; | 826 size_t index = 0u; |
| 866 while (toolbar_items().size() > index && | 827 while (toolbar_items().size() > index && |
| 867 toolbar_items()[index].id != action_id) | 828 toolbar_items()[index].id != action_id) |
| 868 ++index; | 829 ++index; |
| 869 return index < visible_icon_count(); | 830 return index < visible_icon_count(); |
| 870 } | 831 } |
| OLD | NEW |