| 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 |