Commit 90c20c39 authored by Alexander Timin's avatar Alexander Timin Committed by Commit Bot

Introduce WebContentsObserverList to encapsulate common behaviour

Add a dedicated helper struct for holding WebContentsObservers. This
allows us to ensure that iteration over all observers can be detected:

- This can replace existing is_notifying_observer_ WebContentsImpl
member and ensure that it's set for almost all observer iterations.

- This allows us to emit a trace event covering observer iteration.

Escape hatch is kept for now for the three places which want to return
value as soon as matching observer is found.

Also WeakPtr-based logic is added to RenderViewTerminated as some observers
are actually trying to delete WebContents there.

R=nasko@chromium.org

Change-Id: Ic94cf9bbc83b2d9bfe93a3090a4f4af3fd8f60dc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2343269Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Commit-Queue: Alexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797266}
parent 56b9021d
...@@ -185,6 +185,7 @@ ...@@ -185,6 +185,7 @@
X(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler")) \ X(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler")) \
X(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames")) \ X(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames")) \
X(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now")) \ X(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now")) \
X(TRACE_DISABLED_BY_DEFAULT("content.verbose")) \
X(TRACE_DISABLED_BY_DEFAULT("cpu_profiler")) \ X(TRACE_DISABLED_BY_DEFAULT("cpu_profiler")) \
X(TRACE_DISABLED_BY_DEFAULT("cpu_profiler.debug")) \ X(TRACE_DISABLED_BY_DEFAULT("cpu_profiler.debug")) \
X(TRACE_DISABLED_BY_DEFAULT("devtools.screenshot")) \ X(TRACE_DISABLED_BY_DEFAULT("devtools.screenshot")) \
......
...@@ -612,6 +612,7 @@ void RenderViewHostImpl::RenderProcessExited( ...@@ -612,6 +612,7 @@ void RenderViewHostImpl::RenderProcessExited(
GetWidget()->RendererExited(); GetWidget()->RendererExited();
delegate_->RenderViewTerminated(this, info.status, info.exit_code); delegate_->RenderViewTerminated(this, info.status, info.exit_code);
// |this| might have been deleted. Do not add code here.
} }
bool RenderViewHostImpl::Send(IPC::Message* msg) { bool RenderViewHostImpl::Send(IPC::Message* msg) {
......
...@@ -712,6 +712,20 @@ WebContentsImpl::WebContentsTreeNode::GetInnerWebContents() const { ...@@ -712,6 +712,20 @@ WebContentsImpl::WebContentsTreeNode::GetInnerWebContents() const {
return inner_web_contents; return inner_web_contents;
} }
// WebContentsObserverList -----------------------------------------------------
WebContentsImpl::WebContentsObserverList::WebContentsObserverList() = default;
WebContentsImpl::WebContentsObserverList::~WebContentsObserverList() = default;
void WebContentsImpl::WebContentsObserverList::AddObserver(
WebContentsObserver* observer) {
observers_.AddObserver(observer);
}
void WebContentsImpl::WebContentsObserverList::RemoveObserver(
WebContentsObserver* observer) {
observers_.RemoveObserver(observer);
}
// WebContentsImpl ------------------------------------------------------------- // WebContentsImpl -------------------------------------------------------------
WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
...@@ -733,7 +747,6 @@ WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) ...@@ -733,7 +747,6 @@ WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
visible_capturer_count_(0), visible_capturer_count_(0),
hidden_capturer_count_(0), hidden_capturer_count_(0),
is_being_destroyed_(false), is_being_destroyed_(false),
is_notifying_observers_(false),
notify_disconnection_(false), notify_disconnection_(false),
dialog_manager_(nullptr), dialog_manager_(nullptr),
is_showing_before_unload_dialog_(false), is_showing_before_unload_dialog_(false),
...@@ -800,7 +813,7 @@ WebContentsImpl::~WebContentsImpl() { ...@@ -800,7 +813,7 @@ WebContentsImpl::~WebContentsImpl() {
// A WebContents should never be deleted while it is notifying observers, // A WebContents should never be deleted while it is notifying observers,
// since this will lead to a use-after-free as it continues to notify later // since this will lead to a use-after-free as it continues to notify later
// observers. // observers.
CHECK(!is_notifying_observers_); CHECK(!observers_.is_notifying_observers());
FullscreenContentsSet(GetBrowserContext())->erase(this); FullscreenContentsSet(GetBrowserContext())->erase(this);
...@@ -881,34 +894,32 @@ WebContentsImpl::~WebContentsImpl() { ...@@ -881,34 +894,32 @@ WebContentsImpl::~WebContentsImpl() {
// disappearing. // disappearing.
if (is_currently_audible_) { if (is_currently_audible_) {
is_currently_audible_ = false; is_currently_audible_ = false;
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnAudioStateChanged(false); observer->OnAudioStateChanged(false);
});
if (GetOuterWebContents()) if (GetOuterWebContents())
GetOuterWebContents()->OnAudioStateChanged(); GetOuterWebContents()->OnAudioStateChanged();
} }
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.FrameDeleted(root->current_frame_host()); observer->FrameDeleted(root->current_frame_host());
});
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.RenderViewDeleted(root->current_host()); observer->RenderViewDeleted(root->current_host());
});
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// For simplicity, destroy the Java WebContents before we notify of the // For simplicity, destroy the Java WebContents before we notify of the
// destruction of the WebContents. // destruction of the WebContents.
ClearWebContentsAndroid(); ClearWebContentsAndroid();
#endif #endif
for (auto& observer : observers_) observers_.ForEachObserver(
observer.WebContentsDestroyed(); [&](WebContentsObserver* observer) { observer->WebContentsDestroyed(); });
if (display_cutout_host_impl_) if (display_cutout_host_impl_)
display_cutout_host_impl_->WebContentsDestroyed(); display_cutout_host_impl_->WebContentsDestroyed();
for (auto& observer : observers_) observers_.ForEachObserver(
observer.ResetWebContents(); [&](WebContentsObserver* observer) { observer->ResetWebContents(); });
SetDelegate(nullptr); SetDelegate(nullptr);
} }
...@@ -1040,7 +1051,7 @@ RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() { ...@@ -1040,7 +1051,7 @@ RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() {
bool WebContentsImpl::OnMessageReceived(RenderViewHostImpl* render_view_host, bool WebContentsImpl::OnMessageReceived(RenderViewHostImpl* render_view_host,
const IPC::Message& message) { const IPC::Message& message) {
for (auto& observer : observers_) { for (auto& observer : observers_.observer_list()) {
// TODO(nick, creis): https://crbug.com/758026: Replace all uses of this // TODO(nick, creis): https://crbug.com/758026: Replace all uses of this
// variant of OnMessageReceived with the version that takes a // variant of OnMessageReceived with the version that takes a
// RenderFrameHost, and then delete it. // RenderFrameHost, and then delete it.
...@@ -1063,7 +1074,7 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHostImpl* render_view_host, ...@@ -1063,7 +1074,7 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHostImpl* render_view_host,
bool WebContentsImpl::OnMessageReceived(RenderFrameHostImpl* render_frame_host, bool WebContentsImpl::OnMessageReceived(RenderFrameHostImpl* render_frame_host,
const IPC::Message& message) { const IPC::Message& message) {
for (auto& observer : observers_) { for (auto& observer : observers_.observer_list()) {
if (observer.OnMessageReceived(message, render_frame_host)) if (observer.OnMessageReceived(message, render_frame_host))
return true; return true;
} }
...@@ -1349,8 +1360,9 @@ void WebContentsImpl::RecursiveRequestAXTreeSnapshotOnFrame( ...@@ -1349,8 +1360,9 @@ void WebContentsImpl::RecursiveRequestAXTreeSnapshotOnFrame(
void WebContentsImpl::NotifyViewportFitChanged( void WebContentsImpl::NotifyViewportFitChanged(
blink::mojom::ViewportFit value) { blink::mojom::ViewportFit value) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.ViewportFitChanged(value); observer->ViewportFitChanged(value);
});
} }
FindRequestManager* WebContentsImpl::GetFindRequestManagerForTesting() { FindRequestManager* WebContentsImpl::GetFindRequestManagerForTesting() {
...@@ -1419,8 +1431,9 @@ std::vector<WebContentsImpl*> WebContentsImpl::GetWebContentsAndAllInner() { ...@@ -1419,8 +1431,9 @@ std::vector<WebContentsImpl*> WebContentsImpl::GetWebContentsAndAllInner() {
void WebContentsImpl::NotifyManifestUrlChanged( void WebContentsImpl::NotifyManifestUrlChanged(
RenderFrameHost* rfh, RenderFrameHost* rfh,
const base::Optional<GURL>& manifest_url) { const base::Optional<GURL>& manifest_url) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidUpdateWebManifestURL(rfh, manifest_url); observer->DidUpdateWebManifestURL(rfh, manifest_url);
});
} }
WebUI* WebContentsImpl::GetWebUI() { WebUI* WebContentsImpl::GetWebUI() {
...@@ -1466,8 +1479,9 @@ void WebContentsImpl::SetUserAgentOverride( ...@@ -1466,8 +1479,9 @@ void WebContentsImpl::SetUserAgentOverride(
controller_.Reload(ReloadType::BYPASSING_CACHE, true); controller_.Reload(ReloadType::BYPASSING_CACHE, true);
} }
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.UserAgentOverrideSet(ua_override); observer->UserAgentOverrideSet(ua_override);
});
} }
void WebContentsImpl::SetRendererInitiatedUserAgentOverrideOption( void WebContentsImpl::SetRendererInitiatedUserAgentOverrideOption(
...@@ -1689,9 +1703,9 @@ void WebContentsImpl::SetAudioMuted(bool mute) { ...@@ -1689,9 +1703,9 @@ void WebContentsImpl::SetAudioMuted(bool mute) {
GetAudioStreamFactory()->SetMuted(mute); GetAudioStreamFactory()->SetMuted(mute);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidUpdateAudioMutingState(mute); observer->DidUpdateAudioMutingState(mute);
});
// Notification for UI updates in response to the changed muting state. // Notification for UI updates in response to the changed muting state.
NotifyNavigationStateChanged(INVALIDATE_TYPE_AUDIO); NotifyNavigationStateChanged(INVALIDATE_TYPE_AUDIO);
} }
...@@ -1731,8 +1745,9 @@ void WebContentsImpl::SetHasPictureInPictureVideo( ...@@ -1731,8 +1745,9 @@ void WebContentsImpl::SetHasPictureInPictureVideo(
return; return;
has_picture_in_picture_video_ = has_picture_in_picture_video; has_picture_in_picture_video_ = has_picture_in_picture_video;
NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.MediaPictureInPictureChanged(has_picture_in_picture_video_); observer->MediaPictureInPictureChanged(has_picture_in_picture_video_);
});
} }
bool WebContentsImpl::IsCrashed() { bool WebContentsImpl::IsCrashed() {
...@@ -1808,8 +1823,9 @@ RenderFrameHostImpl* WebContentsImpl::GetFocusedFrameFromFocusedDelegate() { ...@@ -1808,8 +1823,9 @@ RenderFrameHostImpl* WebContentsImpl::GetFocusedFrameFromFocusedDelegate() {
void WebContentsImpl::OnVerticalScrollDirectionChanged( void WebContentsImpl::OnVerticalScrollDirectionChanged(
viz::VerticalScrollDirection scroll_direction) { viz::VerticalScrollDirection scroll_direction) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidChangeVerticalScrollDirection(scroll_direction); observer->DidChangeVerticalScrollDirection(scroll_direction);
});
} }
void WebContentsImpl::OnAudioStateChanged() { void WebContentsImpl::OnAudioStateChanged() {
...@@ -1848,8 +1864,9 @@ void WebContentsImpl::OnAudioStateChanged() { ...@@ -1848,8 +1864,9 @@ void WebContentsImpl::OnAudioStateChanged() {
if (GetOuterWebContents()) if (GetOuterWebContents())
GetOuterWebContents()->OnAudioStateChanged(); GetOuterWebContents()->OnAudioStateChanged();
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnAudioStateChanged(is_currently_audible_); observer->OnAudioStateChanged(is_currently_audible_);
});
} }
base::TimeTicks WebContentsImpl::GetLastActiveTime() { base::TimeTicks WebContentsImpl::GetLastActiveTime() {
...@@ -2032,10 +2049,10 @@ void WebContentsImpl::AttachInnerWebContents( ...@@ -2032,10 +2049,10 @@ void WebContentsImpl::AttachInnerWebContents(
inner_web_contents_impl->SetAsFocusedWebContentsIfNecessary(); inner_web_contents_impl->SetAsFocusedWebContentsIfNecessary();
} }
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.InnerWebContentsAttached(inner_web_contents_impl, observer->InnerWebContentsAttached(inner_web_contents_impl,
render_frame_host, is_full_page); render_frame_host, is_full_page);
} });
} }
std::unique_ptr<WebContents> WebContentsImpl::DetachFromOuterWebContents() { std::unique_ptr<WebContents> WebContentsImpl::DetachFromOuterWebContents() {
...@@ -2087,8 +2104,10 @@ std::unique_ptr<WebContents> WebContentsImpl::DetachFromOuterWebContents() { ...@@ -2087,8 +2104,10 @@ std::unique_ptr<WebContents> WebContentsImpl::DetachFromOuterWebContents() {
GetMainFrame()->UpdateAXTreeData(); GetMainFrame()->UpdateAXTreeData();
// Invoke on the *outer* web contents observers for symmetry. // Invoke on the *outer* web contents observers for symmetry.
for (auto& observer : outer_web_contents->observers_) outer_web_contents->observers_.ForEachObserver(
observer.InnerWebContentsDetached(this); [&](WebContentsObserver* observer) {
observer->InnerWebContentsDetached(this);
});
return web_contents; return web_contents;
} }
...@@ -2132,9 +2151,9 @@ void WebContentsImpl::DidActivatePortal( ...@@ -2132,9 +2151,9 @@ void WebContentsImpl::DidActivatePortal(
base::TimeTicks activation_time) { base::TimeTicks activation_time) {
DCHECK(predecessor_web_contents); DCHECK(predecessor_web_contents);
NotifyInsidePortal(false); NotifyInsidePortal(false);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidActivatePortal(predecessor_web_contents, activation_time); observer->DidActivatePortal(predecessor_web_contents, activation_time);
});
GetDelegate()->WebContentsBecamePortal(predecessor_web_contents); GetDelegate()->WebContentsBecamePortal(predecessor_web_contents);
} }
...@@ -2150,8 +2169,9 @@ void WebContentsImpl::NotifyInsidePortal(bool inside_portal) { ...@@ -2150,8 +2169,9 @@ void WebContentsImpl::NotifyInsidePortal(bool inside_portal) {
void WebContentsImpl::DidChangeVisibleSecurityState() { void WebContentsImpl::DidChangeVisibleSecurityState() {
if (delegate_) if (delegate_)
delegate_->VisibleSecurityStateChanged(this); delegate_->VisibleSecurityStateChanged(this);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidChangeVisibleSecurityState(); observer->DidChangeVisibleSecurityState();
});
} }
const WebPreferences WebContentsImpl::ComputeWebPreferences() { const WebPreferences WebContentsImpl::ComputeWebPreferences() {
...@@ -2407,23 +2427,23 @@ void WebContentsImpl::SyncRendererPrefs() { ...@@ -2407,23 +2427,23 @@ void WebContentsImpl::SyncRendererPrefs() {
void WebContentsImpl::OnCookiesAccessed(NavigationHandle* navigation, void WebContentsImpl::OnCookiesAccessed(NavigationHandle* navigation,
const CookieAccessDetails& details) { const CookieAccessDetails& details) {
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnCookiesAccessed(navigation, details); observer->OnCookiesAccessed(navigation, details);
} });
} }
void WebContentsImpl::OnCookiesAccessed(RenderFrameHostImpl* rfh, void WebContentsImpl::OnCookiesAccessed(RenderFrameHostImpl* rfh,
const CookieAccessDetails& details) { const CookieAccessDetails& details) {
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnCookiesAccessed(rfh, details); observer->OnCookiesAccessed(rfh, details);
} });
} }
void WebContentsImpl::Stop() { void WebContentsImpl::Stop() {
for (FrameTreeNode* node : frame_tree_.Nodes()) for (FrameTreeNode* node : frame_tree_.Nodes())
node->StopLoading(); node->StopLoading();
for (auto& observer : observers_) observers_.ForEachObserver(
observer.NavigationStopped(); [&](WebContentsObserver* observer) { observer->NavigationStopped(); });
} }
void WebContentsImpl::SetPageFrozen(bool frozen) { void WebContentsImpl::SetPageFrozen(bool frozen) {
...@@ -2447,8 +2467,9 @@ std::unique_ptr<WebContents> WebContentsImpl::Clone() { ...@@ -2447,8 +2467,9 @@ std::unique_ptr<WebContents> WebContentsImpl::Clone() {
std::unique_ptr<WebContentsImpl> tc = std::unique_ptr<WebContentsImpl> tc =
CreateWithOpener(create_params, opener_rfh); CreateWithOpener(create_params, opener_rfh);
tc->GetController().CopyStateFrom(&controller_, true); tc->GetController().CopyStateFrom(&controller_, true);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidCloneToNewWebContents(this, tc.get()); observer->DidCloneToNewWebContents(this, tc.get());
});
return tc; return tc;
} }
...@@ -2709,8 +2730,9 @@ void WebContentsImpl::RenderWidgetDeleted( ...@@ -2709,8 +2730,9 @@ void WebContentsImpl::RenderWidgetDeleted(
fullscreen_widget_process_id_) { fullscreen_widget_process_id_) {
if (delegate_ && delegate_->EmbedsFullscreenWidget()) if (delegate_ && delegate_->EmbedsFullscreenWidget())
delegate_->ExitFullscreenModeForTab(this); delegate_->ExitFullscreenModeForTab(this);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidDestroyFullscreenWidget(); observer->DidDestroyFullscreenWidget();
});
fullscreen_widget_process_id_ = ChildProcessHost::kInvalidUniqueID; fullscreen_widget_process_id_ = ChildProcessHost::kInvalidUniqueID;
fullscreen_widget_routing_id_ = MSG_ROUTING_NONE; fullscreen_widget_routing_id_ = MSG_ROUTING_NONE;
if (fullscreen_widget_had_focus_at_shutdown_) if (fullscreen_widget_had_focus_at_shutdown_)
...@@ -2748,8 +2770,9 @@ void WebContentsImpl::RenderWidgetWasResized( ...@@ -2748,8 +2770,9 @@ void WebContentsImpl::RenderWidgetWasResized(
if (!rfh || render_widget_host != rfh->GetRenderWidgetHost()) if (!rfh || render_widget_host != rfh->GetRenderWidgetHost())
return; return;
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.MainFrameWasResized(width_changed); observer->MainFrameWasResized(width_changed);
});
} }
KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent( KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
...@@ -2910,9 +2933,9 @@ void WebContentsImpl::EnterFullscreenMode( ...@@ -2910,9 +2933,9 @@ void WebContentsImpl::EnterFullscreenMode(
delegate_->RequestKeyboardLock(this, esc_key_locked_); delegate_->RequestKeyboardLock(this, esc_key_locked_);
} }
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidToggleFullscreenModeForTab(IsFullscreen(), false); observer->DidToggleFullscreenModeForTab(IsFullscreen(), false);
});
FullscreenContentsSet(GetBrowserContext())->insert(this); FullscreenContentsSet(GetBrowserContext())->insert(this);
} }
...@@ -2949,9 +2972,9 @@ void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) { ...@@ -2949,9 +2972,9 @@ void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) {
current_fullscreen_frame_ = nullptr; current_fullscreen_frame_ = nullptr;
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidToggleFullscreenModeForTab(IsFullscreen(), will_cause_resize); observer->DidToggleFullscreenModeForTab(IsFullscreen(), will_cause_resize);
} });
if (display_cutout_host_impl_) if (display_cutout_host_impl_)
display_cutout_host_impl_->DidExitFullscreen(); display_cutout_host_impl_->DidExitFullscreen();
...@@ -3000,9 +3023,9 @@ void WebContentsImpl::FullscreenFrameSetUpdated() { ...@@ -3000,9 +3023,9 @@ void WebContentsImpl::FullscreenFrameSetUpdated() {
return; return;
current_fullscreen_frame_ = new_fullscreen_frame; current_fullscreen_frame_ = new_fullscreen_frame;
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidAcquireFullscreen(new_fullscreen_frame); observer->DidAcquireFullscreen(new_fullscreen_frame);
});
if (display_cutout_host_impl_) if (display_cutout_host_impl_)
display_cutout_host_impl_->DidAcquireFullscreen(new_fullscreen_frame); display_cutout_host_impl_->DidAcquireFullscreen(new_fullscreen_frame);
} }
...@@ -3374,13 +3397,13 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow( ...@@ -3374,13 +3397,13 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
params.target_url, new_contents_impl); params.target_url, new_contents_impl);
} }
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidOpenRequestedURL(new_contents_impl, opener, params.target_url, observer->DidOpenRequestedURL(new_contents_impl, opener, params.target_url,
params.referrer.To<Referrer>(), params.referrer.To<Referrer>(),
params.disposition, ui::PAGE_TRANSITION_LINK, params.disposition, ui::PAGE_TRANSITION_LINK,
false, // started_from_context_menu false, // started_from_context_menu
true); // renderer_initiated true); // renderer_initiated
} });
// Any new WebContents opened while this WebContents is in fullscreen can be // Any new WebContents opened while this WebContents is in fullscreen can be
// used to confuse the user, so drop fullscreen. // used to confuse the user, so drop fullscreen.
...@@ -3601,8 +3624,9 @@ void WebContentsImpl::ShowCreatedWidget(int process_id, ...@@ -3601,8 +3624,9 @@ void WebContentsImpl::ShowCreatedWidget(int process_id,
} else { } else {
widget_host_view->InitAsFullscreen(view); widget_host_view->InitAsFullscreen(view);
} }
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidShowFullscreenWidget(); observer->DidShowFullscreenWidget();
});
if (!widget_host_view->HasFocus()) if (!widget_host_view->HasFocus())
widget_host_view->Focus(); widget_host_view->Focus();
} else { } else {
...@@ -3748,20 +3772,23 @@ void WebContentsImpl::AXTreeIDForMainFrameHasChanged() { ...@@ -3748,20 +3772,23 @@ void WebContentsImpl::AXTreeIDForMainFrameHasChanged() {
if (rwhv) if (rwhv)
rwhv->SetMainFrameAXTreeID(GetMainFrame()->GetAXTreeID()); rwhv->SetMainFrameAXTreeID(GetMainFrame()->GetAXTreeID());
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.AXTreeIDForMainFrameHasChanged(); observer->AXTreeIDForMainFrameHasChanged();
});
} }
void WebContentsImpl::AccessibilityEventReceived( void WebContentsImpl::AccessibilityEventReceived(
const AXEventNotificationDetails& details) { const AXEventNotificationDetails& details) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.AccessibilityEventReceived(details); observer->AccessibilityEventReceived(details);
});
} }
void WebContentsImpl::AccessibilityLocationChangesReceived( void WebContentsImpl::AccessibilityLocationChangesReceived(
const std::vector<AXLocationChangeNotificationDetails>& details) { const std::vector<AXLocationChangeNotificationDetails>& details) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.AccessibilityLocationChangesReceived(details); observer->AccessibilityLocationChangesReceived(details);
});
} }
base::string16 WebContentsImpl::DumpAccessibilityTree( base::string16 WebContentsImpl::DumpAccessibilityTree(
...@@ -3848,8 +3875,8 @@ void WebContentsImpl::SetNotWaitingForResponse() { ...@@ -3848,8 +3875,8 @@ void WebContentsImpl::SetNotWaitingForResponse() {
waiting_for_response_ = false; waiting_for_response_ = false;
if (delegate_) if (delegate_)
delegate_->LoadingStateChanged(this, is_load_to_different_document_); delegate_->LoadingStateChanged(this, is_load_to_different_document_);
for (auto& observer : observers_) observers_.ForEachObserver(
observer.DidReceiveResponse(); [&](WebContentsObserver* observer) { observer->DidReceiveResponse(); });
} }
void WebContentsImpl::SendScreenRects() { void WebContentsImpl::SendScreenRects() {
...@@ -3990,12 +4017,12 @@ WebContents* WebContentsImpl::OpenURL(const OpenURLParams& params) { ...@@ -3990,12 +4017,12 @@ WebContents* WebContentsImpl::OpenURL(const OpenURLParams& params) {
} }
if (new_contents && source_render_frame_host && new_contents != this) { if (new_contents && source_render_frame_host && new_contents != this) {
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidOpenRequestedURL( observer->DidOpenRequestedURL(
new_contents, source_render_frame_host, params.url, params.referrer, new_contents, source_render_frame_host, params.url, params.referrer,
params.disposition, params.transition, params.disposition, params.transition,
params.started_from_context_menu, params.is_renderer_initiated); params.started_from_context_menu, params.is_renderer_initiated);
} });
} }
return new_contents; return new_contents;
...@@ -4077,8 +4104,8 @@ void WebContentsImpl::Paste() { ...@@ -4077,8 +4104,8 @@ void WebContentsImpl::Paste() {
return; return;
input_handler->Paste(); input_handler->Paste();
for (auto& observer : observers_) observers_.ForEachObserver(
observer.OnPaste(); [&](WebContentsObserver* observer) { observer->OnPaste(); });
RecordAction(base::UserMetricsAction("Paste")); RecordAction(base::UserMetricsAction("Paste"));
} }
...@@ -4088,8 +4115,8 @@ void WebContentsImpl::PasteAndMatchStyle() { ...@@ -4088,8 +4115,8 @@ void WebContentsImpl::PasteAndMatchStyle() {
return; return;
input_handler->PasteAndMatchStyle(); input_handler->PasteAndMatchStyle();
for (auto& observer : observers_) observers_.ForEachObserver(
observer.OnPaste(); [&](WebContentsObserver* observer) { observer->OnPaste(); });
RecordAction(base::UserMetricsAction("PasteAndMatchStyle")); RecordAction(base::UserMetricsAction("PasteAndMatchStyle"));
} }
...@@ -4418,21 +4445,24 @@ void WebContentsImpl::SetVisibilityAndNotifyObservers(Visibility visibility) { ...@@ -4418,21 +4445,24 @@ void WebContentsImpl::SetVisibilityAndNotifyObservers(Visibility visibility) {
// for the first time. // for the first time.
if (visibility != previous_visibility || if (visibility != previous_visibility ||
(visibility == Visibility::VISIBLE && !did_first_set_visible_)) { (visibility == Visibility::VISIBLE && !did_first_set_visible_)) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnVisibilityChanged(visibility); observer->OnVisibilityChanged(visibility);
});
} }
} }
void WebContentsImpl::NotifyWebContentsFocused( void WebContentsImpl::NotifyWebContentsFocused(
RenderWidgetHost* render_widget_host) { RenderWidgetHost* render_widget_host) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnWebContentsFocused(render_widget_host); observer->OnWebContentsFocused(render_widget_host);
});
} }
void WebContentsImpl::NotifyWebContentsLostFocus( void WebContentsImpl::NotifyWebContentsLostFocus(
RenderWidgetHost* render_widget_host) { RenderWidgetHost* render_widget_host) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnWebContentsLostFocus(render_widget_host); observer->OnWebContentsLostFocus(render_widget_host);
});
} }
void WebContentsImpl::SystemDragEnded(RenderWidgetHost* source_rwh) { void WebContentsImpl::SystemDragEnded(RenderWidgetHost* source_rwh) {
...@@ -4723,9 +4753,9 @@ void WebContentsImpl::DidStartNavigation(NavigationHandle* navigation_handle) { ...@@ -4723,9 +4753,9 @@ void WebContentsImpl::DidStartNavigation(NavigationHandle* navigation_handle) {
if (navigation_handle->IsInMainFrame()) if (navigation_handle->IsInMainFrame())
favicon_urls_.clear(); favicon_urls_.clear();
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidStartNavigation(navigation_handle); observer->DidStartNavigation(navigation_handle);
});
if (navigation_handle->IsInMainFrame()) { if (navigation_handle->IsInMainFrame()) {
// When the browser is started with about:blank as the startup URL, focus // When the browser is started with about:blank as the startup URL, focus
// the location bar (which will also select its contents) so people can // the location bar (which will also select its contents) so people can
...@@ -4749,9 +4779,9 @@ void WebContentsImpl::DidRedirectNavigation( ...@@ -4749,9 +4779,9 @@ void WebContentsImpl::DidRedirectNavigation(
NavigationHandle* navigation_handle) { NavigationHandle* navigation_handle) {
TRACE_EVENT1("navigation", "WebContentsImpl::DidRedirectNavigation", TRACE_EVENT1("navigation", "WebContentsImpl::DidRedirectNavigation",
"navigation_handle", navigation_handle); "navigation_handle", navigation_handle);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidRedirectNavigation(navigation_handle); observer->DidRedirectNavigation(navigation_handle);
});
// Notify accessibility if this is a reload. This has to called on the // Notify accessibility if this is a reload. This has to called on the
// BrowserAccessibilityManager associated with the old RFHI. // BrowserAccessibilityManager associated with the old RFHI.
if (navigation_handle->GetReloadType() != ReloadType::NONE) { if (navigation_handle->GetReloadType() != ReloadType::NONE) {
...@@ -4769,9 +4799,9 @@ void WebContentsImpl::ReadyToCommitNavigation( ...@@ -4769,9 +4799,9 @@ void WebContentsImpl::ReadyToCommitNavigation(
NavigationHandle* navigation_handle) { NavigationHandle* navigation_handle) {
TRACE_EVENT1("navigation", "WebContentsImpl::ReadyToCommitNavigation", TRACE_EVENT1("navigation", "WebContentsImpl::ReadyToCommitNavigation",
"navigation_handle", navigation_handle); "navigation_handle", navigation_handle);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.ReadyToCommitNavigation(navigation_handle); observer->ReadyToCommitNavigation(navigation_handle);
});
// If any domains are blocked from accessing 3D APIs because they may // If any domains are blocked from accessing 3D APIs because they may
// have caused the GPU to reset recently, unblock them here if the user // have caused the GPU to reset recently, unblock them here if the user
// initiated this navigation. This implies that the user was involved in // initiated this navigation. This implies that the user was involved in
...@@ -4820,9 +4850,9 @@ void WebContentsImpl::DidFinishNavigation(NavigationHandle* navigation_handle) { ...@@ -4820,9 +4850,9 @@ void WebContentsImpl::DidFinishNavigation(NavigationHandle* navigation_handle) {
TRACE_EVENT1("navigation", "WebContentsImpl::DidFinishNavigation", TRACE_EVENT1("navigation", "WebContentsImpl::DidFinishNavigation",
"navigation_handle", navigation_handle); "navigation_handle", navigation_handle);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidFinishNavigation(navigation_handle); observer->DidFinishNavigation(navigation_handle);
});
if (display_cutout_host_impl_) if (display_cutout_host_impl_)
display_cutout_host_impl_->DidFinishNavigation(navigation_handle); display_cutout_host_impl_->DidFinishNavigation(navigation_handle);
...@@ -4905,9 +4935,9 @@ void WebContentsImpl::DidFailLoadWithError( ...@@ -4905,9 +4935,9 @@ void WebContentsImpl::DidFailLoadWithError(
RenderFrameHostImpl* render_frame_host, RenderFrameHostImpl* render_frame_host,
const GURL& url, const GURL& url,
int error_code) { int error_code) {
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidFailLoad(render_frame_host, url, error_code); observer->DidFailLoad(render_frame_host, url, error_code);
} });
} }
void WebContentsImpl::NotifyChangedNavigationState( void WebContentsImpl::NotifyChangedNavigationState(
...@@ -5014,9 +5044,9 @@ bool WebContentsImpl::CanOverscrollContent() const { ...@@ -5014,9 +5044,9 @@ bool WebContentsImpl::CanOverscrollContent() const {
void WebContentsImpl::OnThemeColorChanged(RenderViewHostImpl* source) { void WebContentsImpl::OnThemeColorChanged(RenderViewHostImpl* source) {
if (source->did_first_visually_non_empty_paint() && if (source->did_first_visually_non_empty_paint() &&
last_sent_theme_color_ != source->theme_color()) { last_sent_theme_color_ != source->theme_color()) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidChangeThemeColor(); observer->DidChangeThemeColor();
last_sent_theme_color_ = source->theme_color(); });
} }
} }
...@@ -5026,9 +5056,10 @@ void WebContentsImpl::DidLoadResourceFromMemoryCache( ...@@ -5026,9 +5056,10 @@ void WebContentsImpl::DidLoadResourceFromMemoryCache(
const std::string& http_method, const std::string& http_method,
const std::string& mime_type, const std::string& mime_type,
network::mojom::RequestDestination request_destination) { network::mojom::RequestDestination request_destination) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidLoadResourceFromMemoryCache(url, mime_type, observer->DidLoadResourceFromMemoryCache(url, mime_type,
request_destination); request_destination);
});
if (url.is_valid() && url.SchemeIsHTTPOrHTTPS()) { if (url.is_valid() && url.SchemeIsHTTPOrHTTPS()) {
StoragePartition* partition = source->GetProcess()->GetStoragePartition(); StoragePartition* partition = source->GetProcess()->GetStoragePartition();
...@@ -5046,8 +5077,9 @@ void WebContentsImpl::DidContainInsecureFormAction() { ...@@ -5046,8 +5077,9 @@ void WebContentsImpl::DidContainInsecureFormAction() {
} }
void WebContentsImpl::DocumentAvailableInMainFrame() { void WebContentsImpl::DocumentAvailableInMainFrame() {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DocumentAvailableInMainFrame(); observer->DocumentAvailableInMainFrame();
});
} }
void WebContentsImpl::OnDidRunInsecureContent(RenderFrameHostImpl* source, void WebContentsImpl::OnDidRunInsecureContent(RenderFrameHostImpl* source,
...@@ -5179,10 +5211,10 @@ void WebContentsImpl::ResourceLoadComplete( ...@@ -5179,10 +5211,10 @@ void WebContentsImpl::ResourceLoadComplete(
RenderFrameHost* render_frame_host, RenderFrameHost* render_frame_host,
const GlobalRequestID& request_id, const GlobalRequestID& request_id,
blink::mojom::ResourceLoadInfoPtr resource_load_info) { blink::mojom::ResourceLoadInfoPtr resource_load_info) {
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.ResourceLoadComplete(render_frame_host, request_id, observer->ResourceLoadComplete(render_frame_host, request_id,
*resource_load_info); *resource_load_info);
} });
} }
const WebPreferences& WebContentsImpl::GetOrCreateWebPreferences() { const WebPreferences& WebContentsImpl::GetOrCreateWebPreferences() {
...@@ -5281,8 +5313,9 @@ void WebContentsImpl::OnDidRunContentWithCertificateErrors( ...@@ -5281,8 +5313,9 @@ void WebContentsImpl::OnDidRunContentWithCertificateErrors(
} }
void WebContentsImpl::DOMContentLoaded(RenderFrameHost* render_frame_host) { void WebContentsImpl::DOMContentLoaded(RenderFrameHost* render_frame_host) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DOMContentLoaded(render_frame_host); observer->DOMContentLoaded(render_frame_host);
});
} }
void WebContentsImpl::OnDidFinishLoad(RenderFrameHost* render_frame_host, void WebContentsImpl::OnDidFinishLoad(RenderFrameHost* render_frame_host,
...@@ -5290,9 +5323,9 @@ void WebContentsImpl::OnDidFinishLoad(RenderFrameHost* render_frame_host, ...@@ -5290,9 +5323,9 @@ void WebContentsImpl::OnDidFinishLoad(RenderFrameHost* render_frame_host,
GURL validated_url(url); GURL validated_url(url);
render_frame_host->GetProcess()->FilterURL(false, &validated_url); render_frame_host->GetProcess()->FilterURL(false, &validated_url);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidFinishLoad(render_frame_host, validated_url); observer->DidFinishLoad(render_frame_host, validated_url);
});
size_t tree_size = frame_tree_.root()->GetFrameTreeSize(); size_t tree_size = frame_tree_.root()->GetFrameTreeSize();
if (max_loaded_frame_count_ < tree_size) if (max_loaded_frame_count_ < tree_size)
max_loaded_frame_count_ = tree_size; max_loaded_frame_count_ = tree_size;
...@@ -5348,8 +5381,9 @@ void WebContentsImpl::OnPageScaleFactorChanged(RenderFrameHostImpl* source, ...@@ -5348,8 +5381,9 @@ void WebContentsImpl::OnPageScaleFactorChanged(RenderFrameHostImpl* source,
} }
#endif // !defined(OS_ANDROID) #endif // !defined(OS_ANDROID)
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnPageScaleFactorChanged(page_scale_factor); observer->OnPageScaleFactorChanged(page_scale_factor);
});
} }
void WebContentsImpl::OnTextAutosizerPageInfoChanged( void WebContentsImpl::OnTextAutosizerPageInfoChanged(
...@@ -5434,8 +5468,9 @@ void WebContentsImpl::OnAppCacheAccessed(const GURL& manifest_url, ...@@ -5434,8 +5468,9 @@ void WebContentsImpl::OnAppCacheAccessed(const GURL& manifest_url,
// |manifest_url|? // |manifest_url|?
// Notify observers about navigation. // Notify observers about navigation.
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.AppCacheAccessed(manifest_url, blocked_by_policy); observer->AppCacheAccessed(manifest_url, blocked_by_policy);
});
} }
void WebContentsImpl::DomOperationResponse(const std::string& json_string) { void WebContentsImpl::DomOperationResponse(const std::string& json_string) {
...@@ -5466,18 +5501,18 @@ void WebContentsImpl::OnServiceWorkerAccessed( ...@@ -5466,18 +5501,18 @@ void WebContentsImpl::OnServiceWorkerAccessed(
RenderFrameHost* render_frame_host, RenderFrameHost* render_frame_host,
const GURL& scope, const GURL& scope,
AllowServiceWorkerResult allowed) { AllowServiceWorkerResult allowed) {
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnServiceWorkerAccessed(render_frame_host, scope, allowed); observer->OnServiceWorkerAccessed(render_frame_host, scope, allowed);
} });
} }
void WebContentsImpl::OnServiceWorkerAccessed( void WebContentsImpl::OnServiceWorkerAccessed(
NavigationHandle* navigation, NavigationHandle* navigation,
const GURL& scope, const GURL& scope,
AllowServiceWorkerResult allowed) { AllowServiceWorkerResult allowed) {
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnServiceWorkerAccessed(navigation, scope, allowed); observer->OnServiceWorkerAccessed(navigation, scope, allowed);
} });
} }
void WebContentsImpl::OnColorChooserFactoryReceiver( void WebContentsImpl::OnColorChooserFactoryReceiver(
...@@ -5504,15 +5539,17 @@ void WebContentsImpl::OpenColorChooser( ...@@ -5504,15 +5539,17 @@ void WebContentsImpl::OpenColorChooser(
#if BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_PLUGINS)
void WebContentsImpl::OnPepperInstanceCreated(RenderFrameHostImpl* source, void WebContentsImpl::OnPepperInstanceCreated(RenderFrameHostImpl* source,
int32_t pp_instance) { int32_t pp_instance) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.PepperInstanceCreated(); observer->PepperInstanceCreated();
});
pepper_playback_observer_->PepperInstanceCreated(source, pp_instance); pepper_playback_observer_->PepperInstanceCreated(source, pp_instance);
} }
void WebContentsImpl::OnPepperInstanceDeleted(RenderFrameHostImpl* source, void WebContentsImpl::OnPepperInstanceDeleted(RenderFrameHostImpl* source,
int32_t pp_instance) { int32_t pp_instance) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.PepperInstanceDeleted(); observer->PepperInstanceDeleted();
});
pepper_playback_observer_->PepperInstanceDeleted(source, pp_instance); pepper_playback_observer_->PepperInstanceDeleted(source, pp_instance);
} }
...@@ -5522,8 +5559,9 @@ void WebContentsImpl::OnPepperPluginHung(RenderFrameHostImpl* source, ...@@ -5522,8 +5559,9 @@ void WebContentsImpl::OnPepperPluginHung(RenderFrameHostImpl* source,
bool is_hung) { bool is_hung) {
UMA_HISTOGRAM_COUNTS_1M("Pepper.PluginHung", 1); UMA_HISTOGRAM_COUNTS_1M("Pepper.PluginHung", 1);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.PluginHungStatusChanged(plugin_child_id, path, is_hung); observer->PluginHungStatusChanged(plugin_child_id, path, is_hung);
});
} }
void WebContentsImpl::OnPepperStartsPlayback(RenderFrameHostImpl* source, void WebContentsImpl::OnPepperStartsPlayback(RenderFrameHostImpl* source,
...@@ -5541,8 +5579,9 @@ void WebContentsImpl::OnPluginCrashed(RenderFrameHostImpl* source, ...@@ -5541,8 +5579,9 @@ void WebContentsImpl::OnPluginCrashed(RenderFrameHostImpl* source,
base::ProcessId plugin_pid) { base::ProcessId plugin_pid) {
// TODO(nick): Eliminate the |plugin_pid| parameter, which can't be trusted, // TODO(nick): Eliminate the |plugin_pid| parameter, which can't be trusted,
// and is only used by WebTestControlHost. // and is only used by WebTestControlHost.
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.PluginCrashed(plugin_path, plugin_pid); observer->PluginCrashed(plugin_path, plugin_pid);
});
} }
void WebContentsImpl::OnRequestPpapiBrokerPermission( void WebContentsImpl::OnRequestPpapiBrokerPermission(
...@@ -5593,8 +5632,9 @@ void WebContentsImpl::UpdateFaviconURL( ...@@ -5593,8 +5632,9 @@ void WebContentsImpl::UpdateFaviconURL(
favicon_urls_ = std::move(candidates); favicon_urls_ = std::move(candidates);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidUpdateFaviconURL(source, favicon_urls_); observer->DidUpdateFaviconURL(source, favicon_urls_);
});
} }
void WebContentsImpl::SetIsOverlayContent(bool is_overlay_content) { void WebContentsImpl::SetIsOverlayContent(bool is_overlay_content) {
...@@ -5605,13 +5645,14 @@ void WebContentsImpl::DidFirstVisuallyNonEmptyPaint( ...@@ -5605,13 +5645,14 @@ void WebContentsImpl::DidFirstVisuallyNonEmptyPaint(
RenderViewHostImpl* source) { RenderViewHostImpl* source) {
// TODO(nick): When this is ported to FrameHostMsg_, we should only listen if // TODO(nick): When this is ported to FrameHostMsg_, we should only listen if
// |source| is the main frame. // |source| is the main frame.
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidFirstVisuallyNonEmptyPaint(); observer->DidFirstVisuallyNonEmptyPaint();
});
if (source->theme_color() != last_sent_theme_color_) { if (source->theme_color() != last_sent_theme_color_) {
// Theme color should have updated by now if there was one. // Theme color should have updated by now if there was one.
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidChangeThemeColor(); observer->DidChangeThemeColor();
});
last_sent_theme_color_ = source->theme_color(); last_sent_theme_color_ = source->theme_color();
} }
} }
...@@ -5625,8 +5666,9 @@ WebContentsImpl* WebContentsImpl::GetPortalHostWebContents() { ...@@ -5625,8 +5666,9 @@ WebContentsImpl* WebContentsImpl::GetPortalHostWebContents() {
} }
void WebContentsImpl::NotifyBeforeFormRepostWarningShow() { void WebContentsImpl::NotifyBeforeFormRepostWarningShow() {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.BeforeFormRepostWarningShow(); observer->BeforeFormRepostWarningShow();
});
} }
void WebContentsImpl::ActivateAndShowRepostFormWarningDialog() { void WebContentsImpl::ActivateAndShowRepostFormWarningDialog() {
...@@ -5665,9 +5707,8 @@ void WebContentsImpl::UpdateTitleForEntry(NavigationEntry* entry, ...@@ -5665,9 +5707,8 @@ void WebContentsImpl::UpdateTitleForEntry(NavigationEntry* entry,
// Lastly, set the title for the view. // Lastly, set the title for the view.
view_->SetPageTitle(final_title); view_->SetPageTitle(final_title);
for (auto& observer : observers_) observers_.ForEachObserver(
observer.TitleWasSet(entry); [&](WebContentsObserver* observer) { observer->TitleWasSet(entry); });
// Broadcast notifications when the UI should be updated. // Broadcast notifications when the UI should be updated.
if (entry == controller_.GetEntryAtOffset(0)) if (entry == controller_.GetEntryAtOffset(0))
NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE); NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE);
...@@ -5675,8 +5716,9 @@ void WebContentsImpl::UpdateTitleForEntry(NavigationEntry* entry, ...@@ -5675,8 +5716,9 @@ void WebContentsImpl::UpdateTitleForEntry(NavigationEntry* entry,
void WebContentsImpl::SendChangeLoadProgress() { void WebContentsImpl::SendChangeLoadProgress() {
loading_last_progress_update_ = base::TimeTicks::Now(); loading_last_progress_update_ = base::TimeTicks::Now();
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.LoadProgressChanged(frame_tree_.load_progress()); observer->LoadProgressChanged(frame_tree_.load_progress());
});
} }
void WebContentsImpl::ResetLoadProgressState() { void WebContentsImpl::ResetLoadProgressState() {
...@@ -5716,13 +5758,13 @@ void WebContentsImpl::LoadingStateChanged(bool to_different_document, ...@@ -5716,13 +5758,13 @@ void WebContentsImpl::LoadingStateChanged(bool to_different_document,
TRACE_EVENT_ASYNC_BEGIN2("browser,navigation", "WebContentsImpl Loading", TRACE_EVENT_ASYNC_BEGIN2("browser,navigation", "WebContentsImpl Loading",
this, "URL", url, "Main FrameTreeNode id", this, "URL", url, "Main FrameTreeNode id",
GetFrameTree()->root()->frame_tree_node_id()); GetFrameTree()->root()->frame_tree_node_id());
for (auto& observer : observers_) observers_.ForEachObserver(
observer.DidStartLoading(); [&](WebContentsObserver* observer) { observer->DidStartLoading(); });
} else { } else {
TRACE_EVENT_ASYNC_END1("browser,navigation", "WebContentsImpl Loading", TRACE_EVENT_ASYNC_END1("browser,navigation", "WebContentsImpl Loading",
this, "URL", url); this, "URL", url);
for (auto& observer : observers_) observers_.ForEachObserver(
observer.DidStopLoading(); [&](WebContentsObserver* observer) { observer->DidStopLoading(); });
} }
// TODO(avi): Remove. http://crbug.com/170921 // TODO(avi): Remove. http://crbug.com/170921
...@@ -5741,9 +5783,9 @@ void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_view, ...@@ -5741,9 +5783,9 @@ void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_view,
// notification so that clients that pick up a pointer to |this| can NULL the // notification so that clients that pick up a pointer to |this| can NULL the
// pointer. See Bug 1230284. // pointer. See Bug 1230284.
notify_disconnection_ = true; notify_disconnection_ = true;
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.RenderViewHostChanged(old_view, new_view); observer->RenderViewHostChanged(old_view, new_view);
});
view_->RenderViewHostChanged(old_view, new_view); view_->RenderViewHostChanged(old_view, new_view);
// If this is an inner WebContents that has swapped views, we need to reattach // If this is an inner WebContents that has swapped views, we need to reattach
...@@ -5770,8 +5812,9 @@ void WebContentsImpl::NotifyFrameSwapped(RenderFrameHost* old_frame, ...@@ -5770,8 +5812,9 @@ void WebContentsImpl::NotifyFrameSwapped(RenderFrameHost* old_frame,
new_widget->SetImportance(old_widget->importance()); new_widget->SetImportance(old_widget->importance());
} }
#endif #endif
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.RenderFrameHostChanged(old_frame, new_frame); observer->RenderFrameHostChanged(old_frame, new_frame);
});
} }
// TODO(avi): Remove this entire function because this notification is already // TODO(avi): Remove this entire function because this notification is already
...@@ -5789,25 +5832,29 @@ void WebContentsImpl::NotifyDisconnected() { ...@@ -5789,25 +5832,29 @@ void WebContentsImpl::NotifyDisconnected() {
void WebContentsImpl::NotifyNavigationEntryCommitted( void WebContentsImpl::NotifyNavigationEntryCommitted(
const LoadCommittedDetails& load_details) { const LoadCommittedDetails& load_details) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.NavigationEntryCommitted(load_details); observer->NavigationEntryCommitted(load_details);
});
} }
void WebContentsImpl::NotifyNavigationEntryChanged( void WebContentsImpl::NotifyNavigationEntryChanged(
const EntryChangedDetails& change_details) { const EntryChangedDetails& change_details) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.NavigationEntryChanged(change_details); observer->NavigationEntryChanged(change_details);
});
} }
void WebContentsImpl::NotifyNavigationListPruned( void WebContentsImpl::NotifyNavigationListPruned(
const PrunedDetails& pruned_details) { const PrunedDetails& pruned_details) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.NavigationListPruned(pruned_details); observer->NavigationListPruned(pruned_details);
});
} }
void WebContentsImpl::NotifyNavigationEntriesDeleted() { void WebContentsImpl::NotifyNavigationEntriesDeleted() {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.NavigationEntriesDeleted(); observer->NavigationEntriesDeleted();
});
} }
void WebContentsImpl::OnAssociatedInterfaceRequest( void WebContentsImpl::OnAssociatedInterfaceRequest(
...@@ -5823,7 +5870,7 @@ void WebContentsImpl::OnInterfaceRequest( ...@@ -5823,7 +5870,7 @@ void WebContentsImpl::OnInterfaceRequest(
RenderFrameHost* render_frame_host, RenderFrameHost* render_frame_host,
const std::string& interface_name, const std::string& interface_name,
mojo::ScopedMessagePipeHandle* interface_pipe) { mojo::ScopedMessagePipeHandle* interface_pipe) {
for (auto& observer : observers_) { for (auto& observer : observers_.observer_list()) {
observer.OnInterfaceRequestFromFrame(render_frame_host, interface_name, observer.OnInterfaceRequestFromFrame(render_frame_host, interface_name,
interface_pipe); interface_pipe);
if (!interface_pipe->is_valid()) if (!interface_pipe->is_valid())
...@@ -5844,8 +5891,9 @@ const GURL& WebContentsImpl::GetMainFrameLastCommittedURL() { ...@@ -5844,8 +5891,9 @@ const GURL& WebContentsImpl::GetMainFrameLastCommittedURL() {
} }
void WebContentsImpl::RenderFrameCreated(RenderFrameHost* render_frame_host) { void WebContentsImpl::RenderFrameCreated(RenderFrameHost* render_frame_host) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.RenderFrameCreated(render_frame_host); observer->RenderFrameCreated(render_frame_host);
});
UpdateAccessibilityModeOnFrame(render_frame_host); UpdateAccessibilityModeOnFrame(render_frame_host);
if (display_cutout_host_impl_) if (display_cutout_host_impl_)
...@@ -5877,10 +5925,9 @@ void WebContentsImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) { ...@@ -5877,10 +5925,9 @@ void WebContentsImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
RecordMaxFrameCountUMA(max_loaded_frame_count_); RecordMaxFrameCountUMA(max_loaded_frame_count_);
} }
is_notifying_observers_ = true; observers_.ForEachObserver([&](WebContentsObserver* observer) {
for (auto& observer : observers_) observer->RenderFrameDeleted(render_frame_host);
observer.RenderFrameDeleted(render_frame_host); });
is_notifying_observers_ = false;
#if BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_PLUGINS)
pepper_playback_observer_->RenderFrameDeleted(render_frame_host); pepper_playback_observer_->RenderFrameDeleted(render_frame_host);
#endif #endif
...@@ -6259,8 +6306,9 @@ void WebContentsImpl::FocusOuterAttachmentFrameChain() { ...@@ -6259,8 +6306,9 @@ void WebContentsImpl::FocusOuterAttachmentFrameChain() {
} }
void WebContentsImpl::InnerWebContentsCreated(WebContents* inner_web_contents) { void WebContentsImpl::InnerWebContentsCreated(WebContents* inner_web_contents) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.InnerWebContentsCreated(inner_web_contents); observer->InnerWebContentsCreated(inner_web_contents);
});
} }
void WebContentsImpl::InnerWebContentsAttached( void WebContentsImpl::InnerWebContentsAttached(
...@@ -6284,8 +6332,9 @@ void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { ...@@ -6284,8 +6332,9 @@ void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
Source<WebContents>(this), Source<WebContents>(this),
Details<RenderViewHost>(render_view_host)); Details<RenderViewHost>(render_view_host));
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.RenderViewCreated(render_view_host); observer->RenderViewCreated(render_view_host);
});
if (delegate_) if (delegate_)
RenderFrameDevToolsAgentHost::WebContentsCreated(this); RenderFrameDevToolsAgentHost::WebContentsCreated(this);
} }
...@@ -6314,9 +6363,8 @@ void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) { ...@@ -6314,9 +6363,8 @@ void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) {
view_->Focus(); view_->Focus();
} }
for (auto& observer : observers_) observers_.ForEachObserver(
observer.RenderViewReady(); [&](WebContentsObserver* observer) { observer->RenderViewReady(); });
view_->RenderViewReady(); view_->RenderViewReady();
} }
...@@ -6351,13 +6399,22 @@ void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh, ...@@ -6351,13 +6399,22 @@ void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh,
NotifyDisconnected(); NotifyDisconnected();
SetIsCrashed(status, error_code); SetIsCrashed(status, error_code);
for (auto& observer : observers_) TRACE_EVENT0("content", "Dispatching WebContentsObserver::RenderProcessGone");
observer.RenderProcessGone(GetCrashedStatus()); // Some observers might destroy WebContents in RenderViewTerminated.
base::WeakPtr<WebContentsImpl> weak_ptr = weak_factory_.GetWeakPtr();
auto crashed_status = GetCrashedStatus();
for (auto& observer : observers_.observer_list()) {
observer.RenderProcessGone(crashed_status);
if (!weak_ptr)
return;
}
// |this| might have been deleted. Do not add code here.
} }
void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) { void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) {
for (auto& observer : observers_) observers_.ForEachObserver(
observer.RenderViewDeleted(rvh); [&](WebContentsObserver* observer) { observer->RenderViewDeleted(rvh); });
} }
void WebContentsImpl::UpdateTargetURL(RenderViewHost* render_view_host, void WebContentsImpl::UpdateTargetURL(RenderViewHost* render_view_host,
...@@ -6549,26 +6606,30 @@ void WebContentsImpl::DidAccessInitialDocument() { ...@@ -6549,26 +6606,30 @@ void WebContentsImpl::DidAccessInitialDocument() {
void WebContentsImpl::DidChangeName(RenderFrameHost* render_frame_host, void WebContentsImpl::DidChangeName(RenderFrameHost* render_frame_host,
const std::string& name) { const std::string& name) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.FrameNameChanged(render_frame_host, name); observer->FrameNameChanged(render_frame_host, name);
});
} }
void WebContentsImpl::DidReceiveFirstUserActivation( void WebContentsImpl::DidReceiveFirstUserActivation(
RenderFrameHost* render_frame_host) { RenderFrameHost* render_frame_host) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.FrameReceivedFirstUserActivation(render_frame_host); observer->FrameReceivedFirstUserActivation(render_frame_host);
});
} }
void WebContentsImpl::DidChangeDisplayState(RenderFrameHost* render_frame_host, void WebContentsImpl::DidChangeDisplayState(RenderFrameHost* render_frame_host,
bool is_display_none) { bool is_display_none) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.FrameDisplayStateChanged(render_frame_host, is_display_none); observer->FrameDisplayStateChanged(render_frame_host, is_display_none);
});
} }
void WebContentsImpl::FrameSizeChanged(RenderFrameHost* render_frame_host, void WebContentsImpl::FrameSizeChanged(RenderFrameHost* render_frame_host,
const gfx::Size& frame_size) { const gfx::Size& frame_size) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.FrameSizeChanged(render_frame_host, frame_size); observer->FrameSizeChanged(render_frame_host, frame_size);
});
} }
void WebContentsImpl::DocumentOnLoadCompleted( void WebContentsImpl::DocumentOnLoadCompleted(
...@@ -6577,10 +6638,9 @@ void WebContentsImpl::DocumentOnLoadCompleted( ...@@ -6577,10 +6638,9 @@ void WebContentsImpl::DocumentOnLoadCompleted(
GetRenderViewHost()->DocumentOnLoadCompletedInMainFrame(); GetRenderViewHost()->DocumentOnLoadCompletedInMainFrame();
is_notifying_observers_ = true; observers_.ForEachObserver([&](WebContentsObserver* observer) {
for (auto& observer : observers_) observer->DocumentOnLoadCompletedInMainFrame();
observer.DocumentOnLoadCompletedInMainFrame(); });
is_notifying_observers_ = false;
// TODO(avi): Remove. http://crbug.com/170921 // TODO(avi): Remove. http://crbug.com/170921
NotificationService::current()->Notify( NotificationService::current()->Notify(
...@@ -6819,8 +6879,9 @@ void WebContentsImpl::OnFocusedElementChangedInFrame( ...@@ -6819,8 +6879,9 @@ void WebContentsImpl::OnFocusedElementChangedInFrame(
Source<RenderViewHost>(GetRenderViewHost()), Source<RenderViewHost>(GetRenderViewHost()),
Details<FocusedNodeDetails>(&details)); Details<FocusedNodeDetails>(&details));
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnFocusChangedInPage(&details); observer->OnFocusChangedInPage(&details);
});
} }
bool WebContentsImpl::DidAddMessageToConsole( bool WebContentsImpl::DidAddMessageToConsole(
...@@ -6828,9 +6889,9 @@ bool WebContentsImpl::DidAddMessageToConsole( ...@@ -6828,9 +6889,9 @@ bool WebContentsImpl::DidAddMessageToConsole(
const base::string16& message, const base::string16& message,
int32_t line_no, int32_t line_no,
const base::string16& source_id) { const base::string16& source_id) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnDidAddMessageToConsole(log_level, message, line_no, source_id); observer->OnDidAddMessageToConsole(log_level, message, line_no, source_id);
});
if (!delegate_) if (!delegate_)
return false; return false;
return delegate_->DidAddMessageToConsole(this, log_level, message, line_no, return delegate_->DidAddMessageToConsole(this, log_level, message, line_no,
...@@ -6850,8 +6911,9 @@ void WebContentsImpl::DidReceiveInputEvent( ...@@ -6850,8 +6911,9 @@ void WebContentsImpl::DidReceiveInputEvent(
if (event.GetType() != blink::WebInputEvent::Type::kGestureScrollBegin) if (event.GetType() != blink::WebInputEvent::Type::kGestureScrollBegin)
last_interactive_input_event_time_ = ui::EventTimeForNow(); last_interactive_input_event_time_ = ui::EventTimeForNow();
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.DidGetUserInteraction(event); observer->DidGetUserInteraction(event);
});
} }
bool WebContentsImpl::ShouldIgnoreInputEvents() { bool WebContentsImpl::ShouldIgnoreInputEvents() {
...@@ -6881,8 +6943,8 @@ void WebContentsImpl::FocusOwningWebContents( ...@@ -6881,8 +6943,8 @@ void WebContentsImpl::FocusOwningWebContents(
void WebContentsImpl::OnIgnoredUIEvent() { void WebContentsImpl::OnIgnoredUIEvent() {
// Notify observers. // Notify observers.
for (auto& observer : observers_) observers_.ForEachObserver(
observer.DidGetIgnoredUIEvent(); [&](WebContentsObserver* observer) { observer->DidGetIgnoredUIEvent(); });
} }
void WebContentsImpl::RendererUnresponsive( void WebContentsImpl::RendererUnresponsive(
...@@ -6901,9 +6963,9 @@ void WebContentsImpl::RendererUnresponsive( ...@@ -6901,9 +6963,9 @@ void WebContentsImpl::RendererUnresponsive(
if (!render_widget_host->renderer_initialized()) if (!render_widget_host->renderer_initialized())
return; return;
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnRendererUnresponsive(render_widget_host->GetProcess()); observer->OnRendererUnresponsive(render_widget_host->GetProcess());
});
if (delegate_) if (delegate_)
delegate_->RendererUnresponsive(this, render_widget_host, delegate_->RendererUnresponsive(this, render_widget_host,
std::move(hang_monitor_restarter)); std::move(hang_monitor_restarter));
...@@ -6911,9 +6973,9 @@ void WebContentsImpl::RendererUnresponsive( ...@@ -6911,9 +6973,9 @@ void WebContentsImpl::RendererUnresponsive(
void WebContentsImpl::RendererResponsive( void WebContentsImpl::RendererResponsive(
RenderWidgetHostImpl* render_widget_host) { RenderWidgetHostImpl* render_widget_host) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnRendererResponsive(render_widget_host->GetProcess()); observer->OnRendererResponsive(render_widget_host->GetProcess());
});
if (delegate_) if (delegate_)
delegate_->RendererResponsive(this, render_widget_host); delegate_->RendererResponsive(this, render_widget_host);
} }
...@@ -6944,8 +7006,9 @@ void WebContentsImpl::SubframeCrashed( ...@@ -6944,8 +7006,9 @@ void WebContentsImpl::SubframeCrashed(
void WebContentsImpl::BeforeUnloadFiredFromRenderManager( void WebContentsImpl::BeforeUnloadFiredFromRenderManager(
bool proceed, const base::TimeTicks& proceed_time, bool proceed, const base::TimeTicks& proceed_time,
bool* proceed_to_fire_unload) { bool* proceed_to_fire_unload) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.BeforeUnloadFired(proceed, proceed_time); observer->BeforeUnloadFired(proceed, proceed_time);
});
if (delegate_) if (delegate_)
delegate_->BeforeUnloadFired(this, proceed, proceed_to_fire_unload); delegate_->BeforeUnloadFired(this, proceed, proceed_to_fire_unload);
// Note: |this| might be deleted at this point. // Note: |this| might be deleted at this point.
...@@ -7186,8 +7249,9 @@ void WebContentsImpl::OnDialogClosed(int render_process_id, ...@@ -7186,8 +7249,9 @@ void WebContentsImpl::OnDialogClosed(int render_process_id,
// Update the URL display either way, to avoid showing a stale URL. // Update the URL display either way, to avoid showing a stale URL.
NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.BeforeUnloadDialogCancelled(); observer->BeforeUnloadDialogCancelled();
});
} }
std::move(response_callback).Run(success, user_input); std::move(response_callback).Run(success, user_input);
...@@ -7291,8 +7355,9 @@ gfx::Size WebContentsImpl::GetSizeForMainFrame() { ...@@ -7291,8 +7355,9 @@ gfx::Size WebContentsImpl::GetSizeForMainFrame() {
} }
void WebContentsImpl::OnFrameRemoved(RenderFrameHost* render_frame_host) { void WebContentsImpl::OnFrameRemoved(RenderFrameHost* render_frame_host) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.FrameDeleted(render_frame_host); observer->FrameDeleted(render_frame_host);
});
} }
void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) { void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
...@@ -7396,10 +7461,10 @@ void WebContentsImpl::DecrementBluetoothConnectedDeviceCount() { ...@@ -7396,10 +7461,10 @@ void WebContentsImpl::DecrementBluetoothConnectedDeviceCount() {
void WebContentsImpl::OnIsConnectedToBluetoothDeviceChanged( void WebContentsImpl::OnIsConnectedToBluetoothDeviceChanged(
bool is_connected_to_bluetooth_device) { bool is_connected_to_bluetooth_device) {
NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
for (auto& observer : observers_) { observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnIsConnectedToBluetoothDeviceChanged( observer->OnIsConnectedToBluetoothDeviceChanged(
is_connected_to_bluetooth_device); is_connected_to_bluetooth_device);
} });
} }
void WebContentsImpl::IncrementBluetoothScanningSessionsCount() { void WebContentsImpl::IncrementBluetoothScanningSessionsCount() {
...@@ -7613,8 +7678,9 @@ void WebContentsImpl::MediaStartedPlaying( ...@@ -7613,8 +7678,9 @@ void WebContentsImpl::MediaStartedPlaying(
if (media_info.has_video) if (media_info.has_video)
currently_playing_video_count_++; currently_playing_video_count_++;
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.MediaStartedPlaying(media_info, id); observer->MediaStartedPlaying(media_info, id);
});
} }
void WebContentsImpl::MediaStoppedPlaying( void WebContentsImpl::MediaStoppedPlaying(
...@@ -7624,26 +7690,29 @@ void WebContentsImpl::MediaStoppedPlaying( ...@@ -7624,26 +7690,29 @@ void WebContentsImpl::MediaStoppedPlaying(
if (media_info.has_video) if (media_info.has_video)
currently_playing_video_count_--; currently_playing_video_count_--;
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.MediaStoppedPlaying(media_info, id, reason); observer->MediaStoppedPlaying(media_info, id, reason);
});
} }
void WebContentsImpl::MediaResized(const gfx::Size& size, void WebContentsImpl::MediaResized(const gfx::Size& size,
const MediaPlayerId& id) { const MediaPlayerId& id) {
cached_video_sizes_[id] = size; cached_video_sizes_[id] = size;
for (auto& observer : observers_) observers_.ForEachObserver(
observer.MediaResized(size, id); [&](WebContentsObserver* observer) { observer->MediaResized(size, id); });
} }
void WebContentsImpl::MediaBufferUnderflow(const MediaPlayerId& id) { void WebContentsImpl::MediaBufferUnderflow(const MediaPlayerId& id) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.MediaBufferUnderflow(id); observer->MediaBufferUnderflow(id);
});
} }
void WebContentsImpl::MediaEffectivelyFullscreenChanged(bool is_fullscreen) { void WebContentsImpl::MediaEffectivelyFullscreenChanged(bool is_fullscreen) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.MediaEffectivelyFullscreenChanged(is_fullscreen); observer->MediaEffectivelyFullscreenChanged(is_fullscreen);
});
} }
base::Optional<gfx::Size> WebContentsImpl::GetFullscreenVideoSize() { base::Optional<gfx::Size> WebContentsImpl::GetFullscreenVideoSize() {
...@@ -7661,21 +7730,24 @@ int WebContentsImpl::GetCurrentlyPlayingVideoCount() { ...@@ -7661,21 +7730,24 @@ int WebContentsImpl::GetCurrentlyPlayingVideoCount() {
void WebContentsImpl::AudioContextPlaybackStarted(RenderFrameHost* host, void WebContentsImpl::AudioContextPlaybackStarted(RenderFrameHost* host,
int context_id) { int context_id) {
WebContentsObserver::AudioContextId audio_context_id(host, context_id); WebContentsObserver::AudioContextId audio_context_id(host, context_id);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.AudioContextPlaybackStarted(audio_context_id); observer->AudioContextPlaybackStarted(audio_context_id);
});
} }
void WebContentsImpl::AudioContextPlaybackStopped(RenderFrameHost* host, void WebContentsImpl::AudioContextPlaybackStopped(RenderFrameHost* host,
int context_id) { int context_id) {
WebContentsObserver::AudioContextId audio_context_id(host, context_id); WebContentsObserver::AudioContextId audio_context_id(host, context_id);
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.AudioContextPlaybackStopped(audio_context_id); observer->AudioContextPlaybackStopped(audio_context_id);
});
} }
void WebContentsImpl::OnFrameAudioStateChanged(RenderFrameHost* host, void WebContentsImpl::OnFrameAudioStateChanged(RenderFrameHost* host,
bool is_audible) { bool is_audible) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.OnFrameAudioStateChanged(host, is_audible); observer->OnFrameAudioStateChanged(host, is_audible);
});
} }
media::MediaMetricsProvider::RecordAggregateWatchTimeCallback media::MediaMetricsProvider::RecordAggregateWatchTimeCallback
...@@ -7755,7 +7827,7 @@ bool WebContentsImpl::ShowPopupMenu( ...@@ -7755,7 +7827,7 @@ bool WebContentsImpl::ShowPopupMenu(
std::vector<blink::mojom::MenuItemPtr>* menu_items, std::vector<blink::mojom::MenuItemPtr>* menu_items,
bool right_aligned, bool right_aligned,
bool allow_multiple_selection) { bool allow_multiple_selection) {
for (auto& observer : observers_) { for (auto& observer : observers_.observer_list()) {
if (observer.ShowPopupMenu(render_frame_host, popup_client, bounds, if (observer.ShowPopupMenu(render_frame_host, popup_client, bounds,
item_height, font_size, selected_item, item_height, font_size, selected_item,
menu_items, right_aligned, menu_items, right_aligned,
...@@ -7886,8 +7958,9 @@ void WebContentsImpl::SetOpenerForNewContents(FrameTreeNode* opener, ...@@ -7886,8 +7958,9 @@ void WebContentsImpl::SetOpenerForNewContents(FrameTreeNode* opener,
void WebContentsImpl::MediaMutedStatusChanged(const MediaPlayerId& id, void WebContentsImpl::MediaMutedStatusChanged(const MediaPlayerId& id,
bool muted) { bool muted) {
for (auto& observer : observers_) observers_.ForEachObserver([&](WebContentsObserver* observer) {
observer.MediaMutedStatusChanged(id, muted); observer->MediaMutedStatusChanged(id, muted);
});
} }
void WebContentsImpl::SetVisibilityForChildViews(bool visible) { void WebContentsImpl::SetVisibilityForChildViews(bool visible) {
......
...@@ -1395,6 +1395,40 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents, ...@@ -1395,6 +1395,40 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
WebContentsImpl* focused_web_contents_; WebContentsImpl* focused_web_contents_;
}; };
// Container for WebContentsObservers, which knows when we are iterating over
// observer set.
class WebContentsObserverList {
public:
WebContentsObserverList();
~WebContentsObserverList();
void AddObserver(WebContentsObserver* observer);
void RemoveObserver(WebContentsObserver* observer);
template <class ForEachCallable>
void ForEachObserver(const ForEachCallable& callable) {
TRACE_EVENT0("content", "Iterating over WebContentsObservers");
base::AutoReset<bool> scope(&is_notifying_observers_, true);
for (WebContentsObserver& observer : observers_) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
"Dispatching WebContentsObserver callback");
callable(&observer);
}
}
bool is_notifying_observers() { return is_notifying_observers_; }
// Exposed to deal with IPC message handlers which need to stop iteration
// early.
const base::ObserverList<WebContentsObserver>::Unchecked& observer_list() {
return observers_;
}
private:
bool is_notifying_observers_ = false;
base::ObserverList<WebContentsObserver>::Unchecked observers_;
};
// See WebContents::Create for a description of these parameters. // See WebContents::Create for a description of these parameters.
explicit WebContentsImpl(BrowserContext* browser_context); explicit WebContentsImpl(BrowserContext* browser_context);
...@@ -1719,7 +1753,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents, ...@@ -1719,7 +1753,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// This MUST be listed above frame_tree_ since at destruction time the // This MUST be listed above frame_tree_ since at destruction time the
// latter might cause RenderViewHost's destructor to call us and we might use // latter might cause RenderViewHost's destructor to call us and we might use
// the observer list then. // the observer list then.
base::ObserverList<WebContentsObserver>::Unchecked observers_; WebContentsObserverList observers_;
// Associated interface receiver sets attached to this WebContents. // Associated interface receiver sets attached to this WebContents.
std::map<std::string, WebContentsReceiverSet*> receiver_sets_; std::map<std::string, WebContentsReceiverSet*> receiver_sets_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment