web_contents_impl.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h"
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <utility>
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/command_line.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/debug/trace_event.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/lazy_instance.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/logging.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/metrics/histogram.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/metrics/stats_counters.h"
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/process/process.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/string16.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/string_util.h"
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/time/time.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/browser_plugin/browser_plugin_embedder.h"
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/browser_plugin/browser_plugin_guest.h"
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/browser_plugin/browser_plugin_guest_manager.h"
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/child_process_security_policy_impl.h"
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/devtools/render_view_devtools_agent_host.h"
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/dom_storage/session_storage_namespace_impl.h"
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/download/download_stats.h"
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/download/mhtml_generation_manager.h"
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/browser/download/save_package.h"
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/browser/frame_host/cross_process_frame_connector.h"
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/browser/frame_host/interstitial_page_impl.h"
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/frame_host/navigation_entry_impl.h"
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/browser/frame_host/navigator_impl.h"
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/frame_host/render_frame_host_impl.h"
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/frame_host/render_widget_host_view_child_frame.h"
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/host_zoom_map_impl.h"
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/loader/resource_dispatcher_host_impl.h"
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/message_port_message_filter.h"
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/message_port_service.h"
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/power_save_blocker_impl.h"
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/renderer_host/render_process_host_impl.h"
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h"
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_impl.h"
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/site_instance_impl.h"
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/web_contents/web_contents_view_guest.h"
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/webui/generic_handler.h"
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/webui/web_ui_controller_factory_registry.h"
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/webui/web_ui_impl.h"
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/common/browser_plugin/browser_plugin_constants.h"
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/common/browser_plugin/browser_plugin_messages.h"
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/common/frame_messages.h"
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/common/image_messages.h"
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/common/ssl_status_serialization.h"
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/common/view_messages.h"
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/port/browser/render_view_host_delegate_view.h"
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/port/browser/render_widget_host_view_port.h"
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/ax_event_notification_details.h"
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/browser_context.h"
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/color_chooser.h"
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/content_browser_client.h"
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/devtools_agent_host.h"
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/download_manager.h"
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/download_url_parameters.h"
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/invalidate_type.h"
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/javascript_dialog_manager.h"
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/load_from_memory_cache_details.h"
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/load_notification_details.h"
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/navigation_details.h"
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_details.h"
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_service.h"
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/resource_request_details.h"
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/storage_partition.h"
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/user_metrics.h"
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/web_contents_view.h"
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/common/bindings_policy.h"
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/common/content_constants.h"
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/common/content_switches.h"
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/common/page_zoom.h"
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/common/result_codes.h"
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/common/url_constants.h"
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/common/url_utils.h"
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/mime_util.h"
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/net_util.h"
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/http/http_cache.h"
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/http/http_transaction_factory.h"
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/url_request/url_request_context.h"
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/base/layout.h"
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/display.h"
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/screen.h"
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gl/gl_switches.h"
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "webkit/common/webpreferences.h"
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_ANDROID)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/android/date_time_chooser_android.h"
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h"
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/web_contents/web_contents_android.h"
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/common/java_bridge_messages.h"
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/android/content_view_core.h"
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_MACOSX)
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/mac/foundation_util.h"
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gl/io_surface_support_mac.h"
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Cross-Site Navigations
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// If a WebContentsImpl is told to navigate to a different web site (as
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// determined by SiteInstance), it will replace its current RenderViewHost with
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// a new RenderViewHost dedicated to the new SiteInstance.  This works as
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// follows:
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - RVHM::Navigate determines whether the destination is cross-site, and if so,
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   it creates a pending_render_view_host_.
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - The pending RVH is "suspended," so that no navigation messages are sent to
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   its renderer until the beforeunload JavaScript handler has a chance to
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   run in the current RVH.
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - The pending RVH tells CrossSiteRequestManager (a thread-safe singleton)
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   that it has a pending cross-site request.  We will check this on the IO
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   thread when deciding how to handle the response.
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - The current RVH runs its beforeunload handler.  If it returns false, we
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   cancel all the pending logic.  Otherwise we allow the pending RVH to send
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   the navigation request to its renderer.
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - ResourceDispatcherHost receives a ResourceRequest on the IO thread for the
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   main resource load on the pending RVH.  It creates a
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   CrossSiteResourceHandler to check whether a process swap is needed when
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   the request is ready to commit.
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - When RDH receives a response, the BufferedResourceHandler determines
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   whether it is a download.  If so, it sends a message to the new renderer
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   causing it to cancel the request, and the download proceeds. For now, the
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   pending RVH remains until the next DidNavigate event for this
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   WebContentsImpl. This isn't ideal, but it doesn't affect any functionality.
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - After RDH receives a response and determines that it is safe and not a
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   download, the CrossSiteResourceHandler checks whether a process swap is
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   needed (either because CrossSiteRequestManager has state for it or because
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   a transfer was needed for a redirect).
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - If so, CrossSiteResourceHandler pauses the response to first run the old
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   page's unload handler.  It does this by asynchronously calling the
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   OnCrossSiteResponse method of RenderFrameHostManager on the UI thread,
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   which sends a SwapOut message to the current RVH.
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - Once the unload handler is finished, RVHM::SwappedOut checks if a transfer
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   to a new process is needed, based on the stored pending_nav_params_.  (This
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   is independent of whether we started out with a cross-process navigation.)
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   - If not, it just tells the ResourceDispatcherHost to resume the response
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//     to its current RenderViewHost.
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   - If so, it cancels the current pending RenderViewHost and sets up a new
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//     navigation using RequestTransferURL.  When the transferred request
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//     arrives in the ResourceDispatcherHost, we transfer the response and
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//     resume it.
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - The pending renderer sends a FrameNavigate message that invokes the
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   DidNavigate method.  This replaces the current RVH with the
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   pending RVH.
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// - The previous renderer is kept swapped out in RenderFrameHostManager in case
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   the user goes back.  The process only stays live if another tab is using
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//   it, but if so, the existing frame relationships will be maintained.
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace content {
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kDotGoogleDotCom[] = ".google.com";
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_ANDROID)
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kWebContentsAndroidKey[] = "web_contents_android";
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif  // OS_ANDROID
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback> >
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)g_created_callbacks = LAZY_INSTANCE_INITIALIZER;
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static int StartDownload(content::RenderViewHost* rvh,
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         const GURL& url,
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         bool is_favicon,
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         uint32_t max_bitmap_size) {
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static int g_next_image_download_id = 0;
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rvh->Send(new ImageMsg_DownloadImage(rvh->GetRoutingID(),
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       ++g_next_image_download_id,
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       url,
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       is_favicon,
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       max_bitmap_size));
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return g_next_image_download_id;
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void NotifyCacheOnIO(
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_refptr<net::URLRequestContextGetter> request_context,
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& url,
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& http_method) {
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  request_context->GetURLRequestContext()->http_transaction_factory()->
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetCache()->OnExternalCacheHit(url, http_method);
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Helper function for retrieving all the sites in a frame tree.
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool CollectSites(BrowserContext* context,
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                  std::set<GURL>* sites,
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                  FrameTreeNode* node) {
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sites->insert(SiteInstance::GetSiteForURL(context, node->current_url()));
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ForEachFrameInternal(
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::Callback<void(RenderFrameHost*)>& on_frame,
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    FrameTreeNode* node) {
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  on_frame.Run(node->current_frame_host());
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ForEachPendingFrameInternal(
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::Callback<void(RenderFrameHost*)>& on_frame,
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    FrameTreeNode* node) {
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RenderFrameHost* pending_frame_host =
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      node->render_manager()->pending_frame_host();
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (pending_frame_host)
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    on_frame.Run(pending_frame_host);
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SendToAllFramesInternal(IPC::Message* message, RenderFrameHost* rfh) {
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  IPC::Message* message_copy = new IPC::Message(*message);
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  message_copy->set_routing_id(rfh->GetRoutingID());
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rfh->Send(message_copy);
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void RunRenderFrameDeleted(
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ObserverList<WebContentsObserver>* observer_list,
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RenderFrameHost* render_frame_host) {
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FOR_EACH_OBSERVER(WebContentsObserver,
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    *observer_list,
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    RenderFrameDeleted(render_frame_host));
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WebContents* WebContents::Create(const WebContents::CreateParams& params) {
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return WebContentsImpl::CreateWithOpener(
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      params, static_cast<WebContentsImpl*>(params.opener));
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WebContents* WebContents::CreateWithSessionStorage(
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const WebContents::CreateParams& params,
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const SessionStorageNamespaceMap& session_storage_namespace_map) {
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebContentsImpl* new_contents = new WebContentsImpl(
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      params.browser_context, NULL);
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (SessionStorageNamespaceMap::const_iterator it =
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           session_storage_namespace_map.begin();
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != session_storage_namespace_map.end();
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it) {
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    new_contents->GetController()
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        .SetSessionStorageNamespace(it->first, it->second.get());
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  new_contents->Init(params);
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return new_contents;
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WebContentsImpl::AddCreatedCallback(const CreatedCallback& callback) {
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  g_created_callbacks.Get().push_back(callback);
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WebContentsImpl::RemoveCreatedCallback(const CreatedCallback& callback) {
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < g_created_callbacks.Get().size(); ++i) {
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (g_created_callbacks.Get().at(i).Equals(callback)) {
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      g_created_callbacks.Get().erase(g_created_callbacks.Get().begin() + i);
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return;
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WebContents* WebContents::FromRenderViewHost(const RenderViewHost* rvh) {
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return rvh->GetDelegate()->GetAsWebContents();
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WebContents* WebContents::FromRenderFrameHost(RenderFrameHost* rfh) {
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RenderFrameHostImpl* rfh_impl = static_cast<RenderFrameHostImpl*>(rfh);
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!rfh_impl)
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return NULL;
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return rfh_impl->delegate()->GetAsWebContents();
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// WebContentsImpl::DestructionObserver ----------------------------------------
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class WebContentsImpl::DestructionObserver : public WebContentsObserver {
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DestructionObserver(WebContentsImpl* owner, WebContents* watched_contents)
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : WebContentsObserver(watched_contents),
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        owner_(owner) {
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // WebContentsObserver:
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    owner_->OnWebContentsDestroyed(static_cast<WebContentsImpl*>(web_contents));
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebContentsImpl* owner_;
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DestructionObserver);
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// WebContentsImpl -------------------------------------------------------------
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WebContentsImpl::WebContentsImpl(
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BrowserContext* browser_context,
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WebContentsImpl* opener)
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : delegate_(NULL),
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      controller_(this, browser_context),
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      render_view_host_delegate_view_(NULL),
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      opener_(opener),
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_WIN)
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      accessible_parent_(NULL),
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      frame_tree_(new NavigatorImpl(&controller_, this),
3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                  this, this, this, this),
3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      is_loading_(false),
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING),
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      crashed_error_code_(0),
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      waiting_for_response_(false),
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      load_state_(net::LOAD_STATE_IDLE, base::string16()),
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      upload_size_(0),
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      upload_position_(0),
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      displayed_insecure_content_(false),
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      capturer_count_(0),
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      should_normally_be_visible_(true),
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      is_being_destroyed_(false),
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      notify_disconnection_(false),
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      dialog_manager_(NULL),
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      is_showing_before_unload_dialog_(false),
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      last_active_time_(base::TimeTicks::Now()),
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      closed_by_user_gesture_(false),
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      minimum_zoom_percent_(static_cast<int>(kMinimumZoomFactor * 100)),
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      maximum_zoom_percent_(static_cast<int>(kMaximumZoomFactor * 100)),
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      temporary_zoom_settings_(false),
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      color_chooser_identifier_(0),
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      render_view_message_source_(NULL),
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      fullscreen_widget_routing_id_(MSG_ROUTING_NONE),
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      is_subframe_(false) {
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < g_created_callbacks.Get().size(); i++)
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    g_created_callbacks.Get().at(i).Run(this);
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  frame_tree_.SetFrameRemoveListener(
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&WebContentsImpl::OnFrameRemoved,
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 base::Unretained(this)));
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WebContentsImpl::~WebContentsImpl() {
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  is_being_destroyed_ = true;
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Delete all RFH pending shutdown, which will lead the corresponding RVH to
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // shutdown and be deleted as well.
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  frame_tree_.ForEach(
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&RenderFrameHostManager::ClearRFHsPendingShutdown));
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ClearAllPowerSaveBlockers();
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (std::set<RenderWidgetHostImpl*>::iterator iter =
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           created_widgets_.begin(); iter != created_widgets_.end(); ++iter) {
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    (*iter)->DetachDelegate();
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  created_widgets_.clear();
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Clear out any JavaScript state.
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (dialog_manager_)
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    dialog_manager_->WebContentsDestroyed(this);
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (color_chooser_)
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    color_chooser_->End();
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NotifyDisconnected();
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Notify any observer that have a reference on this WebContents.
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NotificationService::current()->Notify(
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      NOTIFICATION_WEB_CONTENTS_DESTROYED,
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Source<WebContents>(this),
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      NotificationService::NoDetails());
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::Callback<void(RenderFrameHost*)> run_render_frame_deleted_callback =
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&RunRenderFrameDeleted, base::Unretained(&observers_));
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  frame_tree_.ForEach(base::Bind(&ForEachPendingFrameInternal,
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 run_render_frame_deleted_callback));
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RenderViewHost* pending_rvh = GetRenderManager()->pending_render_view_host();
3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (pending_rvh) {
3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    FOR_EACH_OBSERVER(WebContentsObserver,
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      observers_,
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      RenderViewDeleted(pending_rvh));
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ForEachFrame(run_render_frame_deleted_callback);
3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FOR_EACH_OBSERVER(WebContentsObserver,
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    observers_,
3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    RenderViewDeleted(GetRenderManager()->current_host()));
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FOR_EACH_OBSERVER(WebContentsObserver,
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    observers_,
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    WebContentsImplDestroyed());
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SetDelegate(NULL);
4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  STLDeleteContainerPairSecondPointers(destruction_observers_.begin(),
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       destruction_observers_.end());
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WebContentsImpl* WebContentsImpl::CreateWithOpener(
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const WebContents::CreateParams& params,
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WebContentsImpl* opener) {
4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT0("browser", "WebContentsImpl::CreateWithOpener");
4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebContentsImpl* new_contents = new WebContentsImpl(
4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      params.browser_context, opener);
4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  new_contents->Init(params);
4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return new_contents;
4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)BrowserPluginGuest* WebContentsImpl::CreateGuest(
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BrowserContext* browser_context,
4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SiteInstance* site_instance,
4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int guest_instance_id,
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<base::DictionaryValue> extra_params) {
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebContentsImpl* new_contents = new WebContentsImpl(browser_context, NULL);
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // This makes |new_contents| act as a guest.
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // For more info, see comment above class BrowserPluginGuest.
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BrowserPluginGuest::Create(
4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      guest_instance_id, site_instance, new_contents, extra_params.Pass());
4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebContents::CreateParams create_params(browser_context, site_instance);
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  new_contents->Init(create_params);
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // We are instantiating a WebContents for browser plugin. Set its subframe bit
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // to true.
4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  new_contents->is_subframe_ = true;
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return new_contents->browser_plugin_guest_.get();
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() {
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return GetRenderManager();
4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        const IPC::Message& message) {
4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return OnMessageReceived(render_view_host, NULL, message);
4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host,
4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        RenderFrameHost* render_frame_host,
4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        const IPC::Message& message) {
4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(render_view_host || render_frame_host);
4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (GetWebUI() &&
4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      static_cast<WebUIImpl*>(GetWebUI())->OnMessageReceived(message)) {
4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ObserverListBase<WebContentsObserver>::Iterator it(observers_);
4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebContentsObserver* observer;
4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  while ((observer = it.GetNext()) != NULL)
4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (observer->OnMessageReceived(message))
4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return true;
4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Message handlers should be aware of which
4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // RenderViewHost/RenderFrameHost sent the message, which is temporarily
4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // stored in render_(view|frame)_message_source_.
4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (render_frame_host) {
4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (RenderViewDevToolsAgentHost::DispatchIPCMessage(
4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        render_frame_host->GetRenderViewHost(), message))
4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return true;
4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    render_frame_message_source_ = render_frame_host;
4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (RenderViewDevToolsAgentHost::DispatchIPCMessage(
4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        render_view_host, message))
4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return true;
4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    render_view_message_source_ = render_view_host;
4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool handled = true;
4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool message_is_ok = true;
4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP_EX(WebContentsImpl, message, message_is_ok)
4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_PepperPluginHung, OnPepperPluginHung)
4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_PluginCrashed, OnPluginCrashed)
4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_DomOperationResponse,
4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnDomOperationResponse)
4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache,
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnDidLoadResourceFromMemoryCache)
4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_DidDisplayInsecureContent,
4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnDidDisplayInsecureContent)
4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_DidRunInsecureContent,
4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnDidRunInsecureContent)
4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishDocumentLoad,
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnDocumentLoadedInFrame)
4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FrameHostMsg_DidFinishLoad, OnDidFinishLoad)
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_GoToEntryAtOffset, OnGoToEntryAtOffset)
4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateZoomLimits, OnUpdateZoomLimits)
4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_EnumerateDirectory, OnEnumerateDirectory)
4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterProtocolHandler,
4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnRegisterProtocolHandler)
4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_Find_Reply, OnFindReply)
5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_AppCacheAccessed, OnAppCacheAccessed)
5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_OpenColorChooser, OnOpenColorChooser)
5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_EndColorChooser, OnEndColorChooser)
50303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_SetSelectedColorInColorChooser,
5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnSetSelectedColorInColorChooser)
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_WebUISend, OnWebUISend)
5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_RequestPpapiBrokerPermission,
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnRequestPpapiBrokerPermission)
5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginHostMsg_AllocateInstanceID,
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                OnBrowserPluginMessage(message))
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginHostMsg_Attach,
51103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                OnBrowserPluginMessage(message))
5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ImageHostMsg_DidDownloadImage, OnDidDownloadImage)
5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFaviconURL, OnUpdateFaviconURL)
5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_ANDROID)
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_FindMatchRects_Reply,
5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnFindMatchRectsReply)
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_OpenDateTimeDialog,
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnOpenDateTimeDialog)
5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(JavaBridgeHostMsg_GetChannelHandle,
5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    OnJavaBridgeGetChannelHandle)
5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_MediaPlayingNotification,
5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnMediaPlayingNotification)
5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_MediaPausedNotification,
5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnMediaPausedNotification)
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_DidFirstVisuallyNonEmptyPaint,
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnFirstVisuallyNonEmptyPaint)
5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewHostMsg_ShowValidationMessage,
5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnShowValidationMessage)
5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_HANDLER(ViewHostMsg_HideValidationMessage,
5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        OnHideValidationMessage)
5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_HANDLER(ViewHostMsg_MoveValidationMessage,
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        OnMoveValidationMessage)
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    IPC_MESSAGE_UNHANDLED(handled = false)
5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  IPC_END_MESSAGE_MAP_EX()
5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  render_view_message_source_ = NULL;
5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  render_frame_message_source_ = NULL;
5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
539  if (!message_is_ok) {
540    RecordAction(base::UserMetricsAction("BadMessageTerminate_RVD"));
541    GetRenderProcessHost()->ReceivedBadMessage();
542  }
543
544  return handled;
545}
546
547void WebContentsImpl::RunFileChooser(
548    RenderViewHost* render_view_host,
549    const FileChooserParams& params) {
550  if (delegate_)
551    delegate_->RunFileChooser(this, params);
552}
553
554NavigationControllerImpl& WebContentsImpl::GetController() {
555  return controller_;
556}
557
558const NavigationControllerImpl& WebContentsImpl::GetController() const {
559  return controller_;
560}
561
562BrowserContext* WebContentsImpl::GetBrowserContext() const {
563  return controller_.GetBrowserContext();
564}
565
566const GURL& WebContentsImpl::GetURL() const {
567  // We may not have a navigation entry yet.
568  NavigationEntry* entry = controller_.GetVisibleEntry();
569  return entry ? entry->GetVirtualURL() : GURL::EmptyGURL();
570}
571
572const GURL& WebContentsImpl::GetVisibleURL() const {
573  // We may not have a navigation entry yet.
574  NavigationEntry* entry = controller_.GetVisibleEntry();
575  return entry ? entry->GetVirtualURL() : GURL::EmptyGURL();
576}
577
578const GURL& WebContentsImpl::GetLastCommittedURL() const {
579  // We may not have a navigation entry yet.
580  NavigationEntry* entry = controller_.GetLastCommittedEntry();
581  return entry ? entry->GetVirtualURL() : GURL::EmptyGURL();
582}
583
584WebContentsDelegate* WebContentsImpl::GetDelegate() {
585  return delegate_;
586}
587
588void WebContentsImpl::SetDelegate(WebContentsDelegate* delegate) {
589  // TODO(cbentzel): remove this debugging code?
590  if (delegate == delegate_)
591    return;
592  if (delegate_)
593    delegate_->Detach(this);
594  delegate_ = delegate;
595  if (delegate_) {
596    delegate_->Attach(this);
597    // Ensure the visible RVH reflects the new delegate's preferences.
598    if (view_)
599      view_->SetOverscrollControllerEnabled(delegate->CanOverscrollContent());
600  }
601}
602
603RenderProcessHost* WebContentsImpl::GetRenderProcessHost() const {
604  RenderViewHostImpl* host = GetRenderManager()->current_host();
605  return host ? host->GetProcess() : NULL;
606}
607
608RenderFrameHost* WebContentsImpl::GetMainFrame() {
609  return frame_tree_.root()->current_frame_host();
610}
611
612RenderFrameHost* WebContentsImpl::GetFocusedFrame() {
613  if (!frame_tree_.GetFocusedFrame())
614    return NULL;
615  return frame_tree_.GetFocusedFrame()->current_frame_host();
616}
617
618void WebContentsImpl::ForEachFrame(
619    const base::Callback<void(RenderFrameHost*)>& on_frame) {
620  frame_tree_.ForEach(base::Bind(&ForEachFrameInternal, on_frame));
621}
622
623void WebContentsImpl::SendToAllFrames(IPC::Message* message) {
624  ForEachFrame(base::Bind(&SendToAllFramesInternal, message));
625  delete message;
626}
627
628RenderViewHost* WebContentsImpl::GetRenderViewHost() const {
629  return GetRenderManager()->current_host();
630}
631
632WebContents* WebContentsImpl::GetEmbedderWebContents() const {
633  BrowserPluginGuest* guest = GetBrowserPluginGuest();
634  if (guest)
635    return guest->embedder_web_contents();
636  return NULL;
637}
638
639int WebContentsImpl::GetEmbeddedInstanceID() const {
640  BrowserPluginGuest* guest = GetBrowserPluginGuest();
641  if (guest)
642    return guest->instance_id();
643  return 0;
644}
645
646int WebContentsImpl::GetRoutingID() const {
647  if (!GetRenderViewHost())
648    return MSG_ROUTING_NONE;
649
650  return GetRenderViewHost()->GetRoutingID();
651}
652
653int WebContentsImpl::GetFullscreenWidgetRoutingID() const {
654  return fullscreen_widget_routing_id_;
655}
656
657RenderWidgetHostView* WebContentsImpl::GetRenderWidgetHostView() const {
658  return GetRenderManager()->GetRenderWidgetHostView();
659}
660
661RenderWidgetHostViewPort* WebContentsImpl::GetRenderWidgetHostViewPort() const {
662  BrowserPluginGuest* guest = GetBrowserPluginGuest();
663  if (guest && guest->embedder_web_contents()) {
664    return guest->embedder_web_contents()->GetRenderWidgetHostViewPort();
665  }
666  return RenderWidgetHostViewPort::FromRWHV(GetRenderWidgetHostView());
667}
668
669RenderWidgetHostView* WebContentsImpl::GetFullscreenRenderWidgetHostView()
670    const {
671  RenderWidgetHost* const widget_host =
672      RenderWidgetHostImpl::FromID(GetRenderProcessHost()->GetID(),
673                                   GetFullscreenWidgetRoutingID());
674  return widget_host ? widget_host->GetView() : NULL;
675}
676
677WebContentsView* WebContentsImpl::GetView() const {
678  return view_.get();
679}
680
681WebUI* WebContentsImpl::CreateWebUI(const GURL& url) {
682  WebUIImpl* web_ui = new WebUIImpl(this);
683  WebUIController* controller = WebUIControllerFactoryRegistry::GetInstance()->
684      CreateWebUIControllerForURL(web_ui, url);
685  if (controller) {
686    web_ui->AddMessageHandler(new GenericHandler());
687    web_ui->SetController(controller);
688    return web_ui;
689  }
690
691  delete web_ui;
692  return NULL;
693}
694
695WebUI* WebContentsImpl::GetWebUI() const {
696  return GetRenderManager()->web_ui() ? GetRenderManager()->web_ui()
697      : GetRenderManager()->pending_web_ui();
698}
699
700WebUI* WebContentsImpl::GetCommittedWebUI() const {
701  return GetRenderManager()->web_ui();
702}
703
704void WebContentsImpl::SetUserAgentOverride(const std::string& override) {
705  if (GetUserAgentOverride() == override)
706    return;
707
708  renderer_preferences_.user_agent_override = override;
709
710  // Send the new override string to the renderer.
711  RenderViewHost* host = GetRenderViewHost();
712  if (host)
713    host->SyncRendererPrefs();
714
715  // Reload the page if a load is currently in progress to avoid having
716  // different parts of the page loaded using different user agents.
717  NavigationEntry* entry = controller_.GetVisibleEntry();
718  if (is_loading_ && entry != NULL && entry->GetIsOverridingUserAgent())
719    controller_.ReloadIgnoringCache(true);
720
721  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
722                    UserAgentOverrideSet(override));
723}
724
725const std::string& WebContentsImpl::GetUserAgentOverride() const {
726  return renderer_preferences_.user_agent_override;
727}
728
729#if defined(OS_WIN)
730void WebContentsImpl::SetParentNativeViewAccessible(
731gfx::NativeViewAccessible accessible_parent) {
732  accessible_parent_ = accessible_parent;
733  if (GetRenderViewHost())
734    GetRenderViewHostImpl()->SetParentNativeViewAccessible(accessible_parent);
735}
736#endif
737
738const base::string16& WebContentsImpl::GetTitle() const {
739  // Transient entries take precedence. They are used for interstitial pages
740  // that are shown on top of existing pages.
741  NavigationEntry* entry = controller_.GetTransientEntry();
742  std::string accept_languages =
743      GetContentClient()->browser()->GetAcceptLangs(
744          GetBrowserContext());
745  if (entry) {
746    return entry->GetTitleForDisplay(accept_languages);
747  }
748  WebUI* our_web_ui = GetRenderManager()->pending_web_ui() ?
749      GetRenderManager()->pending_web_ui() : GetRenderManager()->web_ui();
750  if (our_web_ui) {
751    // Don't override the title in view source mode.
752    entry = controller_.GetVisibleEntry();
753    if (!(entry && entry->IsViewSourceMode())) {
754      // Give the Web UI the chance to override our title.
755      const base::string16& title = our_web_ui->GetOverriddenTitle();
756      if (!title.empty())
757        return title;
758    }
759  }
760
761  // We use the title for the last committed entry rather than a pending
762  // navigation entry. For example, when the user types in a URL, we want to
763  // keep the old page's title until the new load has committed and we get a new
764  // title.
765  entry = controller_.GetLastCommittedEntry();
766
767  // We make an exception for initial navigations.
768  if (controller_.IsInitialNavigation()) {
769    // We only want to use the title from the visible entry in one of two cases:
770    // 1. There's already a committed entry for an initial navigation, in which
771    //    case we are doing a history navigation in a new tab (e.g., Ctrl+Back).
772    // 2. The pending entry has been explicitly assigned a title to display.
773    //
774    // If there's no last committed entry and no assigned title, we should fall
775    // back to |page_title_when_no_navigation_entry_| rather than showing the
776    // URL.
777    if (entry ||
778        (controller_.GetVisibleEntry() &&
779         !controller_.GetVisibleEntry()->GetTitle().empty())) {
780      entry = controller_.GetVisibleEntry();
781    }
782  }
783
784  if (entry) {
785    return entry->GetTitleForDisplay(accept_languages);
786  }
787
788  // |page_title_when_no_navigation_entry_| is finally used
789  // if no title cannot be retrieved.
790  return page_title_when_no_navigation_entry_;
791}
792
793int32 WebContentsImpl::GetMaxPageID() {
794  return GetMaxPageIDForSiteInstance(GetSiteInstance());
795}
796
797int32 WebContentsImpl::GetMaxPageIDForSiteInstance(
798    SiteInstance* site_instance) {
799  if (max_page_ids_.find(site_instance->GetId()) == max_page_ids_.end())
800    max_page_ids_[site_instance->GetId()] = -1;
801
802  return max_page_ids_[site_instance->GetId()];
803}
804
805void WebContentsImpl::UpdateMaxPageID(int32 page_id) {
806  UpdateMaxPageIDForSiteInstance(GetSiteInstance(), page_id);
807}
808
809void WebContentsImpl::UpdateMaxPageIDForSiteInstance(
810    SiteInstance* site_instance, int32 page_id) {
811  if (GetMaxPageIDForSiteInstance(site_instance) < page_id)
812    max_page_ids_[site_instance->GetId()] = page_id;
813}
814
815void WebContentsImpl::CopyMaxPageIDsFrom(WebContents* web_contents) {
816  WebContentsImpl* contents = static_cast<WebContentsImpl*>(web_contents);
817  max_page_ids_ = contents->max_page_ids_;
818}
819
820SiteInstance* WebContentsImpl::GetSiteInstance() const {
821  return GetRenderManager()->current_host()->GetSiteInstance();
822}
823
824SiteInstance* WebContentsImpl::GetPendingSiteInstance() const {
825  RenderViewHost* dest_rvh = GetRenderManager()->pending_render_view_host() ?
826      GetRenderManager()->pending_render_view_host() :
827      GetRenderManager()->current_host();
828  return dest_rvh->GetSiteInstance();
829}
830
831bool WebContentsImpl::IsLoading() const {
832  return is_loading_;
833}
834
835bool WebContentsImpl::IsWaitingForResponse() const {
836  return waiting_for_response_;
837}
838
839const net::LoadStateWithParam& WebContentsImpl::GetLoadState() const {
840  return load_state_;
841}
842
843const base::string16& WebContentsImpl::GetLoadStateHost() const {
844  return load_state_host_;
845}
846
847uint64 WebContentsImpl::GetUploadSize() const {
848  return upload_size_;
849}
850
851uint64 WebContentsImpl::GetUploadPosition() const {
852  return upload_position_;
853}
854
855std::set<GURL> WebContentsImpl::GetSitesInTab() const {
856  std::set<GURL> sites;
857  frame_tree_.ForEach(base::Bind(&CollectSites,
858                                 base::Unretained(GetBrowserContext()),
859                                 base::Unretained(&sites)));
860  return sites;
861}
862
863const std::string& WebContentsImpl::GetEncoding() const {
864  return encoding_;
865}
866
867bool WebContentsImpl::DisplayedInsecureContent() const {
868  return displayed_insecure_content_;
869}
870
871void WebContentsImpl::IncrementCapturerCount(const gfx::Size& capture_size) {
872  DCHECK(!is_being_destroyed_);
873  ++capturer_count_;
874  DVLOG(1) << "There are now " << capturer_count_
875           << " capturing(s) of WebContentsImpl@" << this;
876
877  // Note: This provides a hint to upstream code to size the views optimally
878  // for quality (e.g., to avoid scaling).
879  if (!capture_size.IsEmpty() && preferred_size_for_capture_.IsEmpty()) {
880    preferred_size_for_capture_ = capture_size;
881    OnPreferredSizeChanged(preferred_size_);
882  }
883}
884
885void WebContentsImpl::DecrementCapturerCount() {
886  --capturer_count_;
887  DVLOG(1) << "There are now " << capturer_count_
888           << " capturing(s) of WebContentsImpl@" << this;
889  DCHECK_LE(0, capturer_count_);
890
891  if (is_being_destroyed_)
892    return;
893
894  if (capturer_count_ == 0) {
895    const gfx::Size old_size = preferred_size_for_capture_;
896    preferred_size_for_capture_ = gfx::Size();
897    OnPreferredSizeChanged(old_size);
898  }
899
900  if (IsHidden()) {
901    DVLOG(1) << "Executing delayed WasHidden().";
902    WasHidden();
903  }
904}
905
906int WebContentsImpl::GetCapturerCount() const {
907  return capturer_count_;
908}
909
910bool WebContentsImpl::IsCrashed() const {
911  return (crashed_status_ == base::TERMINATION_STATUS_PROCESS_CRASHED ||
912          crashed_status_ == base::TERMINATION_STATUS_ABNORMAL_TERMINATION ||
913          crashed_status_ == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
914}
915
916void WebContentsImpl::SetIsCrashed(base::TerminationStatus status,
917                                   int error_code) {
918  if (status == crashed_status_)
919    return;
920
921  crashed_status_ = status;
922  crashed_error_code_ = error_code;
923  NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
924}
925
926base::TerminationStatus WebContentsImpl::GetCrashedStatus() const {
927  return crashed_status_;
928}
929
930bool WebContentsImpl::IsBeingDestroyed() const {
931  return is_being_destroyed_;
932}
933
934void WebContentsImpl::NotifyNavigationStateChanged(unsigned changed_flags) {
935  if (delegate_)
936    delegate_->NavigationStateChanged(this, changed_flags);
937}
938
939base::TimeTicks WebContentsImpl::GetLastActiveTime() const {
940  return last_active_time_;
941}
942
943void WebContentsImpl::WasShown() {
944  controller_.SetActive(true);
945  RenderWidgetHostViewPort* rwhv =
946      RenderWidgetHostViewPort::FromRWHV(GetRenderWidgetHostView());
947  if (rwhv) {
948    rwhv->Show();
949#if defined(OS_MACOSX)
950    rwhv->SetActive(true);
951#endif
952  }
953
954  last_active_time_ = base::TimeTicks::Now();
955
956  // The resize rect might have changed while this was inactive -- send the new
957  // one to make sure it's up to date.
958  RenderViewHostImpl* rvh =
959      static_cast<RenderViewHostImpl*>(GetRenderViewHost());
960  if (rvh) {
961    rvh->ResizeRectChanged(GetRootWindowResizerRect());
962  }
963
964  FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasShown());
965
966  should_normally_be_visible_ = true;
967}
968
969void WebContentsImpl::WasHidden() {
970  // If there are entities capturing screenshots or video (e.g., mirroring),
971  // don't activate the "disable rendering" optimization.
972  if (capturer_count_ == 0) {
973    // |GetRenderViewHost()| can be NULL if the user middle clicks a link to
974    // open a tab in the background, then closes the tab before selecting it.
975    // This is because closing the tab calls WebContentsImpl::Destroy(), which
976    // removes the |GetRenderViewHost()|; then when we actually destroy the
977    // window, OnWindowPosChanged() notices and calls WasHidden() (which
978    // calls us).
979    RenderWidgetHostViewPort* rwhv =
980        RenderWidgetHostViewPort::FromRWHV(GetRenderWidgetHostView());
981    if (rwhv)
982      rwhv->Hide();
983  }
984
985  FOR_EACH_OBSERVER(WebContentsObserver, observers_, WasHidden());
986
987  should_normally_be_visible_ = false;
988}
989
990bool WebContentsImpl::NeedToFireBeforeUnload() {
991  // TODO(creis): Should we fire even for interstitial pages?
992  return WillNotifyDisconnection() &&
993      !ShowingInterstitialPage() &&
994      !static_cast<RenderViewHostImpl*>(
995          GetRenderViewHost())->SuddenTerminationAllowed();
996}
997
998void WebContentsImpl::Stop() {
999  GetRenderManager()->Stop();
1000  FOR_EACH_OBSERVER(WebContentsObserver, observers_, NavigationStopped());
1001}
1002
1003WebContents* WebContentsImpl::Clone() {
1004  // We use our current SiteInstance since the cloned entry will use it anyway.
1005  // We pass our own opener so that the cloned page can access it if it was
1006  // before.
1007  CreateParams create_params(GetBrowserContext(), GetSiteInstance());
1008  create_params.initial_size = view_->GetContainerSize();
1009  WebContentsImpl* tc = CreateWithOpener(create_params, opener_);
1010  tc->GetController().CopyStateFrom(controller_);
1011  FOR_EACH_OBSERVER(WebContentsObserver,
1012                    observers_,
1013                    DidCloneToNewWebContents(this, tc));
1014  return tc;
1015}
1016
1017void WebContentsImpl::Observe(int type,
1018                              const NotificationSource& source,
1019                              const NotificationDetails& details) {
1020  switch (type) {
1021    case NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: {
1022      RenderWidgetHost* host = Source<RenderWidgetHost>(source).ptr();
1023      for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
1024           i != pending_widget_views_.end(); ++i) {
1025        if (host->GetView() == i->second) {
1026          pending_widget_views_.erase(i);
1027          break;
1028        }
1029      }
1030      break;
1031    }
1032    default:
1033      NOTREACHED();
1034  }
1035}
1036
1037WebContents* WebContentsImpl::GetWebContents() {
1038  return this;
1039}
1040
1041void WebContentsImpl::Init(const WebContents::CreateParams& params) {
1042  // This is set before initializing the render manager since
1043  // RenderFrameHostManager::Init calls back into us via its delegate to ask if
1044  // it should be hidden.
1045  should_normally_be_visible_ = !params.initially_hidden;
1046
1047  GetRenderManager()->Init(
1048      params.browser_context, params.site_instance, params.routing_id,
1049      params.main_frame_routing_id);
1050
1051  view_.reset(GetContentClient()->browser()->
1052      OverrideCreateWebContentsView(this, &render_view_host_delegate_view_));
1053  if (view_) {
1054    CHECK(render_view_host_delegate_view_);
1055  } else {
1056    WebContentsViewDelegate* delegate =
1057        GetContentClient()->browser()->GetWebContentsViewDelegate(this);
1058
1059    if (browser_plugin_guest_) {
1060      scoped_ptr<WebContentsViewPort> platform_view(CreateWebContentsView(
1061          this, delegate, &render_view_host_delegate_view_));
1062
1063      WebContentsViewGuest* rv = new WebContentsViewGuest(
1064          this, browser_plugin_guest_.get(), platform_view.Pass(),
1065          render_view_host_delegate_view_);
1066      render_view_host_delegate_view_ = rv;
1067      view_.reset(rv);
1068    } else {
1069      // Regular WebContentsView.
1070      view_.reset(CreateWebContentsView(
1071          this, delegate, &render_view_host_delegate_view_));
1072    }
1073    CHECK(render_view_host_delegate_view_);
1074  }
1075  CHECK(view_.get());
1076
1077  gfx::Size initial_size = params.initial_size;
1078  view_->CreateView(initial_size, params.context);
1079
1080  // Listen for whether our opener gets destroyed.
1081  if (opener_)
1082    AddDestructionObserver(opener_);
1083
1084  registrar_.Add(this,
1085                 NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
1086                 NotificationService::AllBrowserContextsAndSources());
1087#if defined(OS_ANDROID)
1088  java_bridge_dispatcher_host_manager_.reset(
1089      new JavaBridgeDispatcherHostManager(this));
1090  date_time_chooser_.reset(new DateTimeChooserAndroid());
1091#endif
1092}
1093
1094void WebContentsImpl::OnWebContentsDestroyed(WebContentsImpl* web_contents) {
1095  RemoveDestructionObserver(web_contents);
1096
1097  // Clear the opener if it has been closed.
1098  if (web_contents == opener_) {
1099    opener_ = NULL;
1100    return;
1101  }
1102  // Clear a pending contents that has been closed before being shown.
1103  for (PendingContents::iterator iter = pending_contents_.begin();
1104       iter != pending_contents_.end();
1105       ++iter) {
1106    if (iter->second != web_contents)
1107      continue;
1108    pending_contents_.erase(iter);
1109    return;
1110  }
1111  NOTREACHED();
1112}
1113
1114void WebContentsImpl::AddDestructionObserver(WebContentsImpl* web_contents) {
1115  if (!ContainsKey(destruction_observers_, web_contents)) {
1116    destruction_observers_[web_contents] =
1117        new DestructionObserver(this, web_contents);
1118  }
1119}
1120
1121void WebContentsImpl::RemoveDestructionObserver(WebContentsImpl* web_contents) {
1122  DestructionObservers::iterator iter =
1123      destruction_observers_.find(web_contents);
1124  if (iter != destruction_observers_.end()) {
1125    delete destruction_observers_[web_contents];
1126    destruction_observers_.erase(iter);
1127  }
1128}
1129
1130void WebContentsImpl::AddObserver(WebContentsObserver* observer) {
1131  observers_.AddObserver(observer);
1132}
1133
1134void WebContentsImpl::RemoveObserver(WebContentsObserver* observer) {
1135  observers_.RemoveObserver(observer);
1136}
1137
1138void WebContentsImpl::Activate() {
1139  if (delegate_)
1140    delegate_->ActivateContents(this);
1141}
1142
1143void WebContentsImpl::Deactivate() {
1144  if (delegate_)
1145    delegate_->DeactivateContents(this);
1146}
1147
1148void WebContentsImpl::LostCapture() {
1149  if (delegate_)
1150    delegate_->LostCapture();
1151}
1152
1153void WebContentsImpl::RenderWidgetDeleted(
1154    RenderWidgetHostImpl* render_widget_host) {
1155  if (is_being_destroyed_) {
1156    // |created_widgets_| might have been destroyed.
1157    return;
1158  }
1159
1160  std::set<RenderWidgetHostImpl*>::iterator iter =
1161      created_widgets_.find(render_widget_host);
1162  if (iter != created_widgets_.end())
1163    created_widgets_.erase(iter);
1164
1165  if (render_widget_host &&
1166      render_widget_host->GetRoutingID() == fullscreen_widget_routing_id_) {
1167    if (delegate_ && delegate_->EmbedsFullscreenWidget())
1168      delegate_->ToggleFullscreenModeForTab(this, false);
1169    FOR_EACH_OBSERVER(WebContentsObserver,
1170                      observers_,
1171                      DidDestroyFullscreenWidget(
1172                          fullscreen_widget_routing_id_));
1173    fullscreen_widget_routing_id_ = MSG_ROUTING_NONE;
1174  }
1175}
1176
1177bool WebContentsImpl::PreHandleKeyboardEvent(
1178    const NativeWebKeyboardEvent& event,
1179    bool* is_keyboard_shortcut) {
1180  return delegate_ &&
1181      delegate_->PreHandleKeyboardEvent(this, event, is_keyboard_shortcut);
1182}
1183
1184void WebContentsImpl::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
1185  if (browser_plugin_embedder_ &&
1186      browser_plugin_embedder_->HandleKeyboardEvent(event)) {
1187    return;
1188  }
1189
1190  if (delegate_)
1191    delegate_->HandleKeyboardEvent(this, event);
1192}
1193
1194bool WebContentsImpl::HandleWheelEvent(
1195    const blink::WebMouseWheelEvent& event) {
1196#if !defined(OS_MACOSX)
1197  // On platforms other than Mac, control+mousewheel changes zoom. On Mac, this
1198  // isn't done for two reasons:
1199  //   -the OS already has a gesture to do this through pinch-zoom
1200  //   -if a user starts an inertial scroll, let's go, and presses control
1201  //      (i.e. control+tab) then the OS's buffered scroll events will come in
1202  //      with control key set which isn't what the user wants
1203  if (delegate_ &&
1204      event.wheelTicksY &&
1205      (event.modifiers & blink::WebInputEvent::ControlKey)) {
1206    delegate_->ContentsZoomChange(event.wheelTicksY > 0);
1207    return true;
1208  }
1209#endif
1210  return false;
1211}
1212
1213bool WebContentsImpl::PreHandleGestureEvent(
1214    const blink::WebGestureEvent& event) {
1215  return delegate_ && delegate_->PreHandleGestureEvent(this, event);
1216}
1217
1218#if defined(OS_WIN)
1219gfx::NativeViewAccessible WebContentsImpl::GetParentNativeViewAccessible() {
1220  return accessible_parent_;
1221}
1222#endif
1223
1224void WebContentsImpl::HandleMouseDown() {
1225  if (delegate_)
1226    delegate_->HandleMouseDown();
1227}
1228
1229void WebContentsImpl::HandleMouseUp() {
1230  if (delegate_)
1231    delegate_->HandleMouseUp();
1232}
1233
1234void WebContentsImpl::HandlePointerActivate() {
1235  if (delegate_)
1236    delegate_->HandlePointerActivate();
1237}
1238
1239void WebContentsImpl::HandleGestureBegin() {
1240  if (delegate_)
1241    delegate_->HandleGestureBegin();
1242}
1243
1244void WebContentsImpl::HandleGestureEnd() {
1245  if (delegate_)
1246    delegate_->HandleGestureEnd();
1247}
1248
1249void WebContentsImpl::ToggleFullscreenMode(bool enter_fullscreen) {
1250  // This method is being called to enter or leave renderer-initiated fullscreen
1251  // mode.  Either way, make sure any existing fullscreen widget is shut down
1252  // first.
1253  RenderWidgetHostView* const widget_view = GetFullscreenRenderWidgetHostView();
1254  if (widget_view)
1255    RenderWidgetHostImpl::From(widget_view->GetRenderWidgetHost())->Shutdown();
1256
1257  if (delegate_)
1258    delegate_->ToggleFullscreenModeForTab(this, enter_fullscreen);
1259}
1260
1261bool WebContentsImpl::IsFullscreenForCurrentTab() const {
1262  return delegate_ ? delegate_->IsFullscreenForTabOrPending(this) : false;
1263}
1264
1265void WebContentsImpl::RequestToLockMouse(bool user_gesture,
1266                                         bool last_unlocked_by_target) {
1267  if (delegate_) {
1268    delegate_->RequestToLockMouse(this, user_gesture, last_unlocked_by_target);
1269  } else {
1270    GotResponseToLockMouseRequest(false);
1271  }
1272}
1273
1274void WebContentsImpl::LostMouseLock() {
1275  if (delegate_)
1276    delegate_->LostMouseLock();
1277}
1278
1279void WebContentsImpl::CreateNewWindow(
1280    int render_process_id,
1281    int route_id,
1282    int main_frame_route_id,
1283    const ViewHostMsg_CreateWindow_Params& params,
1284    SessionStorageNamespace* session_storage_namespace) {
1285  // We usually create the new window in the same BrowsingInstance (group of
1286  // script-related windows), by passing in the current SiteInstance.  However,
1287  // if the opener is being suppressed (in a non-guest), we create a new
1288  // SiteInstance in its own BrowsingInstance.
1289  bool is_guest = GetRenderProcessHost()->IsGuest();
1290
1291  // If the opener is to be suppressed, the new window can be in any process.
1292  // Since routing ids are process specific, we must not have one passed in
1293  // as argument here.
1294  DCHECK(!params.opener_suppressed || route_id == MSG_ROUTING_NONE);
1295
1296  scoped_refptr<SiteInstance> site_instance =
1297      params.opener_suppressed && !is_guest ?
1298      SiteInstance::CreateForURL(GetBrowserContext(), params.target_url) :
1299      GetSiteInstance();
1300
1301  // A message to create a new window can only come from the active process for
1302  // this WebContentsImpl instance. If any other process sends the request,
1303  // it is invalid and the process must be terminated.
1304  if (GetRenderProcessHost()->GetID() != render_process_id) {
1305    base::ProcessHandle process_handle =
1306        RenderProcessHost::FromID(render_process_id)->GetHandle();
1307    if (process_handle != base::kNullProcessHandle) {
1308      RecordAction(
1309          base::UserMetricsAction("Terminate_ProcessMismatch_CreateNewWindow"));
1310      base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false);
1311    }
1312    return;
1313  }
1314
1315  // We must assign the SessionStorageNamespace before calling Init().
1316  //
1317  // http://crbug.com/142685
1318  const std::string& partition_id =
1319      GetContentClient()->browser()->
1320          GetStoragePartitionIdForSite(GetBrowserContext(),
1321                                       site_instance->GetSiteURL());
1322  StoragePartition* partition = BrowserContext::GetStoragePartition(
1323      GetBrowserContext(), site_instance.get());
1324  DOMStorageContextWrapper* dom_storage_context =
1325      static_cast<DOMStorageContextWrapper*>(partition->GetDOMStorageContext());
1326  SessionStorageNamespaceImpl* session_storage_namespace_impl =
1327      static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace);
1328  CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context));
1329
1330  if (delegate_ &&
1331      !delegate_->ShouldCreateWebContents(this,
1332                                          route_id,
1333                                          params.window_container_type,
1334                                          params.frame_name,
1335                                          params.target_url,
1336                                          partition_id,
1337                                          session_storage_namespace)) {
1338    if (route_id != MSG_ROUTING_NONE &&
1339        !RenderViewHost::FromID(render_process_id, route_id)) {
1340      // If the embedder didn't create a WebContents for this route, we need to
1341      // delete the RenderView that had already been created.
1342      Send(new ViewMsg_Close(route_id));
1343    }
1344    GetRenderViewHost()->GetProcess()->ResumeRequestsForView(route_id);
1345    GetRenderViewHost()->GetProcess()->ResumeRequestsForView(
1346        main_frame_route_id);
1347    return;
1348  }
1349
1350  // Create the new web contents. This will automatically create the new
1351  // WebContentsView. In the future, we may want to create the view separately.
1352  WebContentsImpl* new_contents =
1353      new WebContentsImpl(GetBrowserContext(),
1354                          params.opener_suppressed ? NULL : this);
1355
1356  new_contents->GetController().SetSessionStorageNamespace(
1357      partition_id,
1358      session_storage_namespace);
1359  CreateParams create_params(GetBrowserContext(), site_instance.get());
1360  create_params.routing_id = route_id;
1361  create_params.main_frame_routing_id = main_frame_route_id;
1362  if (!is_guest) {
1363    create_params.context = view_->GetNativeView();
1364    create_params.initial_size = view_->GetContainerSize();
1365  } else {
1366    // This makes |new_contents| act as a guest.
1367    // For more info, see comment above class BrowserPluginGuest.
1368    int instance_id = GetBrowserPluginGuestManager()->get_next_instance_id();
1369    WebContentsImpl* new_contents_impl =
1370        static_cast<WebContentsImpl*>(new_contents);
1371    BrowserPluginGuest::CreateWithOpener(instance_id,
1372                                         new_contents_impl->opener() != NULL,
1373                                         new_contents_impl,
1374                                         GetBrowserPluginGuest());
1375  }
1376  if (params.disposition == NEW_BACKGROUND_TAB)
1377    create_params.initially_hidden = true;
1378  new_contents->Init(create_params);
1379
1380  // Save the window for later if we're not suppressing the opener (since it
1381  // will be shown immediately).
1382  if (!params.opener_suppressed) {
1383    if (!is_guest) {
1384      WebContentsViewPort* new_view = new_contents->view_.get();
1385
1386      // TODO(brettw): It seems bogus that we have to call this function on the
1387      // newly created object and give it one of its own member variables.
1388      new_view->CreateViewForWidget(new_contents->GetRenderViewHost());
1389    }
1390    // Save the created window associated with the route so we can show it
1391    // later.
1392    DCHECK_NE(MSG_ROUTING_NONE, route_id);
1393    pending_contents_[route_id] = new_contents;
1394    AddDestructionObserver(new_contents);
1395  }
1396
1397  if (delegate_) {
1398    delegate_->WebContentsCreated(
1399        this, params.opener_frame_id, params.frame_name,
1400        params.target_url, new_contents);
1401  }
1402
1403  if (params.opener_suppressed) {
1404    // When the opener is suppressed, the original renderer cannot access the
1405    // new window.  As a result, we need to show and navigate the window here.
1406    bool was_blocked = false;
1407    if (delegate_) {
1408      gfx::Rect initial_pos;
1409      delegate_->AddNewContents(
1410          this, new_contents, params.disposition, initial_pos,
1411          params.user_gesture, &was_blocked);
1412    }
1413    if (!was_blocked) {
1414      OpenURLParams open_params(params.target_url,
1415                                Referrer(),
1416                                CURRENT_TAB,
1417                                PAGE_TRANSITION_LINK,
1418                                true /* is_renderer_initiated */);
1419      open_params.user_gesture = params.user_gesture;
1420      new_contents->OpenURL(open_params);
1421    }
1422  }
1423}
1424
1425void WebContentsImpl::CreateNewWidget(int render_process_id,
1426                                      int route_id,
1427                                      blink::WebPopupType popup_type) {
1428  CreateNewWidget(render_process_id, route_id, false, popup_type);
1429}
1430
1431void WebContentsImpl::CreateNewFullscreenWidget(int render_process_id,
1432                                                int route_id) {
1433  CreateNewWidget(render_process_id, route_id, true, blink::WebPopupTypeNone);
1434}
1435
1436void WebContentsImpl::CreateNewWidget(int render_process_id,
1437                                      int route_id,
1438                                      bool is_fullscreen,
1439                                      blink::WebPopupType popup_type) {
1440  RenderProcessHost* process = GetRenderProcessHost();
1441  // A message to create a new widget can only come from the active process for
1442  // this WebContentsImpl instance. If any other process sends the request,
1443  // it is invalid and the process must be terminated.
1444  if (process->GetID() != render_process_id) {
1445    base::ProcessHandle process_handle =
1446        RenderProcessHost::FromID(render_process_id)->GetHandle();
1447    if (process_handle != base::kNullProcessHandle) {
1448      RecordAction(
1449          base::UserMetricsAction("Terminate_ProcessMismatch_CreateNewWidget"));
1450      base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false);
1451    }
1452    return;
1453  }
1454
1455  RenderWidgetHostImpl* widget_host =
1456      new RenderWidgetHostImpl(this, process, route_id, IsHidden());
1457  created_widgets_.insert(widget_host);
1458
1459  RenderWidgetHostViewPort* widget_view = RenderWidgetHostViewPort::FromRWHV(
1460      view_->CreateViewForPopupWidget(widget_host));
1461  if (!widget_view)
1462    return;
1463  if (!is_fullscreen) {
1464    // Popups should not get activated.
1465    widget_view->SetPopupType(popup_type);
1466  }
1467  // Save the created widget associated with the route so we can show it later.
1468  pending_widget_views_[route_id] = widget_view;
1469
1470#if defined(OS_MACOSX)
1471  // A RenderWidgetHostViewMac has lifetime scoped to the view. We'll retain it
1472  // to allow it to survive the trip without being hosted.
1473  base::mac::NSObjectRetain(widget_view->GetNativeView());
1474#endif
1475}
1476
1477void WebContentsImpl::ShowCreatedWindow(int route_id,
1478                                        WindowOpenDisposition disposition,
1479                                        const gfx::Rect& initial_pos,
1480                                        bool user_gesture) {
1481  WebContentsImpl* contents = GetCreatedWindow(route_id);
1482  if (contents) {
1483    WebContentsDelegate* delegate = GetDelegate();
1484    if (delegate) {
1485      delegate->AddNewContents(
1486          this, contents, disposition, initial_pos, user_gesture, NULL);
1487    }
1488  }
1489}
1490
1491void WebContentsImpl::ShowCreatedWidget(int route_id,
1492                                        const gfx::Rect& initial_pos) {
1493  ShowCreatedWidget(route_id, false, initial_pos);
1494}
1495
1496void WebContentsImpl::ShowCreatedFullscreenWidget(int route_id) {
1497  ShowCreatedWidget(route_id, true, gfx::Rect());
1498}
1499
1500void WebContentsImpl::ShowCreatedWidget(int route_id,
1501                                        bool is_fullscreen,
1502                                        const gfx::Rect& initial_pos) {
1503  RenderWidgetHostViewPort* widget_host_view =
1504      RenderWidgetHostViewPort::FromRWHV(GetCreatedWidget(route_id));
1505  if (!widget_host_view)
1506    return;
1507  if (is_fullscreen) {
1508    DCHECK_EQ(MSG_ROUTING_NONE, fullscreen_widget_routing_id_);
1509    fullscreen_widget_routing_id_ = route_id;
1510    if (delegate_ && delegate_->EmbedsFullscreenWidget()) {
1511      widget_host_view->InitAsChild(GetRenderWidgetHostView()->GetNativeView());
1512      delegate_->ToggleFullscreenModeForTab(this, true);
1513    } else {
1514      widget_host_view->InitAsFullscreen(GetRenderWidgetHostViewPort());
1515    }
1516    FOR_EACH_OBSERVER(WebContentsObserver,
1517                      observers_,
1518                      DidShowFullscreenWidget(route_id));
1519    if (!widget_host_view->HasFocus())
1520      widget_host_view->Focus();
1521  } else {
1522    widget_host_view->InitAsPopup(GetRenderWidgetHostViewPort(), initial_pos);
1523  }
1524
1525  RenderWidgetHostImpl* render_widget_host_impl =
1526      RenderWidgetHostImpl::From(widget_host_view->GetRenderWidgetHost());
1527  render_widget_host_impl->Init();
1528  // Only allow privileged mouse lock for fullscreen render widget, which is
1529  // used to implement Pepper Flash fullscreen.
1530  render_widget_host_impl->set_allow_privileged_mouse_lock(is_fullscreen);
1531
1532#if defined(OS_MACOSX)
1533  // A RenderWidgetHostViewMac has lifetime scoped to the view. Now that it's
1534  // properly embedded (or purposefully ignored) we can release the retain we
1535  // took in CreateNewWidget().
1536  base::mac::NSObjectRelease(widget_host_view->GetNativeView());
1537#endif
1538}
1539
1540WebContentsImpl* WebContentsImpl::GetCreatedWindow(int route_id) {
1541  PendingContents::iterator iter = pending_contents_.find(route_id);
1542
1543  // Certain systems can block the creation of new windows. If we didn't succeed
1544  // in creating one, just return NULL.
1545  if (iter == pending_contents_.end()) {
1546    return NULL;
1547  }
1548
1549  WebContentsImpl* new_contents = iter->second;
1550  pending_contents_.erase(route_id);
1551  RemoveDestructionObserver(new_contents);
1552
1553  // Don't initialize the guest WebContents immediately.
1554  if (new_contents->GetRenderProcessHost()->IsGuest())
1555    return new_contents;
1556
1557  if (!new_contents->GetRenderProcessHost()->HasConnection() ||
1558      !new_contents->GetRenderViewHost()->GetView())
1559    return NULL;
1560
1561  // TODO(brettw): It seems bogus to reach into here and initialize the host.
1562  static_cast<RenderViewHostImpl*>(new_contents->GetRenderViewHost())->Init();
1563  return new_contents;
1564}
1565
1566RenderWidgetHostView* WebContentsImpl::GetCreatedWidget(int route_id) {
1567  PendingWidgetViews::iterator iter = pending_widget_views_.find(route_id);
1568  if (iter == pending_widget_views_.end()) {
1569    DCHECK(false);
1570    return NULL;
1571  }
1572
1573  RenderWidgetHostView* widget_host_view = iter->second;
1574  pending_widget_views_.erase(route_id);
1575
1576  RenderWidgetHost* widget_host = widget_host_view->GetRenderWidgetHost();
1577  if (!widget_host->GetProcess()->HasConnection()) {
1578    // The view has gone away or the renderer crashed. Nothing to do.
1579    return NULL;
1580  }
1581
1582  return widget_host_view;
1583}
1584
1585void WebContentsImpl::RequestMediaAccessPermission(
1586    const MediaStreamRequest& request,
1587    const MediaResponseCallback& callback) {
1588  if (delegate_) {
1589    delegate_->RequestMediaAccessPermission(this, request, callback);
1590  } else {
1591    callback.Run(MediaStreamDevices(),
1592                 MEDIA_DEVICE_INVALID_STATE,
1593                 scoped_ptr<MediaStreamUI>());
1594  }
1595}
1596
1597SessionStorageNamespace* WebContentsImpl::GetSessionStorageNamespace(
1598    SiteInstance* instance) {
1599  return controller_.GetSessionStorageNamespace(instance);
1600}
1601
1602FrameTree* WebContentsImpl::GetFrameTree() {
1603  return &frame_tree_;
1604}
1605
1606void WebContentsImpl::AccessibilityEventReceived(
1607    const std::vector<AXEventNotificationDetails>& details) {
1608  FOR_EACH_OBSERVER(
1609      WebContentsObserver, observers_, AccessibilityEventReceived(details));
1610}
1611
1612void WebContentsImpl::OnShowValidationMessage(
1613    const gfx::Rect& anchor_in_root_view,
1614    const base::string16& main_text,
1615    const base::string16& sub_text) {
1616  if (delegate_)
1617    delegate_->ShowValidationMessage(
1618        this, anchor_in_root_view, main_text, sub_text);
1619}
1620
1621void WebContentsImpl::OnHideValidationMessage() {
1622  if (delegate_)
1623    delegate_->HideValidationMessage(this);
1624}
1625
1626void WebContentsImpl::OnMoveValidationMessage(
1627    const gfx::Rect& anchor_in_root_view) {
1628  if (delegate_)
1629    delegate_->MoveValidationMessage(this, anchor_in_root_view);
1630}
1631
1632void WebContentsImpl::DidSendScreenRects(RenderWidgetHostImpl* rwh) {
1633  if (browser_plugin_embedder_)
1634    browser_plugin_embedder_->DidSendScreenRects();
1635}
1636
1637void WebContentsImpl::UpdatePreferredSize(const gfx::Size& pref_size) {
1638  const gfx::Size old_size = GetPreferredSize();
1639  preferred_size_ = pref_size;
1640  OnPreferredSizeChanged(old_size);
1641}
1642
1643void WebContentsImpl::ResizeDueToAutoResize(const gfx::Size& new_size) {
1644  if (delegate_)
1645    delegate_->ResizeDueToAutoResize(this, new_size);
1646}
1647
1648WebContents* WebContentsImpl::OpenURL(const OpenURLParams& params) {
1649  if (!delegate_)
1650    return NULL;
1651
1652  WebContents* new_contents = delegate_->OpenURLFromTab(this, params);
1653  return new_contents;
1654}
1655
1656bool WebContentsImpl::Send(IPC::Message* message) {
1657  if (!GetRenderViewHost()) {
1658    delete message;
1659    return false;
1660  }
1661
1662  return GetRenderViewHost()->Send(message);
1663}
1664
1665bool WebContentsImpl::NavigateToPendingEntry(
1666    NavigationController::ReloadType reload_type) {
1667  return frame_tree_.root()->navigator()->NavigateToPendingEntry(
1668      frame_tree_.GetMainFrame(), reload_type);
1669}
1670
1671void WebContentsImpl::RenderFrameForInterstitialPageCreated(
1672    RenderFrameHost* render_frame_host) {
1673  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
1674                    RenderFrameForInterstitialPageCreated(render_frame_host));
1675}
1676
1677void WebContentsImpl::AttachInterstitialPage(
1678    InterstitialPageImpl* interstitial_page) {
1679  DCHECK(interstitial_page);
1680  GetRenderManager()->set_interstitial_page(interstitial_page);
1681
1682  // Cancel any visible dialogs so that they don't interfere with the
1683  // interstitial.
1684  if (dialog_manager_)
1685    dialog_manager_->CancelActiveAndPendingDialogs(this);
1686
1687  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
1688                    DidAttachInterstitialPage());
1689}
1690
1691void WebContentsImpl::DetachInterstitialPage() {
1692  if (GetInterstitialPage())
1693    GetRenderManager()->remove_interstitial_page();
1694  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
1695                    DidDetachInterstitialPage());
1696}
1697
1698void WebContentsImpl::SetHistoryLengthAndPrune(
1699    const SiteInstance* site_instance,
1700    int history_length,
1701    int32 minimum_page_id) {
1702  // SetHistoryLengthAndPrune doesn't work when there are pending cross-site
1703  // navigations. Callers should ensure that this is the case.
1704  if (GetRenderManager()->pending_render_view_host()) {
1705    NOTREACHED();
1706    return;
1707  }
1708  RenderViewHostImpl* rvh = GetRenderViewHostImpl();
1709  if (!rvh) {
1710    NOTREACHED();
1711    return;
1712  }
1713  if (site_instance && rvh->GetSiteInstance() != site_instance) {
1714    NOTREACHED();
1715    return;
1716  }
1717  Send(new ViewMsg_SetHistoryLengthAndPrune(GetRoutingID(),
1718                                            history_length,
1719                                            minimum_page_id));
1720}
1721
1722void WebContentsImpl::FocusThroughTabTraversal(bool reverse) {
1723  if (ShowingInterstitialPage()) {
1724    GetRenderManager()->interstitial_page()->FocusThroughTabTraversal(reverse);
1725    return;
1726  }
1727  GetRenderViewHostImpl()->SetInitialFocus(reverse);
1728}
1729
1730bool WebContentsImpl::ShowingInterstitialPage() const {
1731  return GetRenderManager()->interstitial_page() != NULL;
1732}
1733
1734InterstitialPage* WebContentsImpl::GetInterstitialPage() const {
1735  return GetRenderManager()->interstitial_page();
1736}
1737
1738bool WebContentsImpl::IsSavable() {
1739  // WebKit creates Document object when MIME type is application/xhtml+xml,
1740  // so we also support this MIME type.
1741  return contents_mime_type_ == "text/html" ||
1742         contents_mime_type_ == "text/xml" ||
1743         contents_mime_type_ == "application/xhtml+xml" ||
1744         contents_mime_type_ == "text/plain" ||
1745         contents_mime_type_ == "text/css" ||
1746         net::IsSupportedJavascriptMimeType(contents_mime_type_.c_str());
1747}
1748
1749void WebContentsImpl::OnSavePage() {
1750  // If we can not save the page, try to download it.
1751  if (!IsSavable()) {
1752    RecordDownloadSource(INITIATED_BY_SAVE_PACKAGE_ON_NON_HTML);
1753    SaveFrame(GetURL(), Referrer());
1754    return;
1755  }
1756
1757  Stop();
1758
1759  // Create the save package and possibly prompt the user for the name to save
1760  // the page as. The user prompt is an asynchronous operation that runs on
1761  // another thread.
1762  save_package_ = new SavePackage(this);
1763  save_package_->GetSaveInfo();
1764}
1765
1766// Used in automated testing to bypass prompting the user for file names.
1767// Instead, the names and paths are hard coded rather than running them through
1768// file name sanitation and extension / mime checking.
1769bool WebContentsImpl::SavePage(const base::FilePath& main_file,
1770                               const base::FilePath& dir_path,
1771                               SavePageType save_type) {
1772  // Stop the page from navigating.
1773  Stop();
1774
1775  save_package_ = new SavePackage(this, save_type, main_file, dir_path);
1776  return save_package_->Init(SavePackageDownloadCreatedCallback());
1777}
1778
1779void WebContentsImpl::SaveFrame(const GURL& url,
1780                                const Referrer& referrer) {
1781  if (!GetURL().is_valid())
1782    return;
1783  bool is_main_frame = (url == GetURL());
1784
1785  DownloadManager* dlm =
1786      BrowserContext::GetDownloadManager(GetBrowserContext());
1787  if (!dlm)
1788    return;
1789  int64 post_id = -1;
1790  if (is_main_frame) {
1791    const NavigationEntry* entry = controller_.GetLastCommittedEntry();
1792    if (entry)
1793      post_id = entry->GetPostID();
1794  }
1795  scoped_ptr<DownloadUrlParameters> params(
1796      DownloadUrlParameters::FromWebContents(this, url));
1797  params->set_referrer(referrer);
1798  params->set_post_id(post_id);
1799  params->set_prefer_cache(true);
1800  if (post_id >= 0)
1801    params->set_method("POST");
1802  params->set_prompt(true);
1803  dlm->DownloadUrl(params.Pass());
1804}
1805
1806void WebContentsImpl::GenerateMHTML(
1807    const base::FilePath& file,
1808    const base::Callback<void(int64)>& callback) {
1809  MHTMLGenerationManager::GetInstance()->SaveMHTML(this, file, callback);
1810}
1811
1812// TODO(nasko): Rename this method to IsVisibleEntry.
1813bool WebContentsImpl::IsActiveEntry(int32 page_id) {
1814  NavigationEntryImpl* visible_entry =
1815      NavigationEntryImpl::FromNavigationEntry(controller_.GetVisibleEntry());
1816  return (visible_entry != NULL &&
1817          visible_entry->site_instance() == GetSiteInstance() &&
1818          visible_entry->GetPageID() == page_id);
1819}
1820
1821const std::string& WebContentsImpl::GetContentsMimeType() const {
1822  return contents_mime_type_;
1823}
1824
1825bool WebContentsImpl::WillNotifyDisconnection() const {
1826  return notify_disconnection_;
1827}
1828
1829void WebContentsImpl::SetOverrideEncoding(const std::string& encoding) {
1830  SetEncoding(encoding);
1831  Send(new ViewMsg_SetPageEncoding(GetRoutingID(), encoding));
1832}
1833
1834void WebContentsImpl::ResetOverrideEncoding() {
1835  encoding_.clear();
1836  Send(new ViewMsg_ResetPageEncodingToDefault(GetRoutingID()));
1837}
1838
1839RendererPreferences* WebContentsImpl::GetMutableRendererPrefs() {
1840  return &renderer_preferences_;
1841}
1842
1843void WebContentsImpl::Close() {
1844  Close(GetRenderViewHost());
1845}
1846
1847void WebContentsImpl::DragSourceEndedAt(int client_x, int client_y,
1848    int screen_x, int screen_y, blink::WebDragOperation operation) {
1849  if (browser_plugin_embedder_.get())
1850    browser_plugin_embedder_->DragSourceEndedAt(client_x, client_y,
1851        screen_x, screen_y, operation);
1852  if (GetRenderViewHost())
1853    GetRenderViewHostImpl()->DragSourceEndedAt(client_x, client_y,
1854        screen_x, screen_y, operation);
1855}
1856
1857void WebContentsImpl::DragSourceMovedTo(int client_x, int client_y,
1858                                        int screen_x, int screen_y) {
1859  if (browser_plugin_embedder_.get())
1860    browser_plugin_embedder_->DragSourceMovedTo(client_x, client_y,
1861                                                screen_x, screen_y);
1862  if (GetRenderViewHost())
1863    GetRenderViewHostImpl()->DragSourceMovedTo(client_x, client_y,
1864                                               screen_x, screen_y);
1865}
1866
1867void WebContentsImpl::DidGetResourceResponseStart(
1868  const ResourceRequestDetails& details) {
1869  controller_.ssl_manager()->DidStartResourceResponse(details);
1870
1871  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
1872                    DidGetResourceResponseStart(details));
1873
1874  // TODO(avi): Remove. http://crbug.com/170921
1875  NotificationService::current()->Notify(
1876      NOTIFICATION_RESOURCE_RESPONSE_STARTED,
1877      Source<WebContents>(this),
1878      Details<const ResourceRequestDetails>(&details));
1879}
1880
1881void WebContentsImpl::DidGetRedirectForResourceRequest(
1882  RenderViewHost* render_view_host,
1883  const ResourceRedirectDetails& details) {
1884  controller_.ssl_manager()->DidReceiveResourceRedirect(details);
1885
1886  FOR_EACH_OBSERVER(
1887      WebContentsObserver,
1888      observers_,
1889      DidGetRedirectForResourceRequest(render_view_host, details));
1890
1891  // TODO(avi): Remove. http://crbug.com/170921
1892  NotificationService::current()->Notify(
1893      NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
1894      Source<WebContents>(this),
1895      Details<const ResourceRedirectDetails>(&details));
1896}
1897
1898void WebContentsImpl::SystemDragEnded() {
1899  if (GetRenderViewHost())
1900    GetRenderViewHostImpl()->DragSourceSystemDragEnded();
1901  if (delegate_)
1902    delegate_->DragEnded();
1903  if (browser_plugin_embedder_.get())
1904    browser_plugin_embedder_->SystemDragEnded();
1905}
1906
1907void WebContentsImpl::UserGestureDone() {
1908  OnUserGesture();
1909}
1910
1911void WebContentsImpl::SetClosedByUserGesture(bool value) {
1912  closed_by_user_gesture_ = value;
1913}
1914
1915bool WebContentsImpl::GetClosedByUserGesture() const {
1916  return closed_by_user_gesture_;
1917}
1918
1919double WebContentsImpl::GetZoomLevel() const {
1920  HostZoomMapImpl* zoom_map = static_cast<HostZoomMapImpl*>(
1921      HostZoomMap::GetForBrowserContext(GetBrowserContext()));
1922  if (!zoom_map)
1923    return 0;
1924
1925  double zoom_level;
1926  if (temporary_zoom_settings_) {
1927    zoom_level = zoom_map->GetTemporaryZoomLevel(
1928        GetRenderProcessHost()->GetID(), GetRenderViewHost()->GetRoutingID());
1929  } else {
1930    GURL url;
1931    NavigationEntry* entry = GetController().GetLastCommittedEntry();
1932    // Since zoom map is updated using rewritten URL, use rewritten URL
1933    // to get the zoom level.
1934    url = entry ? entry->GetURL() : GURL::EmptyGURL();
1935    zoom_level = zoom_map->GetZoomLevelForHostAndScheme(url.scheme(),
1936        net::GetHostOrSpecFromURL(url));
1937  }
1938  return zoom_level;
1939}
1940
1941int WebContentsImpl::GetZoomPercent(bool* enable_increment,
1942                                    bool* enable_decrement) const {
1943  *enable_decrement = *enable_increment = false;
1944  // Calculate the zoom percent from the factor. Round up to the nearest whole
1945  // number.
1946  int percent = static_cast<int>(
1947      ZoomLevelToZoomFactor(GetZoomLevel()) * 100 + 0.5);
1948  *enable_decrement = percent > minimum_zoom_percent_;
1949  *enable_increment = percent < maximum_zoom_percent_;
1950  return percent;
1951}
1952
1953void WebContentsImpl::ViewSource() {
1954  if (!delegate_)
1955    return;
1956
1957  NavigationEntry* entry = GetController().GetLastCommittedEntry();
1958  if (!entry)
1959    return;
1960
1961  delegate_->ViewSourceForTab(this, entry->GetURL());
1962}
1963
1964void WebContentsImpl::ViewFrameSource(const GURL& url,
1965                                      const PageState& page_state) {
1966  if (!delegate_)
1967    return;
1968
1969  delegate_->ViewSourceForFrame(this, url, page_state);
1970}
1971
1972int WebContentsImpl::GetMinimumZoomPercent() const {
1973  return minimum_zoom_percent_;
1974}
1975
1976int WebContentsImpl::GetMaximumZoomPercent() const {
1977  return maximum_zoom_percent_;
1978}
1979
1980gfx::Size WebContentsImpl::GetPreferredSize() const {
1981  return capturer_count_ == 0 ? preferred_size_ : preferred_size_for_capture_;
1982}
1983
1984bool WebContentsImpl::GotResponseToLockMouseRequest(bool allowed) {
1985  return GetRenderViewHost() ?
1986      GetRenderViewHostImpl()->GotResponseToLockMouseRequest(allowed) : false;
1987}
1988
1989bool WebContentsImpl::HasOpener() const {
1990  return opener_ != NULL;
1991}
1992
1993void WebContentsImpl::DidChooseColorInColorChooser(SkColor color) {
1994  Send(new ViewMsg_DidChooseColorResponse(
1995      GetRoutingID(), color_chooser_identifier_, color));
1996}
1997
1998void WebContentsImpl::DidEndColorChooser() {
1999  Send(new ViewMsg_DidEndColorChooser(GetRoutingID(),
2000                                      color_chooser_identifier_));
2001  color_chooser_.reset();
2002  color_chooser_identifier_ = 0;
2003}
2004
2005int WebContentsImpl::DownloadImage(const GURL& url,
2006                                   bool is_favicon,
2007                                   uint32_t max_bitmap_size,
2008                                   const ImageDownloadCallback& callback) {
2009  RenderViewHost* host = GetRenderViewHost();
2010  int id = StartDownload(host, url, is_favicon, max_bitmap_size);
2011  image_download_map_[id] = callback;
2012  return id;
2013}
2014
2015bool WebContentsImpl::IsSubframe() const {
2016  return is_subframe_;
2017}
2018
2019void WebContentsImpl::SetZoomLevel(double level) {
2020  Send(new ViewMsg_SetZoomLevel(GetRoutingID(), level));
2021  BrowserPluginEmbedder* embedder = GetBrowserPluginEmbedder();
2022  if (embedder)
2023    embedder->SetZoomLevel(level);
2024}
2025
2026void WebContentsImpl::Find(int request_id,
2027                           const base::string16& search_text,
2028                           const blink::WebFindOptions& options) {
2029  Send(new ViewMsg_Find(GetRoutingID(), request_id, search_text, options));
2030}
2031
2032void WebContentsImpl::StopFinding(StopFindAction action) {
2033  Send(new ViewMsg_StopFinding(GetRoutingID(), action));
2034}
2035
2036bool WebContentsImpl::FocusLocationBarByDefault() {
2037  NavigationEntry* entry = controller_.GetVisibleEntry();
2038  if (entry && entry->GetURL() == GURL(kAboutBlankURL))
2039    return true;
2040  return delegate_ && delegate_->ShouldFocusLocationBarByDefault(this);
2041}
2042
2043void WebContentsImpl::SetFocusToLocationBar(bool select_all) {
2044  if (delegate_)
2045    delegate_->SetFocusToLocationBar(select_all);
2046}
2047
2048void WebContentsImpl::DidStartProvisionalLoad(
2049    RenderFrameHostImpl* render_frame_host,
2050    int parent_routing_id,
2051    bool is_main_frame,
2052    const GURL& validated_url,
2053    bool is_error_page,
2054    bool is_iframe_srcdoc) {
2055  if (is_main_frame)
2056    DidChangeLoadProgress(0);
2057
2058  // --site-per-process mode has a short-term hack allowing cross-process
2059  // subframe pages to commit thinking they are top-level.  Correct it here to
2060  // avoid confusing the observers.
2061  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) &&
2062      render_frame_host != GetMainFrame()) {
2063    is_main_frame = false;
2064  }
2065
2066  // Notify observers about the start of the provisional load.
2067  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2068                    DidStartProvisionalLoadForFrame(
2069                        render_frame_host->GetRoutingID(), parent_routing_id,
2070                        is_main_frame, validated_url, is_error_page,
2071                        is_iframe_srcdoc,
2072                        render_frame_host->render_view_host()));
2073
2074  if (is_main_frame) {
2075    FOR_EACH_OBSERVER(
2076        WebContentsObserver,
2077        observers_,
2078        ProvisionalChangeToMainFrameUrl(validated_url,
2079                                        render_frame_host));
2080  }
2081}
2082
2083void WebContentsImpl::DidFailProvisionalLoadWithError(
2084    RenderFrameHostImpl* render_frame_host,
2085    const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) {
2086  GURL validated_url(params.url);
2087  FOR_EACH_OBSERVER(
2088      WebContentsObserver,
2089      observers_,
2090      DidFailProvisionalLoad(render_frame_host->GetRoutingID(),
2091                             params.frame_unique_name,
2092                             params.is_main_frame,
2093                             validated_url,
2094                             params.error_code,
2095                             params.error_description,
2096                             render_frame_host->render_view_host()));
2097}
2098
2099void WebContentsImpl::DidFailLoadWithError(
2100    RenderFrameHostImpl* render_frame_host,
2101    const GURL& url,
2102    bool is_main_frame,
2103    int error_code,
2104    const base::string16& error_description) {
2105  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2106                    DidFailLoad(render_frame_host->GetRoutingID(),
2107                                url, is_main_frame,
2108                                error_code, error_description,
2109                                render_frame_host->render_view_host()));
2110}
2111
2112void WebContentsImpl::NotifyChangedNavigationState(
2113    InvalidateTypes changed_flags) {
2114  NotifyNavigationStateChanged(changed_flags);
2115}
2116
2117void WebContentsImpl::AboutToNavigateRenderFrame(
2118      RenderFrameHostImpl* render_frame_host) {
2119  // Notify observers that we will navigate in this RenderView.
2120  FOR_EACH_OBSERVER(
2121      WebContentsObserver,
2122      observers_,
2123      AboutToNavigateRenderView(render_frame_host->render_view_host()));
2124}
2125
2126void WebContentsImpl::DidStartNavigationToPendingEntry(
2127      RenderFrameHostImpl* render_frame_host,
2128      const GURL& url,
2129      NavigationController::ReloadType reload_type) {
2130  // Notify observers about navigation.
2131  FOR_EACH_OBSERVER(
2132      WebContentsObserver,
2133      observers_,
2134      DidStartNavigationToPendingEntry(url, reload_type));
2135}
2136
2137void WebContentsImpl::RequestOpenURL(RenderFrameHostImpl* render_frame_host,
2138                                     const OpenURLParams& params) {
2139  int source_render_frame_id = render_frame_host->GetRoutingID();
2140  WebContents* new_contents = OpenURL(params);
2141
2142  if (new_contents) {
2143    // Notify observers.
2144    FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2145                      DidOpenRequestedURL(new_contents,
2146                                          params.url,
2147                                          params.referrer,
2148                                          params.disposition,
2149                                          params.transition,
2150                                          source_render_frame_id));
2151  }
2152}
2153
2154void WebContentsImpl::DidRedirectProvisionalLoad(
2155    RenderFrameHostImpl* render_frame_host,
2156    const GURL& validated_target_url) {
2157  // Notify observers about the provisional change in the main frame URL.
2158  FOR_EACH_OBSERVER(
2159      WebContentsObserver,
2160      observers_,
2161      ProvisionalChangeToMainFrameUrl(validated_target_url,
2162                                      render_frame_host));
2163}
2164
2165void WebContentsImpl::DidCommitProvisionalLoad(
2166    RenderFrameHostImpl* render_frame_host,
2167    const base::string16& frame_unique_name,
2168    bool is_main_frame,
2169    const GURL& url,
2170    PageTransition transition_type) {
2171  RenderViewHost* render_view_host = render_frame_host->render_view_host();
2172  int render_frame_id = render_frame_host->GetRoutingID();
2173  // Notify observers about the commit of the provisional load.
2174  FOR_EACH_OBSERVER(
2175      WebContentsObserver,
2176      observers_,
2177      DidCommitProvisionalLoadForFrame(render_frame_id,
2178                                       frame_unique_name,
2179                                       is_main_frame,
2180                                       url,
2181                                       transition_type,
2182                                       render_view_host));
2183}
2184
2185void WebContentsImpl::DidNavigateMainFramePostCommit(
2186    const LoadCommittedDetails& details,
2187    const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
2188  if (details.is_navigation_to_different_page()) {
2189    // Clear the status bubble. This is a workaround for a bug where WebKit
2190    // doesn't let us know that the cursor left an element during a
2191    // transition (this is also why the mouse cursor remains as a hand after
2192    // clicking on a link); see bugs 1184641 and 980803. We don't want to
2193    // clear the bubble when a user navigates to a named anchor in the same
2194    // page.
2195    UpdateTargetURL(details.entry->GetPageID(), GURL());
2196  }
2197
2198  if (!details.is_in_page) {
2199    // Once the main frame is navigated, we're no longer considered to have
2200    // displayed insecure content.
2201    displayed_insecure_content_ = false;
2202    SSLManager::NotifySSLInternalStateChanged(
2203        GetController().GetBrowserContext());
2204  }
2205
2206  // Notify observers about navigation.
2207  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2208                    DidNavigateMainFrame(details, params));
2209
2210  if (delegate_) {
2211    delegate_->DidNavigateMainFramePostCommit(this);
2212    view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
2213  }
2214}
2215
2216void WebContentsImpl::DidNavigateAnyFramePostCommit(
2217    RenderFrameHostImpl* render_frame_host,
2218    const LoadCommittedDetails& details,
2219    const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
2220  // If we navigate off the page, close all JavaScript dialogs.
2221  if (dialog_manager_ && !details.is_in_page)
2222    dialog_manager_->CancelActiveAndPendingDialogs(this);
2223
2224  // Notify observers about navigation.
2225  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2226                    DidNavigateAnyFrame(details, params));
2227}
2228
2229void WebContentsImpl::SetMainFrameMimeType(const std::string& mime_type) {
2230  contents_mime_type_ = mime_type;
2231}
2232
2233bool WebContentsImpl::CanOverscrollContent() {
2234  if (delegate_)
2235    return delegate_->CanOverscrollContent();
2236
2237  return false;
2238}
2239
2240void WebContentsImpl::OnDidLoadResourceFromMemoryCache(
2241    const GURL& url,
2242    const std::string& security_info,
2243    const std::string& http_method,
2244    const std::string& mime_type,
2245    ResourceType::Type resource_type) {
2246  base::StatsCounter cache("WebKit.CacheHit");
2247  cache.Increment();
2248
2249  // Send out a notification that we loaded a resource from our memory cache.
2250  int cert_id = 0;
2251  net::CertStatus cert_status = 0;
2252  int security_bits = -1;
2253  int connection_status = 0;
2254  SignedCertificateTimestampIDStatusList signed_certificate_timestamp_ids;
2255  DeserializeSecurityInfo(security_info, &cert_id, &cert_status,
2256                          &security_bits, &connection_status,
2257                          &signed_certificate_timestamp_ids);
2258  // TODO(alcutter,eranm): Pass signed_certificate_timestamp_ids into details
2259  LoadFromMemoryCacheDetails details(
2260      url, GetRenderProcessHost()->GetID(), cert_id, cert_status, http_method,
2261      mime_type, resource_type);
2262
2263  controller_.ssl_manager()->DidLoadFromMemoryCache(details);
2264
2265  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2266                    DidLoadResourceFromMemoryCache(details));
2267
2268  if (url.is_valid() && url.SchemeIsHTTPOrHTTPS()) {
2269    scoped_refptr<net::URLRequestContextGetter> request_context(
2270        resource_type == ResourceType::MEDIA ?
2271            GetBrowserContext()->GetMediaRequestContextForRenderProcess(
2272                GetRenderProcessHost()->GetID()) :
2273            GetBrowserContext()->GetRequestContextForRenderProcess(
2274                GetRenderProcessHost()->GetID()));
2275    BrowserThread::PostTask(
2276        BrowserThread::IO,
2277        FROM_HERE,
2278        base::Bind(&NotifyCacheOnIO, request_context, url, http_method));
2279  }
2280}
2281
2282void WebContentsImpl::OnDidDisplayInsecureContent() {
2283  RecordAction(base::UserMetricsAction("SSL.DisplayedInsecureContent"));
2284  displayed_insecure_content_ = true;
2285  SSLManager::NotifySSLInternalStateChanged(
2286      GetController().GetBrowserContext());
2287}
2288
2289void WebContentsImpl::OnDidRunInsecureContent(
2290    const std::string& security_origin, const GURL& target_url) {
2291  LOG(WARNING) << security_origin << " ran insecure content from "
2292               << target_url.possibly_invalid_spec();
2293  RecordAction(base::UserMetricsAction("SSL.RanInsecureContent"));
2294  if (EndsWith(security_origin, kDotGoogleDotCom, false))
2295    RecordAction(base::UserMetricsAction("SSL.RanInsecureContentGoogle"));
2296  controller_.ssl_manager()->DidRunInsecureContent(security_origin);
2297  displayed_insecure_content_ = true;
2298  SSLManager::NotifySSLInternalStateChanged(
2299      GetController().GetBrowserContext());
2300}
2301
2302void WebContentsImpl::OnDocumentLoadedInFrame() {
2303  CHECK(render_frame_message_source_);
2304  CHECK(!render_view_message_source_);
2305  RenderFrameHostImpl* rfh =
2306      static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2307
2308  FOR_EACH_OBSERVER(WebContentsObserver,
2309                    observers_,
2310                    DocumentLoadedInFrame(rfh->GetRoutingID(),
2311                                          rfh->render_view_host()));
2312}
2313
2314void WebContentsImpl::OnDidFinishLoad(
2315    const GURL& url,
2316    bool is_main_frame) {
2317  if (!render_frame_message_source_) {
2318    RecordAction(base::UserMetricsAction("BadMessageTerminate_RVD2"));
2319    GetRenderProcessHost()->ReceivedBadMessage();
2320    return;
2321  }
2322
2323  RenderFrameHostImpl* rfh =
2324      static_cast<RenderFrameHostImpl*>(render_frame_message_source_);
2325
2326  // --site-per-process mode has a short-term hack allowing cross-process
2327  // subframe pages to commit thinking they are top-level.  Correct it here to
2328  // avoid confusing the observers.
2329  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) &&
2330      rfh != GetMainFrame()) {
2331    is_main_frame = false;
2332  }
2333
2334  GURL validated_url(url);
2335  RenderProcessHost* render_process_host =
2336      render_frame_message_source_->GetProcess();
2337  render_process_host->FilterURL(false, &validated_url);
2338
2339  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2340                    DidFinishLoad(rfh->GetRoutingID(), validated_url,
2341                                  is_main_frame, rfh->render_view_host()));
2342}
2343
2344void WebContentsImpl::OnGoToEntryAtOffset(int offset) {
2345  if (!delegate_ || delegate_->OnGoToEntryOffset(offset))
2346    controller_.GoToOffset(offset);
2347}
2348
2349void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent,
2350                                         int maximum_percent,
2351                                         bool remember) {
2352  minimum_zoom_percent_ = minimum_percent;
2353  maximum_zoom_percent_ = maximum_percent;
2354  temporary_zoom_settings_ = !remember;
2355}
2356
2357void WebContentsImpl::OnEnumerateDirectory(int request_id,
2358                                           const base::FilePath& path) {
2359  if (!delegate_)
2360    return;
2361
2362  ChildProcessSecurityPolicyImpl* policy =
2363      ChildProcessSecurityPolicyImpl::GetInstance();
2364  if (policy->CanReadFile(GetRenderProcessHost()->GetID(), path))
2365    delegate_->EnumerateDirectory(this, request_id, path);
2366}
2367
2368void WebContentsImpl::OnRegisterProtocolHandler(const std::string& protocol,
2369                                                const GURL& url,
2370                                                const base::string16& title,
2371                                                bool user_gesture) {
2372  if (!delegate_)
2373    return;
2374
2375  ChildProcessSecurityPolicyImpl* policy =
2376      ChildProcessSecurityPolicyImpl::GetInstance();
2377  if (policy->IsPseudoScheme(protocol))
2378    return;
2379
2380  delegate_->RegisterProtocolHandler(this, protocol, url, title, user_gesture);
2381}
2382
2383void WebContentsImpl::OnFindReply(int request_id,
2384                                  int number_of_matches,
2385                                  const gfx::Rect& selection_rect,
2386                                  int active_match_ordinal,
2387                                  bool final_update) {
2388  if (delegate_) {
2389    delegate_->FindReply(this, request_id, number_of_matches, selection_rect,
2390                         active_match_ordinal, final_update);
2391  }
2392}
2393
2394#if defined(OS_ANDROID)
2395void WebContentsImpl::OnFindMatchRectsReply(
2396    int version,
2397    const std::vector<gfx::RectF>& rects,
2398    const gfx::RectF& active_rect) {
2399  if (delegate_)
2400    delegate_->FindMatchRectsReply(this, version, rects, active_rect);
2401}
2402
2403void WebContentsImpl::OnOpenDateTimeDialog(
2404    const ViewHostMsg_DateTimeDialogValue_Params& value) {
2405  date_time_chooser_->ShowDialog(ContentViewCore::FromWebContents(this),
2406                                 GetRenderViewHost(),
2407                                 value.dialog_type,
2408                                 value.dialog_value,
2409                                 value.minimum,
2410                                 value.maximum,
2411                                 value.step,
2412                                 value.suggestions);
2413}
2414
2415void WebContentsImpl::OnJavaBridgeGetChannelHandle(IPC::Message* reply_msg) {
2416  java_bridge_dispatcher_host_manager_->OnGetChannelHandle(
2417      render_frame_message_source_, reply_msg);
2418}
2419
2420#endif
2421
2422void WebContentsImpl::OnPepperPluginHung(int plugin_child_id,
2423                                         const base::FilePath& path,
2424                                         bool is_hung) {
2425  UMA_HISTOGRAM_COUNTS("Pepper.PluginHung", 1);
2426
2427  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2428                    PluginHungStatusChanged(plugin_child_id, path, is_hung));
2429}
2430
2431void WebContentsImpl::OnPluginCrashed(const base::FilePath& plugin_path,
2432                                      base::ProcessId plugin_pid) {
2433  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2434                    PluginCrashed(plugin_path, plugin_pid));
2435}
2436
2437void WebContentsImpl::OnDomOperationResponse(const std::string& json_string,
2438                                             int automation_id) {
2439  DomOperationNotificationDetails details(json_string, automation_id);
2440  NotificationService::current()->Notify(
2441      NOTIFICATION_DOM_OPERATION_RESPONSE,
2442      Source<WebContents>(this),
2443      Details<DomOperationNotificationDetails>(&details));
2444}
2445
2446void WebContentsImpl::OnAppCacheAccessed(const GURL& manifest_url,
2447                                         bool blocked_by_policy) {
2448  // Notify observers about navigation.
2449  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2450                    AppCacheAccessed(manifest_url, blocked_by_policy));
2451}
2452
2453void WebContentsImpl::OnOpenColorChooser(
2454      int color_chooser_id,
2455      SkColor color,
2456      const std::vector<ColorSuggestion>& suggestions) {
2457  ColorChooser* new_color_chooser =
2458      delegate_->OpenColorChooser(this, color, suggestions);
2459  if (!new_color_chooser)
2460    return;
2461  if (color_chooser_)
2462    color_chooser_->End();
2463  color_chooser_.reset(new_color_chooser);
2464  color_chooser_identifier_ = color_chooser_id;
2465}
2466
2467void WebContentsImpl::OnEndColorChooser(int color_chooser_id) {
2468  if (color_chooser_ &&
2469      color_chooser_id == color_chooser_identifier_)
2470    color_chooser_->End();
2471}
2472
2473void WebContentsImpl::OnSetSelectedColorInColorChooser(int color_chooser_id,
2474                                                       SkColor color) {
2475  if (color_chooser_ &&
2476      color_chooser_id == color_chooser_identifier_)
2477    color_chooser_->SetSelectedColor(color);
2478}
2479
2480// This exists for render views that don't have a WebUI, but do have WebUI
2481// bindings enabled.
2482void WebContentsImpl::OnWebUISend(const GURL& source_url,
2483                                  const std::string& name,
2484                                  const base::ListValue& args) {
2485  if (delegate_)
2486    delegate_->WebUISend(this, source_url, name, args);
2487}
2488
2489void WebContentsImpl::OnRequestPpapiBrokerPermission(
2490    int routing_id,
2491    const GURL& url,
2492    const base::FilePath& plugin_path) {
2493  if (!delegate_) {
2494    OnPpapiBrokerPermissionResult(routing_id, false);
2495    return;
2496  }
2497
2498  if (!delegate_->RequestPpapiBrokerPermission(
2499      this, url, plugin_path,
2500      base::Bind(&WebContentsImpl::OnPpapiBrokerPermissionResult,
2501                 base::Unretained(this), routing_id))) {
2502    NOTIMPLEMENTED();
2503    OnPpapiBrokerPermissionResult(routing_id, false);
2504  }
2505}
2506
2507void WebContentsImpl::OnPpapiBrokerPermissionResult(int routing_id,
2508                                                    bool result) {
2509  Send(new ViewMsg_PpapiBrokerPermissionResult(routing_id, result));
2510}
2511
2512void WebContentsImpl::OnBrowserPluginMessage(const IPC::Message& message) {
2513  // This creates a BrowserPluginEmbedder, which handles all the BrowserPlugin
2514  // specific messages for this WebContents. This means that any message from
2515  // a BrowserPlugin prior to this will be ignored.
2516  // For more info, see comment above classes BrowserPluginEmbedder and
2517  // BrowserPluginGuest.
2518  CHECK(!browser_plugin_embedder_.get());
2519  browser_plugin_embedder_.reset(BrowserPluginEmbedder::Create(this));
2520  browser_plugin_embedder_->OnMessageReceived(message);
2521}
2522
2523void WebContentsImpl::OnDidDownloadImage(
2524    int id,
2525    int http_status_code,
2526    const GURL& image_url,
2527    const std::vector<SkBitmap>& bitmaps,
2528    const std::vector<gfx::Size>& original_bitmap_sizes) {
2529  if (bitmaps.size() != original_bitmap_sizes.size())
2530    return;
2531
2532  ImageDownloadMap::iterator iter = image_download_map_.find(id);
2533  if (iter == image_download_map_.end()) {
2534    // Currently WebContents notifies us of ANY downloads so that it is
2535    // possible to get here.
2536    return;
2537  }
2538  if (!iter->second.is_null()) {
2539    iter->second.Run(
2540        id, http_status_code, image_url, bitmaps, original_bitmap_sizes);
2541  }
2542  image_download_map_.erase(id);
2543}
2544
2545void WebContentsImpl::OnUpdateFaviconURL(
2546    int32 page_id,
2547    const std::vector<FaviconURL>& candidates) {
2548  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2549                    DidUpdateFaviconURL(page_id, candidates));
2550}
2551
2552void WebContentsImpl::OnMediaPlayingNotification(int64 player_cookie,
2553                                                 bool has_video,
2554                                                 bool has_audio) {
2555// Chrome OS does its own detection of audio and video.
2556#if !defined(OS_CHROMEOS)
2557  scoped_ptr<PowerSaveBlocker> blocker;
2558  if (has_video) {
2559    blocker = PowerSaveBlocker::Create(
2560        PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, "Playing video");
2561#if defined(OS_ANDROID)
2562    static_cast<PowerSaveBlockerImpl*>(blocker.get())
2563        ->InitDisplaySleepBlocker(GetView()->GetNativeView());
2564#endif
2565  } else if (has_audio) {
2566    blocker = PowerSaveBlocker::Create(
2567        PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, "Playing audio");
2568  }
2569
2570  if (blocker) {
2571    power_save_blockers_[render_view_message_source_][player_cookie] =
2572        blocker.release();
2573  }
2574#endif  // !defined(OS_CHROMEOS)
2575}
2576
2577void WebContentsImpl::OnMediaPausedNotification(int64 player_cookie) {
2578  // Chrome OS does its own detection of audio and video.
2579#if !defined(OS_CHROMEOS)
2580  delete power_save_blockers_[render_view_message_source_][player_cookie];
2581  power_save_blockers_[render_view_message_source_].erase(player_cookie);
2582#endif  // !defined(OS_CHROMEOS)
2583}
2584
2585void WebContentsImpl::OnFirstVisuallyNonEmptyPaint(int32 page_id) {
2586  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2587                    DidFirstVisuallyNonEmptyPaint(page_id));
2588}
2589
2590void WebContentsImpl::DidChangeVisibleSSLState() {
2591  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2592                    DidChangeVisibleSSLState());
2593}
2594
2595void WebContentsImpl::NotifyBeforeFormRepostWarningShow() {
2596  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2597                    BeforeFormRepostWarningShow());
2598}
2599
2600
2601void WebContentsImpl::ActivateAndShowRepostFormWarningDialog() {
2602  Activate();
2603  if (delegate_)
2604    delegate_->ShowRepostFormWarningDialog(this);
2605}
2606
2607// Notifies the RenderWidgetHost instance about the fact that the page is
2608// loading, or done loading.
2609void WebContentsImpl::SetIsLoading(RenderViewHost* render_view_host,
2610                                   bool is_loading,
2611                                   LoadNotificationDetails* details) {
2612  if (is_loading == is_loading_)
2613    return;
2614
2615  if (!is_loading) {
2616    load_state_ = net::LoadStateWithParam(net::LOAD_STATE_IDLE,
2617                                          base::string16());
2618    load_state_host_.clear();
2619    upload_size_ = 0;
2620    upload_position_ = 0;
2621  }
2622
2623  GetRenderManager()->SetIsLoading(is_loading);
2624
2625  is_loading_ = is_loading;
2626  waiting_for_response_ = is_loading;
2627
2628  if (delegate_)
2629    delegate_->LoadingStateChanged(this);
2630  NotifyNavigationStateChanged(INVALIDATE_TYPE_LOAD);
2631
2632  std::string url = (details ? details->url.possibly_invalid_spec() : "NULL");
2633  if (is_loading) {
2634    TRACE_EVENT_ASYNC_BEGIN1("browser", "WebContentsImpl Loading", this,
2635                             "URL", url);
2636    FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2637                      DidStartLoading(render_view_host));
2638  } else {
2639    TRACE_EVENT_ASYNC_END1("browser", "WebContentsImpl Loading", this,
2640                           "URL", url);
2641    FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2642                      DidStopLoading(render_view_host));
2643  }
2644
2645  // TODO(avi): Remove. http://crbug.com/170921
2646  int type = is_loading ? NOTIFICATION_LOAD_START : NOTIFICATION_LOAD_STOP;
2647  NotificationDetails det = NotificationService::NoDetails();
2648  if (details)
2649      det = Details<LoadNotificationDetails>(details);
2650  NotificationService::current()->Notify(
2651      type, Source<NavigationController>(&controller_), det);
2652}
2653
2654void WebContentsImpl::UpdateMaxPageIDIfNecessary(RenderViewHost* rvh) {
2655  // If we are creating a RVH for a restored controller, then we need to make
2656  // sure the RenderView starts with a next_page_id_ larger than the number
2657  // of restored entries.  This must be called before the RenderView starts
2658  // navigating (to avoid a race between the browser updating max_page_id and
2659  // the renderer updating next_page_id_).  Because of this, we only call this
2660  // from CreateRenderView and allow that to notify the RenderView for us.
2661  int max_restored_page_id = controller_.GetMaxRestoredPageID();
2662  if (max_restored_page_id >
2663      GetMaxPageIDForSiteInstance(rvh->GetSiteInstance()))
2664    UpdateMaxPageIDForSiteInstance(rvh->GetSiteInstance(),
2665                                   max_restored_page_id);
2666}
2667
2668bool WebContentsImpl::UpdateTitleForEntry(NavigationEntryImpl* entry,
2669                                          const base::string16& title) {
2670  // For file URLs without a title, use the pathname instead. In the case of a
2671  // synthesized title, we don't want the update to count toward the "one set
2672  // per page of the title to history."
2673  base::string16 final_title;
2674  bool explicit_set;
2675  if (entry && entry->GetURL().SchemeIsFile() && title.empty()) {
2676    final_title = base::UTF8ToUTF16(entry->GetURL().ExtractFileName());
2677    explicit_set = false;  // Don't count synthetic titles toward the set limit.
2678  } else {
2679    base::TrimWhitespace(title, base::TRIM_ALL, &final_title);
2680    explicit_set = true;
2681  }
2682
2683  // If a page is created via window.open and never navigated,
2684  // there will be no navigation entry. In this situation,
2685  // |page_title_when_no_navigation_entry_| will be used for page title.
2686  if (entry) {
2687    if (final_title == entry->GetTitle())
2688      return false;  // Nothing changed, don't bother.
2689
2690    entry->SetTitle(final_title);
2691  } else {
2692    if (page_title_when_no_navigation_entry_ == final_title)
2693      return false;  // Nothing changed, don't bother.
2694
2695    page_title_when_no_navigation_entry_ = final_title;
2696  }
2697
2698  // Lastly, set the title for the view.
2699  view_->SetPageTitle(final_title);
2700
2701  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2702                    TitleWasSet(entry, explicit_set));
2703
2704  // TODO(avi): Remove. http://crbug.com/170921
2705  std::pair<NavigationEntry*, bool> details =
2706      std::make_pair(entry, explicit_set);
2707  NotificationService::current()->Notify(
2708      NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
2709      Source<WebContents>(this),
2710      Details<std::pair<NavigationEntry*, bool> >(&details));
2711
2712  return true;
2713}
2714
2715void WebContentsImpl::NotifySwapped(RenderViewHost* old_host,
2716                                    RenderViewHost* new_host) {
2717  // After sending out a swap notification, we need to send a disconnect
2718  // notification so that clients that pick up a pointer to |this| can NULL the
2719  // pointer.  See Bug 1230284.
2720  notify_disconnection_ = true;
2721  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2722                    RenderViewHostChanged(old_host, new_host));
2723
2724  // TODO(avi): Remove. http://crbug.com/170921
2725  std::pair<RenderViewHost*, RenderViewHost*> details =
2726      std::make_pair(old_host, new_host);
2727  NotificationService::current()->Notify(
2728      NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
2729      Source<WebContents>(this),
2730      Details<std::pair<RenderViewHost*, RenderViewHost*> >(&details));
2731
2732  // Ensure that the associated embedder gets cleared after a RenderViewHost
2733  // gets swapped, so we don't reuse the same embedder next time a
2734  // RenderViewHost is attached to this WebContents.
2735  RemoveBrowserPluginEmbedder();
2736}
2737
2738// TODO(avi): Remove this entire function because this notification is already
2739// covered by two observer functions. http://crbug.com/170921
2740void WebContentsImpl::NotifyDisconnected() {
2741  if (!notify_disconnection_)
2742    return;
2743
2744  notify_disconnection_ = false;
2745  NotificationService::current()->Notify(
2746      NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
2747      Source<WebContents>(this),
2748      NotificationService::NoDetails());
2749}
2750
2751void WebContentsImpl::NotifyNavigationEntryCommitted(
2752    const LoadCommittedDetails& load_details) {
2753  FOR_EACH_OBSERVER(
2754      WebContentsObserver, observers_, NavigationEntryCommitted(load_details));
2755}
2756
2757bool WebContentsImpl::OnMessageReceived(RenderFrameHost* render_frame_host,
2758                                        const IPC::Message& message) {
2759  return OnMessageReceived(NULL, render_frame_host, message);
2760}
2761
2762void WebContentsImpl::RenderFrameCreated(RenderFrameHost* render_frame_host) {
2763  // Note this is only for subframes, the notification for the main frame
2764  // happens in RenderViewCreated.
2765  FOR_EACH_OBSERVER(WebContentsObserver,
2766                    observers_,
2767                    RenderFrameCreated(render_frame_host));
2768}
2769
2770void WebContentsImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
2771  FOR_EACH_OBSERVER(WebContentsObserver,
2772                    observers_,
2773                    RenderFrameDeleted(render_frame_host));
2774}
2775
2776void WebContentsImpl::WorkerCrashed(RenderFrameHost* render_frame_host) {
2777  if (delegate_)
2778    delegate_->WorkerCrashed(this);
2779}
2780
2781void WebContentsImpl::ShowContextMenu(RenderFrameHost* render_frame_host,
2782                                      const ContextMenuParams& params) {
2783  // Allow WebContentsDelegates to handle the context menu operation first.
2784  if (delegate_ && delegate_->HandleContextMenu(params))
2785    return;
2786
2787  render_view_host_delegate_view_->ShowContextMenu(render_frame_host, params);
2788}
2789
2790WebContents* WebContentsImpl::GetAsWebContents() {
2791  return this;
2792}
2793
2794RenderViewHostDelegateView* WebContentsImpl::GetDelegateView() {
2795  return render_view_host_delegate_view_;
2796}
2797
2798RendererPreferences WebContentsImpl::GetRendererPrefs(
2799    BrowserContext* browser_context) const {
2800  return renderer_preferences_;
2801}
2802
2803gfx::Rect WebContentsImpl::GetRootWindowResizerRect() const {
2804  if (delegate_)
2805    return delegate_->GetRootWindowResizerRect();
2806  return gfx::Rect();
2807}
2808
2809void WebContentsImpl::RemoveBrowserPluginEmbedder() {
2810  if (browser_plugin_embedder_)
2811    browser_plugin_embedder_.reset();
2812}
2813
2814void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
2815  // Don't send notifications if we are just creating a swapped-out RVH for
2816  // the opener chain.  These won't be used for view-source or WebUI, so it's
2817  // ok to return early.
2818  if (static_cast<RenderViewHostImpl*>(render_view_host)->IsSwappedOut())
2819    return;
2820
2821  if (delegate_)
2822    view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
2823
2824  NotificationService::current()->Notify(
2825      NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
2826      Source<WebContents>(this),
2827      Details<RenderViewHost>(render_view_host));
2828
2829  // When we're creating views, we're still doing initial setup, so we always
2830  // use the pending Web UI rather than any possibly existing committed one.
2831  if (GetRenderManager()->pending_web_ui())
2832    GetRenderManager()->pending_web_ui()->RenderViewCreated(render_view_host);
2833
2834  NavigationEntry* entry = controller_.GetPendingEntry();
2835  if (entry && entry->IsViewSourceMode()) {
2836    // Put the renderer in view source mode.
2837    render_view_host->Send(
2838        new ViewMsg_EnableViewSourceMode(render_view_host->GetRoutingID()));
2839  }
2840
2841  view_->RenderViewCreated(render_view_host);
2842
2843  FOR_EACH_OBSERVER(
2844      WebContentsObserver, observers_, RenderViewCreated(render_view_host));
2845
2846  // We tell the observers now instead of when the main RenderFrameHostImpl is
2847  // constructed because otherwise it would be too early (i.e. IPCs sent to the
2848  // frame would be dropped because it's not created yet).
2849  RenderFrameHost* main_frame = render_view_host->GetMainFrame();
2850  FOR_EACH_OBSERVER(
2851      WebContentsObserver, observers_, RenderFrameCreated(main_frame));
2852}
2853
2854void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) {
2855  if (rvh != GetRenderViewHost()) {
2856    // Don't notify the world, since this came from a renderer in the
2857    // background.
2858    return;
2859  }
2860
2861  notify_disconnection_ = true;
2862  // TODO(avi): Remove. http://crbug.com/170921
2863  NotificationService::current()->Notify(
2864      NOTIFICATION_WEB_CONTENTS_CONNECTED,
2865      Source<WebContents>(this),
2866      NotificationService::NoDetails());
2867
2868  bool was_crashed = IsCrashed();
2869  SetIsCrashed(base::TERMINATION_STATUS_STILL_RUNNING, 0);
2870
2871  // Restore the focus to the tab (otherwise the focus will be on the top
2872  // window).
2873  if (was_crashed && !FocusLocationBarByDefault() &&
2874      (!delegate_ || delegate_->ShouldFocusPageAfterCrash())) {
2875    view_->Focus();
2876  }
2877
2878  FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewReady());
2879}
2880
2881void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh,
2882                                           base::TerminationStatus status,
2883                                           int error_code) {
2884  if (rvh != GetRenderViewHost()) {
2885    // The pending page's RenderViewHost is gone.
2886    return;
2887  }
2888
2889  // Ensure fullscreen mode is exited in the |delegate_| since a crashed
2890  // renderer may not have made a clean exit.
2891  if (IsFullscreenForCurrentTab())
2892    ToggleFullscreenMode(false);
2893
2894  // Cancel any visible dialogs so they are not left dangling over the sad tab.
2895  if (dialog_manager_)
2896    dialog_manager_->CancelActiveAndPendingDialogs(this);
2897
2898  ClearPowerSaveBlockers(rvh);
2899  SetIsLoading(rvh, false, NULL);
2900  NotifyDisconnected();
2901  SetIsCrashed(status, error_code);
2902  GetView()->OnTabCrashed(GetCrashedStatus(), crashed_error_code_);
2903
2904  FOR_EACH_OBSERVER(WebContentsObserver,
2905                    observers_,
2906                    RenderProcessGone(GetCrashedStatus()));
2907}
2908
2909void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) {
2910  ClearPowerSaveBlockers(rvh);
2911  GetRenderManager()->RenderViewDeleted(rvh);
2912  FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh));
2913}
2914
2915void WebContentsImpl::UpdateState(RenderViewHost* rvh,
2916                                  int32 page_id,
2917                                  const PageState& page_state) {
2918  // Ensure that this state update comes from either the active RVH or one of
2919  // the swapped out RVHs.  We don't expect to hear from any other RVHs.
2920  // TODO(nasko): This should go through RenderFrameHost.
2921  // TODO(creis): We can't update state for cross-process subframes until we
2922  // have FrameNavigationEntries.  Once we do, this should be a DCHECK.
2923  if (rvh != GetRenderViewHost() &&
2924      !GetRenderManager()->IsRVHOnSwappedOutList(
2925          static_cast<RenderViewHostImpl*>(rvh)))
2926    return;
2927
2928  // We must be prepared to handle state updates for any page, these occur
2929  // when the user is scrolling and entering form data, as well as when we're
2930  // leaving a page, in which case our state may have already been moved to
2931  // the next page. The navigation controller will look up the appropriate
2932  // NavigationEntry and update it when it is notified via the delegate.
2933
2934  int entry_index = controller_.GetEntryIndexWithPageID(
2935      rvh->GetSiteInstance(), page_id);
2936  if (entry_index < 0)
2937    return;
2938  NavigationEntry* entry = controller_.GetEntryAtIndex(entry_index);
2939
2940  if (page_state == entry->GetPageState())
2941    return;  // Nothing to update.
2942  entry->SetPageState(page_state);
2943  controller_.NotifyEntryChanged(entry, entry_index);
2944}
2945
2946void WebContentsImpl::UpdateTitle(RenderViewHost* rvh,
2947                                  int32 page_id,
2948                                  const base::string16& title,
2949                                  base::i18n::TextDirection title_direction) {
2950  // If we have a title, that's a pretty good indication that we've started
2951  // getting useful data.
2952  SetNotWaitingForResponse();
2953
2954  // Try to find the navigation entry, which might not be the current one.
2955  // For example, it might be from a pending RVH for the pending entry.
2956  NavigationEntryImpl* entry = controller_.GetEntryWithPageID(
2957      rvh->GetSiteInstance(), page_id);
2958
2959  // We can handle title updates when we don't have an entry in
2960  // UpdateTitleForEntry, but only if the update is from the current RVH.
2961  if (!entry && rvh != GetRenderViewHost())
2962    return;
2963
2964  // TODO(evan): make use of title_direction.
2965  // http://code.google.com/p/chromium/issues/detail?id=27094
2966  if (!UpdateTitleForEntry(entry, title))
2967    return;
2968
2969  // Broadcast notifications when the UI should be updated.
2970  if (entry == controller_.GetEntryAtOffset(0))
2971    NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE);
2972}
2973
2974void WebContentsImpl::UpdateEncoding(RenderViewHost* render_view_host,
2975                                     const std::string& encoding) {
2976  SetEncoding(encoding);
2977}
2978
2979void WebContentsImpl::UpdateTargetURL(int32 page_id, const GURL& url) {
2980  if (delegate_)
2981    delegate_->UpdateTargetURL(this, page_id, url);
2982}
2983
2984void WebContentsImpl::Close(RenderViewHost* rvh) {
2985#if defined(OS_MACOSX)
2986  // The UI may be in an event-tracking loop, such as between the
2987  // mouse-down and mouse-up in text selection or a button click.
2988  // Defer the close until after tracking is complete, so that we
2989  // don't free objects out from under the UI.
2990  // TODO(shess): This could get more fine-grained.  For instance,
2991  // closing a tab in another window while selecting text in the
2992  // current window's Omnibox should be just fine.
2993  if (view_->IsEventTracking()) {
2994    view_->CloseTabAfterEventTracking();
2995    return;
2996  }
2997#endif
2998
2999  // Ignore this if it comes from a RenderViewHost that we aren't showing.
3000  if (delegate_ && rvh == GetRenderViewHost())
3001    delegate_->CloseContents(this);
3002}
3003
3004void WebContentsImpl::SwappedOut(RenderViewHost* rvh) {
3005  if (rvh == GetRenderViewHost()) {
3006    // Exit fullscreen mode before the current RVH is swapped out.  For numerous
3007    // cases, there is no guarantee the renderer would/could initiate an exit.
3008    // Example: http://crbug.com/347232
3009    if (IsFullscreenForCurrentTab()) {
3010      if (rvh)
3011        rvh->ExitFullscreen();
3012      DCHECK(!IsFullscreenForCurrentTab());
3013    }
3014
3015    if (delegate_)
3016      delegate_->SwappedOut(this);
3017  }
3018
3019  // Allow the navigation to proceed.
3020  GetRenderManager()->SwappedOut(rvh);
3021}
3022
3023void WebContentsImpl::RequestMove(const gfx::Rect& new_bounds) {
3024  if (delegate_ && delegate_->IsPopupOrPanel(this))
3025    delegate_->MoveContents(this, new_bounds);
3026}
3027
3028void WebContentsImpl::DidStartLoading(RenderFrameHost* render_frame_host) {
3029  SetIsLoading(render_frame_host->GetRenderViewHost(), true, NULL);
3030}
3031
3032void WebContentsImpl::DidStopLoading(RenderFrameHost* render_frame_host) {
3033  scoped_ptr<LoadNotificationDetails> details;
3034
3035  // Use the last committed entry rather than the active one, in case a
3036  // pending entry has been created.
3037  NavigationEntry* entry = controller_.GetLastCommittedEntry();
3038  Navigator* navigator = frame_tree_.root()->navigator();
3039
3040  // An entry may not exist for a stop when loading an initial blank page or
3041  // if an iframe injected by script into a blank page finishes loading.
3042  if (entry) {
3043    base::TimeDelta elapsed =
3044        base::TimeTicks::Now() - navigator->GetCurrentLoadStart();
3045
3046    details.reset(new LoadNotificationDetails(
3047        entry->GetVirtualURL(),
3048        entry->GetTransitionType(),
3049        elapsed,
3050        &controller_,
3051        controller_.GetCurrentEntryIndex()));
3052  }
3053
3054  SetIsLoading(render_frame_host->GetRenderViewHost(), false, details.get());
3055}
3056
3057void WebContentsImpl::DidCancelLoading() {
3058  controller_.DiscardNonCommittedEntries();
3059
3060  // Update the URL display.
3061  NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
3062}
3063
3064void WebContentsImpl::DidChangeLoadProgress(double progress) {
3065  if (delegate_)
3066    delegate_->LoadProgressChanged(this, progress);
3067}
3068
3069void WebContentsImpl::DidDisownOpener(RenderViewHost* rvh) {
3070  if (opener_) {
3071    // Clear our opener so that future cross-process navigations don't have an
3072    // opener assigned.
3073    RemoveDestructionObserver(opener_);
3074    opener_ = NULL;
3075  }
3076
3077  // Notify all swapped out RenderViewHosts for this tab.  This is important
3078  // in case we go back to them, or if another window in those processes tries
3079  // to access window.opener.
3080  GetRenderManager()->DidDisownOpener(rvh);
3081}
3082
3083void WebContentsImpl::DidAccessInitialDocument() {
3084  // Update the URL display.
3085  NotifyNavigationStateChanged(content::INVALIDATE_TYPE_URL);
3086}
3087
3088void WebContentsImpl::DocumentAvailableInMainFrame(
3089    RenderViewHost* render_view_host) {
3090  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
3091                    DocumentAvailableInMainFrame());
3092}
3093
3094void WebContentsImpl::DocumentOnLoadCompletedInMainFrame(
3095    RenderViewHost* render_view_host,
3096    int32 page_id) {
3097  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
3098                    DocumentOnLoadCompletedInMainFrame(page_id));
3099
3100  // TODO(avi): Remove. http://crbug.com/170921
3101  NotificationService::current()->Notify(
3102      NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
3103      Source<WebContents>(this),
3104      Details<int>(&page_id));
3105}
3106
3107void WebContentsImpl::RouteCloseEvent(RenderViewHost* rvh) {
3108  // Tell the active RenderViewHost to run unload handlers and close, as long
3109  // as the request came from a RenderViewHost in the same BrowsingInstance.
3110  // In most cases, we receive this from a swapped out RenderViewHost.
3111  // It is possible to receive it from one that has just been swapped in,
3112  // in which case we might as well deliver the message anyway.
3113  if (rvh->GetSiteInstance()->IsRelatedSiteInstance(GetSiteInstance()))
3114    GetRenderViewHost()->ClosePage();
3115}
3116
3117void WebContentsImpl::RouteMessageEvent(
3118    RenderViewHost* rvh,
3119    const ViewMsg_PostMessage_Params& params) {
3120  // Only deliver the message to the active RenderViewHost if the request
3121  // came from a RenderViewHost in the same BrowsingInstance or if this
3122  // WebContents is dedicated to a browser plugin guest.
3123  // Note: This check means that an embedder could theoretically receive a
3124  // postMessage from anyone (not just its own guests). However, this is
3125  // probably not a risk for apps since other pages won't have references
3126  // to App windows.
3127  if (!rvh->GetSiteInstance()->IsRelatedSiteInstance(GetSiteInstance()) &&
3128      !GetBrowserPluginGuest() && !GetBrowserPluginEmbedder())
3129    return;
3130
3131  ViewMsg_PostMessage_Params new_params(params);
3132
3133  if (!params.message_port_ids.empty()) {
3134    MessagePortMessageFilter* message_port_message_filter =
3135        static_cast<RenderProcessHostImpl*>(GetRenderProcessHost())
3136            ->message_port_message_filter();
3137    std::vector<int> new_routing_ids(params.message_port_ids.size());
3138    for (size_t i = 0; i < params.message_port_ids.size(); ++i) {
3139      new_routing_ids[i] = message_port_message_filter->GetNextRoutingID();
3140      MessagePortService::GetInstance()->UpdateMessagePort(
3141          params.message_port_ids[i],
3142          message_port_message_filter,
3143          new_routing_ids[i]);
3144    }
3145    new_params.new_routing_ids = new_routing_ids;
3146  }
3147
3148  // If there is a source_routing_id, translate it to the routing ID for
3149  // the equivalent swapped out RVH in the target process.  If we need
3150  // to create a swapped out RVH for the source tab, we create its opener
3151  // chain as well, since those will also be accessible to the target page.
3152  if (new_params.source_routing_id != MSG_ROUTING_NONE) {
3153    // Try to look up the WebContents for the source page.
3154    WebContentsImpl* source_contents = NULL;
3155    RenderViewHostImpl* source_rvh = RenderViewHostImpl::FromID(
3156        rvh->GetProcess()->GetID(), params.source_routing_id);
3157    if (source_rvh) {
3158      source_contents = static_cast<WebContentsImpl*>(
3159          source_rvh->GetDelegate()->GetAsWebContents());
3160    }
3161
3162    if (source_contents) {
3163      if (GetBrowserPluginGuest()) {
3164        // We create a swapped out RenderView for the embedder in the guest's
3165        // render process but we intentionally do not expose the embedder's
3166        // opener chain to it.
3167        new_params.source_routing_id =
3168            source_contents->CreateSwappedOutRenderView(GetSiteInstance());
3169      } else {
3170        new_params.source_routing_id =
3171            source_contents->CreateOpenerRenderViews(GetSiteInstance());
3172      }
3173    } else {
3174      // We couldn't find it, so don't pass a source frame.
3175      new_params.source_routing_id = MSG_ROUTING_NONE;
3176    }
3177  }
3178
3179  // In most cases, we receive this from a swapped out RenderViewHost.
3180  // It is possible to receive it from one that has just been swapped in,
3181  // in which case we might as well deliver the message anyway.
3182  Send(new ViewMsg_PostMessageEvent(GetRoutingID(), new_params));
3183}
3184
3185void WebContentsImpl::RunJavaScriptMessage(
3186    RenderViewHost* rvh,
3187    const base::string16& message,
3188    const base::string16& default_prompt,
3189    const GURL& frame_url,
3190    JavaScriptMessageType javascript_message_type,
3191    IPC::Message* reply_msg,
3192    bool* did_suppress_message) {
3193  // Suppress JavaScript dialogs when requested. Also suppress messages when
3194  // showing an interstitial as it's shown over the previous page and we don't
3195  // want the hidden page's dialogs to interfere with the interstitial.
3196  bool suppress_this_message =
3197      static_cast<RenderViewHostImpl*>(rvh)->IsSwappedOut() ||
3198      ShowingInterstitialPage() ||
3199      !delegate_ ||
3200      delegate_->ShouldSuppressDialogs() ||
3201      !delegate_->GetJavaScriptDialogManager();
3202
3203  if (!suppress_this_message) {
3204    std::string accept_lang = GetContentClient()->browser()->
3205      GetAcceptLangs(GetBrowserContext());
3206    dialog_manager_ = delegate_->GetJavaScriptDialogManager();
3207    dialog_manager_->RunJavaScriptDialog(
3208        this,
3209        frame_url.GetOrigin(),
3210        accept_lang,
3211        javascript_message_type,
3212        message,
3213        default_prompt,
3214        base::Bind(&WebContentsImpl::OnDialogClosed,
3215                   base::Unretained(this),
3216                   rvh,
3217                   reply_msg),
3218        &suppress_this_message);
3219  }
3220
3221  *did_suppress_message = suppress_this_message;
3222
3223  if (suppress_this_message) {
3224    // If we are suppressing messages, just reply as if the user immediately
3225    // pressed "Cancel".
3226    OnDialogClosed(rvh, reply_msg, false, base::string16());
3227  }
3228
3229  // OnDialogClosed (two lines up) may have caused deletion of this object (see
3230  // http://crbug.com/288961 ). The only safe thing to do here is return.
3231}
3232
3233void WebContentsImpl::RunBeforeUnloadConfirm(RenderViewHost* rvh,
3234                                             const base::string16& message,
3235                                             bool is_reload,
3236                                             IPC::Message* reply_msg) {
3237  RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(rvh);
3238  if (delegate_)
3239    delegate_->WillRunBeforeUnloadConfirm();
3240
3241  bool suppress_this_message =
3242      rvhi->rvh_state() != RenderViewHostImpl::STATE_DEFAULT ||
3243      !delegate_ ||
3244      delegate_->ShouldSuppressDialogs() ||
3245      !delegate_->GetJavaScriptDialogManager();
3246  if (suppress_this_message) {
3247    // The reply must be sent to the RVH that sent the request.
3248    rvhi->JavaScriptDialogClosed(reply_msg, true, base::string16());
3249    return;
3250  }
3251
3252  is_showing_before_unload_dialog_ = true;
3253  dialog_manager_ = delegate_->GetJavaScriptDialogManager();
3254  dialog_manager_->RunBeforeUnloadDialog(
3255      this, message, is_reload,
3256      base::Bind(&WebContentsImpl::OnDialogClosed, base::Unretained(this), rvh,
3257                 reply_msg));
3258}
3259
3260bool WebContentsImpl::AddMessageToConsole(int32 level,
3261                                          const base::string16& message,
3262                                          int32 line_no,
3263                                          const base::string16& source_id) {
3264  if (!delegate_)
3265    return false;
3266  return delegate_->AddMessageToConsole(this, level, message, line_no,
3267                                        source_id);
3268}
3269
3270WebPreferences WebContentsImpl::GetWebkitPrefs() {
3271  // We want to base the page config off of the actual URL, rather than the
3272  // virtual URL.
3273  // TODO(nasko): Investigate how to remove the GetActiveEntry usage here,
3274  // as it is deprecated and can be out of sync with GetRenderViewHost().
3275  GURL url = controller_.GetActiveEntry()
3276      ? controller_.GetActiveEntry()->GetURL() : GURL::EmptyGURL();
3277
3278  return GetRenderManager()->current_host()->GetWebkitPrefs(url);
3279}
3280
3281int WebContentsImpl::CreateSwappedOutRenderView(
3282    SiteInstance* instance) {
3283  return GetRenderManager()->CreateRenderFrame(instance, MSG_ROUTING_NONE,
3284                                               true, true);
3285}
3286
3287void WebContentsImpl::OnUserGesture() {
3288  // Notify observers.
3289  FOR_EACH_OBSERVER(WebContentsObserver, observers_, DidGetUserGesture());
3290
3291  ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
3292  if (rdh)  // NULL in unittests.
3293    rdh->OnUserGesture(this);
3294}
3295
3296void WebContentsImpl::OnIgnoredUIEvent() {
3297  // Notify observers.
3298  FOR_EACH_OBSERVER(WebContentsObserver, observers_, DidGetIgnoredUIEvent());
3299}
3300
3301void WebContentsImpl::RendererUnresponsive(RenderViewHost* rvh,
3302                                           bool is_during_beforeunload,
3303                                           bool is_during_unload) {
3304  // Don't show hung renderer dialog for a swapped out RVH.
3305  if (rvh != GetRenderViewHost())
3306    return;
3307
3308  RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(rvh);
3309
3310  // Ignore renderer unresponsive event if debugger is attached to the tab
3311  // since the event may be a result of the renderer sitting on a breakpoint.
3312  // See http://crbug.com/65458
3313  if (DevToolsAgentHost::IsDebuggerAttached(this))
3314    return;
3315
3316  if (is_during_beforeunload || is_during_unload) {
3317    // Hang occurred while firing the beforeunload/unload handler.
3318    // Pretend the handler fired so tab closing continues as if it had.
3319    rvhi->set_sudden_termination_allowed(true);
3320
3321    if (!GetRenderManager()->ShouldCloseTabOnUnresponsiveRenderer())
3322      return;
3323
3324    // If the tab hangs in the beforeunload/unload handler there's really
3325    // nothing we can do to recover. If the hang is in the beforeunload handler,
3326    // pretend the beforeunload listeners have all fired and allow the delegate
3327    // to continue closing; the user will not have the option of cancelling the
3328    // close. Otherwise, pretend the unload listeners have all fired and close
3329    // the tab.
3330    bool close = true;
3331    if (is_during_beforeunload) {
3332      delegate_->BeforeUnloadFired(this, true, &close);
3333    }
3334    if (close)
3335      Close(rvh);
3336    return;
3337  }
3338
3339  if (!GetRenderViewHostImpl() || !GetRenderViewHostImpl()->IsRenderViewLive())
3340    return;
3341
3342  if (delegate_)
3343    delegate_->RendererUnresponsive(this);
3344}
3345
3346void WebContentsImpl::RendererResponsive(RenderViewHost* render_view_host) {
3347  if (delegate_)
3348    delegate_->RendererResponsive(this);
3349}
3350
3351void WebContentsImpl::LoadStateChanged(
3352    const GURL& url,
3353    const net::LoadStateWithParam& load_state,
3354    uint64 upload_position,
3355    uint64 upload_size) {
3356  load_state_ = load_state;
3357  upload_position_ = upload_position;
3358  upload_size_ = upload_size;
3359  load_state_host_ = net::IDNToUnicode(url.host(),
3360      GetContentClient()->browser()->GetAcceptLangs(
3361          GetBrowserContext()));
3362  if (load_state_.state == net::LOAD_STATE_READING_RESPONSE)
3363    SetNotWaitingForResponse();
3364  if (IsLoading()) {
3365    NotifyNavigationStateChanged(INVALIDATE_TYPE_LOAD | INVALIDATE_TYPE_TAB);
3366  }
3367}
3368
3369void WebContentsImpl::BeforeUnloadFiredFromRenderManager(
3370    bool proceed, const base::TimeTicks& proceed_time,
3371    bool* proceed_to_fire_unload) {
3372  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
3373                    BeforeUnloadFired(proceed_time));
3374  if (delegate_)
3375    delegate_->BeforeUnloadFired(this, proceed, proceed_to_fire_unload);
3376  // Note: |this| might be deleted at this point.
3377}
3378
3379void WebContentsImpl::RenderProcessGoneFromRenderManager(
3380    RenderViewHost* render_view_host) {
3381  DCHECK(crashed_status_ != base::TERMINATION_STATUS_STILL_RUNNING);
3382  RenderViewTerminated(render_view_host, crashed_status_, crashed_error_code_);
3383}
3384
3385void WebContentsImpl::UpdateRenderViewSizeForRenderManager() {
3386  // TODO(brettw) this is a hack. See WebContentsView::SizeContents.
3387  gfx::Size size = GetSizeForNewRenderView();
3388  // 0x0 isn't a valid window size (minimal window size is 1x1) but it may be
3389  // here during container initialization and normal window size will be set
3390  // later. In case of tab duplication this resizing to 0x0 prevents setting
3391  // normal size later so just ignore it.
3392  if (!size.IsEmpty())
3393    view_->SizeContents(size);
3394}
3395
3396void WebContentsImpl::CancelModalDialogsForRenderManager() {
3397  // We need to cancel modal dialogs when doing a process swap, since the load
3398  // deferrer would prevent us from swapping out.
3399  if (dialog_manager_)
3400    dialog_manager_->CancelActiveAndPendingDialogs(this);
3401}
3402
3403void WebContentsImpl::NotifySwappedFromRenderManager(RenderViewHost* old_host,
3404                                                     RenderViewHost* new_host) {
3405  NotifySwapped(old_host, new_host);
3406
3407  // Make sure the visible RVH reflects the new delegate's preferences.
3408  if (delegate_)
3409    view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
3410
3411  view_->RenderViewSwappedIn(new_host);
3412}
3413
3414int WebContentsImpl::CreateOpenerRenderViewsForRenderManager(
3415    SiteInstance* instance) {
3416  if (!opener_)
3417    return MSG_ROUTING_NONE;
3418
3419  // Recursively create RenderViews for anything else in the opener chain.
3420  return opener_->CreateOpenerRenderViews(instance);
3421}
3422
3423int WebContentsImpl::CreateOpenerRenderViews(SiteInstance* instance) {
3424  int opener_route_id = MSG_ROUTING_NONE;
3425
3426  // If this tab has an opener, ensure it has a RenderView in the given
3427  // SiteInstance as well.
3428  if (opener_)
3429    opener_route_id = opener_->CreateOpenerRenderViews(instance);
3430
3431  // If any of the renderers (current, pending, or swapped out) for this
3432  // WebContents has the same SiteInstance, use it.
3433  if (GetRenderManager()->current_host()->GetSiteInstance() == instance)
3434    return GetRenderManager()->current_host()->GetRoutingID();
3435
3436  if (GetRenderManager()->pending_render_view_host() &&
3437      GetRenderManager()->pending_render_view_host()->GetSiteInstance() ==
3438          instance)
3439    return GetRenderManager()->pending_render_view_host()->GetRoutingID();
3440
3441  RenderViewHostImpl* rvh = GetRenderManager()->GetSwappedOutRenderViewHost(
3442      instance);
3443  if (rvh)
3444    return rvh->GetRoutingID();
3445
3446  // Create a swapped out RenderView in the given SiteInstance if none exists,
3447  // setting its opener to the given route_id.  Return the new view's route_id.
3448  return GetRenderManager()->CreateRenderFrame(instance, opener_route_id,
3449                                               true, true);
3450}
3451
3452NavigationControllerImpl& WebContentsImpl::GetControllerForRenderManager() {
3453  return GetController();
3454}
3455
3456WebUIImpl* WebContentsImpl::CreateWebUIForRenderManager(const GURL& url) {
3457  return static_cast<WebUIImpl*>(CreateWebUI(url));
3458}
3459
3460NavigationEntry*
3461    WebContentsImpl::GetLastCommittedNavigationEntryForRenderManager() {
3462  return controller_.GetLastCommittedEntry();
3463}
3464
3465bool WebContentsImpl::CreateRenderViewForRenderManager(
3466    RenderViewHost* render_view_host,
3467    int opener_route_id,
3468    CrossProcessFrameConnector* frame_connector) {
3469  TRACE_EVENT0("browser", "WebContentsImpl::CreateRenderViewForRenderManager");
3470  // Can be NULL during tests.
3471  RenderWidgetHostView* rwh_view;
3472  // TODO(kenrb): RenderWidgetHostViewChildFrame special casing is temporary
3473  // until RenderWidgetHost is attached to RenderFrameHost. We need to special
3474  // case this because RWH is still a base class of RenderViewHost, and child
3475  // frame RWHVs are unique in that they do not have their own WebContents.
3476  if (frame_connector) {
3477    RenderWidgetHostViewChildFrame* rwh_view_child =
3478        new RenderWidgetHostViewChildFrame(render_view_host);
3479    frame_connector->set_view(rwh_view_child);
3480    rwh_view = rwh_view_child;
3481  } else {
3482    rwh_view = view_->CreateViewForWidget(render_view_host);
3483  }
3484
3485  // Now that the RenderView has been created, we need to tell it its size.
3486  if (rwh_view)
3487    rwh_view->SetSize(GetSizeForNewRenderView());
3488
3489  // Make sure we use the correct starting page_id in the new RenderView.
3490  UpdateMaxPageIDIfNecessary(render_view_host);
3491  int32 max_page_id =
3492      GetMaxPageIDForSiteInstance(render_view_host->GetSiteInstance());
3493
3494  if (!static_cast<RenderViewHostImpl*>(
3495          render_view_host)->CreateRenderView(base::string16(),
3496                                              opener_route_id,
3497                                              max_page_id)) {
3498    return false;
3499  }
3500
3501#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
3502  // Force a ViewMsg_Resize to be sent, needed to make plugins show up on
3503  // linux. See crbug.com/83941.
3504  if (rwh_view) {
3505    if (RenderWidgetHost* render_widget_host = rwh_view->GetRenderWidgetHost())
3506      render_widget_host->WasResized();
3507  }
3508#endif
3509
3510  return true;
3511}
3512
3513#if defined(OS_ANDROID)
3514base::android::ScopedJavaLocalRef<jobject>
3515WebContentsImpl::GetJavaWebContents() {
3516  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3517
3518  WebContentsAndroid* web_contents_android =
3519      static_cast<WebContentsAndroid*>(GetUserData(kWebContentsAndroidKey));
3520  if (!web_contents_android) {
3521    web_contents_android = new WebContentsAndroid(this);
3522    SetUserData(kWebContentsAndroidKey, web_contents_android);
3523  }
3524  return web_contents_android->GetJavaObject();
3525}
3526
3527bool WebContentsImpl::CreateRenderViewForInitialEmptyDocument() {
3528  return CreateRenderViewForRenderManager(GetRenderViewHost(),
3529                                          MSG_ROUTING_NONE,
3530                                          NULL);
3531}
3532#endif
3533
3534void WebContentsImpl::OnDialogClosed(RenderViewHost* rvh,
3535                                     IPC::Message* reply_msg,
3536                                     bool success,
3537                                     const base::string16& user_input) {
3538  if (is_showing_before_unload_dialog_ && !success) {
3539    // If a beforeunload dialog is canceled, we need to stop the throbber from
3540    // spinning, since we forced it to start spinning in Navigate.
3541    DidStopLoading(rvh->GetMainFrame());
3542    controller_.DiscardNonCommittedEntries();
3543
3544    FOR_EACH_OBSERVER(WebContentsObserver, observers_,
3545                      BeforeUnloadDialogCancelled());
3546  }
3547  is_showing_before_unload_dialog_ = false;
3548  static_cast<RenderViewHostImpl*>(
3549      rvh)->JavaScriptDialogClosed(reply_msg, success, user_input);
3550}
3551
3552void WebContentsImpl::SetEncoding(const std::string& encoding) {
3553  encoding_ = GetContentClient()->browser()->
3554      GetCanonicalEncodingNameByAliasName(encoding);
3555}
3556
3557void WebContentsImpl::CreateViewAndSetSizeForRVH(RenderViewHost* rvh) {
3558  RenderWidgetHostView* rwh_view = view_->CreateViewForWidget(rvh);
3559  // Can be NULL during tests.
3560  if (rwh_view)
3561    rwh_view->SetSize(GetView()->GetContainerSize());
3562}
3563
3564bool WebContentsImpl::IsHidden() {
3565  return capturer_count_ == 0 && !should_normally_be_visible_;
3566}
3567
3568RenderFrameHostManager* WebContentsImpl::GetRenderManager() const {
3569  return frame_tree_.root()->render_manager();
3570}
3571
3572RenderViewHostImpl* WebContentsImpl::GetRenderViewHostImpl() {
3573  return static_cast<RenderViewHostImpl*>(GetRenderViewHost());
3574}
3575
3576BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const {
3577  return browser_plugin_guest_.get();
3578}
3579
3580void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) {
3581  CHECK(!browser_plugin_guest_);
3582  browser_plugin_guest_.reset(guest);
3583}
3584
3585BrowserPluginEmbedder* WebContentsImpl::GetBrowserPluginEmbedder() const {
3586  return browser_plugin_embedder_.get();
3587}
3588
3589BrowserPluginGuestManager*
3590    WebContentsImpl::GetBrowserPluginGuestManager() const {
3591  return static_cast<BrowserPluginGuestManager*>(
3592      GetBrowserContext()->GetUserData(
3593          browser_plugin::kBrowserPluginGuestManagerKeyName));
3594}
3595
3596void WebContentsImpl::ClearPowerSaveBlockers(
3597    RenderViewHost* render_view_host) {
3598  STLDeleteValues(&power_save_blockers_[render_view_host]);
3599  power_save_blockers_.erase(render_view_host);
3600}
3601
3602void WebContentsImpl::ClearAllPowerSaveBlockers() {
3603  for (PowerSaveBlockerMap::iterator i(power_save_blockers_.begin());
3604       i != power_save_blockers_.end(); ++i)
3605    STLDeleteValues(&power_save_blockers_[i->first]);
3606  power_save_blockers_.clear();
3607}
3608
3609gfx::Size WebContentsImpl::GetSizeForNewRenderView() const {
3610  gfx::Size size;
3611  if (delegate_)
3612    size = delegate_->GetSizeForNewRenderView(this);
3613  if (size.IsEmpty())
3614    size = view_->GetContainerSize();
3615  return size;
3616}
3617
3618void WebContentsImpl::OnFrameRemoved(
3619    RenderViewHostImpl* render_view_host,
3620    int frame_routing_id) {
3621   FOR_EACH_OBSERVER(WebContentsObserver, observers_,
3622                     FrameDetached(render_view_host, frame_routing_id));
3623}
3624
3625void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
3626  if (!delegate_)
3627    return;
3628  const gfx::Size new_size = GetPreferredSize();
3629  if (new_size != old_size)
3630    delegate_->UpdatePreferredSize(this, new_size);
3631}
3632
3633}  // namespace content
3634