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 |