#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "content/browser/accessibility/accessibility_mode_helper.h"
+#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/browser_plugin/browser_plugin_embedder.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
-#include "content/browser/browser_plugin/browser_plugin_guest_manager.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/render_view_devtools_agent_host.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/frame_host/navigator_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/frame_host/render_widget_host_view_child_frame.h"
+#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/power_save_blocker_impl.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_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/common/view_messages.h"
#include "content/public/browser/ax_event_notification_details.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_plugin_guest_manager.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/notification_details.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"
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
+#include "content/public/common/web_preferences.h"
#include "net/base/mime_util.h"
#include "net/base/net_util.h"
#include "net/http/http_cache.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
#include "ui/gl/gl_switches.h"
-#include "webkit/common/webpreferences.h"
#if defined(OS_ANDROID)
+#include "content/browser/android/content_view_core_impl.h"
#include "content/browser/android/date_time_chooser_android.h"
#include "content/browser/media/android/browser_media_player_manager.h"
-#include "content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h"
#include "content/browser/web_contents/web_contents_android.h"
-#include "content/common/java_bridge_messages.h"
#include "content/public/browser/android/content_view_core.h"
#endif
#if defined(OS_MACOSX)
#include "base/mac/foundation_util.h"
-#include "ui/gl/io_surface_support_mac.h"
#endif
// Cross-Site Navigations
namespace content {
namespace {
+const int kMinimumDelayBetweenLoadingUpdatesMS = 100;
+
+// This matches what Blink's ProgressTracker has traditionally used for a
+// minimum progress value.
+const double kMinimumLoadingProgress = 0.1;
+
const char kDotGoogleDotCom[] = ".google.com";
#if defined(OS_ANDROID)
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) {
rfh->Send(message_copy);
}
-void RunRenderFrameDeleted(
- ObserverList<WebContentsObserver>* observer_list,
- RenderFrameHost* render_frame_host) {
- FOR_EACH_OBSERVER(WebContentsObserver,
- *observer_list,
- RenderFrameDeleted(render_frame_host));
+void AddRenderWidgetHostViewToSet(std::set<RenderWidgetHostView*>* set,
+ RenderFrameHost* rfh) {
+ RenderWidgetHostView* rwhv = static_cast<RenderFrameHostImpl*>(rfh)
+ ->frame_tree_node()
+ ->render_manager()
+ ->GetRenderWidgetHostView();
+ set->insert(rwhv);
+}
+
+void SetAccessibilityModeOnFrame(AccessibilityMode mode,
+ RenderFrameHost* frame_host) {
+ static_cast<RenderFrameHostImpl*>(frame_host)->SetAccessibilityMode(mode);
}
} // namespace
frame_tree_(new NavigatorImpl(&controller_, this),
this, this, this, this),
is_loading_(false),
+ is_load_to_different_document_(false),
crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING),
crashed_error_code_(0),
waiting_for_response_(false),
load_state_(net::LOAD_STATE_IDLE, base::string16()),
+ loading_total_progress_(0.0),
+ loading_frames_in_progress_(0),
upload_size_(0),
upload_position_(0),
displayed_insecure_content_(false),
closed_by_user_gesture_(false),
minimum_zoom_percent_(static_cast<int>(kMinimumZoomFactor * 100)),
maximum_zoom_percent_(static_cast<int>(kMaximumZoomFactor * 100)),
- temporary_zoom_settings_(false),
totalPinchGestureAmount_(0),
currentPinchZoomStepDelta_(0),
render_view_message_source_(NULL),
fullscreen_widget_routing_id_(MSG_ROUTING_NONE),
+ fullscreen_widget_had_focus_at_shutdown_(false),
is_subframe_(false),
- last_dialog_suppressed_(false) {
+ force_disable_overscroll_content_(false),
+ last_dialog_suppressed_(false),
+ 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(
Source<WebContents>(this),
NotificationService::NoDetails());
- base::Callback<void(RenderFrameHost*)> run_render_frame_deleted_callback =
- base::Bind(&RunRenderFrameDeleted, base::Unretained(&observers_));
- frame_tree_.ForEach(base::Bind(&ForEachPendingFrameInternal,
- run_render_frame_deleted_callback));
+ // Destroy all frame tree nodes except for the root; this notifies observers.
+ frame_tree_.ResetForMainFrameSwap();
+ GetRenderManager()->ResetProxyHosts();
- RenderViewHost* pending_rvh = GetRenderManager()->pending_render_view_host();
- if (pending_rvh) {
+ // Manually call the observer methods for the root frame tree node.
+ RenderFrameHostManager* root = GetRenderManager();
+ if (root->pending_frame_host()) {
FOR_EACH_OBSERVER(WebContentsObserver,
observers_,
- RenderViewDeleted(pending_rvh));
+ RenderFrameDeleted(root->pending_frame_host()));
}
+ FOR_EACH_OBSERVER(WebContentsObserver,
+ observers_,
+ RenderFrameDeleted(root->current_frame_host()));
- ForEachFrame(run_render_frame_deleted_callback);
+ if (root->pending_render_view_host()) {
+ FOR_EACH_OBSERVER(WebContentsObserver,
+ observers_,
+ RenderViewDeleted(root->pending_render_view_host()));
+ }
FOR_EACH_OBSERVER(WebContentsObserver,
observers_,
- RenderViewDeleted(GetRenderManager()->current_host()));
+ RenderViewDeleted(root->current_host()));
FOR_EACH_OBSERVER(WebContentsObserver,
observers_,
WebContentsImpl* opener) {
TRACE_EVENT0("browser", "WebContentsImpl::CreateWithOpener");
WebContentsImpl* new_contents = new WebContentsImpl(
- params.browser_context, opener);
+ params.browser_context, params.opener_suppressed ? NULL : opener);
+ if (params.guest_delegate) {
+ // This makes |new_contents| act as a guest.
+ // For more info, see comment above class BrowserPluginGuest.
+ 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;
+ }
new_contents->Init(params);
return new_contents;
}
// static
-BrowserPluginGuest* WebContentsImpl::CreateGuest(
- BrowserContext* browser_context,
- SiteInstance* site_instance,
- int guest_instance_id,
- scoped_ptr<base::DictionaryValue> extra_params) {
- WebContentsImpl* new_contents = new WebContentsImpl(browser_context, NULL);
-
- // This makes |new_contents| act as a guest.
- // For more info, see comment above class BrowserPluginGuest.
- BrowserPluginGuest::Create(
- guest_instance_id, site_instance, new_contents, extra_params.Pass());
-
- WebContents::CreateParams create_params(browser_context, site_instance);
- new_contents->Init(create_params);
-
- // We are instantiating a WebContents for browser plugin. Set its subframe bit
- // to true.
- new_contents->is_subframe_ = true;
-
- return new_contents->browser_plugin_guest_.get();
+std::vector<WebContentsImpl*> WebContentsImpl::GetAllWebContents() {
+ std::vector<WebContentsImpl*> result;
+ scoped_ptr<RenderWidgetHostIterator> widgets(
+ RenderWidgetHostImpl::GetRenderWidgetHosts());
+ std::set<WebContentsImpl*> web_contents_set;
+ while (RenderWidgetHost* rwh = widgets->GetNextHost()) {
+ if (!rwh->IsRenderView())
+ continue;
+ RenderViewHost* rvh = RenderViewHost::From(rwh);
+ if (!rvh)
+ continue;
+ WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
+ if (!web_contents)
+ continue;
+ WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents);
+ if (web_contents_set.find(wci) == web_contents_set.end()) {
+ web_contents_set.insert(wci);
+ result.push_back(wci);
+ }
+ }
+ return result;
}
RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() {
ObserverListBase<WebContentsObserver>::Iterator it(observers_);
WebContentsObserver* observer;
- while ((observer = it.GetNext()) != NULL)
- if (observer->OnMessageReceived(message))
- return true;
+ if (render_frame_host) {
+ while ((observer = it.GetNext()) != NULL)
+ if (observer->OnMessageReceived(message, render_frame_host))
+ return true;
+ } else {
+ while ((observer = it.GetNext()) != NULL)
+ if (observer->OnMessageReceived(message))
+ return true;
+ }
// Message handlers should be aware of which
// RenderViewHost/RenderFrameHost sent the message, which is temporarily
// stored in render_(view|frame)_message_source_.
- if (render_frame_host) {
- if (RenderViewDevToolsAgentHost::DispatchIPCMessage(
- render_frame_host->GetRenderViewHost(), message))
- return true;
+ if (render_frame_host)
render_frame_message_source_ = render_frame_host;
- } else {
- if (RenderViewDevToolsAgentHost::DispatchIPCMessage(
- render_view_host, message))
- return true;
+ else
render_view_message_source_ = render_view_host;
- }
bool handled = true;
- bool message_is_ok = true;
- IPC_BEGIN_MESSAGE_MAP_EX(WebContentsImpl, message, message_is_ok)
+ IPC_BEGIN_MESSAGE_MAP(WebContentsImpl, message)
IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung)
IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed)
IPC_MESSAGE_HANDLER(FrameHostMsg_DomOperationResponse,
OnDomOperationResponse)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeThemeColor,
+ OnThemeColorChanged)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishDocumentLoad,
OnDocumentLoadedInFrame)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishLoad, OnDidFinishLoad)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeLoadProgress,
+ OnDidChangeLoadProgress)
IPC_MESSAGE_HANDLER(FrameHostMsg_OpenColorChooser, OnOpenColorChooser)
IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser)
IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser,
OnMediaPlayingNotification)
IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification,
OnMediaPausedNotification)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidFirstVisuallyNonEmptyPaint,
+ OnFirstVisuallyNonEmptyPaint)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache,
OnDidLoadResourceFromMemoryCache)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidDisplayInsecureContent,
IPC_MESSAGE_HANDLER(ViewHostMsg_EnumerateDirectory, OnEnumerateDirectory)
IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterProtocolHandler,
OnRegisterProtocolHandler)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_UnregisterProtocolHandler,
+ OnUnregisterProtocolHandler)
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_AllocateInstanceID,
- OnBrowserPluginMessage(message))
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_DidFirstVisuallyNonEmptyPaint,
- OnFirstVisuallyNonEmptyPaint)
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowValidationMessage,
OnShowValidationMessage)
IPC_MESSAGE_HANDLER(ViewHostMsg_HideValidationMessage,
OnFindMatchRectsReply)
IPC_MESSAGE_HANDLER(ViewHostMsg_OpenDateTimeDialog,
OnOpenDateTimeDialog)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(JavaBridgeHostMsg_GetChannelHandle,
- OnJavaBridgeGetChannelHandle)
#endif
IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP_EX()
+ IPC_END_MESSAGE_MAP()
render_view_message_source_ = NULL;
render_frame_message_source_ = NULL;
- if (!message_is_ok) {
- RecordAction(base::UserMetricsAction("BadMessageTerminate_RVD"));
- GetRenderProcessHost()->ReceivedBadMessage();
- }
-
return handled;
}
return entry ? entry->GetVirtualURL() : GURL::EmptyGURL();
}
+ScreenOrientationDispatcherHost* WebContentsImpl::GetScreenOrientationDispatcherHost() {
+ return screen_orientation_dispatcher_host_.get();
+}
+
WebContentsDelegate* WebContentsImpl::GetDelegate() {
return delegate_;
}
delegate_->Attach(this);
// Ensure the visible RVH reflects the new delegate's preferences.
if (view_)
- view_->SetOverscrollControllerEnabled(delegate->CanOverscrollContent());
+ view_->SetOverscrollControllerEnabled(CanOverscrollContent());
}
}
return GetRenderManager()->current_host();
}
-WebContents* WebContentsImpl::GetEmbedderWebContents() const {
- BrowserPluginGuest* guest = GetBrowserPluginGuest();
- if (guest)
- return guest->embedder_web_contents();
- return NULL;
-}
-
-int WebContentsImpl::GetEmbeddedInstanceID() const {
- BrowserPluginGuest* guest = GetBrowserPluginGuest();
- if (guest)
- return guest->instance_id();
- return 0;
-}
-
int WebContentsImpl::GetRoutingID() const {
if (!GetRenderViewHost())
return MSG_ROUTING_NONE;
return view_.get();
}
+void WebContentsImpl::SetAccessibilityMode(AccessibilityMode mode) {
+ if (mode == accessibility_mode_)
+ return;
+
+ accessibility_mode_ = mode;
+ frame_tree_.ForEach(
+ base::Bind(&ForEachFrameInternal,
+ base::Bind(&SetAccessibilityModeOnFrame, mode)));
+ frame_tree_.ForEach(
+ base::Bind(&ForEachPendingFrameInternal,
+ base::Bind(&SetAccessibilityModeOnFrame, mode)));
+}
+
+void WebContentsImpl::AddAccessibilityMode(AccessibilityMode mode) {
+ SetAccessibilityMode(AddAccessibilityModeTo(accessibility_mode_, mode));
+}
+
+void WebContentsImpl::RemoveAccessibilityMode(AccessibilityMode mode) {
+ SetAccessibilityMode(RemoveAccessibilityModeFrom(accessibility_mode_, mode));
+}
+
WebUI* WebContentsImpl::CreateWebUI(const GURL& url) {
WebUIImpl* web_ui = new WebUIImpl(this);
WebUIController* controller = WebUIControllerFactoryRegistry::GetInstance()->
return renderer_preferences_.user_agent_override;
}
+void WebContentsImpl::EnableTreeOnlyAccessibilityMode() {
+ AddAccessibilityMode(AccessibilityModeTreeOnly);
+}
+
+bool WebContentsImpl::IsTreeOnlyAccessibilityModeForTesting() const {
+ return accessibility_mode_ == AccessibilityModeTreeOnly;
+}
+
+bool WebContentsImpl::IsFullAccessibilityModeForTesting() const {
+ return accessibility_mode_ == AccessibilityModeComplete;
+}
+
#if defined(OS_WIN)
void WebContentsImpl::SetParentNativeViewAccessible(
gfx::NativeViewAccessible accessible_parent) {
accessible_parent_ = accessible_parent;
- if (GetRenderViewHost())
- GetRenderViewHostImpl()->SetParentNativeViewAccessible(accessible_parent);
+ RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame());
+ if (rfh)
+ rfh->SetParentNativeViewAccessible(accessible_parent);
}
#endif
return is_loading_;
}
+bool WebContentsImpl::IsLoadingToDifferentDocument() const {
+ return is_loading_ && is_load_to_different_document_;
+}
+
bool WebContentsImpl::IsWaitingForResponse() const {
- return waiting_for_response_;
+ return waiting_for_response_ && is_load_to_different_document_;
}
const net::LoadStateWithParam& WebContentsImpl::GetLoadState() const {
}
const std::string& WebContentsImpl::GetEncoding() const {
- return encoding_;
+ return canonical_encoding_;
}
bool WebContentsImpl::DisplayedInsecureContent() const {
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 ||
return is_being_destroyed_;
}
-void WebContentsImpl::NotifyNavigationStateChanged(unsigned changed_flags) {
+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);
}
void WebContentsImpl::WasShown() {
controller_.SetActive(true);
- RenderWidgetHostView* rwhv = GetRenderWidgetHostView();
- if (rwhv) {
- rwhv->Show();
+
+ std::set<RenderWidgetHostView*> widgets = GetRenderWidgetHostViewsInTree();
+ for (std::set<RenderWidgetHostView*>::iterator iter = widgets.begin();
+ iter != widgets.end();
+ iter++) {
+ if (*iter) {
+ (*iter)->Show();
#if defined(OS_MACOSX)
- rwhv->SetActive(true);
+ (*iter)->SetActive(true);
#endif
+ }
}
last_active_time_ = base::TimeTicks::Now();
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;
// removes the |GetRenderViewHost()|; then when we actually destroy the
// window, OnWindowPosChanged() notices and calls WasHidden() (which
// calls us).
- RenderWidgetHostView* rwhv = GetRenderWidgetHostView();
- if (rwhv)
- rwhv->Hide();
+ std::set<RenderWidgetHostView*> widgets = GetRenderWidgetHostViewsInTree();
+ for (std::set<RenderWidgetHostView*>::iterator iter = widgets.begin();
+ iter != widgets.end();
+ iter++) {
+ 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());
switch (type) {
case NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: {
RenderWidgetHost* host = Source<RenderWidgetHost>(source).ptr();
- for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
- i != pending_widget_views_.end(); ++i) {
- if (host->GetView() == i->second) {
- pending_widget_views_.erase(i);
- break;
+ RenderWidgetHostView* view = host->GetView();
+ if (view == GetFullscreenRenderWidgetHostView()) {
+ // We cannot just call view_->RestoreFocus() here. On some platforms,
+ // attempting to focus the currently-invisible WebContentsView will be
+ // flat-out ignored. Therefore, this boolean is used to track whether
+ // we will request focus after the fullscreen widget has been
+ // destroyed.
+ fullscreen_widget_had_focus_at_shutdown_ = (view && view->HasFocus());
+ } else {
+ for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
+ i != pending_widget_views_.end(); ++i) {
+ if (host->GetView() == i->second) {
+ pending_widget_views_.erase(i);
+ break;
+ }
}
}
break;
registrar_.Add(this,
NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
NotificationService::AllBrowserContextsAndSources());
+
+ geolocation_dispatcher_host_.reset(new GeolocationDispatcherHost(this));
+ midi_dispatcher_host_.reset(new MidiDispatcherHost(this));
+
+ screen_orientation_dispatcher_host_.reset(
+ new ScreenOrientationDispatcherHostImpl(this));
+
+ manifest_manager_host_.reset(new ManifestManagerHost(this));
+
#if defined(OS_ANDROID)
- java_bridge_dispatcher_host_manager_.reset(
- new JavaBridgeDispatcherHostManager(this));
date_time_chooser_.reset(new DateTimeChooserAndroid());
#endif
}
observers_.RemoveObserver(observer);
}
+std::set<RenderWidgetHostView*>
+WebContentsImpl::GetRenderWidgetHostViewsInTree() {
+ std::set<RenderWidgetHostView*> set;
+ if (ShowingInterstitialPage()) {
+ set.insert(GetRenderWidgetHostView());
+ } else {
+ ForEachFrame(
+ base::Bind(&AddRenderWidgetHostViewToSet, base::Unretained(&set)));
+ }
+ return set;
+}
+
void WebContentsImpl::Activate() {
if (delegate_)
delegate_->ActivateContents(this);
DidDestroyFullscreenWidget(
fullscreen_widget_routing_id_));
fullscreen_widget_routing_id_ = MSG_ROUTING_NONE;
+ if (fullscreen_widget_had_focus_at_shutdown_)
+ view_->RestoreFocus();
}
}
browser_plugin_embedder_->HandleKeyboardEvent(event)) {
return;
}
-
if (delegate_)
delegate_->HandleKeyboardEvent(this, event);
}
// Some platforms (eg. Mac) send GesturePinch events for trackpad pinch-zoom.
// Use them to implement browser zoom, as for HandleWheelEvent above.
if (event.type == blink::WebInputEvent::GesturePinchUpdate &&
- event.sourceDevice == blink::WebGestureEvent::Touchpad) {
+ event.sourceDevice == blink::WebGestureDeviceTouchpad) {
// The scale difference necessary to trigger a zoom action. Derived from
// experimentation to find a value that feels reasonable.
const float kZoomStepValue = 0.6f;
return false;
}
-#if defined(OS_WIN)
-gfx::NativeViewAccessible WebContentsImpl::GetParentNativeViewAccessible() {
- return accessible_parent_;
-}
-#endif
-
void WebContentsImpl::HandleMouseDown() {
if (delegate_)
delegate_->HandleMouseDown();
// script-related windows), by passing in the current SiteInstance. However,
// if the opener is being suppressed (in a non-guest), we create a new
// SiteInstance in its own BrowsingInstance.
- bool is_guest = GetRenderProcessHost()->IsGuest();
+ bool is_guest = BrowserPluginGuest::IsGuest(this);
// If the opener is to be suppressed, the new window can be in any process.
// Since routing ids are process specific, we must not have one passed in
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;
}
// Create the new web contents. This will automatically create the new
// WebContentsView. In the future, we may want to create the view separately.
- WebContentsImpl* new_contents =
- new WebContentsImpl(GetBrowserContext(),
- params.opener_suppressed ? NULL : this);
-
- new_contents->GetController().SetSessionStorageNamespace(
- partition_id,
- session_storage_namespace);
CreateParams create_params(GetBrowserContext(), site_instance.get());
create_params.routing_id = route_id;
create_params.main_frame_routing_id = main_frame_route_id;
+ create_params.opener = this;
+ create_params.opener_suppressed = params.opener_suppressed;
+ if (params.disposition == NEW_BACKGROUND_TAB)
+ create_params.initially_hidden = true;
+
+ WebContentsImpl* new_contents = NULL;
if (!is_guest) {
create_params.context = view_->GetNativeView();
create_params.initial_size = GetContainerBounds().size();
- } else {
- // This makes |new_contents| act as a guest.
- // For more info, see comment above class BrowserPluginGuest.
- int instance_id =
- BrowserPluginGuestManager::FromBrowserContext(GetBrowserContext())->
- GetNextInstanceID();
- WebContentsImpl* new_contents_impl =
- static_cast<WebContentsImpl*>(new_contents);
- BrowserPluginGuest::CreateWithOpener(instance_id,
- new_contents_impl->opener() != NULL,
- new_contents_impl,
- GetBrowserPluginGuest());
+ new_contents = static_cast<WebContentsImpl*>(
+ WebContents::Create(create_params));
+ } else {
+ new_contents = GetBrowserPluginGuest()->CreateNewGuestWindow(create_params);
}
- if (params.disposition == NEW_BACKGROUND_TAB)
- create_params.initially_hidden = true;
- new_contents->Init(create_params);
+ new_contents->GetController().SetSessionStorageNamespace(
+ partition_id,
+ session_storage_namespace);
+ new_contents->RenderViewCreated(new_contents->GetRenderViewHost());
// Save the window for later if we're not suppressing the opener (since it
// will be shown immediately).
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;
}
if (is_fullscreen) {
DCHECK_EQ(MSG_ROUTING_NONE, fullscreen_widget_routing_id_);
+ view_->StoreFocus();
fullscreen_widget_routing_id_ = route_id;
if (delegate_ && delegate_->EmbedsFullscreenWidget()) {
widget_host_view->InitAsChild(GetRenderWidgetHostView()->GetNativeView());
RemoveDestructionObserver(new_contents);
// Don't initialize the guest WebContents immediately.
- if (new_contents->GetRenderProcessHost()->IsGuest())
+ if (BrowserPluginGuest::IsGuest(new_contents))
return new_contents;
if (!new_contents->GetRenderProcessHost()->HasConnection() ||
!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);
}
+SessionStorageNamespaceMap WebContentsImpl::GetSessionStorageNamespaceMap() {
+ return controller_.GetSessionStorageNamespaceMap();
+}
+
FrameTree* WebContentsImpl::GetFrameTree() {
return &frame_tree_;
}
+AccessibilityMode WebContentsImpl::GetAccessibilityMode() const {
+ return accessibility_mode_;
+}
+
void WebContentsImpl::AccessibilityEventReceived(
const std::vector<AXEventNotificationDetails>& details) {
FOR_EACH_OBSERVER(
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();
}
+BrowserAccessibilityManager*
+ WebContentsImpl::GetRootBrowserAccessibilityManager() {
+ RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame());
+ return rfh ? rfh->browser_accessibility_manager() : NULL;
+}
+
+BrowserAccessibilityManager*
+ WebContentsImpl::GetOrCreateRootBrowserAccessibilityManager() {
+ RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(GetMainFrame());
+ return rfh ? rfh->GetOrCreateBrowserAccessibilityManager() : NULL;
+}
+
void WebContentsImpl::UpdatePreferredSize(const gfx::Size& pref_size) {
const gfx::Size old_size = GetPreferredSize();
preferred_size_ = pref_size;
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(
}
void WebContentsImpl::Focus() {
- view_->Focus();
+ RenderWidgetHostView* const fullscreen_view =
+ GetFullscreenRenderWidgetHostView();
+ if (fullscreen_view)
+ fullscreen_view->Focus();
+ else
+ view_->Focus();
}
void WebContentsImpl::SetInitialFocus() {
- view_->SetInitialFocus();
+ RenderWidgetHostView* const fullscreen_view =
+ GetFullscreenRenderWidgetHostView();
+ if (fullscreen_view)
+ fullscreen_view->Focus();
+ else
+ view_->SetInitialFocus();
}
void WebContentsImpl::StoreFocus() {
- view_->StoreFocus();
+ if (!GetFullscreenRenderWidgetHostView())
+ view_->StoreFocus();
}
void WebContentsImpl::RestoreFocus() {
- view_->RestoreFocus();
+ RenderWidgetHostView* const fullscreen_view =
+ GetFullscreenRenderWidgetHostView();
+ if (fullscreen_view)
+ fullscreen_view->Focus();
+ else
+ view_->RestoreFocus();
}
void WebContentsImpl::FocusThroughTabTraversal(bool reverse) {
GetRenderManager()->interstitial_page()->FocusThroughTabTraversal(reverse);
return;
}
+ RenderWidgetHostView* const fullscreen_view =
+ GetFullscreenRenderWidgetHostView();
+ if (fullscreen_view) {
+ fullscreen_view->Focus();
+ return;
+ }
GetRenderViewHostImpl()->SetInitialFocus(reverse);
}
MHTMLGenerationManager::GetInstance()->SaveMHTML(this, file, callback);
}
-// TODO(nasko): Rename this method to IsVisibleEntry.
-bool WebContentsImpl::IsActiveEntry(int32 page_id) {
- NavigationEntryImpl* visible_entry =
- NavigationEntryImpl::FromNavigationEntry(controller_.GetVisibleEntry());
- return (visible_entry != NULL &&
- visible_entry->site_instance() == GetSiteInstance() &&
- visible_entry->GetPageID() == page_id);
-}
-
const std::string& WebContentsImpl::GetContentsMimeType() const {
return contents_mime_type_;
}
}
void WebContentsImpl::ResetOverrideEncoding() {
- encoding_.clear();
+ canonical_encoding_.clear();
Send(new ViewMsg_ResetPageEncodingToDefault(GetRoutingID()));
}
return closed_by_user_gesture_;
}
-double WebContentsImpl::GetZoomLevel() const {
- HostZoomMapImpl* zoom_map = static_cast<HostZoomMapImpl*>(
- HostZoomMap::GetForBrowserContext(GetBrowserContext()));
- if (!zoom_map)
- return 0;
-
- double zoom_level;
- if (temporary_zoom_settings_) {
- zoom_level = zoom_map->GetTemporaryZoomLevel(
- GetRenderProcessHost()->GetID(), GetRenderViewHost()->GetRoutingID());
- } else {
- GURL url;
- NavigationEntry* entry = GetController().GetLastCommittedEntry();
- // Since zoom map is updated using rewritten URL, use rewritten URL
- // to get the zoom level.
- url = entry ? entry->GetURL() : GURL::EmptyGURL();
- zoom_level = zoom_map->GetZoomLevelForHostAndScheme(url.scheme(),
- net::GetHostOrSpecFromURL(url));
- }
- return zoom_level;
-}
-
-int WebContentsImpl::GetZoomPercent(bool* enable_increment,
- bool* enable_decrement) const {
- *enable_decrement = *enable_increment = false;
- // Calculate the zoom percent from the factor. Round up to the nearest whole
- // number.
- int percent = static_cast<int>(
- ZoomLevelToZoomFactor(GetZoomLevel()) * 100 + 0.5);
- *enable_decrement = percent > minimum_zoom_percent_;
- *enable_increment = percent < maximum_zoom_percent_;
- return percent;
-}
-
void WebContentsImpl::ViewSource() {
if (!delegate_)
return;
}
bool WebContentsImpl::GotResponseToLockMouseRequest(bool allowed) {
+ if (GetBrowserPluginGuest())
+ return GetBrowserPluginGuest()->LockMouse(allowed);
+
return GetRenderViewHost() ?
GetRenderViewHostImpl()->GotResponseToLockMouseRequest(allowed) : false;
}
return is_subframe_;
}
-void WebContentsImpl::SetZoomLevel(double level) {
- Send(new ViewMsg_SetZoomLevel(GetRoutingID(), level));
- BrowserPluginEmbedder* embedder = GetBrowserPluginEmbedder();
- if (embedder)
- embedder->SetZoomLevel(level);
-}
-
void WebContentsImpl::Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options) {
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(kAboutBlankURL))
+ if (entry && entry->GetURL() == GURL(url::kAboutBlankURL))
return true;
return delegate_ && delegate_->ShouldFocusLocationBarByDefault(this);
}
void WebContentsImpl::DidStartProvisionalLoad(
RenderFrameHostImpl* render_frame_host,
- int parent_routing_id,
const GURL& validated_url,
bool is_error_page,
bool is_iframe_srcdoc) {
- bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame();
- if (is_main_frame)
- DidChangeLoadProgress(0);
-
// Notify observers about the start of the provisional load.
- int render_frame_id = render_frame_host->GetRoutingID();
- RenderViewHost* render_view_host = render_frame_host->render_view_host();
- FOR_EACH_OBSERVER(WebContentsObserver, observers_,
- DidStartProvisionalLoadForFrame(
- render_frame_id, parent_routing_id, is_main_frame,
- validated_url, is_error_page, is_iframe_srcdoc,
- render_view_host));
+ FOR_EACH_OBSERVER(
+ WebContentsObserver,
+ observers_,
+ DidStartProvisionalLoadForFrame(
+ render_frame_host, validated_url, is_error_page, is_iframe_srcdoc));
+}
- if (is_main_frame) {
- FOR_EACH_OBSERVER(
- WebContentsObserver,
- observers_,
- ProvisionalChangeToMainFrameUrl(validated_url,
- render_frame_host));
- }
+void WebContentsImpl::DidStartNavigationTransition(
+ RenderFrameHostImpl* render_frame_host) {
+#if defined(OS_ANDROID)
+ int render_frame_id = render_frame_host->GetRoutingID();
+ GetWebContentsAndroid()->DidStartNavigationTransitionForFrame(
+ render_frame_id);
+#endif
}
void WebContentsImpl::DidFailProvisionalLoadWithError(
RenderFrameHostImpl* render_frame_host,
const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) {
GURL validated_url(params.url);
- int render_frame_id = render_frame_host->GetRoutingID();
- bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame();
- RenderViewHost* render_view_host = render_frame_host->render_view_host();
- FOR_EACH_OBSERVER(
- WebContentsObserver,
- observers_,
- DidFailProvisionalLoad(render_frame_id,
- params.frame_unique_name,
- is_main_frame,
- validated_url,
- params.error_code,
- params.error_description,
- render_view_host));
+ FOR_EACH_OBSERVER(WebContentsObserver,
+ observers_,
+ DidFailProvisionalLoad(render_frame_host,
+ validated_url,
+ params.error_code,
+ params.error_description));
}
void WebContentsImpl::DidFailLoadWithError(
const GURL& url,
int error_code,
const base::string16& error_description) {
- int render_frame_id = render_frame_host->GetRoutingID();
- bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame();
- RenderViewHost* render_view_host = render_frame_host->render_view_host();
- FOR_EACH_OBSERVER(WebContentsObserver, observers_,
- DidFailLoad(render_frame_id, url, is_main_frame, error_code,
- error_description, render_view_host));
+ FOR_EACH_OBSERVER(
+ WebContentsObserver,
+ observers_,
+ DidFailLoad(render_frame_host, url, error_code, error_description));
}
void WebContentsImpl::NotifyChangedNavigationState(
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 base::string16& frame_unique_name,
- bool is_main_frame,
const GURL& url,
- PageTransition transition_type) {
- int render_frame_id = render_frame_host->GetRoutingID();
- RenderViewHost* render_view_host = render_frame_host->render_view_host();
+ ui::PageTransition transition_type) {
// Notify observers about the commit of the provisional load.
- FOR_EACH_OBSERVER(
- WebContentsObserver,
- observers_,
- DidCommitProvisionalLoadForFrame(render_frame_id,
- frame_unique_name,
- is_main_frame,
- url,
- transition_type,
- render_view_host));
+ FOR_EACH_OBSERVER(WebContentsObserver,
+ observers_,
+ DidCommitProvisionalLoadForFrame(
+ render_frame_host, url, transition_type));
}
void WebContentsImpl::DidNavigateMainFramePreCommit(
- const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
+ bool navigation_is_within_page) {
// Ensure fullscreen mode is exited before committing the navigation to a
// different page. The next page will not start out assuming it is in
// fullscreen mode.
- if (controller_.IsURLInPageNavigation(params.url,
- params.was_within_same_page,
- NAVIGATION_TYPE_UNKNOWN)) {
+ if (navigation_is_within_page) {
// No page change? Then, the renderer and browser can remain in fullscreen.
return;
}
// 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) {
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
DidNavigateMainFrame(details, params));
- if (delegate_) {
+ if (delegate_)
delegate_->DidNavigateMainFramePostCommit(this);
- view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
- }
+ view_->SetOverscrollControllerEnabled(CanOverscrollContent());
}
void WebContentsImpl::DidNavigateAnyFramePostCommit(
contents_mime_type_ = mime_type;
}
-bool WebContentsImpl::CanOverscrollContent() {
+bool WebContentsImpl::CanOverscrollContent() const {
+ // Disable overscroll when touch emulation is on. See crbug.com/369938.
+ if (force_disable_overscroll_content_)
+ return false;
+
if (delegate_)
return delegate_->CanOverscrollContent();
return false;
}
+void WebContentsImpl::OnThemeColorChanged(SkColor theme_color) {
+ FOR_EACH_OBSERVER(WebContentsObserver, observers_,
+ DidChangeThemeColor(theme_color));
+}
+
void WebContentsImpl::OnDidLoadResourceFromMemoryCache(
const GURL& url,
const std::string& security_info,
const std::string& http_method,
const std::string& mime_type,
- ResourceType::Type resource_type) {
+ ResourceType resource_type) {
base::StatsCounter cache("WebKit.CacheHit");
cache.Increment();
if (url.is_valid() && url.SchemeIsHTTPOrHTTPS()) {
scoped_refptr<net::URLRequestContextGetter> request_context(
- resource_type == ResourceType::MEDIA ?
+ resource_type == RESOURCE_TYPE_MEDIA ?
GetBrowserContext()->GetMediaRequestContextForRenderProcess(
GetRenderProcessHost()->GetID()) :
GetBrowserContext()->GetRequestContextForRenderProcess(
CHECK(!render_view_message_source_);
RenderFrameHostImpl* rfh =
static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
-
- int render_frame_id = rfh->GetRoutingID();
- RenderViewHost* render_view_host = rfh->render_view_host();
- FOR_EACH_OBSERVER(WebContentsObserver,
- observers_,
- DocumentLoadedInFrame(render_frame_id, render_view_host));
+ FOR_EACH_OBSERVER(
+ WebContentsObserver, observers_, DocumentLoadedInFrame(rfh));
}
void WebContentsImpl::OnDidFinishLoad(
RenderFrameHostImpl* rfh =
static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
- int render_frame_id = rfh->GetRoutingID();
- RenderViewHost* render_view_host = rfh->render_view_host();
- bool is_main_frame = rfh->frame_tree_node()->IsMainFrame();
- FOR_EACH_OBSERVER(WebContentsObserver, observers_,
- DidFinishLoad(render_frame_id, validated_url,
- is_main_frame, render_view_host));
+ FOR_EACH_OBSERVER(
+ WebContentsObserver, observers_, DidFinishLoad(rfh, validated_url));
+}
+
+void WebContentsImpl::OnDidStartLoading(bool to_different_document) {
+ RenderFrameHostImpl* rfh =
+ static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
+ int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
+
+ // It is possible to get multiple calls to OnDidStartLoading that don't have
+ // corresponding calls to OnDidStopLoading:
+ // - With "swappedout://" URLs, this happens when a RenderView gets swapped
+ // out for a cross-process navigation, and it turns into a placeholder for
+ // one being rendered in a different process.
+ // - Also, there might be more than one RenderFrameHost sharing the same
+ // FrameTreeNode (and thus sharing its ID) each sending a start.
+ // - But in the future, once clamy@ moves navigation network requests to the
+ // browser process, there's a good chance that callbacks about starting and
+ // stopping will all be handled by the browser. When that happens, there
+ // should no longer be a start/stop call imbalance. TODO(avi): When this
+ // future arrives, update this code to not allow this case.
+ DCHECK_GE(loading_frames_in_progress_, 0);
+ if (loading_progresses_.find(render_frame_id) == loading_progresses_.end()) {
+ if (loading_frames_in_progress_ == 0)
+ DidStartLoading(rfh, to_different_document);
+ ++loading_frames_in_progress_;
+ }
+
+ loading_progresses_[render_frame_id] = kMinimumLoadingProgress;
+ SendLoadProgressChanged();
+}
+
+void WebContentsImpl::OnDidStopLoading() {
+ RenderFrameHostImpl* rfh =
+ static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
+ int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
+
+ if (loading_progresses_.find(render_frame_id) != loading_progresses_.end()) {
+ // Load stopped while we were still tracking load. Make sure we update
+ // progress based on this frame's completion.
+ loading_progresses_[render_frame_id] = 1.0;
+ SendLoadProgressChanged();
+ // Then we clean-up our states.
+ if (loading_total_progress_ == 1.0)
+ ResetLoadProgressState();
+ }
+
+ // TODO(japhet): This should be a DCHECK, but the pdf plugin sometimes
+ // calls DidStopLoading() without a matching DidStartLoading().
+ if (loading_frames_in_progress_ == 0)
+ return;
+ --loading_frames_in_progress_;
+ if (loading_frames_in_progress_ == 0)
+ DidStopLoading(rfh);
+}
+
+void WebContentsImpl::OnDidChangeLoadProgress(double load_progress) {
+ RenderFrameHostImpl* rfh =
+ static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
+ int64 render_frame_id = rfh->frame_tree_node()->frame_tree_node_id();
+
+ loading_progresses_[render_frame_id] = load_progress;
+
+ // We notify progress change immediately for the first and last updates.
+ // Also, since the message loop may be pretty busy when a page is loaded, it
+ // might not execute a posted task in a timely manner so we make sure to
+ // immediately send progress report if enough time has passed.
+ base::TimeDelta min_delay =
+ base::TimeDelta::FromMilliseconds(kMinimumDelayBetweenLoadingUpdatesMS);
+ if (load_progress == 1.0 || loading_last_progress_update_.is_null() ||
+ base::TimeTicks::Now() - loading_last_progress_update_ > min_delay) {
+ // If there is a pending task to send progress, it is now obsolete.
+ loading_weak_factory_.InvalidateWeakPtrs();
+ SendLoadProgressChanged();
+ if (loading_total_progress_ == 1.0)
+ ResetLoadProgressState();
+ return;
+ }
+
+ if (loading_weak_factory_.HasWeakPtrs())
+ return;
+
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&WebContentsImpl::SendLoadProgressChanged,
+ loading_weak_factory_.GetWeakPtr()),
+ min_delay);
}
void WebContentsImpl::OnGoToEntryAtOffset(int offset) {
}
void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent,
- int maximum_percent,
- bool remember) {
+ int maximum_percent) {
minimum_zoom_percent_ = minimum_percent;
maximum_zoom_percent_ = maximum_percent;
- temporary_zoom_settings_ = !remember;
}
void WebContentsImpl::OnEnumerateDirectory(int request_id,
if (policy->IsPseudoScheme(protocol))
return;
- delegate_->RegisterProtocolHandler(this, protocol, url, title, user_gesture);
+ delegate_->RegisterProtocolHandler(this, protocol, url, user_gesture);
+}
+
+void WebContentsImpl::OnUnregisterProtocolHandler(const std::string& protocol,
+ const GURL& url,
+ bool user_gesture) {
+ if (!delegate_)
+ return;
+
+ ChildProcessSecurityPolicyImpl* policy =
+ ChildProcessSecurityPolicyImpl::GetInstance();
+ if (policy->IsPseudoScheme(protocol))
+ return;
+
+ delegate_->UnregisterProtocolHandler(this, protocol, url, user_gesture);
}
void WebContentsImpl::OnFindReply(int request_id,
value.suggestions);
}
-void WebContentsImpl::OnJavaBridgeGetChannelHandle(IPC::Message* reply_msg) {
- java_bridge_dispatcher_host_manager_->OnGetChannelHandle(
- render_frame_message_source_, reply_msg);
-}
-
#endif
void WebContentsImpl::OnPepperPluginHung(int plugin_child_id,
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) {
-// Chrome OS does its own detection of audio and video.
+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
- } else if (has_audio) {
- blocker = PowerSaveBlocker::Create(
- PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, "Playing audio");
+#endif
+}
+
+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 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();
+ }
}
- if (blocker) {
- power_save_blockers_[render_frame_message_source_][player_cookie] =
- blocker.release();
+ 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();
}
-#endif // !defined(OS_CHROMEOS)
}
void WebContentsImpl::OnMediaPausedNotification(int64 player_cookie) {
- // Chrome OS does its own detection of audio and video.
-#if !defined(OS_CHROMEOS)
- delete power_save_blockers_[render_frame_message_source_][player_cookie];
- power_save_blockers_[render_frame_message_source_].erase(player_cookie);
-#endif // !defined(OS_CHROMEOS)
+ RemoveMediaPlayerEntry(player_cookie, &active_audio_players_);
+ RemoveMediaPlayerEntry(player_cookie, &active_video_players_);
+ MaybeReleasePowerSaveBlockers();
}
void WebContentsImpl::OnFirstVisuallyNonEmptyPaint() {
}
void WebContentsImpl::DidChangeVisibleSSLState() {
- FOR_EACH_OBSERVER(WebContentsObserver, observers_,
- DidChangeVisibleSSLState());
+ if (delegate_)
+ delegate_->VisibleSSLStateChanged(this);
}
void WebContentsImpl::NotifyBeforeFormRepostWarningShow() {
BeforeFormRepostWarningShow());
}
-
void WebContentsImpl::ActivateAndShowRepostFormWarningDialog() {
Activate();
if (delegate_)
is_loading_ = is_loading;
waiting_for_response_ = is_loading;
+ is_load_to_different_document_ = to_different_document;
if (delegate_)
delegate_->LoadingStateChanged(this, to_different_document);
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));
}
return true;
}
-void WebContentsImpl::NotifySwapped(RenderViewHost* old_host,
- RenderViewHost* new_host) {
+void WebContentsImpl::SendLoadProgressChanged() {
+ loading_last_progress_update_ = base::TimeTicks::Now();
+ double progress = 0.0;
+ int frame_count = 0;
+
+ for (LoadingProgressMap::iterator it = loading_progresses_.begin();
+ it != loading_progresses_.end();
+ ++it) {
+ progress += it->second;
+ ++frame_count;
+ }
+ if (frame_count == 0)
+ return;
+ progress /= frame_count;
+ DCHECK(progress <= 1.0);
+
+ if (progress <= loading_total_progress_)
+ return;
+ loading_total_progress_ = progress;
+
+ if (delegate_)
+ delegate_->LoadProgressChanged(this, progress);
+}
+
+void WebContentsImpl::ResetLoadProgressState() {
+ loading_progresses_.clear();
+ loading_total_progress_ = 0.0;
+ loading_weak_factory_.InvalidateWeakPtrs();
+ loading_last_progress_update_ = base::TimeTicks();
+}
+
+void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host,
+ RenderViewHost* new_host) {
// After sending out a swap notification, we need to send a disconnect
// notification so that clients that pick up a pointer to |this| can NULL the
// pointer. See Bug 1230284.
RemoveBrowserPluginEmbedder();
}
+void WebContentsImpl::NotifyFrameSwapped(RenderFrameHost* old_host,
+ RenderFrameHost* new_host) {
+ FOR_EACH_OBSERVER(WebContentsObserver,
+ observers_,
+ RenderFrameHostChanged(old_host, new_host));
+}
+
// TODO(avi): Remove this entire function because this notification is already
// covered by two observer functions. http://crbug.com/170921
void WebContentsImpl::NotifyDisconnected() {
FOR_EACH_OBSERVER(WebContentsObserver,
observers_,
RenderFrameCreated(render_frame_host));
+ SetAccessibilityModeOnFrame(accessibility_mode_, render_frame_host);
}
void WebContentsImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
void WebContentsImpl::ShowContextMenu(RenderFrameHost* render_frame_host,
const ContextMenuParams& params) {
+ ContextMenuParams context_menu_params(params);
// Allow WebContentsDelegates to handle the context menu operation first.
- if (delegate_ && delegate_->HandleContextMenu(params))
+ if (GetBrowserPluginGuest()) {
+ WebContentsViewGuest* view_guest =
+ static_cast<WebContentsViewGuest*>(GetView());
+ context_menu_params = view_guest->ConvertContextMenuParams(params);
+ }
+ if (delegate_ && delegate_->HandleContextMenu(context_menu_params))
return;
- render_view_host_delegate_view_->ShowContextMenu(render_frame_host, params);
+ render_view_host_delegate_view_->ShowContextMenu(render_frame_host,
+ context_menu_params);
}
void WebContentsImpl::RunJavaScriptMessage(
return delegate_->IsNeverVisible(this);
}
+#if defined(OS_WIN)
+gfx::NativeViewAccessible WebContentsImpl::GetParentNativeViewAccessible() {
+ return accessible_parent_;
+}
+#endif
+
RenderViewHostDelegateView* WebContentsImpl::GetDelegateView() {
return render_view_host_delegate_view_;
}
return;
if (delegate_)
- view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
+ view_->SetOverscrollControllerEnabled(CanOverscrollContent());
NotificationService::current()->Notify(
NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
RenderFrameHost* main_frame = render_view_host->GetMainFrame();
FOR_EACH_OBSERVER(
WebContentsObserver, observers_, RenderFrameCreated(main_frame));
+ SetAccessibilityModeOnFrame(accessibility_mode_, main_frame);
}
void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) {
if (dialog_manager_)
dialog_manager_->CancelActiveAndPendingDialogs(this);
+ if (delegate_)
+ delegate_->HideValidationMessage(this);
+
SetIsLoading(rvh, false, true, NULL);
NotifyDisconnected();
SetIsCrashed(status, error_code);
-#if defined(OS_ANDROID)
- if (GetRenderViewHostImpl()->media_player_manager())
- GetRenderViewHostImpl()->media_player_manager()->DestroyAllMediaPlayers();
-#endif
+ // Reset the loading progress. TODO(avi): What does it mean to have a
+ // "renderer crash" when there is more than one renderer process serving a
+ // webpage? Once this function is called at a more granular frame level, we
+ // probably will need to more granularly reset the state here.
+ ResetLoadProgressState();
+ loading_frames_in_progress_ = 0;
FOR_EACH_OBSERVER(WebContentsObserver,
observers_,
controller_.NotifyEntryChanged(entry, entry_index);
}
-void WebContentsImpl::UpdateTitle(RenderViewHost* rvh,
- int32 page_id,
- const base::string16& title,
- base::i18n::TextDirection title_direction) {
- // If we have a title, that's a pretty good indication that we've started
- // getting useful data.
- SetNotWaitingForResponse();
-
- // Try to find the navigation entry, which might not be the current one.
- // For example, it might be from a pending RVH for the pending entry.
- NavigationEntryImpl* entry = controller_.GetEntryWithPageID(
- rvh->GetSiteInstance(), page_id);
-
- // We can handle title updates when we don't have an entry in
- // UpdateTitleForEntry, but only if the update is from the current RVH.
- if (!entry && rvh != GetRenderViewHost())
- return;
-
- // TODO(evan): make use of title_direction.
- // http://code.google.com/p/chromium/issues/detail?id=27094
- if (!UpdateTitleForEntry(entry, title))
- return;
-
- // Broadcast notifications when the UI should be updated.
- if (entry == controller_.GetEntryAtOffset(0))
- NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE);
-}
-
-void WebContentsImpl::UpdateEncoding(RenderViewHost* render_view_host,
- const std::string& encoding) {
- SetEncoding(encoding);
-}
-
-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) {
delegate_->SwappedOut(this);
}
+void WebContentsImpl::DidDeferAfterResponseStarted(
+ const TransitionLayerData& transition_data) {
+#if defined(OS_ANDROID)
+ GetWebContentsAndroid()->DidDeferAfterResponseStarted(transition_data);
+#endif
+}
+
+bool WebContentsImpl::WillHandleDeferAfterResponseStarted() {
+#if defined(OS_ANDROID)
+ return GetWebContentsAndroid()->WillHandleDeferAfterResponseStarted();
+#else
+ return false;
+#endif
+}
+
void WebContentsImpl::RequestMove(const gfx::Rect& new_bounds) {
if (delegate_ && delegate_->IsPopupOrPanel(this))
delegate_->MoveContents(this, new_bounds);
NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
}
-void WebContentsImpl::DidChangeLoadProgress(double progress) {
- if (delegate_)
- delegate_->LoadProgressChanged(this, progress);
-}
-
void WebContentsImpl::DidAccessInitialDocument() {
has_accessed_initial_document_ = true;
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(
NotificationService::NoDetails());
}
+void WebContentsImpl::UpdateTitle(RenderFrameHost* render_frame_host,
+ int32 page_id,
+ const base::string16& title,
+ base::i18n::TextDirection title_direction) {
+ RenderViewHost* rvh = render_frame_host->GetRenderViewHost();
+
+ // If we have a title, that's a pretty good indication that we've started
+ // getting useful data.
+ SetNotWaitingForResponse();
+
+ // Try to find the navigation entry, which might not be the current one.
+ // For example, it might be from a pending RVH for the pending entry.
+ NavigationEntryImpl* entry = controller_.GetEntryWithPageID(
+ rvh->GetSiteInstance(), page_id);
+
+ // We can handle title updates when we don't have an entry in
+ // UpdateTitleForEntry, but only if the update is from the current RVH.
+ // TODO(avi): Change to make decisions based on the RenderFrameHost.
+ if (!entry && rvh != GetRenderViewHost())
+ return;
+
+ // TODO(evan): make use of title_direction.
+ // http://code.google.com/p/chromium/issues/detail?id=27094
+ if (!UpdateTitleForEntry(entry, title))
+ return;
+
+ // Broadcast notifications when the UI should be updated.
+ if (entry == controller_.GetEntryAtOffset(0))
+ NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE);
+}
+
+void WebContentsImpl::UpdateEncoding(RenderFrameHost* render_frame_host,
+ const std::string& encoding) {
+ SetEncoding(encoding);
+}
+
void WebContentsImpl::DocumentAvailableInMainFrame(
RenderViewHost* render_view_host) {
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
source_id);
}
-WebPreferences WebContentsImpl::GetWebkitPrefs() {
+WebPreferences WebContentsImpl::ComputeWebkitPrefs() {
// We want to base the page config off of the actual URL, rather than the
// virtual URL.
// TODO(nasko): Investigate how to remove the GetActiveEntry usage here,
GURL url = controller_.GetActiveEntry()
? controller_.GetActiveEntry()->GetURL() : GURL::EmptyGURL();
- return GetRenderManager()->current_host()->GetWebkitPrefs(url);
+ return GetRenderManager()->current_host()->ComputeWebkitPrefs(url);
}
int WebContentsImpl::CreateSwappedOutRenderView(
SiteInstance* instance) {
- return GetRenderManager()->CreateRenderFrame(instance, MSG_ROUTING_NONE,
- true, true);
+ return GetRenderManager()->CreateRenderFrame(
+ instance, MSG_ROUTING_NONE, true, true, true);
}
void WebContentsImpl::OnUserGesture() {
if (load_state_.state == net::LOAD_STATE_READING_RESPONSE)
SetNotWaitingForResponse();
if (IsLoading()) {
- NotifyNavigationStateChanged(INVALIDATE_TYPE_LOAD | INVALIDATE_TYPE_TAB);
+ NotifyNavigationStateChanged(static_cast<InvalidateTypes>(
+ INVALIDATE_TYPE_LOAD | INVALIDATE_TYPE_TAB));
}
}
dialog_manager_->CancelActiveAndPendingDialogs(this);
}
-void WebContentsImpl::NotifySwappedFromRenderManager(RenderViewHost* old_host,
- RenderViewHost* new_host) {
- NotifySwapped(old_host, new_host);
+void WebContentsImpl::NotifySwappedFromRenderManager(RenderFrameHost* old_host,
+ RenderFrameHost* new_host,
+ bool is_main_frame) {
+ if (is_main_frame) {
+ NotifyViewSwapped(old_host ? old_host->GetRenderViewHost() : NULL,
+ new_host->GetRenderViewHost());
- // Make sure the visible RVH reflects the new delegate's preferences.
- if (delegate_)
- view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
+ // Make sure the visible RVH reflects the new delegate's preferences.
+ if (delegate_)
+ view_->SetOverscrollControllerEnabled(CanOverscrollContent());
+
+ view_->RenderViewSwappedIn(new_host->GetRenderViewHost());
+ }
- view_->RenderViewSwappedIn(new_host);
+ NotifyFrameSwapped(old_host, new_host);
}
int WebContentsImpl::CreateOpenerRenderViewsForRenderManager(
// Create a swapped out RenderView in the given SiteInstance if none exists,
// setting its opener to the given route_id. Return the new view's route_id.
- return GetRenderManager()->CreateRenderFrame(instance, opener_route_id,
- true, true);
+ return GetRenderManager()->CreateRenderFrame(
+ instance, opener_route_id, true, true, true);
}
NavigationControllerImpl& WebContentsImpl::GetControllerForRenderManager() {
bool WebContentsImpl::CreateRenderViewForRenderManager(
RenderViewHost* render_view_host,
int opener_route_id,
- CrossProcessFrameConnector* frame_connector) {
- TRACE_EVENT0("browser", "WebContentsImpl::CreateRenderViewForRenderManager");
+ int proxy_routing_id,
+ bool for_main_frame_navigation) {
+ TRACE_EVENT0("browser,navigation",
+ "WebContentsImpl::CreateRenderViewForRenderManager");
// Can be NULL during tests.
RenderWidgetHostViewBase* rwh_view;
// TODO(kenrb): RenderWidgetHostViewChildFrame special casing is temporary
// until RenderWidgetHost is attached to RenderFrameHost. We need to special
// case this because RWH is still a base class of RenderViewHost, and child
// frame RWHVs are unique in that they do not have their own WebContents.
- if (frame_connector) {
+ if (!for_main_frame_navigation) {
RenderWidgetHostViewChildFrame* rwh_view_child =
new RenderWidgetHostViewChildFrame(render_view_host);
- frame_connector->set_view(rwh_view_child);
rwh_view = rwh_view_child;
} else {
rwh_view = view_->CreateViewForWidget(render_view_host);
if (!static_cast<RenderViewHostImpl*>(
render_view_host)->CreateRenderView(base::string16(),
opener_route_id,
+ proxy_routing_id,
max_page_id,
created_with_opener_)) {
return false;
return true;
}
+bool WebContentsImpl::CreateRenderFrameForRenderManager(
+ RenderFrameHost* render_frame_host,
+ int parent_routing_id) {
+ TRACE_EVENT0("browser,navigation",
+ "WebContentsImpl::CreateRenderFrameForRenderManager");
+
+ RenderFrameHostImpl* rfh =
+ static_cast<RenderFrameHostImpl*>(render_frame_host);
+ if (!rfh->CreateRenderFrame(parent_routing_id))
+ return false;
+
+ // TODO(nasko): When RenderWidgetHost is owned by RenderFrameHost, the passed
+ // RenderFrameHost will have to be associated with the appropriate
+ // RenderWidgetHostView or a new one should be created here.
+
+ return true;
+}
+
#if defined(OS_ANDROID)
base::android::ScopedJavaLocalRef<jobject>
WebContentsImpl::GetJavaWebContents() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return GetWebContentsAndroid()->GetJavaObject();
+}
+WebContentsAndroid* WebContentsImpl::GetWebContentsAndroid() {
WebContentsAndroid* web_contents_android =
static_cast<WebContentsAndroid*>(GetUserData(kWebContentsAndroidKey));
if (!web_contents_android) {
web_contents_android = new WebContentsAndroid(this);
SetUserData(kWebContentsAndroidKey, web_contents_android);
}
- return web_contents_android->GetJavaObject();
+ return web_contents_android;
}
bool WebContentsImpl::CreateRenderViewForInitialEmptyDocument() {
return CreateRenderViewForRenderManager(GetRenderViewHost(),
MSG_ROUTING_NONE,
- NULL);
+ MSG_ROUTING_NONE,
+ true);
}
#elif defined(OS_MACOSX)
-void WebContentsImpl::SetAllowOverlappingViews(bool overlapping) {
- view_->SetAllowOverlappingViews(overlapping);
-}
-
-bool WebContentsImpl::GetAllowOverlappingViews() {
- return view_->GetAllowOverlappingViews();
-}
-
-void WebContentsImpl::SetOverlayView(WebContents* overlay,
- const gfx::Point& offset) {
- view_->SetOverlayView(static_cast<WebContentsImpl*>(overlay)->GetView(),
- offset);
+void WebContentsImpl::SetAllowOtherViews(bool allow) {
+ view_->SetAllowOtherViews(allow);
}
-void WebContentsImpl::RemoveOverlayView() {
- view_->RemoveOverlayView();
+bool WebContentsImpl::GetAllowOtherViews() {
+ return view_->GetAllowOtherViews();
}
#endif
}
void WebContentsImpl::SetEncoding(const std::string& encoding) {
- encoding_ = GetContentClient()->browser()->
+ if (encoding == last_reported_encoding_)
+ return;
+ last_reported_encoding_ = encoding;
+
+ canonical_encoding_ = GetContentClient()->browser()->
GetCanonicalEncodingNameByAliasName(encoding);
}
void WebContentsImpl::ClearPowerSaveBlockers(
RenderFrameHost* render_frame_host) {
- STLDeleteValues(&power_save_blockers_[render_frame_host]);
- power_save_blockers_.erase(render_frame_host);
+ RemoveAllMediaPlayerEntries(render_frame_host, &active_audio_players_);
+ RemoveAllMediaPlayerEntries(render_frame_host, &active_video_players_);
+ MaybeReleasePowerSaveBlockers();
}
void WebContentsImpl::ClearAllPowerSaveBlockers() {
- for (PowerSaveBlockerMap::iterator i(power_save_blockers_.begin());
- i != power_save_blockers_.end(); ++i)
- STLDeleteValues(&power_save_blockers_[i->first]);
- power_save_blockers_.clear();
+ active_audio_players_.clear();
+ active_video_players_.clear();
+ audio_power_save_blocker_.reset();
+ video_power_save_blocker_.reset();
}
gfx::Size WebContentsImpl::GetSizeForNewRenderView() {
return size;
}
-void WebContentsImpl::OnFrameRemoved(
- RenderViewHostImpl* render_view_host,
- int frame_routing_id) {
- FOR_EACH_OBSERVER(WebContentsObserver, observers_,
- FrameDetached(render_view_host, frame_routing_id));
+void WebContentsImpl::OnFrameRemoved(RenderFrameHost* render_frame_host) {
+ FOR_EACH_OBSERVER(
+ WebContentsObserver, observers_, FrameDetached(render_frame_host));
}
void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
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