15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_guest.h"
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/message_loop/message_loop.h"
80f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/strings/stringprintf.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/browser_context.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/browser_thread.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/child_process_security_policy.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/native_web_keyboard_event.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_details.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/notification_service.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_source.h"
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_types.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/render_process_host.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/render_widget_host_view.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/resource_request_details.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/site_instance.h"
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/browser/storage_partition.h"
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/user_metrics.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/web_contents.h"
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/public/browser/web_contents_delegate.h"
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/public/common/media_stream_request.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/page_zoom.h"
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/common/result_codes.h"
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/common/stop_find_action.h"
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/common/url_constants.h"
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/extensions_api_client.h"
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_view/web_view_internal_api.h"
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/extension_system.h"
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/browser/guest_view/guest_view_manager.h"
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_constants.h"
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_permission_helper.h"
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_permission_types.h"
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "extensions/common/constants.h"
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "extensions/common/extension_messages.h"
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/guest_view/guest_view_constants.h"
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/strings/grit/extensions_strings.h"
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ipc/ipc_message_macros.h"
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/base/escape.h"
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "net/base/net_errors.h"
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/base/models/simple_menu_model.h"
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction;
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using content::RenderFrameHost;
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing content::ResourceType;
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing content::WebContents;
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace extensions {
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace {
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string WindowOpenDispositionToString(
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WindowOpenDisposition window_open_disposition) {
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (window_open_disposition) {
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case IGNORE_ACTION:
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return "ignore";
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case SAVE_TO_DISK:
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return "save_to_disk";
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case CURRENT_TAB:
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return "current_tab";
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case NEW_BACKGROUND_TAB:
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return "new_background_tab";
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case NEW_FOREGROUND_TAB:
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return "new_foreground_tab";
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case NEW_WINDOW:
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return "new_window";
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case NEW_POPUP:
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return "new_popup";
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    default:
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      NOTREACHED() << "Unknown Window Open Disposition";
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return "ignore";
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstatic std::string TerminationStatusToString(base::TerminationStatus status) {
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  switch (status) {
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case base::TERMINATION_STATUS_NORMAL_TERMINATION:
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return "normal";
867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case base::TERMINATION_STATUS_STILL_RUNNING:
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return "abnormal";
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return "killed";
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case base::TERMINATION_STATUS_PROCESS_CRASHED:
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return "crashed";
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case base::TERMINATION_STATUS_MAX_ENUM:
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      break;
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  NOTREACHED() << "Unknown Termination Status.";
977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return "unknown";
987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)std::string GetStoragePartitionIdFromSiteURL(const GURL& site_url) {
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const std::string& partition_id = site_url.query();
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool persist_storage = site_url.path().find("persist") != std::string::npos;
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return (persist_storage ? webview::kPersistPrefix : "") + partition_id;
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ParsePartitionParam(const base::DictionaryValue& create_params,
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         std::string* storage_partition_id,
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         bool* persist_storage) {
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string partition_str;
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!create_params.GetString(webview::kStoragePartitionId, &partition_str)) {
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Since the "persist:" prefix is in ASCII, StartsWith will work fine on
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // UTF-8 encoded |partition_id|. If the prefix is a match, we can safely
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // remove the prefix without splicing in the middle of a multi-byte codepoint.
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // We can use the rest of the string as UTF-8 encoded one.
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (StartsWithASCII(partition_str, "persist:", true)) {
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    size_t index = partition_str.find(":");
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CHECK(index != std::string::npos);
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // It is safe to do index + 1, since we tested for the full prefix above.
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    *storage_partition_id = partition_str.substr(index + 1);
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (storage_partition_id->empty()) {
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // TODO(lazyboy): Better way to deal with this error.
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    *persist_storage = true;
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    *storage_partition_id = partition_str;
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    *persist_storage = false;
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)GuestViewBase* WebViewGuest::Create(content::BrowserContext* browser_context,
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    int guest_instance_id) {
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return new WebViewGuest(browser_context, guest_instance_id);
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// static
14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool WebViewGuest::GetGuestPartitionConfigForSite(
14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GURL& site,
14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    std::string* partition_domain,
14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    std::string* partition_name,
14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    bool* in_memory) {
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!site.SchemeIs(content::kGuestScheme))
15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Since guest URLs are only used for packaged apps, there must be an app
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // id in the URL.
15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  CHECK(site.has_host());
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  *partition_domain = site.host();
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Since persistence is optional, the path must either be empty or the
15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // literal string.
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  *in_memory = (site.path() != "/persist");
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The partition name is user supplied value, which we have encoded when the
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // URL was created, so it needs to be decoded.
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  *partition_name =
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      net::UnescapeURLComponent(site.query(), net::UnescapeRule::NORMAL);
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return true;
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static
1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst char WebViewGuest::Type[] = "webview";
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int WebViewGuest::GetViewInstanceId(WebContents* contents) {
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  WebViewGuest* guest = FromWebContents(contents);
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!guest)
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return guestview::kInstanceIDNone;
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return guest->view_instance_id();
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char* WebViewGuest::GetAPINamespace() const {
1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return webview::kAPINamespace;
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint WebViewGuest::GetTaskPrefix() const {
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return IDS_EXTENSION_TASK_MANAGER_WEBVIEW_TAG_PREFIX;
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewGuest::CreateWebContents(
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& embedder_extension_id,
188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int embedder_render_process_id,
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const GURL& embedder_site_url,
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::DictionaryValue& create_params,
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const WebContentsCreatedCallback& callback) {
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::RenderProcessHost* embedder_render_process_host =
193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      content::RenderProcessHost::FromID(embedder_render_process_id);
194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string storage_partition_id;
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool persist_storage = false;
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string storage_partition_string;
197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ParsePartitionParam(create_params, &storage_partition_id, &persist_storage);
198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Validate that the partition id coming from the renderer is valid UTF-8,
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // since we depend on this in other parts of the code, such as FilePath
200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // creation. If the validation fails, treat it as a bad message and kill the
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // renderer process.
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!base::IsStringUTF8(storage_partition_id)) {
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::RecordAction(
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::UserMetricsAction("BadMessageTerminate_BPGM"));
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::KillProcess(
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        embedder_render_process_host->GetHandle(),
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    callback.Run(NULL);
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string url_encoded_partition = net::EscapeQueryParamValue(
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      storage_partition_id, false);
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The SiteInstance of a given webview tag is based on the fact that it's
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // a guest process in addition to which platform application or which WebUI
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // page the tag belongs to and what storage partition is in use, rather than
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the URL that the tag is being navigated to.
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string partition_domain;
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (embedder_extension_id.empty()) {
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(content::ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        embedder_render_process_id));
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    partition_domain = embedder_site_url.host();
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    partition_domain = embedder_extension_id;
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GURL guest_site(base::StringPrintf("%s://%s/%s?%s",
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     content::kGuestScheme,
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     partition_domain.c_str(),
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     persist_storage ? "persist" : "",
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     url_encoded_partition.c_str()));
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If we already have a webview tag in the same app using the same storage
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // partition, we should use the same SiteInstance so the existing tag and
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the new tag can script each other.
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GuestViewManager* guest_view_manager =
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      GuestViewManager::FromBrowserContext(
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          embedder_render_process_host->GetBrowserContext());
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::SiteInstance* guest_site_instance =
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      guest_view_manager->GetGuestSiteInstance(guest_site);
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!guest_site_instance) {
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Create the SiteInstance in a new BrowsingInstance, which will ensure
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // that webview tags are also not allowed to send messages across
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // different partitions.
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    guest_site_instance = content::SiteInstance::CreateForURL(
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        embedder_render_process_host->GetBrowserContext(), guest_site);
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  WebContents::CreateParams params(
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      embedder_render_process_host->GetBrowserContext(),
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      guest_site_instance);
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  params.guest_delegate = this;
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  callback.Run(WebContents::Create(params));
251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void WebViewGuest::DidAttachToEmbedder() {
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SetUpAutoSize();
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string name;
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (attach_params()->GetString(webview::kAttributeName, &name)) {
2586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // If the guest window's name is empty, then the WebView tag's name is
2596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // assigned. Otherwise, the guest window's name takes precedence over the
2606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // WebView tag's name.
2616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (name_.empty())
2626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      name_ = name;
2636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ReportFrameNameChange(name_);
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
26668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::string user_agent_override;
26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (attach_params()->GetString(webview::kParameterUserAgentOverride,
26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 &user_agent_override)) {
26968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SetUserAgentOverride(user_agent_override);
27068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else {
27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SetUserAgentOverride("");
27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
27368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string src;
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (attach_params()->GetString(webview::kAttributeSrc, &src) && !src.empty())
2766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    NavigateGuest(src);
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (GetOpener()) {
2796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // We need to do a navigation here if the target URL has changed between
2806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // the time the WebContents was created and the time it was attached.
2816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // We also need to do an initial navigation if a RenderView was never
2826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // created for the new window in cases where there is no referrer.
2836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    PendingWindowMap::iterator it =
2846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        GetOpener()->pending_new_windows_.find(this);
2856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (it != GetOpener()->pending_new_windows_.end()) {
2866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      const NewWindowInfo& new_window_info = it->second;
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (new_window_info.changed || !web_contents()->HasOpener())
2886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        NavigateGuest(new_window_info.url.spec());
2896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    } else {
2906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      NOTREACHED();
2916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
2926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Once a new guest is attached to the DOM of the embedder page, then the
2946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // lifetime of the new guest is no longer managed by the opener guest.
2956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    GetOpener()->pending_new_windows_.erase(this);
2966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool allow_transparency = false;
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attach_params()->GetBoolean(webview::kAttributeAllowTransparency,
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              &allow_transparency);
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We need to set the background opaque flag after navigation to ensure that
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // there is a RenderWidgetHostView available.
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetAllowTransparency(allow_transparency);
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (web_view_guest_delegate_)
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    web_view_guest_delegate_->OnDidAttachToEmbedder();
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewGuest::DidInitialize() {
3106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  script_executor_.reset(
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new ScriptExecutor(web_contents(), &script_observers_));
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  notification_registrar_.Add(this,
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              content::Source<WebContents>(web_contents()));
316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  notification_registrar_.Add(this,
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              content::Source<WebContents>(web_contents()));
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (web_view_guest_delegate_)
32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    web_view_guest_delegate_->OnDidInitialize();
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AttachWebViewHelpers(web_contents());
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewGuest::AttachWebViewHelpers(WebContents* contents) {
32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (web_view_guest_delegate_)
32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    web_view_guest_delegate_->OnAttachWebViewHelpers(contents);
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  web_view_permission_helper_.reset(new WebViewPermissionHelper(this));
330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WebViewGuest::DidStopLoading() {
33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new GuestViewBase::Event(webview::kEventLoadStop, args.Pass()));
33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::EmbedderDestroyed() {
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (web_view_guest_delegate_)
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    web_view_guest_delegate_->OnEmbedderDestroyed();
341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WebViewGuest::GuestDestroyed() {
34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Clean up custom context menu items for this guest.
34503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (web_view_guest_delegate_)
34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    web_view_guest_delegate_->OnGuestDestroyed();
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RemoveWebViewStateFromIOThread(web_contents());
34846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WebViewGuest::GuestReady() {
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The guest RenderView should always live in an isolated guest process.
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(web_contents()->GetRenderProcessHost()->IsIsolatedGuest());
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Send(new ExtensionMsg_SetFrameName(web_contents()->GetRoutingID(), name_));
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We don't want to accidentally set the opacity of an interstitial page.
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // WebContents::GetRenderWidgetHostView will return the RWHV of an
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // interstitial page if one is showing at this time. We only want opacity
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // to apply to web pages.
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_contents()->GetRenderViewHost()->GetView()->
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SetBackgroundOpaque(guest_opaque_);
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WebViewGuest::GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                 const gfx::Size& new_size) {
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  args->SetInteger(webview::kOldHeight, old_size.height());
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  args->SetInteger(webview::kOldWidth, old_size.width());
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  args->SetInteger(webview::kNewHeight, new_size.height());
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  args->SetInteger(webview::kNewWidth, new_size.width());
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DispatchEventToEmbedder(
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new GuestViewBase::Event(webview::kEventSizeChanged, args.Pass()));
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool WebViewGuest::IsAutoSizeSupported() const {
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool WebViewGuest::IsDragAndDropEnabled() const {
37946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return true;
38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WebViewGuest::WillDestroy() {
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!attached() && GetOpener())
38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    GetOpener()->pending_new_windows_.erase(this);
38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DestroyUnattachedWindows();
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DispatchEventToEmbedder(
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new GuestViewBase::Event(webview::kEventPluginDestroyed, args.Pass()));
39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool WebViewGuest::AddMessageToConsole(WebContents* source,
393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       int32 level,
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       const base::string16& message,
3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                       int32 line_no,
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       const base::string16& source_id) {
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Log levels are from base/logging.h: LogSeverity.
3997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  args->SetInteger(webview::kLevel, level);
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  args->SetString(webview::kMessage, message);
4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  args->SetInteger(webview::kLine, line_no);
4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  args->SetString(webview::kSourceId, source_id);
403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
4045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass()));
405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::CloseContents(WebContents* source) {
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new GuestViewBase::Event(webview::kEventClose, args.Pass()));
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::FindReply(WebContents* source,
415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             int request_id,
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             int number_of_matches,
417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             const gfx::Rect& selection_rect,
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             int active_match_ordinal,
419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             bool final_update) {
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  find_helper_.FindReply(request_id,
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         number_of_matches,
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         selection_rect,
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         active_match_ordinal,
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         final_update);
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool WebViewGuest::HandleContextMenu(
428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const content::ContextMenuParams& params) {
42903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!web_view_guest_delegate_)
43003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
43103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return web_view_guest_delegate_->HandleContextMenu(params);
4327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::HandleKeyboardEvent(
435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    WebContents* source,
4367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const content::NativeWebKeyboardEvent& event) {
437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!attached())
438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
4397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (HandleKeyboardShortcuts(event))
441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
4427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Send the unhandled keyboard events back to the embedder to reprocess them.
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(fsamuel): This introduces the possibility of out-of-order keyboard
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // events because the guest may be arbitrarily delayed when responding to
446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // keyboard events. In that time, the embedder may have received and processed
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // additional key events. This needs to be fixed as soon as possible.
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // See http://crbug.com/229882.
449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  embedder_web_contents()->GetDelegate()->HandleKeyboardEvent(
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      web_contents(), event);
4517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::LoadProgressChanged(content::WebContents* source,
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       double progress) {
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  args->SetString(guestview::kUrl, web_contents()->GetURL().spec());
45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  args->SetDouble(webview::kProgress, progress);
458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
4595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new GuestViewBase::Event(webview::kEventLoadProgress, args.Pass()));
46058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
46158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void WebViewGuest::LoadAbort(bool is_top_level,
4633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             const GURL& url,
4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             const std::string& error_type) {
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  args->SetBoolean(guestview::kIsTopLevel, is_top_level);
467424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  args->SetString(guestview::kUrl, url.possibly_invalid_spec());
4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  args->SetString(guestview::kReason, error_type);
469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
4705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new GuestViewBase::Event(webview::kEventLoadAbort, args.Pass()));
4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void WebViewGuest::OnFrameNameChanged(bool is_top_level,
47403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                      const std::string& name) {
475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!is_top_level)
476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (name_ == name)
479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ReportFrameNameChange(name);
482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
484116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewGuest::CreateNewGuestWebViewWindow(
485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const content::OpenURLParams& params) {
486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GuestViewManager* guest_manager =
487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GuestViewManager::FromBrowserContext(browser_context());
488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Set the attach params to use the same partition as the opener.
489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We pull the partition information from the site's URL, which is of the
490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // form guest://site/{persist}?{partition_name}.
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const GURL& site_url = web_contents()->GetSiteInstance()->GetSiteURL();
492f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const std::string storage_partition_id =
493f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      GetStoragePartitionIdFromSiteURL(site_url);
494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::DictionaryValue create_params;
495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  create_params.SetString(webview::kStoragePartitionId, storage_partition_id);
496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  guest_manager->CreateGuest(WebViewGuest::Type,
4986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             embedder_extension_id(),
4996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             embedder_web_contents(),
5006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             create_params,
5016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             base::Bind(&WebViewGuest::NewGuestWebViewCallback,
5026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                        base::Unretained(this),
5036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                        params));
504116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
505116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
506116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewGuest::NewGuestWebViewCallback(
507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const content::OpenURLParams& params,
508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::WebContents* guest_web_contents) {
509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  WebViewGuest* new_guest = WebViewGuest::FromWebContents(guest_web_contents);
510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  new_guest->SetOpener(this);
511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Take ownership of |new_guest|.
513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pending_new_windows_.insert(
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::make_pair(new_guest, NewWindowInfo(params.url, std::string())));
515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Request permission to show the new window.
5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RequestNewWindowPermission(params.disposition,
5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             gfx::Rect(),
519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             params.user_gesture,
5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             new_guest->web_contents());
521cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
52358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// TODO(fsamuel): Find a reliable way to test the 'responsive' and
52458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// 'unresponsive' events.
525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::RendererResponsive(content::WebContents* source) {
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
52758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  args->SetInteger(webview::kProcessId,
5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   web_contents()->GetRenderProcessHost()->GetID());
529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
5305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new GuestViewBase::Event(webview::kEventResponsive, args.Pass()));
53158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}
53258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::RendererUnresponsive(content::WebContents* source) {
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
53558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  args->SetInteger(webview::kProcessId,
5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   web_contents()->GetRenderProcessHost()->GetID());
537116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
5385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new GuestViewBase::Event(webview::kEventUnresponsive, args.Pass()));
53958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}
54058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WebViewGuest::Observe(int type,
542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                           const content::NotificationSource& source,
543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                           const content::NotificationDetails& details) {
544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  switch (type) {
545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: {
5461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DCHECK_EQ(content::Source<WebContents>(source).ptr(), web_contents());
5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (content::Source<WebContents>(source).ptr() == web_contents())
548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        LoadHandlerCalled();
549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: {
5521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DCHECK_EQ(content::Source<WebContents>(source).ptr(), web_contents());
553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      content::ResourceRedirectDetails* resource_redirect_details =
554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          content::Details<content::ResourceRedirectDetails>(details).ptr();
5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      bool is_top_level = resource_redirect_details->resource_type ==
5565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          content::RESOURCE_TYPE_MAIN_FRAME;
557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      LoadRedirect(resource_redirect_details->url,
558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   resource_redirect_details->new_url,
559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   is_top_level);
560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    default:
563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      NOTREACHED() << "Unexpected notification sent.";
564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)double WebViewGuest::GetZoom() {
56903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!web_view_guest_delegate_)
57003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return 1.0;
57103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return web_view_guest_delegate_->GetZoom();
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebViewGuest::Find(
575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::string16& search_text,
576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const blink::WebFindOptions& options,
5776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_refptr<WebViewInternalFindFunction> find_function) {
5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  find_helper_.Find(web_contents(), search_text, options, find_function);
579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebViewGuest::StopFinding(content::StopFindAction action) {
582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  find_helper_.CancelAllFindSessions();
5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_contents()->StopFinding(action);
584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WebViewGuest::Go(int relative_index) {
5871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_contents()->GetController().GoToOffset(relative_index);
588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
589eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid WebViewGuest::Reload() {
5917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // TODO(fsamuel): Don't check for repost because we don't want to show
5927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Chromium's repost warning. We might want to implement a separate API
5937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // for registering a callback if a repost is about to happen.
5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_contents()->GetController().Reload(false);
5957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
5967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
59768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WebViewGuest::SetUserAgentOverride(
59868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& user_agent_override) {
5996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (!attached())
6006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return;
60168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  is_overriding_user_agent_ = !user_agent_override.empty();
6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_overriding_user_agent_) {
603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::RecordAction(UserMetricsAction("WebView.Guest.OverrideUA"));
6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_contents()->SetUserAgentOverride(user_agent_override);
60668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
60768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid WebViewGuest::Stop() {
6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_contents()->Stop();
6107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid WebViewGuest::Terminate() {
613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::RecordAction(UserMetricsAction("WebView.Guest.Terminate"));
6147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::ProcessHandle process_handle =
6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      web_contents()->GetRenderProcessHost()->GetHandle();
6167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (process_handle)
6177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false);
6187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool WebViewGuest::ClearData(const base::Time remove_since,
6213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             uint32 removal_mask,
6223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             const base::Closure& callback) {
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::RecordAction(UserMetricsAction("WebView.Guest.ClearData"));
6243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content::StoragePartition* partition =
6253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      content::BrowserContext::GetStoragePartition(
6261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          web_contents()->GetBrowserContext(),
6271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          web_contents()->GetSiteInstance());
6283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!partition)
6303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
6313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  partition->ClearData(
6333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      removal_mask,
6343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL,
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GURL(),
636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      content::StoragePartition::OriginMatcherFunction(),
6373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      remove_since,
6383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      base::Time::Now(),
6393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback);
6403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return true;
6413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WebViewGuest::WebViewGuest(content::BrowserContext* browser_context,
6445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           int guest_instance_id)
6455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : GuestView<WebViewGuest>(browser_context, guest_instance_id),
6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      find_helper_(this),
6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      is_overriding_user_agent_(false),
6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      guest_opaque_(true),
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      javascript_dialog_helper_(this) {
6501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_view_guest_delegate_.reset(
6511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ExtensionsAPIClient::Get()->CreateWebViewGuestDelegate(this));
6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochWebViewGuest::~WebViewGuest() {
655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WebViewGuest::DidCommitProvisionalLoadForFrame(
658116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::RenderFrameHost* render_frame_host,
659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GURL& url,
6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ui::PageTransition transition_type) {
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  args->SetString(guestview::kUrl, url.spec());
663116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  args->SetBoolean(guestview::kIsTopLevel, !render_frame_host->GetParent());
6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  args->SetString(webview::kInternalBaseURLForDataURL,
6651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  web_contents()
6661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ->GetController()
6671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      .GetLastCommittedEntry()
6681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ->GetBaseURLForDataURL()
6691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      .spec());
670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  args->SetInteger(webview::kInternalCurrentEntryIndex,
6711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   web_contents()->GetController().GetCurrentEntryIndex());
672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  args->SetInteger(webview::kInternalEntryCount,
6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   web_contents()->GetController().GetEntryCount());
674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  args->SetInteger(webview::kInternalProcessId,
6751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   web_contents()->GetRenderProcessHost()->GetID());
676116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
6775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new GuestViewBase::Event(webview::kEventLoadCommit, args.Pass()));
6781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  find_helper_.CancelAllFindSessions();
68003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (web_view_guest_delegate_) {
68103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    web_view_guest_delegate_->OnDidCommitProvisionalLoadForFrame(
68203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        !render_frame_host->GetParent());
68303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid WebViewGuest::DidFailProvisionalLoad(
687116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::RenderFrameHost* render_frame_host,
6887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const GURL& validated_url,
6897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int error_code,
690116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::string16& error_description) {
6916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  LoadAbort(!render_frame_host->GetParent(), validated_url,
6926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            net::ErrorToShortString(error_code));
6937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WebViewGuest::DidStartProvisionalLoadForFrame(
696116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::RenderFrameHost* render_frame_host,
697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GURL& validated_url,
698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    bool is_error_page,
699116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool is_iframe_srcdoc) {
7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  args->SetString(guestview::kUrl, validated_url.spec());
702116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  args->SetBoolean(guestview::kIsTopLevel, !render_frame_host->GetParent());
703116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
7045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new GuestViewBase::Event(webview::kEventLoadStart, args.Pass()));
705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebViewGuest::DocumentLoadedInFrame(
708116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::RenderFrameHost* render_frame_host) {
70903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (web_view_guest_delegate_)
71003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    web_view_guest_delegate_->OnDocumentLoadedInFrame(render_frame_host);
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
713cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool WebViewGuest::OnMessageReceived(const IPC::Message& message,
714cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     RenderFrameHost* render_frame_host) {
715cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool handled = true;
716cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(WebViewGuest, message)
71703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionHostMsg_FrameNameChanged, OnFrameNameChanged)
718cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
720cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return handled;
721cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
722cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
723cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::RenderProcessGone(base::TerminationStatus status) {
724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Cancel all find sessions in progress.
725cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  find_helper_.CancelAllFindSessions();
726cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  args->SetInteger(webview::kProcessId,
7291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   web_contents()->GetRenderProcessHost()->GetID());
730cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  args->SetString(webview::kReason, TerminationStatusToString(status));
731116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
732116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new GuestViewBase::Event(webview::kEventExit, args.Pass()));
733cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void WebViewGuest::UserAgentOverrideSet(const std::string& user_agent) {
7366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (!attached())
7376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return;
7381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::NavigationController& controller = web_contents()->GetController();
739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::NavigationEntry* entry = controller.GetVisibleEntry();
740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!entry)
741a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
742a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  entry->SetIsOverridingUserAgent(!user_agent.empty());
7431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_contents()->GetController().Reload(false);
744a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
745a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
746cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::ReportFrameNameChange(const std::string& name) {
747cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  name_ = name;
748cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
749cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  args->SetString(webview::kName, name);
750116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
751cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new GuestViewBase::Event(webview::kEventFrameNameChanged, args.Pass()));
752cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
753cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WebViewGuest::LoadHandlerCalled() {
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
756116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
7575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new GuestViewBase::Event(webview::kEventContentLoad, args.Pass()));
758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
759eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WebViewGuest::LoadRedirect(const GURL& old_url,
761eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                const GURL& new_url,
762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                bool is_top_level) {
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  args->SetBoolean(guestview::kIsTopLevel, is_top_level);
765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  args->SetString(webview::kNewURL, new_url.spec());
766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  args->SetString(webview::kOldURL, old_url.spec());
767116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DispatchEventToEmbedder(
7685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new GuestViewBase::Event(webview::kEventLoadRedirect, args.Pass()));
769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
770eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
771116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewGuest::PushWebViewStateToIOThread() {
7721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const GURL& site_url = web_contents()->GetSiteInstance()->GetSiteURL();
773f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string partition_domain;
774f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string partition_id;
775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool in_memory;
776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!GetGuestPartitionConfigForSite(
777f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          site_url, &partition_domain, &partition_id, &in_memory)) {
778f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
780f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
781f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  WebViewRendererState::WebViewInfo web_view_info;
7836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  web_view_info.embedder_process_id = embedder_render_process_id();
7846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  web_view_info.instance_id = view_instance_id();
7856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  web_view_info.partition_id = partition_id;
7866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  web_view_info.embedder_extension_id = embedder_extension_id();
787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  content::BrowserThread::PostTask(
7896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      content::BrowserThread::IO,
7906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      FROM_HERE,
791116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&WebViewRendererState::AddGuest,
792116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(WebViewRendererState::GetInstance()),
7931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 web_contents()->GetRenderProcessHost()->GetID(),
7941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 web_contents()->GetRoutingID(),
7956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 web_view_info));
796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// static
799116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebViewGuest::RemoveWebViewStateFromIOThread(
800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    WebContents* web_contents) {
801eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  content::BrowserThread::PostTask(
802eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      content::BrowserThread::IO, FROM_HERE,
803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(
804116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          &WebViewRendererState::RemoveGuest,
805116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Unretained(WebViewRendererState::GetInstance()),
806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          web_contents->GetRenderProcessHost()->GetID(),
807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          web_contents->GetRoutingID()));
808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
8093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
810116680a4aac90f2aa7413d9095a592090648e557Ben Murdochcontent::WebContents* WebViewGuest::CreateNewGuestWindow(
811116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const content::WebContents::CreateParams& create_params) {
812116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GuestViewManager* guest_manager =
813116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      GuestViewManager::FromBrowserContext(browser_context());
814116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return guest_manager->CreateGuestWithWebContentsParams(
815116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      WebViewGuest::Type,
816116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      embedder_extension_id(),
817116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      embedder_web_contents()->GetRenderProcessHost()->GetID(),
818116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      create_params);
819116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
820116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
8210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WebViewGuest::RequestMediaAccessPermission(
822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    content::WebContents* source,
8230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const content::MediaStreamRequest& request,
8240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const content::MediaResponseCallback& callback) {
825116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  web_view_permission_helper_->RequestMediaAccessPermission(source,
826116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                            request,
827116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                            callback);
8280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
8290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
8301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool WebViewGuest::CheckMediaAccessPermission(content::WebContents* source,
8311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                              const GURL& security_origin,
8321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                              content::MediaStreamType type) {
8331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return web_view_permission_helper_->CheckMediaAccessPermission(
8341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      source, security_origin, type);
8351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
8361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WebViewGuest::CanDownload(
838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    content::RenderViewHost* render_view_host,
8390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& url,
840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& request_method,
8410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::Callback<void(bool)>& callback) {
842116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  web_view_permission_helper_->CanDownload(render_view_host,
843116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                           url,
844116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                           request_method,
845116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                           callback);
8460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
8470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
8480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WebViewGuest::RequestPointerLockPermission(
8490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool user_gesture,
8500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool last_unlocked_by_target,
8510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::Callback<void(bool)>& callback) {
852116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  web_view_permission_helper_->RequestPointerLockPermission(
853116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      user_gesture,
854116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      last_unlocked_by_target,
855116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      callback);
8560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
8570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
8586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void WebViewGuest::WillAttachToEmbedder() {
8596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // We must install the mapping from guests to WebViews prior to resuming
8606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // suspended resource loads so that the WebRequest API will catch resource
8616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // requests.
862116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PushWebViewStateToIOThread();
8636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
8646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
8650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochcontent::JavaScriptDialogManager*
8660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    WebViewGuest::GetJavaScriptDialogManager() {
8670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return &javascript_dialog_helper_;
8680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
8690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
870cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)content::ColorChooser* WebViewGuest::OpenColorChooser(
871cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    WebContents* web_contents,
872cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SkColor color,
873cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::vector<content::ColorSuggestion>& suggestions) {
874cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!attached() || !embedder_web_contents()->GetDelegate())
875cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NULL;
876cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return embedder_web_contents()->GetDelegate()->OpenColorChooser(
877cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      web_contents, color, suggestions);
878cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
879cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
880cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::NavigateGuest(const std::string& src) {
88134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  if (!attached())
88234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    return;
88334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
884cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GURL url = ResolveURL(src);
885cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
886cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Do not allow navigating a guest to schemes other than known safe schemes.
887cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This will block the embedder trying to load unwanted schemes, e.g.
888cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // chrome://settings.
889cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool scheme_is_blocked =
890cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      (!content::ChildProcessSecurityPolicy::GetInstance()->IsWebSafeScheme(
891f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)           url.scheme()) &&
892f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)       !url.SchemeIs(url::kAboutScheme)) ||
893cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url.SchemeIs(url::kJavaScriptScheme);
894cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (scheme_is_blocked || !url.is_valid()) {
8956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    LoadAbort(true /* is_top_level */, url,
8966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              net::ErrorToShortString(net::ERR_ABORTED));
897cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
898cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
899cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
900cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GURL validated_url(url);
9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_contents()->GetRenderProcessHost()->FilterURL(false, &validated_url);
902cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // As guests do not swap processes on navigation, only navigations to
903cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // normal web URLs are supported.  No protocol handlers are installed for
904cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // other schemes (e.g., WebUI or extensions), and no permissions or bindings
905cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // can be granted to the guest process.
906cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LoadURLWithParams(validated_url,
907cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    content::Referrer(),
9081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
9091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    web_contents());
910cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
911cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
912cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool WebViewGuest::HandleKeyboardShortcuts(
913cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const content::NativeWebKeyboardEvent& event) {
914cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event.type != blink::WebInputEvent::RawKeyDown)
915cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
916cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
917cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If the user hits the escape key without any modifiers then unlock the
918cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // mouse if necessary.
919cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if ((event.windowsKeyCode == ui::VKEY_ESCAPE) &&
920cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !(event.modifiers & blink::WebInputEvent::InputModifiers)) {
9211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return web_contents()->GotResponseToLockMouseRequest(false);
922cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
923cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
924cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_MACOSX)
925cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event.modifiers != blink::WebInputEvent::MetaKey)
926cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
927cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
928cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event.windowsKeyCode == ui::VKEY_OEM_4) {
929cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Go(-1);
930cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
931cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
932cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
933cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event.windowsKeyCode == ui::VKEY_OEM_6) {
934cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Go(1);
935cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
936cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#else
938cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event.windowsKeyCode == ui::VKEY_BROWSER_BACK) {
939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Go(-1);
940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
942cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (event.windowsKeyCode == ui::VKEY_BROWSER_FORWARD) {
944cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Go(1);
945cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return false;
950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
9525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WebViewGuest::SetUpAutoSize() {
9535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Read the autosize parameters passed in from the embedder.
9545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool auto_size_enabled = false;
95503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  attach_params()->GetBoolean(webview::kAttributeAutoSize, &auto_size_enabled);
9565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int max_height = 0;
9585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int max_width = 0;
95903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  attach_params()->GetInteger(webview::kAttributeMaxHeight, &max_height);
96003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  attach_params()->GetInteger(webview::kAttributeMaxWidth, &max_width);
9615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int min_height = 0;
9635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int min_width = 0;
96403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  attach_params()->GetInteger(webview::kAttributeMinHeight, &min_height);
96503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  attach_params()->GetInteger(webview::kAttributeMinWidth, &min_width);
9665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Call SetAutoSize to apply all the appropriate validation and clipping of
9685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // values.
9695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SetAutoSize(auto_size_enabled,
9705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              gfx::Size(min_width, min_height),
9715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              gfx::Size(max_width, max_height));
9725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
9735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
97403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void WebViewGuest::ShowContextMenu(
97503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int request_id,
97603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const WebViewGuestDelegate::MenuItemVector* items) {
97703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (web_view_guest_delegate_)
97803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    web_view_guest_delegate_->OnShowContextMenu(request_id, items);
979010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
980cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
981cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::SetName(const std::string& name) {
982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (name_ == name)
983cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  name_ = name;
985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
98603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Send(new ExtensionMsg_SetFrameName(routing_id(), name_));
987cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
988cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
98946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WebViewGuest::SetZoom(double zoom_factor) {
99003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (web_view_guest_delegate_)
99103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    web_view_guest_delegate_->OnSetZoom(zoom_factor);
992cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
993cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
9941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WebViewGuest::SetAllowTransparency(bool allow) {
9951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (guest_opaque_ != allow)
9961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
9971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  guest_opaque_ = !allow;
9991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!web_contents()->GetRenderViewHost()->GetView())
10001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
10011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_contents()->GetRenderViewHost()->GetView()->SetBackgroundOpaque(!allow);
10031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
10041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::AddNewContents(content::WebContents* source,
1006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  content::WebContents* new_contents,
1007cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  WindowOpenDisposition disposition,
1008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  const gfx::Rect& initial_pos,
1009cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  bool user_gesture,
1010cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  bool* was_blocked) {
1011cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (was_blocked)
1012cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *was_blocked = false;
1013cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RequestNewWindowPermission(disposition,
1014cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             initial_pos,
1015cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             user_gesture,
1016cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             new_contents);
1017cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1018cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1019cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)content::WebContents* WebViewGuest::OpenURLFromTab(
1020cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    content::WebContents* source,
1021cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const content::OpenURLParams& params) {
1022cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If the guest wishes to navigate away prior to attachment then we save the
1023cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // navigation to perform upon attachment. Navigation initializes a lot of
1024cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // state that assumes an embedder exists, such as RenderWidgetHostViewGuest.
1025cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Navigation also resumes resource loading which we don't want to allow
1026cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // until attachment.
1027cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!attached()) {
1028cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    WebViewGuest* opener = GetOpener();
1029cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PendingWindowMap::iterator it =
1030cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        opener->pending_new_windows_.find(this);
1031cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (it == opener->pending_new_windows_.end())
1032cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return NULL;
10336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const NewWindowInfo& info = it->second;
10346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    NewWindowInfo new_window_info(params.url, info.name);
10356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    new_window_info.changed = new_window_info.url != info.url;
1036cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    it->second = new_window_info;
1037cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NULL;
1038cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1039cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (params.disposition == CURRENT_TAB) {
1040cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // This can happen for cross-site redirects.
1041cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LoadURLWithParams(params.url, params.referrer, params.transition, source);
1042cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return source;
1043cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1044cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1045116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CreateNewGuestWebViewWindow(params);
1046116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return NULL;
1047cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1048cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1049cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::WebContentsCreated(WebContents* source_contents,
1050cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      int opener_render_frame_id,
1051cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      const base::string16& frame_name,
1052cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      const GURL& target_url,
1053cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      content::WebContents* new_contents) {
1054cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents);
1055cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CHECK(guest);
1056cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  guest->SetOpener(this);
1057cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string guest_name = base::UTF16ToUTF8(frame_name);
1058cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  guest->name_ = guest_name;
1059cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pending_new_windows_.insert(
1060cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      std::make_pair(guest, NewWindowInfo(target_url, guest_name)));
1061cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1062cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1063cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::LoadURLWithParams(const GURL& url,
1064cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     const content::Referrer& referrer,
10651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     ui::PageTransition transition_type,
1066cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     content::WebContents* web_contents) {
1067cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::NavigationController::LoadURLParams load_url_params(url);
1068cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  load_url_params.referrer = referrer;
1069cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  load_url_params.transition_type = transition_type;
1070cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  load_url_params.extra_headers = std::string();
1071cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (is_overriding_user_agent_) {
1072cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    load_url_params.override_user_agent =
1073cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        content::NavigationController::UA_OVERRIDE_TRUE;
1074cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1075cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  web_contents->GetController().LoadURLWithParams(load_url_params);
1076cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1077cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1078cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::RequestNewWindowPermission(
1079cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    WindowOpenDisposition disposition,
1080cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const gfx::Rect& initial_bounds,
1081cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool user_gesture,
1082cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    content::WebContents* new_contents) {
1083cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents);
1084cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!guest)
1085cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1086cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PendingWindowMap::iterator it = pending_new_windows_.find(guest);
1087cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (it == pending_new_windows_.end())
1088cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1089cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const NewWindowInfo& new_window_info = it->second;
1090cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1091f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Retrieve the opener partition info if we have it.
1092f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const GURL& site_url = new_contents->GetSiteInstance()->GetSiteURL();
1093f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string storage_partition_id = GetStoragePartitionIdFromSiteURL(site_url);
1094f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1095cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::DictionaryValue request_info;
10965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  request_info.SetInteger(webview::kInitialHeight, initial_bounds.height());
10975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  request_info.SetInteger(webview::kInitialWidth, initial_bounds.width());
1098cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  request_info.Set(webview::kTargetURL,
1099116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   new base::StringValue(new_window_info.url.spec()));
1100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request_info.Set(webview::kName, new base::StringValue(new_window_info.name));
110103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  request_info.SetInteger(webview::kWindowID, guest->guest_instance_id());
1102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // We pass in partition info so that window-s created through newwindow
1103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // API can use it to set their partition attribute.
1104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  request_info.Set(webview::kStoragePartitionId,
1105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   new base::StringValue(storage_partition_id));
1106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request_info.Set(
1107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      webview::kWindowOpenDisposition,
1108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new base::StringValue(WindowOpenDispositionToString(disposition)));
1109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  web_view_permission_helper_->
1111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW,
1112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        request_info,
1113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        base::Bind(&WebViewGuest::OnWebViewNewWindowResponse,
1114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   base::Unretained(this),
111503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                   guest->guest_instance_id()),
1116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   false /* allowed_by_default */);
1117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::DestroyUnattachedWindows() {
1120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Destroy() reaches in and removes the WebViewGuest from its opener's
1121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // pending_new_windows_ set. To avoid mutating the set while iterating, we
1122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // create a copy of the pending new windows set and iterate over the copy.
1123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PendingWindowMap pending_new_windows(pending_new_windows_);
1124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Clean up unattached new windows opened by this guest.
1125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (PendingWindowMap::const_iterator it = pending_new_windows.begin();
1126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       it != pending_new_windows.end(); ++it) {
1127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    it->first->Destroy();
1128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // All pending windows should be removed from the set after Destroy() is
1130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // called on all of them.
1131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(pending_new_windows_.empty());
1132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)GURL WebViewGuest::ResolveURL(const std::string& src) {
1135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!in_extension()) {
1136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return GURL(src);
1137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GURL default_url(base::StringPrintf("%s://%s/",
11406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                      kExtensionScheme,
1141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      embedder_extension_id().c_str()));
1142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return default_url.Resolve(src);
1143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WebViewGuest::OnWebViewNewWindowResponse(
1146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int new_window_instance_id,
1147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool allow,
1148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& user_input) {
1149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WebViewGuest* guest =
1150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      WebViewGuest::From(embedder_render_process_id(), new_window_instance_id);
1151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!guest)
1152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!allow)
1155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    guest->Destroy();
1156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
11576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
11586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace extensions
1159