#include "content/browser/geolocation/geolocation_dispatcher_host.h"
#include "content/browser/host_zoom_map_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/manifest/manifest_manager_host.h"
+#include "content/browser/media/audio_stream_monitor.h"
+#include "content/browser/media/capture/web_contents_audio_muter.h"
#include "content/browser/media/midi_dispatcher_host.h"
#include "content/browser/message_port_message_filter.h"
#include "content/browser/message_port_service.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
-#include "content/browser/screen_orientation/screen_orientation_dispatcher_host.h"
+#include "content/browser/screen_orientation/screen_orientation_dispatcher_host_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/web_contents/web_contents_view_guest.h"
#include "content/browser/webui/generic_handler.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/browser/resource_request_details.h"
+#include "content/public/browser/screen_orientation_dispatcher_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents_delegate.h"
base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> >
g_created_callbacks = LAZY_INSTANCE_INITIALIZER;
-static int StartDownload(content::RenderFrameHost* rfh,
+static int StartDownload(RenderFrameHost* rfh,
const GURL& url,
bool is_favicon,
uint32_t max_bitmap_size) {
waiting_for_response_(false),
load_state_(net::LOAD_STATE_IDLE, base::string16()),
loading_total_progress_(0.0),
- loading_weak_factory_(this),
loading_frames_in_progress_(0),
upload_size_(0),
upload_position_(0),
fullscreen_widget_routing_id_(MSG_ROUTING_NONE),
fullscreen_widget_had_focus_at_shutdown_(false),
is_subframe_(false),
- touch_emulation_enabled_(false),
+ force_disable_overscroll_content_(false),
last_dialog_suppressed_(false),
accessibility_mode_(
- BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()) {
+ BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()),
+ audio_stream_monitor_(this),
+ loading_weak_factory_(this) {
for (size_t i = 0; i < g_created_callbacks.Get().size(); i++)
g_created_callbacks.Get().at(i).Run(this);
frame_tree_.SetFrameRemoveListener(
if (params.guest_delegate) {
// This makes |new_contents| act as a guest.
// For more info, see comment above class BrowserPluginGuest.
- BrowserPluginGuest::Create(params.guest_delegate->GetGuestInstanceID(),
- new_contents,
- params.guest_delegate);
+ BrowserPluginGuest::Create(new_contents, params.guest_delegate);
// We are instantiating a WebContents for browser plugin. Set its subframe
// bit to true.
new_contents->is_subframe_ = true;
IPC_MESSAGE_HANDLER(ViewHostMsg_Find_Reply, OnFindReply)
IPC_MESSAGE_HANDLER(ViewHostMsg_AppCacheAccessed, OnAppCacheAccessed)
IPC_MESSAGE_HANDLER(ViewHostMsg_WebUISend, OnWebUISend)
+#if defined(ENABLE_PLUGINS)
IPC_MESSAGE_HANDLER(ViewHostMsg_RequestPpapiBrokerPermission,
OnRequestPpapiBrokerPermission)
IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginHostMsg_Attach,
OnBrowserPluginMessage(message))
+#endif
IPC_MESSAGE_HANDLER(ImageHostMsg_DidDownloadImage, OnDidDownloadImage)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFaviconURL, OnUpdateFaviconURL)
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowValidationMessage,
}
void WebContentsImpl::AddAccessibilityMode(AccessibilityMode mode) {
- SetAccessibilityMode(
- content::AddAccessibilityModeTo(accessibility_mode_, mode));
+ SetAccessibilityMode(AddAccessibilityModeTo(accessibility_mode_, mode));
}
void WebContentsImpl::RemoveAccessibilityMode(AccessibilityMode mode) {
- SetAccessibilityMode(
- content::RemoveAccessibilityModeFrom(accessibility_mode_, mode));
+ SetAccessibilityMode(RemoveAccessibilityModeFrom(accessibility_mode_, mode));
}
WebUI* WebContentsImpl::CreateWebUI(const GURL& url) {
return capturer_count_;
}
+bool WebContentsImpl::IsAudioMuted() const {
+ return audio_muter_.get() && audio_muter_->is_muting();
+}
+
+void WebContentsImpl::SetAudioMuted(bool mute) {
+ DVLOG(1) << "SetAudioMuted(mute=" << mute << "), was " << IsAudioMuted()
+ << " for WebContentsImpl@" << this;
+
+ if (mute == IsAudioMuted())
+ return;
+
+ if (mute) {
+ if (!audio_muter_)
+ audio_muter_.reset(new WebContentsAudioMuter(this));
+ audio_muter_->StartMuting();
+ } else {
+ DCHECK(audio_muter_);
+ audio_muter_->StopMuting();
+ }
+
+ // Notification for UI updates in response to the changed muting state.
+ NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
+}
+
bool WebContentsImpl::IsCrashed() const {
return (crashed_status_ == base::TERMINATION_STATUS_PROCESS_CRASHED ||
crashed_status_ == base::TERMINATION_STATUS_ABNORMAL_TERMINATION ||
void WebContentsImpl::NotifyNavigationStateChanged(
InvalidateTypes changed_flags) {
+ // Create and release the audio power save blocker depending on whether the
+ // tab is actively producing audio or not.
+ if (changed_flags == INVALIDATE_TYPE_TAB &&
+ AudioStreamMonitor::monitoring_available()) {
+ if (WasRecentlyAudible()) {
+ if (!audio_power_save_blocker_)
+ CreateAudioPowerSaveBlocker();
+ } else {
+ audio_power_save_blocker_.reset();
+ }
+ }
+
if (delegate_)
delegate_->NavigationStateChanged(this, changed_flags);
}
rvh->ResizeRectChanged(GetRootWindowResizerRect());
}
+ // Restore power save blocker if there are active video players running.
+ if (!active_video_players_.empty() && !video_power_save_blocker_)
+ CreateVideoPowerSaveBlocker();
+
FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasShown());
should_normally_be_visible_ = true;
if (*iter)
(*iter)->Hide();
}
+
+ // Release any video power save blockers held as video is not visible.
+ video_power_save_blocker_.reset();
}
FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasHidden());
midi_dispatcher_host_.reset(new MidiDispatcherHost(this));
screen_orientation_dispatcher_host_.reset(
- new ScreenOrientationDispatcherHost(this));
+ new ScreenOrientationDispatcherHostImpl(this));
+
+ manifest_manager_host_.reset(new ManifestManagerHost(this));
#if defined(OS_ANDROID)
date_time_chooser_.reset(new DateTimeChooserAndroid());
}
void WebContentsImpl::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
+ if (browser_plugin_embedder_ &&
+ browser_plugin_embedder_->HandleKeyboardEvent(event)) {
+ return;
+ }
if (delegate_)
delegate_->HandleKeyboardEvent(this, event);
}
if (process_handle != base::kNullProcessHandle) {
RecordAction(
base::UserMetricsAction("Terminate_ProcessMismatch_CreateNewWindow"));
- base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false);
+ base::KillProcess(process_handle, RESULT_CODE_KILLED, false);
}
return;
}
OpenURLParams open_params(params.target_url,
Referrer(),
CURRENT_TAB,
- PAGE_TRANSITION_LINK,
+ ui::PAGE_TRANSITION_LINK,
true /* is_renderer_initiated */);
open_params.user_gesture = params.user_gesture;
new_contents->OpenURL(open_params);
if (process_handle != base::kNullProcessHandle) {
RecordAction(
base::UserMetricsAction("Terminate_ProcessMismatch_CreateNewWidget"));
- base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false);
+ base::KillProcess(process_handle, RESULT_CODE_KILLED, false);
}
return;
}
!new_contents->GetRenderViewHost()->GetView())
return NULL;
+ // Resume blocked requests for both the RenderViewHost and RenderFrameHost.
// TODO(brettw): It seems bogus to reach into here and initialize the host.
static_cast<RenderViewHostImpl*>(new_contents->GetRenderViewHost())->Init();
+ static_cast<RenderFrameHostImpl*>(new_contents->GetMainFrame())->Init();
+
return new_contents;
}
delegate_->RequestMediaAccessPermission(this, request, callback);
} else {
callback.Run(MediaStreamDevices(),
- MEDIA_DEVICE_INVALID_STATE,
+ MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN,
scoped_ptr<MediaStreamUI>());
}
}
+bool WebContentsImpl::CheckMediaAccessPermission(const GURL& security_origin,
+ MediaStreamType type) {
+ DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
+ type == MEDIA_DEVICE_VIDEO_CAPTURE);
+ return delegate_ &&
+ delegate_->CheckMediaAccessPermission(this, security_origin, type);
+}
+
SessionStorageNamespace* WebContentsImpl::GetSessionStorageNamespace(
SiteInstance* instance) {
return controller_.GetSessionStorageNamespace(instance);
WebContentsObserver, observers_, AccessibilityEventReceived(details));
}
+RenderFrameHost* WebContentsImpl::GetGuestByInstanceID(
+ int browser_plugin_instance_id) {
+ BrowserPluginGuestManager* guest_manager =
+ GetBrowserContext()->GetGuestManager();
+ WebContents* guest = guest_manager->GetGuestByInstanceID(
+ this, browser_plugin_instance_id);
+ if (!guest)
+ return NULL;
+ return guest->GetMainFrame();
+}
+
void WebContentsImpl::OnShowValidationMessage(
const gfx::Rect& anchor_in_root_view,
const base::string16& main_text,
browser_plugin_embedder_->DidSendScreenRects();
}
-void WebContentsImpl::OnTouchEmulationEnabled(bool enabled) {
- touch_emulation_enabled_ = enabled;
- if (view_)
- view_->SetOverscrollControllerEnabled(CanOverscrollContent());
-}
-
BrowserAccessibilityManager*
WebContentsImpl::GetRootBrowserAccessibilityManager() {
RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame());
NavigationController::ReloadType reload_type) {
FrameTreeNode* node = frame_tree_.root();
- // If we are using --site-per-process, we should navigate in the FrameTreeNode
- // specified in the pending entry.
+ // Navigate in the FrameTreeNode specified in the pending entry, if any. This
+ // is currently only used in --site-per-process and tests.
NavigationEntryImpl* pending_entry =
NavigationEntryImpl::FromNavigationEntry(controller_.GetPendingEntry());
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) &&
- pending_entry->frame_tree_node_id() != -1) {
- node = frame_tree_.FindByID(pending_entry->frame_tree_node_id());
+ if (pending_entry->frame_tree_node_id() != -1) {
+ FrameTreeNode* subframe =
+ frame_tree_.FindByID(pending_entry->frame_tree_node_id());
+ DCHECK(subframe);
+ if (subframe)
+ node = subframe;
}
return node->navigator()->NavigateToPendingEntry(
GetMainFrame()->GetRoutingID(), css));
}
+bool WebContentsImpl::WasRecentlyAudible() {
+ return audio_stream_monitor_.WasRecentlyAudible();
+}
+
+void WebContentsImpl::GetManifest(const GetManifestCallback& callback) {
+ manifest_manager_host_->GetManifest(GetMainFrame(), callback);
+}
+
bool WebContentsImpl::FocusLocationBarByDefault() {
NavigationEntry* entry = controller_.GetVisibleEntry();
if (entry && entry->GetURL() == GURL(url::kAboutBlankURL))
observers_,
DidStartProvisionalLoadForFrame(
render_frame_host, validated_url, is_error_page, is_iframe_srcdoc));
-
- if (!render_frame_host->GetParent()) {
- FOR_EACH_OBSERVER(
- WebContentsObserver,
- observers_,
- ProvisionalChangeToMainFrameUrl(validated_url,
- render_frame_host));
- }
}
void WebContentsImpl::DidStartNavigationTransition(
return delegate_->ShouldPreserveAbortedURLs(this);
}
-void WebContentsImpl::DidRedirectProvisionalLoad(
- RenderFrameHostImpl* render_frame_host,
- const GURL& validated_target_url) {
- // Notify observers about the provisional change in the main frame URL.
- FOR_EACH_OBSERVER(
- WebContentsObserver,
- observers_,
- ProvisionalChangeToMainFrameUrl(validated_target_url,
- render_frame_host));
-}
-
void WebContentsImpl::DidCommitProvisionalLoad(
RenderFrameHostImpl* render_frame_host,
const GURL& url,
- PageTransition transition_type) {
+ ui::PageTransition transition_type) {
// Notify observers about the commit of the provisional load.
FOR_EACH_OBSERVER(WebContentsObserver,
observers_,
// clicking on a link); see bugs 1184641 and 980803. We don't want to
// clear the bubble when a user navigates to a named anchor in the same
// page.
- UpdateTargetURL(details.entry->GetPageID(), GURL());
+ UpdateTargetURL(GURL());
}
if (!details.is_in_page) {
bool WebContentsImpl::CanOverscrollContent() const {
// Disable overscroll when touch emulation is on. See crbug.com/369938.
- if (touch_emulation_enabled_)
+ if (force_disable_overscroll_content_)
return false;
if (delegate_)
delegate_->WebUISend(this, source_url, name, args);
}
+#if defined(ENABLE_PLUGINS)
void WebContentsImpl::OnRequestPpapiBrokerPermission(
int routing_id,
const GURL& url,
browser_plugin_embedder_.reset(BrowserPluginEmbedder::Create(this));
browser_plugin_embedder_->OnMessageReceived(message);
}
+#endif
void WebContentsImpl::OnDidDownloadImage(
int id,
DidUpdateFaviconURL(candidates));
}
-void WebContentsImpl::OnMediaPlayingNotification(int64 player_cookie,
- bool has_video,
- bool has_audio) {
+void WebContentsImpl::CreateAudioPowerSaveBlocker() {
+ // ChromeOS has its own way of handling power save blocks for media.
#if !defined(OS_CHROMEOS)
- scoped_ptr<PowerSaveBlocker> blocker;
- if (has_video) {
- blocker = PowerSaveBlocker::Create(
- PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, "Playing video");
+ DCHECK(!audio_power_save_blocker_);
+ audio_power_save_blocker_ = PowerSaveBlocker::Create(
+ PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, "Playing Audio");
+#endif
+}
+
+void WebContentsImpl::CreateVideoPowerSaveBlocker() {
+ // ChromeOS has its own way of handling power save blocks for media.
+#if !defined(OS_CHROMEOS)
+ DCHECK(!video_power_save_blocker_);
+ DCHECK(!active_video_players_.empty());
+ video_power_save_blocker_ = PowerSaveBlocker::Create(
+ PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, "Playing Video");
#if defined(OS_ANDROID)
- static_cast<PowerSaveBlockerImpl*>(blocker.get())
- ->InitDisplaySleepBlocker(GetView()->GetNativeView());
+ static_cast<PowerSaveBlockerImpl*>(video_power_save_blocker_.get())
+ ->InitDisplaySleepBlocker(GetView()->GetNativeView());
+#endif
#endif
- } else if (has_audio) {
- blocker = PowerSaveBlocker::Create(
- PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, "Playing audio");
+}
+
+void WebContentsImpl::MaybeReleasePowerSaveBlockers() {
+ // If there are no more audio players and we don't have audio stream
+ // monitoring, release the audio power save blocker here instead of during
+ // NotifyNavigationStateChanged().
+ if (active_audio_players_.empty() &&
+ !AudioStreamMonitor::monitoring_available()) {
+ audio_power_save_blocker_.reset();
}
- if (blocker) {
- uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_message_source_);
- if (!power_save_blockers_.contains(key)) {
- power_save_blockers_.add(key,
- make_scoped_ptr(new PowerSaveBlockerMapEntry));
+ // If there are no more video players, clear the video power save blocker.
+ if (active_video_players_.empty())
+ video_power_save_blocker_.reset();
+}
+
+void WebContentsImpl::OnMediaPlayingNotification(int64 player_cookie,
+ bool has_video,
+ bool has_audio) {
+ if (has_audio) {
+ AddMediaPlayerEntry(player_cookie, &active_audio_players_);
+
+ // If we don't have audio stream monitoring, allocate the audio power save
+ // blocker here instead of during NotifyNavigationStateChanged().
+ if (!audio_power_save_blocker_ &&
+ !AudioStreamMonitor::monitoring_available()) {
+ CreateAudioPowerSaveBlocker();
}
- PowerSaveBlockerMapEntry* map_entry =
- power_save_blockers_.get(key);
- map_entry->set(player_cookie, blocker.Pass());
}
-#endif // !defined(OS_CHROMEOS)
+
+ if (has_video) {
+ AddMediaPlayerEntry(player_cookie, &active_video_players_);
+
+ // If we're not hidden and have just created a player, create a blocker.
+ if (!video_power_save_blocker_ && !IsHidden())
+ CreateVideoPowerSaveBlocker();
+ }
}
void WebContentsImpl::OnMediaPausedNotification(int64 player_cookie) {
-#if !defined(OS_CHROMEOS)
- uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_message_source_);
- PowerSaveBlockerMapEntry* map_entry = power_save_blockers_.get(key);
- if (map_entry)
- map_entry->erase(player_cookie);
-#endif // !defined(OS_CHROMEOS)
+ RemoveMediaPlayerEntry(player_cookie, &active_audio_players_);
+ RemoveMediaPlayerEntry(player_cookie, &active_video_players_);
+ MaybeReleasePowerSaveBlockers();
}
void WebContentsImpl::OnFirstVisuallyNonEmptyPaint() {
BeforeFormRepostWarningShow());
}
-
void WebContentsImpl::ActivateAndShowRepostFormWarningDialog() {
Activate();
if (delegate_)
std::string url = (details ? details->url.possibly_invalid_spec() : "NULL");
if (is_loading) {
- TRACE_EVENT_ASYNC_BEGIN1("browser", "WebContentsImpl Loading", this,
- "URL", url);
+ TRACE_EVENT_ASYNC_BEGIN1("browser,navigation", "WebContentsImpl Loading",
+ this, "URL", url);
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
DidStartLoading(render_view_host));
} else {
- TRACE_EVENT_ASYNC_END1("browser", "WebContentsImpl Loading", this,
- "URL", url);
+ TRACE_EVENT_ASYNC_END1("browser,navigation", "WebContentsImpl Loading",
+ this, "URL", url);
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
DidStopLoading(render_view_host));
}
controller_.NotifyEntryChanged(entry, entry_index);
}
-void WebContentsImpl::UpdateTargetURL(int32 page_id, const GURL& url) {
+void WebContentsImpl::UpdateTargetURL(const GURL& url) {
if (delegate_)
- delegate_->UpdateTargetURL(this, page_id, url);
+ delegate_->UpdateTargetURL(this, url);
}
void WebContentsImpl::Close(RenderViewHost* rvh) {
controller_.DiscardPendingEntry();
// Update the URL display.
- NotifyNavigationStateChanged(content::INVALIDATE_TYPE_URL);
+ NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
}
void WebContentsImpl::DidDisownOpener(RenderFrameHost* render_frame_host) {
- if (opener_) {
- // Clear our opener so that future cross-process navigations don't have an
- // opener assigned.
- RemoveDestructionObserver(opener_);
- opener_ = NULL;
- }
+ // No action is necessary if the opener has already been cleared.
+ if (!opener_)
+ return;
+
+ // Clear our opener so that future cross-process navigations don't have an
+ // opener assigned.
+ RemoveDestructionObserver(opener_);
+ opener_ = NULL;
// Notify all swapped out RenderViewHosts for this tab. This is important
// in case we go back to them, or if another window in those processes tries
// to access window.opener.
- GetRenderManager()->DidDisownOpener(render_frame_host->GetRenderViewHost());
+ GetRenderManager()->DidDisownOpener(render_frame_host);
}
void WebContentsImpl::DocumentOnLoadCompleted(
int opener_route_id,
int proxy_routing_id,
bool for_main_frame_navigation) {
- TRACE_EVENT0("browser", "WebContentsImpl::CreateRenderViewForRenderManager");
+ TRACE_EVENT0("browser,navigation",
+ "WebContentsImpl::CreateRenderViewForRenderManager");
// Can be NULL during tests.
RenderWidgetHostViewBase* rwh_view;
// TODO(kenrb): RenderWidgetHostViewChildFrame special casing is temporary
bool WebContentsImpl::CreateRenderFrameForRenderManager(
RenderFrameHost* render_frame_host,
int parent_routing_id) {
- TRACE_EVENT0("browser", "WebContentsImpl::CreateRenderFrameForRenderManager");
+ TRACE_EVENT0("browser,navigation",
+ "WebContentsImpl::CreateRenderFrameForRenderManager");
RenderFrameHostImpl* rfh =
static_cast<RenderFrameHostImpl*>(render_frame_host);
#elif defined(OS_MACOSX)
-void WebContentsImpl::SetAllowOverlappingViews(bool overlapping) {
- view_->SetAllowOverlappingViews(overlapping);
-}
-
-bool WebContentsImpl::GetAllowOverlappingViews() {
- return view_->GetAllowOverlappingViews();
-}
-
void WebContentsImpl::SetAllowOtherViews(bool allow) {
view_->SetAllowOtherViews(allow);
}
void WebContentsImpl::ClearPowerSaveBlockers(
RenderFrameHost* render_frame_host) {
-#if !defined(OS_CHROMEOS)
- uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
- scoped_ptr<PowerSaveBlockerMapEntry> map_entry =
- power_save_blockers_.take_and_erase(key);
- if (map_entry)
- map_entry->clear();
-#endif
+ RemoveAllMediaPlayerEntries(render_frame_host, &active_audio_players_);
+ RemoveAllMediaPlayerEntries(render_frame_host, &active_video_players_);
+ MaybeReleasePowerSaveBlockers();
}
void WebContentsImpl::ClearAllPowerSaveBlockers() {
-#if !defined(OS_CHROMEOS)
- power_save_blockers_.clear();
-#endif
+ active_audio_players_.clear();
+ active_video_players_.clear();
+ audio_power_save_blocker_.reset();
+ video_power_save_blocker_.reset();
}
gfx::Size WebContentsImpl::GetSizeForNewRenderView() {
delegate_->UpdatePreferredSize(this, new_size);
}
+void WebContentsImpl::AddMediaPlayerEntry(int64 player_cookie,
+ ActiveMediaPlayerMap* player_map) {
+ const uintptr_t key =
+ reinterpret_cast<uintptr_t>(render_frame_message_source_);
+ DCHECK(std::find((*player_map)[key].begin(),
+ (*player_map)[key].end(),
+ player_cookie) == (*player_map)[key].end());
+ (*player_map)[key].push_back(player_cookie);
+}
+
+void WebContentsImpl::RemoveMediaPlayerEntry(int64 player_cookie,
+ ActiveMediaPlayerMap* player_map) {
+ const uintptr_t key =
+ reinterpret_cast<uintptr_t>(render_frame_message_source_);
+ ActiveMediaPlayerMap::iterator it = player_map->find(key);
+ if (it == player_map->end())
+ return;
+
+ // Remove the player.
+ PlayerList::iterator player_it =
+ std::find(it->second.begin(), it->second.end(), player_cookie);
+ if (player_it != it->second.end())
+ it->second.erase(player_it);
+
+ // If there are no players left, remove the map entry.
+ if (it->second.empty())
+ player_map->erase(it);
+}
+
+void WebContentsImpl::RemoveAllMediaPlayerEntries(
+ RenderFrameHost* render_frame_host,
+ ActiveMediaPlayerMap* player_map) {
+ ActiveMediaPlayerMap::iterator it =
+ player_map->find(reinterpret_cast<uintptr_t>(render_frame_host));
+ if (it == player_map->end())
+ return;
+ player_map->erase(it);
+}
+
void WebContentsImpl::ResumeResponseDeferredAtStart() {
FrameTreeNode* node = frame_tree_.root();
node->render_manager()->ResumeResponseDeferredAtStart();
}
+void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) {
+ force_disable_overscroll_content_ = force_disable;
+ if (view_)
+ view_->SetOverscrollControllerEnabled(CanOverscrollContent());
+}
+
} // namespace content