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 |