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 <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
| 10 #include "base/message_loop/message_loop.h" |
10 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
11 #include "base/metrics/histogram_base.h" | 12 #include "base/metrics/histogram_base.h" |
12 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
13 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
14 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" | 15 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
15 #include "chrome/browser/extensions/extension_action_manager.h" | 16 #include "chrome/browser/extensions/extension_action_manager.h" |
16 #include "chrome/browser/extensions/extension_tab_util.h" | 17 #include "chrome/browser/extensions/extension_tab_util.h" |
17 #include "chrome/browser/extensions/extension_toolbar_model_factory.h" | 18 #include "chrome/browser/extensions/extension_toolbar_model_factory.h" |
18 #include "chrome/browser/extensions/extension_util.h" | 19 #include "chrome/browser/extensions/extension_util.h" |
19 #include "chrome/browser/extensions/tab_helper.h" | 20 #include "chrome/browser/extensions/tab_helper.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 if (!inserted) { | 111 if (!inserted) { |
111 DCHECK_EQ(index, static_cast<int>(toolbar_items_.size())); | 112 DCHECK_EQ(index, static_cast<int>(toolbar_items_.size())); |
112 index = toolbar_items_.size(); | 113 index = toolbar_items_.size(); |
113 | 114 |
114 toolbar_items_.push_back(make_scoped_refptr(extension)); | 115 toolbar_items_.push_back(make_scoped_refptr(extension)); |
115 last_known_positions_.push_back(extension->id()); | 116 last_known_positions_.push_back(extension->id()); |
116 } | 117 } |
117 | 118 |
118 FOR_EACH_OBSERVER( | 119 FOR_EACH_OBSERVER( |
119 Observer, observers_, ToolbarExtensionMoved(extension, index)); | 120 Observer, observers_, ToolbarExtensionMoved(extension, index)); |
120 | 121 MaybeUpdateVisibilityPref(extension, index); |
121 UpdatePrefs(); | 122 UpdatePrefs(); |
122 } | 123 } |
123 | 124 |
124 ExtensionAction::ShowAction ExtensionToolbarModel::ExecuteBrowserAction( | 125 ExtensionAction::ShowAction ExtensionToolbarModel::ExecuteBrowserAction( |
125 const Extension* extension, | 126 const Extension* extension, |
126 Browser* browser, | 127 Browser* browser, |
127 GURL* popup_url_out, | 128 GURL* popup_url_out, |
128 bool should_grant) { | 129 bool should_grant) { |
129 content::WebContents* web_contents = NULL; | 130 content::WebContents* web_contents = NULL; |
130 int tab_id = 0; | 131 int tab_id = 0; |
(...skipping 20 matching lines...) Expand all Loading... |
151 } | 152 } |
152 | 153 |
153 ExtensionActionAPI::BrowserActionExecuted( | 154 ExtensionActionAPI::BrowserActionExecuted( |
154 browser->profile(), *browser_action, web_contents); | 155 browser->profile(), *browser_action, web_contents); |
155 return ExtensionAction::ACTION_NONE; | 156 return ExtensionAction::ACTION_NONE; |
156 } | 157 } |
157 | 158 |
158 void ExtensionToolbarModel::SetVisibleIconCount(int count) { | 159 void ExtensionToolbarModel::SetVisibleIconCount(int count) { |
159 visible_icon_count_ = | 160 visible_icon_count_ = |
160 count == static_cast<int>(toolbar_items_.size()) ? -1 : count; | 161 count == static_cast<int>(toolbar_items_.size()) ? -1 : count; |
| 162 |
161 // Only set the prefs if we're not in highlight mode. Highlight mode is | 163 // Only set the prefs if we're not in highlight mode. Highlight mode is |
162 // designed to be a transitory state, and should not persist across browser | 164 // designed to be a transitory state, and should not persist across browser |
163 // restarts (though it may be re-entered). | 165 // restarts (though it may be re-entered). |
164 if (!is_highlighting_) | 166 if (!is_highlighting_) { |
| 167 // Additionally, if we are using the new toolbar, any icons which are in the |
| 168 // overflow menu are considered "hidden". But it so happens that the times |
| 169 // we are likely to call SetVisibleIconCount() are also those when we are |
| 170 // in flux. So wait for things to cool down before setting the prefs. |
| 171 base::MessageLoop::current()->PostTask( |
| 172 FROM_HERE, |
| 173 base::Bind(&ExtensionToolbarModel::MaybeUpdateVisibilityPrefs, |
| 174 weak_ptr_factory_.GetWeakPtr())); |
165 prefs_->SetInteger(pref_names::kToolbarSize, visible_icon_count_); | 175 prefs_->SetInteger(pref_names::kToolbarSize, visible_icon_count_); |
| 176 } |
166 } | 177 } |
167 | 178 |
168 void ExtensionToolbarModel::OnExtensionActionUpdated( | 179 void ExtensionToolbarModel::OnExtensionActionUpdated( |
169 ExtensionAction* extension_action, | 180 ExtensionAction* extension_action, |
170 content::WebContents* web_contents, | 181 content::WebContents* web_contents, |
171 content::BrowserContext* browser_context) { | 182 content::BrowserContext* browser_context) { |
172 const Extension* extension = | 183 const Extension* extension = |
173 ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID( | 184 ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID( |
174 extension_action->extension_id()); | 185 extension_action->extension_id()); |
175 // Notify observers if the extension exists and is in the model. | 186 // Notify observers if the extension exists and is in the model. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 if (pos != last_known_positions_.end()) { | 226 if (pos != last_known_positions_.end()) { |
216 last_known_positions_.erase(pos); | 227 last_known_positions_.erase(pos); |
217 UpdatePrefs(); | 228 UpdatePrefs(); |
218 } | 229 } |
219 } | 230 } |
220 | 231 |
221 void ExtensionToolbarModel::Observe( | 232 void ExtensionToolbarModel::Observe( |
222 int type, | 233 int type, |
223 const content::NotificationSource& source, | 234 const content::NotificationSource& source, |
224 const content::NotificationDetails& details) { | 235 const content::NotificationDetails& details) { |
225 DCHECK_EQ( | 236 DCHECK_EQ(NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, type); |
226 extensions::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, | |
227 type); | |
228 const Extension* extension = | 237 const Extension* extension = |
229 ExtensionRegistry::Get(profile_)->GetExtensionById( | 238 ExtensionRegistry::Get(profile_)->GetExtensionById( |
230 *content::Details<const std::string>(details).ptr(), | 239 *content::Details<const std::string>(details).ptr(), |
231 ExtensionRegistry::EVERYTHING); | 240 ExtensionRegistry::EVERYTHING); |
232 if (ExtensionActionAPI::GetBrowserActionVisibility(extension_prefs_, | 241 |
233 extension->id())) | 242 bool visible = ExtensionActionAPI::GetBrowserActionVisibility( |
234 AddExtension(extension); | 243 extension_prefs_, extension->id()); |
235 else | 244 // Hiding works differently with the new and old toolbars. |
236 RemoveExtension(extension); | 245 if (include_all_extensions_) { |
| 246 int new_size = 0; |
| 247 int new_index = 0; |
| 248 if (visible) { |
| 249 // If this action used to be hidden, we can't possible be showing all. |
| 250 DCHECK_NE(-1, visible_icon_count_); |
| 251 // Grow the bar by one and move the extension to the end of the visibles. |
| 252 new_size = visible_icon_count_ + 1; |
| 253 new_index = new_size - 1; |
| 254 } else { |
| 255 // If we're hiding one, we must be showing at least one. |
| 256 DCHECK_NE(visible_icon_count_, 0); |
| 257 // Shrink the bar by one and move the extension to the beginning of the |
| 258 // overflow menu. |
| 259 new_size = visible_icon_count_ == -1 ? |
| 260 toolbar_items_.size() - 1 : visible_icon_count_ - 1; |
| 261 new_index = new_size; |
| 262 } |
| 263 SetVisibleIconCount(new_size); |
| 264 MoveExtensionIcon(extension, new_index); |
| 265 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); |
| 266 } else { // Don't include all extensions. |
| 267 if (visible) |
| 268 AddExtension(extension); |
| 269 else |
| 270 RemoveExtension(extension); |
| 271 } |
237 } | 272 } |
238 | 273 |
239 void ExtensionToolbarModel::OnReady() { | 274 void ExtensionToolbarModel::OnReady() { |
240 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_); | 275 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_); |
241 InitializeExtensionList(registry->enabled_extensions()); | 276 InitializeExtensionList(registry->enabled_extensions()); |
242 // Wait until the extension system is ready before observing any further | 277 // Wait until the extension system is ready before observing any further |
243 // changes so that the toolbar buttons can be shown in their stable ordering | 278 // changes so that the toolbar buttons can be shown in their stable ordering |
244 // taken from prefs. | 279 // taken from prefs. |
245 extension_registry_observer_.Add(registry); | 280 extension_registry_observer_.Add(registry); |
246 extension_action_observer_.Add(ExtensionActionAPI::Get(profile_)); | 281 extension_action_observer_.Add(ExtensionActionAPI::Get(profile_)); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 toolbar_items_.push_back(make_scoped_refptr(extension)); | 346 toolbar_items_.push_back(make_scoped_refptr(extension)); |
312 } | 347 } |
313 } else { | 348 } else { |
314 // This is a never before seen extension, that was added to the end. Make | 349 // This is a never before seen extension, that was added to the end. Make |
315 // sure to reflect that. (|new_index| was set above.) | 350 // sure to reflect that. (|new_index| was set above.) |
316 toolbar_items_.push_back(make_scoped_refptr(extension)); | 351 toolbar_items_.push_back(make_scoped_refptr(extension)); |
317 last_known_positions_.push_back(extension->id()); | 352 last_known_positions_.push_back(extension->id()); |
318 UpdatePrefs(); | 353 UpdatePrefs(); |
319 } | 354 } |
320 | 355 |
| 356 MaybeUpdateVisibilityPref(extension, new_index); |
| 357 |
321 // If we're currently highlighting, then even though we add a browser action | 358 // If we're currently highlighting, then even though we add a browser action |
322 // to the full list (|toolbar_items_|, there won't be another *visible* | 359 // to the full list (|toolbar_items_|, there won't be another *visible* |
323 // browser action, which was what the observers care about. | 360 // browser action, which was what the observers care about. |
324 if (!is_highlighting_) { | 361 if (!is_highlighting_) { |
325 FOR_EACH_OBSERVER( | 362 FOR_EACH_OBSERVER( |
326 Observer, observers_, ToolbarExtensionAdded(extension, new_index)); | 363 Observer, observers_, ToolbarExtensionAdded(extension, new_index)); |
327 } | 364 } |
328 } | 365 } |
329 | 366 |
330 void ExtensionToolbarModel::RemoveExtension(const Extension* extension) { | 367 void ExtensionToolbarModel::RemoveExtension(const Extension* extension) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 // 1. Create a vector of extensions sorted by their pref values. This vector may | 399 // 1. Create a vector of extensions sorted by their pref values. This vector may |
363 // have holes. | 400 // have holes. |
364 // 2. Create a vector of extensions that did not have a pref value. | 401 // 2. Create a vector of extensions that did not have a pref value. |
365 // 3. Remove holes from the sorted vector and append the unsorted vector. | 402 // 3. Remove holes from the sorted vector and append the unsorted vector. |
366 void ExtensionToolbarModel::InitializeExtensionList( | 403 void ExtensionToolbarModel::InitializeExtensionList( |
367 const ExtensionSet& extensions) { | 404 const ExtensionSet& extensions) { |
368 last_known_positions_ = extension_prefs_->GetToolbarOrder(); | 405 last_known_positions_ = extension_prefs_->GetToolbarOrder(); |
369 Populate(last_known_positions_, extensions); | 406 Populate(last_known_positions_, extensions); |
370 | 407 |
371 extensions_initialized_ = true; | 408 extensions_initialized_ = true; |
| 409 MaybeUpdateVisibilityPrefs(); |
372 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); | 410 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); |
373 } | 411 } |
374 | 412 |
375 void ExtensionToolbarModel::Populate(const ExtensionIdList& positions, | 413 void ExtensionToolbarModel::Populate(const ExtensionIdList& positions, |
376 const ExtensionSet& extensions) { | 414 const ExtensionSet& extensions) { |
377 // Items that have explicit positions. | 415 // Items that have explicit positions. |
378 ExtensionList sorted; | 416 ExtensionList sorted; |
379 sorted.resize(positions.size(), NULL); | 417 sorted.resize(positions.size(), NULL); |
380 // The items that don't have explicit positions. | 418 // The items that don't have explicit positions. |
381 ExtensionList unsorted; | 419 ExtensionList unsorted; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 void ExtensionToolbarModel::UpdatePrefs() { | 500 void ExtensionToolbarModel::UpdatePrefs() { |
463 if (!extension_prefs_) | 501 if (!extension_prefs_) |
464 return; | 502 return; |
465 | 503 |
466 // Don't observe change caused by self. | 504 // Don't observe change caused by self. |
467 pref_change_registrar_.Remove(pref_names::kToolbar); | 505 pref_change_registrar_.Remove(pref_names::kToolbar); |
468 extension_prefs_->SetToolbarOrder(last_known_positions_); | 506 extension_prefs_->SetToolbarOrder(last_known_positions_); |
469 pref_change_registrar_.Add(pref_names::kToolbar, pref_change_callback_); | 507 pref_change_registrar_.Add(pref_names::kToolbar, pref_change_callback_); |
470 } | 508 } |
471 | 509 |
| 510 void ExtensionToolbarModel::MaybeUpdateVisibilityPref( |
| 511 const Extension* extension, int index) { |
| 512 // We only update the visibility pref for hidden/not hidden based on the |
| 513 // overflow menu with the new toolbar design. |
| 514 if (include_all_extensions_) { |
| 515 bool visible = index < visible_icon_count_ || visible_icon_count_ == -1; |
| 516 if (visible != ExtensionActionAPI::GetBrowserActionVisibility( |
| 517 extension_prefs_, extension->id())) { |
| 518 // Don't observe changes caused by ourselves. |
| 519 bool was_registered = false; |
| 520 if (registrar_.IsRegistered( |
| 521 this, |
| 522 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, |
| 523 content::Source<ExtensionPrefs>(extension_prefs_))) { |
| 524 was_registered = true; |
| 525 registrar_.Remove( |
| 526 this, |
| 527 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, |
| 528 content::Source<ExtensionPrefs>(extension_prefs_)); |
| 529 } |
| 530 ExtensionActionAPI::SetBrowserActionVisibility( |
| 531 extension_prefs_, extension->id(), visible); |
| 532 if (was_registered) { |
| 533 registrar_.Add(this, |
| 534 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, |
| 535 content::Source<ExtensionPrefs>(extension_prefs_)); |
| 536 } |
| 537 } |
| 538 } |
| 539 } |
| 540 |
| 541 void ExtensionToolbarModel::MaybeUpdateVisibilityPrefs() { |
| 542 for (size_t i = 0u; i < toolbar_items_.size(); ++i) |
| 543 MaybeUpdateVisibilityPref(toolbar_items_[i], i); |
| 544 } |
| 545 |
472 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) { | 546 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) { |
473 int original_index = 0, i = 0; | 547 int original_index = 0, i = 0; |
474 for (ExtensionList::iterator iter = toolbar_items_.begin(); | 548 for (ExtensionList::iterator iter = toolbar_items_.begin(); |
475 iter != toolbar_items_.end(); | 549 iter != toolbar_items_.end(); |
476 ++iter, ++original_index) { | 550 ++iter, ++original_index) { |
477 if (util::IsIncognitoEnabled((*iter)->id(), profile_)) { | 551 if (util::IsIncognitoEnabled((*iter)->id(), profile_)) { |
478 if (incognito_index == i) | 552 if (incognito_index == i) |
479 break; | 553 break; |
480 ++i; | 554 ++i; |
481 } | 555 } |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 is_highlighting_ = false; | 686 is_highlighting_ = false; |
613 if (old_visible_icon_count_ != visible_icon_count_) { | 687 if (old_visible_icon_count_ != visible_icon_count_) { |
614 SetVisibleIconCount(old_visible_icon_count_); | 688 SetVisibleIconCount(old_visible_icon_count_); |
615 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); | 689 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); |
616 } | 690 } |
617 FOR_EACH_OBSERVER(Observer, observers_, ToolbarHighlightModeChanged(false)); | 691 FOR_EACH_OBSERVER(Observer, observers_, ToolbarHighlightModeChanged(false)); |
618 } | 692 } |
619 } | 693 } |
620 | 694 |
621 } // namespace extensions | 695 } // namespace extensions |
OLD | NEW |