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

Unified Diff: chrome/browser/ui/toolbar/toolbar_actions_model.cc

Issue 1241063003: Support Component Actions in the toolbar. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Switch GetComponentActionId to unix_hacker_style. Created 5 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/toolbar/toolbar_actions_model.cc
diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/ui/toolbar/toolbar_actions_model.cc
similarity index 49%
rename from chrome/browser/extensions/extension_toolbar_model.cc
rename to chrome/browser/ui/toolbar/toolbar_actions_model.cc
index bad90272f3d9505d74700d856ef57f1ffe28ae3a..a9a770fb2dcc48318d862a221a7346b549ee56f2 100644
--- a/chrome/browser/extensions/extension_toolbar_model.cc
+++ b/chrome/browser/ui/toolbar/toolbar_actions_model.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/extensions/extension_toolbar_model.h"
+#include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
#include <algorithm>
#include <string>
@@ -14,124 +14,122 @@
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
#include "chrome/browser/extensions/extension_action_manager.h"
#include "chrome/browser/extensions/extension_tab_util.h"
-#include "chrome/browser/extensions/extension_toolbar_model_factory.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/extensions/extension_action_view_controller.h"
#include "chrome/browser/ui/extensions/extension_toolbar_icon_surfacing_bubble_delegate.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
+#include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
+#include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
+#include "chrome/browser/ui/toolbar/toolbar_actions_model_factory.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/web_contents.h"
-#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/pref_names.h"
-#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/feature_switch.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/one_shot_event.h"
-namespace extensions {
-
-ExtensionToolbarModel::ExtensionToolbarModel(Profile* profile,
- ExtensionPrefs* extension_prefs)
+ToolbarActionsModel::ToolbarActionsModel(
+ Profile* profile,
+ extensions::ExtensionPrefs* extension_prefs)
: profile_(profile),
extension_prefs_(extension_prefs),
prefs_(profile_->GetPrefs()),
- extension_action_api_(ExtensionActionAPI::Get(profile_)),
- extensions_initialized_(false),
- include_all_extensions_(FeatureSwitch::extension_action_redesign()
- ->IsEnabled()),
+ extension_action_api_(extensions::ExtensionActionAPI::Get(profile_)),
+ extension_registry_(extensions::ExtensionRegistry::Get(profile_)),
+ actions_initialized_(false),
+ use_redesign_(extensions::FeatureSwitch::extension_action_redesign()
+ ->IsEnabled()),
highlight_type_(HIGHLIGHT_NONE),
extension_action_observer_(this),
extension_registry_observer_(this),
weak_ptr_factory_(this) {
- ExtensionSystem::Get(profile_)->ready().Post(
- FROM_HERE,
- base::Bind(&ExtensionToolbarModel::OnReady,
- weak_ptr_factory_.GetWeakPtr()));
- visible_icon_count_ = prefs_->GetInteger(pref_names::kToolbarSize);
+ extensions::ExtensionSystem::Get(profile_)->ready().Post(
+ FROM_HERE, base::Bind(&ToolbarActionsModel::OnReady,
+ weak_ptr_factory_.GetWeakPtr()));
+ visible_icon_count_ =
+ prefs_->GetInteger(extensions::pref_names::kToolbarSize);
// We only care about watching the prefs if not in incognito mode.
if (!profile_->IsOffTheRecord()) {
pref_change_registrar_.Init(prefs_);
pref_change_callback_ =
- base::Bind(&ExtensionToolbarModel::OnExtensionToolbarPrefChange,
+ base::Bind(&ToolbarActionsModel::OnActionToolbarPrefChange,
base::Unretained(this));
- pref_change_registrar_.Add(pref_names::kToolbar, pref_change_callback_);
+ pref_change_registrar_.Add(extensions::pref_names::kToolbar,
+ pref_change_callback_);
}
}
-ExtensionToolbarModel::~ExtensionToolbarModel() {
-}
+ToolbarActionsModel::~ToolbarActionsModel() {}
// static
-ExtensionToolbarModel* ExtensionToolbarModel::Get(Profile* profile) {
- return ExtensionToolbarModelFactory::GetForProfile(profile);
+ToolbarActionsModel* ToolbarActionsModel::Get(Profile* profile) {
+ return ToolbarActionsModelFactory::GetForProfile(profile);
}
-void ExtensionToolbarModel::AddObserver(Observer* observer) {
+void ToolbarActionsModel::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
-void ExtensionToolbarModel::RemoveObserver(Observer* observer) {
+void ToolbarActionsModel::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
-void ExtensionToolbarModel::MoveExtensionIcon(const std::string& id,
- size_t index) {
- ExtensionList::iterator pos = toolbar_items_.begin();
- while (pos != toolbar_items_.end() && (*pos)->id() != id)
+void ToolbarActionsModel::MoveActionIcon(const std::string& id, size_t index) {
+ std::vector<ToolbarItem>::iterator pos = toolbar_items_.begin();
+ while (pos != toolbar_items_.end() && (*pos).id != id)
++pos;
if (pos == toolbar_items_.end()) {
NOTREACHED();
return;
}
- scoped_refptr<const Extension> extension = *pos;
+
+ ToolbarItem action = *pos;
toolbar_items_.erase(pos);
- ExtensionIdList::iterator pos_id = std::find(last_known_positions_.begin(),
- last_known_positions_.end(),
- id);
+ std::vector<std::string>::iterator pos_id =
+ std::find(last_known_positions_.begin(), last_known_positions_.end(), id);
if (pos_id != last_known_positions_.end())
last_known_positions_.erase(pos_id);
if (index < toolbar_items_.size()) {
// If the index is not at the end, find the item currently at |index|, and
- // insert |extension| before it in both |toolbar_items_| and
+ // insert |action| before it in |toolbar_items_| and |action|'s id in
// |last_known_positions_|.
- ExtensionList::iterator iter = toolbar_items_.begin() + index;
- last_known_positions_.insert(std::find(last_known_positions_.begin(),
- last_known_positions_.end(),
- (*iter)->id()),
- id);
- toolbar_items_.insert(iter, extension);
+ std::vector<ToolbarItem>::iterator iter = toolbar_items_.begin() + index;
+ last_known_positions_.insert(
+ std::find(last_known_positions_.begin(), last_known_positions_.end(),
+ iter->id),
+ id);
+ toolbar_items_.insert(iter, action);
} else {
- // Otherwise, put |extension| at the end.
+ // Otherwise, put |action| and |id| at the end.
DCHECK_EQ(toolbar_items_.size(), index);
- index = toolbar_items_.size();
- toolbar_items_.push_back(extension);
+ toolbar_items_.push_back(action);
last_known_positions_.push_back(id);
}
- FOR_EACH_OBSERVER(Observer, observers_,
- OnToolbarExtensionMoved(extension.get(), index));
- MaybeUpdateVisibilityPref(extension.get(), index);
+ FOR_EACH_OBSERVER(Observer, observers_, OnToolbarActionMoved(id, index));
+ MaybeUpdateVisibilityPref(action, index);
UpdatePrefs();
}
-void ExtensionToolbarModel::SetVisibleIconCount(size_t count) {
+void ToolbarActionsModel::SetVisibleIconCount(size_t count) {
visible_icon_count_ = (count >= toolbar_items_.size()) ? -1 : count;
// Only set the prefs if we're not in highlight mode and the profile is not
// incognito. Highlight mode is designed to be a transitory state, and should
- // not persist across browser restarts (though it may be re-entered), and we
+ // not persist across browser restarts (though it may be re-entered), and we
// don't store anything in incognito.
if (!is_highlighting() && !profile_->IsOffTheRecord()) {
// Additionally, if we are using the new toolbar, any icons which are in the
@@ -139,43 +137,86 @@ void ExtensionToolbarModel::SetVisibleIconCount(size_t count) {
// we are likely to call SetVisibleIconCount() are also those when we are
// in flux. So wait for things to cool down before setting the prefs.
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&ExtensionToolbarModel::MaybeUpdateVisibilityPrefs,
- weak_ptr_factory_.GetWeakPtr()));
- prefs_->SetInteger(pref_names::kToolbarSize, visible_icon_count_);
+ FROM_HERE, base::Bind(&ToolbarActionsModel::MaybeUpdateVisibilityPrefs,
+ weak_ptr_factory_.GetWeakPtr()));
+ prefs_->SetInteger(extensions::pref_names::kToolbarSize,
+ visible_icon_count_);
}
FOR_EACH_OBSERVER(Observer, observers_, OnToolbarVisibleCountChanged());
}
-void ExtensionToolbarModel::OnExtensionActionUpdated(
+void ToolbarActionsModel::OnExtensionActionUpdated(
ExtensionAction* extension_action,
content::WebContents* web_contents,
content::BrowserContext* browser_context) {
- const Extension* extension =
- ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID(
- extension_action->extension_id());
// Notify observers if the extension exists and is in the model.
- if (std::find(toolbar_items_.begin(), toolbar_items_.end(), extension) !=
- toolbar_items_.end()) {
+ if (std::find(toolbar_items_.begin(), toolbar_items_.end(),
+ ToolbarItem(extension_action->extension_id(),
+ EXTENSION_ACTION)) != toolbar_items_.end()) {
FOR_EACH_OBSERVER(Observer, observers_,
- OnToolbarExtensionUpdated(extension));
+ OnToolbarActionUpdated(extension_action->extension_id()));
}
}
-void ExtensionToolbarModel::OnExtensionActionVisibilityChanged(
+ScopedVector<ToolbarActionViewController> ToolbarActionsModel::CreateActions(
+ Browser* browser,
+ ToolbarActionsBar* bar) {
+ DCHECK(browser);
+ DCHECK(bar);
+ ScopedVector<ToolbarActionViewController> action_list;
+
+ // Get the component action list.
+ ScopedVector<ToolbarActionViewController> component_actions =
+ ComponentToolbarActionsFactory::GetInstance()->GetComponentToolbarActions(
+ browser);
+
+ extensions::ExtensionActionManager* action_manager =
+ extensions::ExtensionActionManager::Get(profile_);
+
+ // toolbar_items() might not equate to toolbar_items_ in the case where a
+ // subset are highlighted.
+ std::vector<ToolbarItem> items = toolbar_items();
+ for (const ToolbarItem& action : items) {
+ if (action.type == EXTENSION_ACTION) {
+ // Get the extension.
+ const extensions::Extension* extension = GetExtensionById(action.id);
+ DCHECK(extension);
+
+ // Create and add an ExtensionActionViewController for the extension.
+ action_list.push_back(new ExtensionActionViewController(
+ extension, browser, action_manager->GetExtensionAction(*extension),
+ bar));
+ } else if (action.type == COMPONENT_ACTION) {
+ DCHECK(use_redesign_);
+ // Find the corresponding action to |action|.
+ for (auto component_action : component_actions) {
+ if (component_action->GetId() == action.id) {
+ action_list.push_back(component_action);
+ break;
+ }
+ }
+ }
+ }
+
+ // We've moved ownership of the subset of the component actions that we
+ // kept track of via toolbar_items() from |component_actions| to
+ // |action_list|, so we don't need to keep track of these.
+ component_actions.weak_clear();
+
+ return action_list.Pass();
+}
+
+void ToolbarActionsModel::OnExtensionActionVisibilityChanged(
const std::string& extension_id,
bool is_now_visible) {
- const Extension* extension =
- ExtensionRegistry::Get(profile_)->GetExtensionById(
- extension_id, ExtensionRegistry::EVERYTHING);
-
// Hiding works differently with the new and old toolbars.
- if (include_all_extensions_) {
- // It's possible that we haven't added this extension yet, if its
+ if (use_redesign_) {
+ // It's possible that we haven't added this action yet, if its
// visibility was adjusted in the course of its initialization.
- if (std::find(toolbar_items_.begin(), toolbar_items_.end(), extension) ==
- toolbar_items_.end())
+ if (std::find(toolbar_items_.begin(), toolbar_items_.end(),
+ ToolbarItem(extension_id, EXTENSION_ACTION)) ==
+ toolbar_items_.end())
return;
int new_size = 0;
@@ -183,20 +224,21 @@ void ExtensionToolbarModel::OnExtensionActionVisibilityChanged(
if (is_now_visible) {
// If this action used to be hidden, we can't possibly be showing all.
DCHECK_LT(visible_icon_count(), toolbar_items_.size());
- // Grow the bar by one and move the extension to the end of the visibles.
+ // Grow the bar by one and move the action to the end of the visibles.
new_size = visible_icon_count() + 1;
new_index = new_size - 1;
} else {
// If we're hiding one, we must be showing at least one.
DCHECK_GE(visible_icon_count(), 0u);
- // Shrink the bar by one and move the extension to the beginning of the
+ // Shrink the bar by one and move the action to the beginning of the
// overflow menu.
new_size = visible_icon_count() - 1;
new_index = new_size;
}
SetVisibleIconCount(new_size);
- MoveExtensionIcon(extension->id(), new_index);
+ MoveActionIcon(extension_id, new_index);
} else { // Don't include all extensions.
+ const extensions::Extension* extension = GetExtensionById(extension_id);
if (is_now_visible)
AddExtension(extension);
else
@@ -204,36 +246,36 @@ void ExtensionToolbarModel::OnExtensionActionVisibilityChanged(
}
}
-void ExtensionToolbarModel::OnExtensionLoaded(
+void ToolbarActionsModel::OnExtensionLoaded(
content::BrowserContext* browser_context,
- const Extension* extension) {
+ const extensions::Extension* extension) {
// We don't want to add the same extension twice. It may have already been
// added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user
// hides the browser action and then disables and enables the extension.
- for (size_t i = 0; i < toolbar_items_.size(); i++) {
- if (toolbar_items_[i].get() == extension)
- return;
- }
+ if (std::find(toolbar_items_.begin(), toolbar_items_.end(),
+ ToolbarItem(extension->id(), EXTENSION_ACTION)) !=
+ toolbar_items_.end())
+ return;
AddExtension(extension);
}
-void ExtensionToolbarModel::OnExtensionUnloaded(
+void ToolbarActionsModel::OnExtensionUnloaded(
content::BrowserContext* browser_context,
- const Extension* extension,
- UnloadedExtensionInfo::Reason reason) {
+ const extensions::Extension* extension,
+ extensions::UnloadedExtensionInfo::Reason reason) {
RemoveExtension(extension);
}
-void ExtensionToolbarModel::OnExtensionUninstalled(
+void ToolbarActionsModel::OnExtensionUninstalled(
content::BrowserContext* browser_context,
- const Extension* extension,
+ const extensions::Extension* extension,
extensions::UninstallReason reason) {
// Remove the extension id from the ordered list, if it exists (the extension
// might not be represented in the list because it might not have an icon).
- ExtensionIdList::iterator pos =
- std::find(last_known_positions_.begin(),
- last_known_positions_.end(), extension->id());
+ std::vector<std::string>::iterator pos =
+ std::find(last_known_positions_.begin(), last_known_positions_.end(),
+ extension->id());
if (pos != last_known_positions_.end()) {
last_known_positions_.erase(pos);
@@ -241,41 +283,38 @@ void ExtensionToolbarModel::OnExtensionUninstalled(
}
}
-void ExtensionToolbarModel::OnReady() {
- ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
- InitializeExtensionList();
+void ToolbarActionsModel::OnReady() {
+ InitializeActionList();
// Wait until the extension system is ready before observing any further
// changes so that the toolbar buttons can be shown in their stable ordering
// taken from prefs.
- extension_registry_observer_.Add(registry);
+ extension_registry_observer_.Add(extension_registry_);
extension_action_observer_.Add(extension_action_api_);
if (ExtensionToolbarIconSurfacingBubbleDelegate::ShouldShowForProfile(
profile_)) {
- ExtensionIdList ids;
- for (const auto& extension : toolbar_items_)
- ids.push_back(extension->id());
- HighlightExtensions(ids, HIGHLIGHT_INFO);
+ std::vector<std::string> ids;
+ for (const ToolbarItem& action : toolbar_items_)
+ ids.push_back(action.id);
+ HighlightActions(ids, HIGHLIGHT_INFO);
}
- extensions_initialized_ = true;
+ actions_initialized_ = true;
FOR_EACH_OBSERVER(Observer, observers_, OnToolbarModelInitialized());
}
-size_t ExtensionToolbarModel::FindNewPositionFromLastKnownGood(
- const Extension* extension) {
- // See if we have last known good position for this extension.
+size_t ToolbarActionsModel::FindNewPositionFromLastKnownGood(
+ const ToolbarItem& action) {
+ // See if we have last known good position for this action.
size_t new_index = 0;
- // Loop through the ID list of known positions, to count the number of visible
- // extension icons preceding |extension|.
- for (ExtensionIdList::const_iterator iter_id = last_known_positions_.begin();
- iter_id < last_known_positions_.end(); ++iter_id) {
- if ((*iter_id) == extension->id())
+ // Loop through the ID list of known positions, to count the number of
+ // visible action icons preceding |action|'s id.
+ for (const std::string& last_pos_id : last_known_positions_) {
+ if (last_pos_id == action.id)
return new_index; // We've found the right position.
- // Found an id, need to see if it is visible.
- for (ExtensionList::const_iterator iter_ext = toolbar_items_.begin();
- iter_ext < toolbar_items_.end(); ++iter_ext) {
- if ((*iter_ext)->id() == (*iter_id)) {
+ // Found an action, need to see if it is visible.
+ for (const ToolbarItem& item : toolbar_items_) {
+ if (item.id == last_pos_id) {
// This extension is visible, update the index value.
++new_index;
break;
@@ -287,19 +326,18 @@ size_t ExtensionToolbarModel::FindNewPositionFromLastKnownGood(
return toolbar_items_.size();
}
-bool ExtensionToolbarModel::ShouldAddExtension(const Extension* extension) {
+bool ToolbarActionsModel::ShouldAddExtension(
+ const extensions::Extension* extension) {
// In incognito mode, don't add any extensions that aren't incognito-enabled.
if (profile_->IsOffTheRecord() &&
- !util::IsIncognitoEnabled(extension->id(), profile_))
+ !extensions::util::IsIncognitoEnabled(extension->id(), profile_))
return false;
- ExtensionActionManager* action_manager =
- ExtensionActionManager::Get(profile_);
- if (include_all_extensions_) {
+ extensions::ExtensionActionManager* action_manager =
+ extensions::ExtensionActionManager::Get(profile_);
+ if (use_redesign_) {
// In this case, we don't care about the browser action visibility, because
// we want to show each extension regardless.
- // TODO(devlin): Extension actions which are not visible should be moved to
- // the overflow menu by default.
return action_manager->GetExtensionAction(*extension) != NULL;
}
@@ -307,34 +345,33 @@ bool ExtensionToolbarModel::ShouldAddExtension(const Extension* extension) {
extension_action_api_->GetBrowserActionVisibility(extension->id());
}
-void ExtensionToolbarModel::AddExtension(const Extension* extension) {
+void ToolbarActionsModel::AddExtension(const extensions::Extension* extension) {
// We only use AddExtension() once the system is initialized.
- DCHECK(extensions_initialized_);
+ DCHECK(actions_initialized_);
if (!ShouldAddExtension(extension))
return;
// See if we have a last known good position for this extension.
bool is_new_extension =
- std::find(last_known_positions_.begin(),
- last_known_positions_.end(),
+ std::find(last_known_positions_.begin(), last_known_positions_.end(),
extension->id()) == last_known_positions_.end();
// New extensions go at the right (end) of the visible extensions. Other
// extensions go at their previous position.
size_t new_index = 0;
if (is_new_extension) {
- new_index = Manifest::IsComponentLocation(extension->location()) ?
- 0 : visible_icon_count();
+ new_index = extensions::Manifest::IsComponentLocation(extension->location())
+ ? 0
+ : visible_icon_count();
// For the last-known position, we use the index of the extension that is
// just before this extension, plus one. (Note that this isn't the same
// as new_index + 1, because last_known_positions_ can include disabled
// extensions.)
int new_last_known_index =
- new_index == 0 ? 0 :
- std::find(last_known_positions_.begin(),
- last_known_positions_.end(),
- toolbar_items_[new_index - 1]->id()) -
- last_known_positions_.begin() + 1;
+ new_index == 0 ? 0 : std::find(last_known_positions_.begin(),
+ last_known_positions_.end(),
+ toolbar_items_[new_index - 1].id) -
+ last_known_positions_.begin() + 1;
// In theory, the extension before this one should always
// be in last known positions, but if something funny happened with prefs,
// make sure we handle it.
@@ -345,17 +382,19 @@ void ExtensionToolbarModel::AddExtension(const Extension* extension) {
last_known_positions_.begin() + new_last_known_index, extension->id());
UpdatePrefs();
} else {
- new_index = FindNewPositionFromLastKnownGood(extension);
+ new_index = FindNewPositionFromLastKnownGood(
+ ToolbarItem(extension->id(), EXTENSION_ACTION));
}
- toolbar_items_.insert(toolbar_items_.begin() + new_index, extension);
+ toolbar_items_.insert(toolbar_items_.begin() + new_index,
+ ToolbarItem(extension->id(), EXTENSION_ACTION));
// If we're currently highlighting, then even though we add a browser action
// to the full list (|toolbar_items_|, there won't be another *visible*
// browser action, which was what the observers care about.
if (!is_highlighting()) {
FOR_EACH_OBSERVER(Observer, observers_,
- OnToolbarExtensionAdded(extension, new_index));
+ OnToolbarActionAdded(extension->id(), new_index));
int visible_count_delta = 0;
if (is_new_extension && !all_icons_visible()) {
@@ -365,13 +404,13 @@ void ExtensionToolbarModel::AddExtension(const Extension* extension) {
} else if (profile_->IsOffTheRecord()) {
// If this is an incognito profile, we also have to check to make sure the
// overflow matches the main bar's status.
- ExtensionToolbarModel* main_model =
- ExtensionToolbarModel::Get(profile_->GetOriginalProfile());
+ ToolbarActionsModel* main_model =
+ ToolbarActionsModel::Get(profile_->GetOriginalProfile());
// Find what the index will be in the main bar. Because Observer calls are
// nondeterministic, we can't just assume the main bar will have the
// extension and look it up.
- size_t main_index =
- main_model->FindNewPositionFromLastKnownGood(extension);
+ size_t main_index = main_model->FindNewPositionFromLastKnownGood(
+ ToolbarItem(extension->id(), EXTENSION_ACTION));
bool visible = main_index < main_model->visible_icon_count();
// We may need to adjust the visible count if the incognito bar isn't
// showing all icons and this one is visible, or if it is showing all
@@ -386,12 +425,16 @@ void ExtensionToolbarModel::AddExtension(const Extension* extension) {
SetVisibleIconCount(visible_icon_count() + visible_count_delta);
}
- MaybeUpdateVisibilityPref(extension, new_index);
+ MaybeUpdateVisibilityPref(ToolbarItem(extension->id(), EXTENSION_ACTION),
+ new_index);
}
-void ExtensionToolbarModel::RemoveExtension(const Extension* extension) {
- ExtensionList::iterator pos =
- std::find(toolbar_items_.begin(), toolbar_items_.end(), extension);
+void ToolbarActionsModel::RemoveExtension(
+ const extensions::Extension* extension) {
+ std::vector<ToolbarItem>::iterator pos =
+ std::find(toolbar_items_.begin(), toolbar_items_.end(),
+ ToolbarItem(extension->id(), EXTENSION_ACTION));
+
if (pos == toolbar_items_.end())
return;
@@ -410,38 +453,38 @@ void ExtensionToolbarModel::RemoveExtension(const Extension* extension) {
// If we're in highlight mode, we also have to remove the extension from
// the highlighted list.
if (is_highlighting()) {
- pos = std::find(highlighted_items_.begin(),
- highlighted_items_.end(),
- extension);
+ pos = std::find(highlighted_items_.begin(), highlighted_items_.end(),
+ ToolbarItem(extension->id(), EXTENSION_ACTION));
if (pos != highlighted_items_.end()) {
highlighted_items_.erase(pos);
FOR_EACH_OBSERVER(Observer, observers_,
- OnToolbarExtensionRemoved(extension));
+ OnToolbarActionRemoved(extension->id()));
// If the highlighted list is now empty, we stop highlighting.
if (highlighted_items_.empty())
StopHighlighting();
}
} else {
FOR_EACH_OBSERVER(Observer, observers_,
- OnToolbarExtensionRemoved(extension));
+ OnToolbarActionRemoved(extension->id()));
}
UpdatePrefs();
if (new_extension_shown) {
size_t newly_visible_index = visible_icon_count() - 1;
- MaybeUpdateVisibilityPref(toolbar_items_[newly_visible_index].get(),
+ MaybeUpdateVisibilityPref(toolbar_items_[newly_visible_index],
newly_visible_index);
}
}
// Combine the currently enabled extensions that have browser actions (which
-// we get from the ExtensionRegistry) with the ordering we get from the
-// pref service. For robustness we use a somewhat inefficient process:
-// 1. Create a vector of extensions sorted by their pref values. This vector may
+// we get from the ExtensionRegistry) and component actions (which we get from
+// ComponentToolbarActionsFactory) with the ordering we get from the pref
+// service. For robustness we use a somewhat inefficient process:
+// 1. Create a vector of actions sorted by their pref values. This vector may
// have holes.
-// 2. Create a vector of extensions that did not have a pref value.
+// 2. Create a vector of actions that did not have a pref value.
// 3. Remove holes from the sorted vector and append the unsorted vector.
-void ExtensionToolbarModel::InitializeExtensionList() {
+void ToolbarActionsModel::InitializeActionList() {
DCHECK(toolbar_items_.empty()); // We shouldn't have any items yet.
last_known_positions_ = extension_prefs_->GetToolbarOrder();
@@ -453,33 +496,51 @@ void ExtensionToolbarModel::InitializeExtensionList() {
MaybeUpdateVisibilityPrefs();
}
-void ExtensionToolbarModel::Populate(ExtensionIdList* positions) {
+void ToolbarActionsModel::Populate(std::vector<std::string>* positions) {
DCHECK(!profile_->IsOffTheRecord());
- const ExtensionSet& extensions =
- ExtensionRegistry::Get(profile_)->enabled_extensions();
- // Items that have explicit positions.
- ExtensionList sorted(positions->size(), NULL);
- // The items that don't have explicit positions.
- ExtensionList unsorted;
-
- // Create the lists.
+
+ std::vector<ToolbarItem> all_actions;
+ // Ids of actions that have explicit positions.
+ std::vector<ToolbarItem> sorted(positions->size(), ToolbarItem());
+ // Ids of actions that don't have explicit positions.
+ std::vector<ToolbarItem> unsorted;
+
+ // Populate the lists.
int hidden = 0;
- for (const scoped_refptr<const Extension>& extension : extensions) {
+ int browser_actions_count = 0;
+ int component_actions_count = 0;
+
+ // First, add the extension action ids to all_actions.
+ const extensions::ExtensionSet& extensions =
+ extension_registry_->enabled_extensions();
+ for (const scoped_refptr<const extensions::Extension>& extension :
+ extensions) {
if (!ShouldAddExtension(extension.get())) {
if (!extension_action_api_->GetBrowserActionVisibility(extension->id()))
++hidden;
continue;
}
- ExtensionIdList::const_iterator pos =
- std::find(positions->begin(), positions->end(), extension->id());
+ all_actions.push_back(ToolbarItem(extension->id(), EXTENSION_ACTION));
+ }
+
+ // Next, add the component action ids.
+ std::vector<std::string> component_ids =
+ ComponentToolbarActionsFactory::GetComponentIds();
+ for (const std::string& id : component_ids)
+ all_actions.push_back(ToolbarItem(id, COMPONENT_ACTION));
+
+ // Add each action id to the appropriate list.
+ for (const ToolbarItem& action : all_actions) {
+ std::vector<std::string>::const_iterator pos =
+ std::find(positions->begin(), positions->end(), action.id);
if (pos != positions->end()) {
- sorted[pos - positions->begin()] = extension;
+ sorted[pos - positions->begin()] = action;
} else {
- // Unknown extension - push it to the back of unsorted, and add it to the
+ // Unknown action - push it to the back of unsorted, and add it to the
// list of ids at the end.
- unsorted.push_back(extension);
- positions->push_back(extension->id());
+ unsorted.push_back(action);
+ positions->push_back(action.id);
}
}
@@ -487,107 +548,137 @@ void ExtensionToolbarModel::Populate(ExtensionIdList* positions) {
sorted.insert(sorted.end(), unsorted.begin(), unsorted.end());
toolbar_items_.reserve(sorted.size());
- for (const scoped_refptr<const Extension>& extension : sorted) {
- // It's possible for the extension order to contain items that aren't
- // actually loaded on this machine. For example, when extension sync is on,
- // we sync the extension order as-is but double-check with the user before
- // syncing NPAPI-containing extensions, so if one of those is not actually
- // synced, we'll get a NULL in the list. This sort of case can also happen
- // if some error prevents an extension from loading.
- if (extension.get()) {
- // We don't notify observers of the added extension yet. Rather, observers
- // should wait for the "OnToolbarModelInitialized" notification, and then
- // bulk-update. (This saves a lot of bouncing-back-and-forth here, and
- // allows observers to ensure that the extension system is always
- // initialized before using the extensions).
- toolbar_items_.push_back(extension);
+ // We don't notify observers of the added extension yet. Rather, observers
+ // should wait for the "OnToolbarModelInitialized" notification, and then
+ // bulk-update. (This saves a lot of bouncing-back-and-forth here, and allows
+ // observers to ensure that the extension system is always initialized before
+ // using the extensions).
+ for (const ToolbarItem& action : sorted) {
+ if (action.type == EXTENSION_ACTION) {
+ // It's possible for the extension order to contain items that aren't
+ // actually loaded on this machine. For example, when extension sync is
+ // on, we sync the extension order as-is but double-check with the user
+ // before syncing NPAPI-containing extensions, so if one of those is not
+ // actually synced, we'll get a NULL in the list. This sort of case can
+ // also happen if some error prevents an extension from loading.
+ if (GetExtensionById(action.id)) {
+ toolbar_items_.push_back(ToolbarItem(action.id, EXTENSION_ACTION));
+ ++browser_actions_count;
+ }
+ } else if (action.type == COMPONENT_ACTION) {
+ toolbar_items_.push_back(ToolbarItem(action.id, COMPONENT_ACTION));
+ ++component_actions_count;
}
}
+ // Histogram names are prefixed with "ExtensionToolbarModel" rather than
+ // "ToolbarActionsModel" for historical reasons.
UMA_HISTOGRAM_COUNTS_100(
"ExtensionToolbarModel.BrowserActionsPermanentlyHidden", hidden);
UMA_HISTOGRAM_COUNTS_100("ExtensionToolbarModel.BrowserActionsCount",
+ browser_actions_count);
+ UMA_HISTOGRAM_COUNTS_100("Toolbar.ActionsModel.ComponentActionsCount",
+ component_actions_count);
+ UMA_HISTOGRAM_COUNTS_100("Toolbar.ActionsModel.OverallActionsCount",
toolbar_items_.size());
if (!toolbar_items_.empty()) {
// Visible count can be -1, meaning: 'show all'. Since UMA converts negative
// values to 0, this would be counted as 'show none' unless we convert it to
// max.
- UMA_HISTOGRAM_COUNTS_100("ExtensionToolbarModel.BrowserActionsVisible",
- visible_icon_count_ == -1 ?
- base::HistogramBase::kSampleType_MAX :
- visible_icon_count_);
+ UMA_HISTOGRAM_COUNTS_100(
+ "ExtensionToolbarModel.BrowserActionsVisible",
+ visible_icon_count_ == -1
+ ? visible_icon_count_
+ : visible_icon_count_ - component_actions_count);
+
+ if (use_redesign_) {
+ // The only time this will useful and possibly vary from
+ // BrowserActionsVisible is when the redesign has been enabled.
+ UMA_HISTOGRAM_COUNTS_100("Toolbar.ActionsModel.ToolbarActionsVisible",
+ visible_icon_count_ == -1
+ ? base::HistogramBase::kSampleType_MAX
+ : visible_icon_count_);
+ }
}
}
-void ExtensionToolbarModel::IncognitoPopulate() {
+void ToolbarActionsModel::IncognitoPopulate() {
DCHECK(profile_->IsOffTheRecord());
- const ExtensionToolbarModel* original_model =
- ExtensionToolbarModel::Get(profile_->GetOriginalProfile());
+ const ToolbarActionsModel* original_model =
+ ToolbarActionsModel::Get(profile_->GetOriginalProfile());
// Find the absolute value of the original model's count.
int original_visible = original_model->visible_icon_count();
- // In incognito mode, we show only those extensions that are
- // incognito-enabled. Further, any actions that were overflowed in regular
- // mode are still overflowed. Order is the same as in regular mode.
+ // In incognito mode, we show only those actions that are incognito-enabled
+ // Further, any actions that were overflowed in regular mode are still
+ // overflowed. Order is the same as in regular mode.
visible_icon_count_ = 0;
- for (ExtensionList::const_iterator iter =
+
+ for (std::vector<ToolbarItem>::const_iterator iter =
original_model->toolbar_items_.begin();
iter != original_model->toolbar_items_.end(); ++iter) {
- if (ShouldAddExtension(iter->get())) {
- toolbar_items_.push_back(*iter);
- if (iter - original_model->toolbar_items_.begin() < original_visible)
- ++visible_icon_count_;
- }
+ // The extension might not be shown in incognito mode. For now, all
+ // component actions are present.
+ if (iter->type == EXTENSION_ACTION &&
+ !ShouldAddExtension(GetExtensionById(iter->id)))
+ continue;
+ toolbar_items_.push_back(*iter);
+ if (iter - original_model->toolbar_items_.begin() < original_visible)
+ ++visible_icon_count_;
}
}
-void ExtensionToolbarModel::UpdatePrefs() {
+void ToolbarActionsModel::UpdatePrefs() {
if (!extension_prefs_ || profile_->IsOffTheRecord())
return;
// Don't observe change caused by self.
- pref_change_registrar_.Remove(pref_names::kToolbar);
+ pref_change_registrar_.Remove(extensions::pref_names::kToolbar);
extension_prefs_->SetToolbarOrder(last_known_positions_);
- pref_change_registrar_.Add(pref_names::kToolbar, pref_change_callback_);
+ pref_change_registrar_.Add(extensions::pref_names::kToolbar,
+ pref_change_callback_);
}
-void ExtensionToolbarModel::MaybeUpdateVisibilityPref(
- const Extension* extension, size_t index) {
+void ToolbarActionsModel::MaybeUpdateVisibilityPref(const ToolbarItem& action,
+ size_t index) {
+ // Component actions don't have prefs to update.
+ if (action.type == COMPONENT_ACTION)
+ return;
+
// We only update the visibility pref for hidden/not hidden based on the
// overflow menu with the new toolbar design.
- if (include_all_extensions_ && !profile_->IsOffTheRecord()) {
+ if (use_redesign_ && !profile_->IsOffTheRecord()) {
bool visible = index < visible_icon_count();
- if (visible != extension_action_api_->GetBrowserActionVisibility(
- extension->id())) {
+ if (visible !=
+ extension_action_api_->GetBrowserActionVisibility(action.id)) {
// Don't observe changes caused by ourselves.
bool was_registered = false;
if (extension_action_observer_.IsObserving(extension_action_api_)) {
was_registered = true;
extension_action_observer_.RemoveAll();
}
- extension_action_api_->SetBrowserActionVisibility(extension->id(),
- visible);
+ extension_action_api_->SetBrowserActionVisibility(action.id, visible);
if (was_registered)
extension_action_observer_.Add(extension_action_api_);
}
}
}
-void ExtensionToolbarModel::MaybeUpdateVisibilityPrefs() {
+void ToolbarActionsModel::MaybeUpdateVisibilityPrefs() {
for (size_t i = 0u; i < toolbar_items_.size(); ++i)
- MaybeUpdateVisibilityPref(toolbar_items_[i].get(), i);
+ MaybeUpdateVisibilityPref(toolbar_items_[i], i);
}
-void ExtensionToolbarModel::OnExtensionToolbarPrefChange() {
+void ToolbarActionsModel::OnActionToolbarPrefChange() {
// If extensions are not ready, defer to later Populate() call.
- if (!extensions_initialized_)
+ if (!actions_initialized_)
return;
// Recalculate |last_known_positions_| to be |pref_positions| followed by
// ones that are only in |last_known_positions_|.
- ExtensionIdList pref_positions = extension_prefs_->GetToolbarOrder();
+ std::vector<std::string> pref_positions = extension_prefs_->GetToolbarOrder();
size_t pref_position_size = pref_positions.size();
for (size_t i = 0; i < last_known_positions_.size(); ++i) {
if (std::find(pref_positions.begin(), pref_positions.end(),
@@ -605,13 +696,12 @@ void ExtensionToolbarModel::OnExtensionToolbarPrefChange() {
if (current_index == -1)
continue;
if (current_index != desired_index) {
- scoped_refptr<const Extension> extension = toolbar_items_[current_index];
+ ToolbarItem action = toolbar_items_[current_index];
toolbar_items_.erase(toolbar_items_.begin() + current_index);
- toolbar_items_.insert(toolbar_items_.begin() + desired_index, extension);
+ toolbar_items_.insert(toolbar_items_.begin() + desired_index, action);
// Notify the observers to keep them up-to-date.
- FOR_EACH_OBSERVER(
- Observer, observers_,
- OnToolbarExtensionMoved(extension.get(), desired_index));
+ FOR_EACH_OBSERVER(Observer, observers_,
+ OnToolbarActionMoved(action.id, desired_index));
}
++desired_index;
}
@@ -620,23 +710,22 @@ void ExtensionToolbarModel::OnExtensionToolbarPrefChange() {
// Need to update pref because we have extra icons. But can't call
// UpdatePrefs() directly within observation closure.
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&ExtensionToolbarModel::UpdatePrefs,
+ FROM_HERE, base::Bind(&ToolbarActionsModel::UpdatePrefs,
weak_ptr_factory_.GetWeakPtr()));
}
}
-int ExtensionToolbarModel::GetIndexForId(const std::string& id) const {
+int ToolbarActionsModel::GetIndexForId(const std::string& id) const {
for (size_t i = 0; i < toolbar_items().size(); ++i) {
- if (toolbar_items()[i]->id() == id)
+ if (toolbar_items()[i].id == id)
return i;
}
return -1;
}
-bool ExtensionToolbarModel::ShowExtensionActionPopup(
- const Extension* extension,
- Browser* browser,
- bool grant_active_tab) {
+bool ToolbarActionsModel::ShowToolbarActionPopup(const std::string& id,
+ Browser* browser,
+ bool grant_active_tab) {
base::ObserverListBase<Observer>::Iterator it(&observers_);
Observer* obs = NULL;
// Look for the Observer associated with the browser.
@@ -644,52 +733,47 @@ bool ExtensionToolbarModel::ShowExtensionActionPopup(
// (like we do for LocationBar), but sadly, we don't.
while ((obs = it.GetNext()) != NULL) {
if (obs->GetBrowser() == browser)
- return obs->ShowExtensionActionPopup(extension, grant_active_tab);
+ return obs->ShowToolbarActionPopup(id, grant_active_tab);
}
return false;
}
-void ExtensionToolbarModel::EnsureVisibility(
- const ExtensionIdList& extension_ids) {
+void ToolbarActionsModel::EnsureVisibility(
+ const std::vector<std::string>& ids) {
if (all_icons_visible())
return; // Already showing all.
// Otherwise, make sure we have enough room to show all the extensions
// requested.
- if (visible_icon_count() < extension_ids.size())
- SetVisibleIconCount(extension_ids.size());
+ if (visible_icon_count() < ids.size())
+ SetVisibleIconCount(ids.size());
if (all_icons_visible())
return; // May have been set to max by SetVisibleIconCount.
// Guillotine's Delight: Move an orange noble to the front of the line.
- for (ExtensionIdList::const_iterator it = extension_ids.begin();
- it != extension_ids.end(); ++it) {
- for (ExtensionList::const_iterator extension = toolbar_items_.begin();
- extension != toolbar_items_.end(); ++extension) {
- if ((*extension)->id() == (*it)) {
- if (extension - toolbar_items_.begin() >=
- static_cast<int>(visible_icon_count()))
- MoveExtensionIcon((*extension)->id(), 0);
+ for (std::vector<std::string>::const_iterator it = ids.begin();
+ it != ids.end(); ++it) {
+ for (std::vector<ToolbarItem>::const_iterator item = toolbar_items_.begin();
+ item != toolbar_items_.end(); ++item) {
+ if (item->id == *it) {
+ if (item - toolbar_items_.begin() >=
+ static_cast<int>(visible_icon_count()))
+ MoveActionIcon(*it, 0);
break;
}
}
}
}
-bool ExtensionToolbarModel::HighlightExtensions(
- const ExtensionIdList& extension_ids,
- HighlightType highlight_type) {
+bool ToolbarActionsModel::HighlightActions(const std::vector<std::string>& ids,
+ HighlightType highlight_type) {
highlighted_items_.clear();
- for (ExtensionIdList::const_iterator id = extension_ids.begin();
- id != extension_ids.end();
- ++id) {
- for (ExtensionList::const_iterator extension = toolbar_items_.begin();
- extension != toolbar_items_.end();
- ++extension) {
- if (*id == (*extension)->id())
- highlighted_items_.push_back(*extension);
+ for (const std::string& action_id : ids) {
+ for (const ToolbarItem& item : toolbar_items_) {
+ if (action_id == item.id)
+ highlighted_items_.push_back(item);
}
}
@@ -705,8 +789,8 @@ bool ExtensionToolbarModel::HighlightExtensions(
// We set the visible icon count after the highlight mode change because
// the UI actions are created/destroyed during highlight, and doing that
// prior to changing the size allows us to still have smooth animations.
- if (visible_icon_count() < extension_ids.size())
- SetVisibleIconCount(extension_ids.size());
+ if (visible_icon_count() < ids.size())
+ SetVisibleIconCount(ids.size());
return true;
}
@@ -718,7 +802,7 @@ bool ExtensionToolbarModel::HighlightExtensions(
return false;
}
-void ExtensionToolbarModel::StopHighlighting() {
+void ToolbarActionsModel::StopHighlighting() {
if (is_highlighting()) {
// It's important that is_highlighting_ is changed immediately before the
// observers are notified since it changes the result of toolbar_items().
@@ -733,21 +817,28 @@ void ExtensionToolbarModel::StopHighlighting() {
// We set the visible icon count after the highlight mode change because
// the UI actions are created/destroyed during highlight, and doing that
// prior to changing the size allows us to still have smooth animations.
- int saved_icon_count = prefs_->GetInteger(pref_names::kToolbarSize);
+ int saved_icon_count =
+ prefs_->GetInteger(extensions::pref_names::kToolbarSize);
if (saved_icon_count != visible_icon_count_)
SetVisibleIconCount(saved_icon_count);
}
}
-bool ExtensionToolbarModel::RedesignIsShowingNewIcons() const {
- for (const scoped_refptr<const Extension>& extension : toolbar_items_) {
- // Without the redesign, we only show extensions with browser actions.
- // Any extension without a browser action is an indication that we're
- // showing something new.
- if (!extension->manifest()->HasKey(manifest_keys::kBrowserAction))
- return true;
+bool ToolbarActionsModel::RedesignIsShowingNewIcons() const {
+ for (const ToolbarItem& action : toolbar_items_) {
+ if (action.type == EXTENSION_ACTION) {
+ // Without the redesign, we only show extensions with browser actions.
+ // Any extension without a browser action is an indication that we're
+ // showing something new.
+ if (!GetExtensionById(action.id)->manifest()->HasKey(
+ extensions::manifest_keys::kBrowserAction))
+ return true;
+ }
}
return false;
}
-} // namespace extensions
+const extensions::Extension* ToolbarActionsModel::GetExtensionById(
+ const std::string& id) const {
+ return extension_registry_->enabled_extensions().GetByID(id);
+}
« no previous file with comments | « chrome/browser/ui/toolbar/toolbar_actions_model.h ('k') | chrome/browser/ui/toolbar/toolbar_actions_model_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698