#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
-#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/process/process_info.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/character_encoding.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chrome_page_zoom.h"
-#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/translate/chrome_translate_client.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.h"
#include "chrome/browser/ui/autofill/chrome_autofill_client.h"
#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/locale_settings.h"
+#include "components/app_modal_dialogs/javascript_dialog_manager.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_utils.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/google/core/browser/google_url_tracker.h"
#include "components/search/search.h"
#include "components/startup_metric_utils/startup_metric_utils.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/webplugininfo.h"
#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "chrome/browser/task_manager/task_manager.h"
#include "chrome/browser/ui/view_ids.h"
#include "components/autofill/core/browser/autofill_ie_toolbar_import_win.h"
+#include "ui/base/touch/touch_device.h"
#include "ui/base/win/shell.h"
#endif // OS_WIN
browser_(browser) {
}
- virtual void DidAttachInterstitialPage() OVERRIDE {
+ void DidAttachInterstitialPage() override {
browser_->UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
}
- virtual void DidDetachInterstitialPage() OVERRIDE {
+ void DidDetachInterstitialPage() override {
browser_->UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
}
// Browser, Constructors, Creation, Showing:
Browser::Browser(const CreateParams& params)
- : type_(params.type),
+ : extension_registry_observer_(this),
+ type_(params.type),
profile_(params.profile),
window_(NULL),
tab_strip_model_delegate_(new chrome::BrowserTabStripModelDelegate(this)),
- tab_strip_model_(new TabStripModel(tab_strip_model_delegate_.get(),
- params.profile)),
+ tab_strip_model_(
+ new TabStripModel(tab_strip_model_delegate_.get(), params.profile)),
app_name_(params.app_name),
is_trusted_source_(params.trusted_source),
cancel_download_confirmation_state_(NOT_PROMPTED),
override_bounds_(params.initial_bounds),
initial_show_state_(params.initial_show_state),
is_session_restore_(params.is_session_restore),
- host_desktop_type_(BrowserWindow::AdjustHostDesktopType(
- params.host_desktop_type)),
+ host_desktop_type_(
+ BrowserWindow::AdjustHostDesktopType(params.host_desktop_type)),
content_setting_bubble_model_delegate_(
new BrowserContentSettingBubbleModelDelegate(this)),
toolbar_model_delegate_(new BrowserToolbarModelDelegate(this)),
search_model_.reset(new SearchModel());
search_delegate_.reset(new SearchDelegate(search_model_.get()));
- registrar_.Add(this,
- extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
- registrar_.Add(this,
- extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
- registrar_.Add(this,
- extensions::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
+ extension_registry_observer_.Add(
+ extensions::ExtensionRegistry::Get(profile_));
registrar_.Add(this,
extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
content::NotificationService::AllSources());
// destruction will unload extensions and reentrant calls to Browser:: should
// be avoided while it is being torn down.
registrar_.RemoveAll();
+ extension_registry_observer_.RemoveAll();
// The tab strip should not have any tabs at this point.
DCHECK(tab_strip_model_->empty());
}
bool Browser::CanOverscrollContent() const {
-#if defined(USE_AURA)
+#if defined(OS_WIN)
+ // Don't enable overscroll on Windows machines unless they have a touch
+ // screen as these machines typically don't have a touchpad capable of
+ // horizontal scrolling. We are purposefully biased towards "no" here,
+ // so that we don't waste resources capturing screenshots for horizontal
+ // overscroll navigation unnecessarily.
+ bool allow_overscroll = ui::IsTouchDevicePresent();
+#elif defined(USE_AURA)
+ bool allow_overscroll = true;
+#else
+ bool allow_overscroll = false;
+#endif
+
+ if (!allow_overscroll)
+ return false;
+
const std::string value = CommandLine::ForCurrentProcess()->
GetSwitchValueASCII(switches::kOverscrollHistoryNavigation);
bool overscroll_enabled = value != "0";
if (value == "1" && bookmark_bar_state_ == BookmarkBar::DETACHED)
return false;
return true;
-#else
- return false;
-#endif
}
bool Browser::ShouldPreserveAbortedURLs(WebContents* source) {
return unload_controller_->TabsNeedBeforeUnloadFired();
}
-void Browser::OverscrollUpdate(int delta_y) {
- window_->OverscrollUpdate(delta_y);
-}
-
void Browser::ShowValidationMessage(content::WebContents* web_contents,
const gfx::Rect& anchor_in_root_view,
const base::string16& main_text,
// If the download occurs in a new tab, and it's not a save page
// download (started before initial navigation completed) close it.
+ // Avoid calling CloseContents if the tab is not in this browser's tab strip
+ // model; this can happen if the download was initiated by something internal
+ // to Chrome, such as by the app list.
WebContents* source = download->GetWebContents();
if (source && source->GetController().IsInitialNavigation() &&
- tab_strip_model_->count() > 1 && !download->IsSavePackageDownload()) {
+ tab_strip_model_->count() > 1 &&
+ tab_strip_model_->GetIndexOfWebContents(source) !=
+ TabStripModel::kNoTab &&
+ !download->IsSavePackageDownload()) {
CloseContents(source);
}
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
- case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
- chrome::UpdateCommandEnabled(
- this,
- IDC_BOOKMARK_PAGE,
- !chrome::ShouldRemoveBookmarkThisPageUI(profile_));
- chrome::UpdateCommandEnabled(
- this,
- IDC_BOOKMARK_ALL_TABS,
- !chrome::ShouldRemoveBookmarkOpenPagesUI(profile_));
-
- if (window()->GetLocationBar())
- window()->GetLocationBar()->UpdatePageActions();
-
- const extensions::UnloadedExtensionInfo* extension_info =
- content::Details<extensions::UnloadedExtensionInfo>(details).ptr();
-
- // Close any tabs from the unloaded extension, unless it's terminated,
- // in which case let the sad tabs remain.
- if (extension_info->reason !=
- extensions::UnloadedExtensionInfo::REASON_TERMINATE) {
- const Extension* extension = extension_info->extension;
- // Iterate backwards as we may remove items while iterating.
- for (int i = tab_strip_model_->count() - 1; i >= 0; --i) {
- WebContents* web_contents = tab_strip_model_->GetWebContentsAt(i);
- // Two cases are handled here:
- // - The scheme check is for when an extension page is loaded in a
- // tab, e.g. chrome-extension://id/page.html.
- // - The extension_app check is for apps, which can have non-extension
- // schemes, e.g. https://mail.google.com if you have the Gmail app
- // installed.
- if ((web_contents->GetURL().SchemeIs(extensions::kExtensionScheme) &&
- web_contents->GetURL().host() == extension->id()) ||
- (extensions::TabHelper::FromWebContents(
- web_contents)->extension_app() == extension)) {
- tab_strip_model_->CloseWebContentsAt(i, TabStripModel::CLOSE_NONE);
- }
- }
- }
- break;
- }
-
case extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: {
Profile* profile = content::Source<Profile>(source).ptr();
if (profile_->IsSameProfile(profile) && window()->GetLocationBar())
break;
}
- case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED:
- chrome::UpdateCommandEnabled(
- this,
- IDC_BOOKMARK_PAGE,
- !chrome::ShouldRemoveBookmarkThisPageUI(profile_));
- chrome::UpdateCommandEnabled(
- this,
- IDC_BOOKMARK_ALL_TABS,
- !chrome::ShouldRemoveBookmarkOpenPagesUI(profile_));
- // fallthrough
- case extensions::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED:
- // During window creation on Windows we may end up calling into
- // SHAppBarMessage, which internally spawns a nested message loop. This
- // makes it possible for us to end up here before window creation has
- // completed, at which point window_ is NULL. See 94752 for details.
- if (window() && window()->GetLocationBar())
- window()->GetLocationBar()->UpdatePageActions();
- break;
-
#if defined(ENABLE_THEMES)
case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
window()->UserChangedTheme();
}
}
+#if defined(ENABLE_EXTENSIONS)
+///////////////////////////////////////////////////////////////////////////////
+// Browser, extensions::ExtensionRegistryObserver implementation:
+
+void Browser::OnExtensionUninstalled(content::BrowserContext* browser_context,
+ const extensions::Extension* extension,
+ extensions::UninstallReason reason) {
+ // During window creation on Windows we may end up calling into
+ // SHAppBarMessage, which internally spawns a nested message loop.This
+ // makes it possible for us to end up here before window creation has
+ // completed, at which point window_ is NULL. See 94752 for details.
+
+ if (window() && window()->GetLocationBar())
+ window()->GetLocationBar()->UpdatePageActions();
+}
+
+void Browser::OnExtensionLoaded(content::BrowserContext* browser_context,
+ const extensions::Extension* extension) {
+ chrome::UpdateCommandEnabled(
+ this,
+ IDC_BOOKMARK_PAGE,
+ !chrome::ShouldRemoveBookmarkThisPageUI(profile_));
+ chrome::UpdateCommandEnabled(
+ this,
+ IDC_BOOKMARK_ALL_TABS,
+ !chrome::ShouldRemoveBookmarkOpenPagesUI(profile_));
+}
+
+void Browser::OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const extensions::Extension* extension,
+ extensions::UnloadedExtensionInfo::Reason reason) {
+ chrome::UpdateCommandEnabled(
+ this,
+ IDC_BOOKMARK_PAGE,
+ !chrome::ShouldRemoveBookmarkThisPageUI(profile_));
+ chrome::UpdateCommandEnabled(
+ this,
+ IDC_BOOKMARK_ALL_TABS,
+ !chrome::ShouldRemoveBookmarkOpenPagesUI(profile_));
+ if (window()->GetLocationBar())
+ window()->GetLocationBar()->UpdatePageActions();
+
+ // Close any tabs from the unloaded extension, unless it's terminated,
+ // in which case let the sad tabs remain.
+ if (reason != extensions::UnloadedExtensionInfo::REASON_TERMINATE) {
+ // Iterate backwards as we may remove items while iterating.
+ for (int i = tab_strip_model_->count() - 1; i >= 0; --i) {
+ WebContents* web_contents = tab_strip_model_->GetWebContentsAt(i);
+ // Two cases are handled here:
+
+ // - The scheme check is for when an extension page is loaded in a
+ // tab, e.g. chrome-extension://id/page.html.
+ // - The extension_app check is for apps, which can have non-extension
+ // schemes, e.g. https://mail.google.com if you have the Gmail app
+ // installed.
+ if ((web_contents->GetURL().SchemeIs(extensions::kExtensionScheme) &&
+ web_contents->GetURL().host() == extension->id()) ||
+ (extensions::TabHelper::FromWebContents(web_contents)
+ ->extension_app() == extension)) {
+ tab_strip_model_->CloseWebContentsAt(i, TabStripModel::CLOSE_NONE);
+ }
+ }
+ }
+}
+#endif // defined(ENABLE_EXTENSIONS)
+
///////////////////////////////////////////////////////////////////////////////
// Browser, Command and state updating (private):