From 38541979ff059ef443c0dc1bc4aab0db146cd060 Mon Sep 17 00:00:00 2001 From: "hanxi@chromium.org" Date: Sat, 26 Apr 2014 00:11:21 +0000 Subject: 1. Handle the case of empty embedder_extension_id in guestview.h. 2. Introduce a template class GuestView to handle the *guestview-specific functions in guestview.h: . Rename GuestView to GuestViewBase, introduce GuestView class, and move *ViewGuest-specific functions to GuestView: -- FromWebContents(...) -- From(...). . Introduce a template member function As() in GuestViewBase to replace all of the As*View functions. 3. In each derived *ViewGuest class , e.g., WebViewGuest & AdViewGuest, define a static variable to show its view type (string). BUG=351824 Review URL: https://codereview.chromium.org/237533008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266297 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/chrome_content_browser_client.cc | 39 +- .../extensions/api/declarative/declarative_api.cc | 2 +- .../browser/extensions/api/webview/webview_api.h | 4 +- chrome/browser/extensions/menu_manager.cc | 2 +- .../chrome_geolocation_permission_context.cc | 2 +- chrome/browser/guest_view/OWNERS | 1 + .../guest_view/ad_view/ad_view_constants.cc | 13 + .../browser/guest_view/ad_view/ad_view_constants.h | 19 + chrome/browser/guest_view/ad_view/ad_view_guest.cc | 58 ++ chrome/browser/guest_view/ad_view/ad_view_guest.h | 49 + chrome/browser/guest_view/guest_view.h | 38 + chrome/browser/guest_view/guest_view_base.cc | 205 ++++ chrome/browser/guest_view/guest_view_base.h | 143 +++ chrome/browser/guest_view/guest_view_constants.cc | 22 + chrome/browser/guest_view/guest_view_constants.h | 28 + .../web_view/context_menu_content_type_web_view.cc | 32 + .../web_view/context_menu_content_type_web_view.h | 31 + .../web_view/javascript_dialog_helper.cc | 104 ++ .../guest_view/web_view/javascript_dialog_helper.h | 53 + .../web_view/plugin_permission_helper.cc | 109 ++ .../guest_view/web_view/plugin_permission_helper.h | 48 + .../guest_view/web_view/web_view_constants.cc | 83 ++ .../guest_view/web_view/web_view_constants.h | 89 ++ .../guest_view/web_view/web_view_find_helper.cc | 279 ++++++ .../guest_view/web_view/web_view_find_helper.h | 186 ++++ .../browser/guest_view/web_view/web_view_guest.cc | 1023 +++++++++++++++++++ .../browser/guest_view/web_view/web_view_guest.h | 323 ++++++ .../web_view/web_view_permission_types.h | 30 + chrome/browser/guestview/OWNERS | 1 - .../browser/guestview/adview/adview_constants.cc | 13 - chrome/browser/guestview/adview/adview_constants.h | 19 - chrome/browser/guestview/adview/adview_guest.cc | 75 -- chrome/browser/guestview/adview/adview_guest.h | 54 - chrome/browser/guestview/guestview.cc | 223 ----- chrome/browser/guestview/guestview.h | 150 --- chrome/browser/guestview/guestview_constants.cc | 22 - chrome/browser/guestview/guestview_constants.h | 28 - .../webview/context_menu_content_type_webview.cc | 32 - .../webview/context_menu_content_type_webview.h | 31 - .../guestview/webview/javascript_dialog_helper.cc | 104 -- .../guestview/webview/javascript_dialog_helper.h | 53 - .../guestview/webview/plugin_permission_helper.cc | 109 -- .../guestview/webview/plugin_permission_helper.h | 48 - .../browser/guestview/webview/webview_constants.cc | 83 -- .../browser/guestview/webview/webview_constants.h | 89 -- .../guestview/webview/webview_find_helper.cc | 279 ------ .../guestview/webview/webview_find_helper.h | 186 ---- chrome/browser/guestview/webview/webview_guest.cc | 1038 -------------------- chrome/browser/guestview/webview/webview_guest.h | 327 ------ .../guestview/webview/webview_permission_types.h | 30 - .../context_menu_content_type_factory.cc | 4 +- .../render_view_context_menu.cc | 2 +- chrome/chrome_browser.gypi | 45 +- 53 files changed, 3015 insertions(+), 3045 deletions(-) create mode 100644 chrome/browser/guest_view/OWNERS create mode 100644 chrome/browser/guest_view/ad_view/ad_view_constants.cc create mode 100644 chrome/browser/guest_view/ad_view/ad_view_constants.h create mode 100644 chrome/browser/guest_view/ad_view/ad_view_guest.cc create mode 100644 chrome/browser/guest_view/ad_view/ad_view_guest.h create mode 100644 chrome/browser/guest_view/guest_view.h create mode 100644 chrome/browser/guest_view/guest_view_base.cc create mode 100644 chrome/browser/guest_view/guest_view_base.h create mode 100644 chrome/browser/guest_view/guest_view_constants.cc create mode 100644 chrome/browser/guest_view/guest_view_constants.h create mode 100644 chrome/browser/guest_view/web_view/context_menu_content_type_web_view.cc create mode 100644 chrome/browser/guest_view/web_view/context_menu_content_type_web_view.h create mode 100644 chrome/browser/guest_view/web_view/javascript_dialog_helper.cc create mode 100644 chrome/browser/guest_view/web_view/javascript_dialog_helper.h create mode 100644 chrome/browser/guest_view/web_view/plugin_permission_helper.cc create mode 100644 chrome/browser/guest_view/web_view/plugin_permission_helper.h create mode 100644 chrome/browser/guest_view/web_view/web_view_constants.cc create mode 100644 chrome/browser/guest_view/web_view/web_view_constants.h create mode 100644 chrome/browser/guest_view/web_view/web_view_find_helper.cc create mode 100644 chrome/browser/guest_view/web_view/web_view_find_helper.h create mode 100644 chrome/browser/guest_view/web_view/web_view_guest.cc create mode 100644 chrome/browser/guest_view/web_view/web_view_guest.h create mode 100644 chrome/browser/guest_view/web_view/web_view_permission_types.h delete mode 100644 chrome/browser/guestview/OWNERS delete mode 100644 chrome/browser/guestview/adview/adview_constants.cc delete mode 100644 chrome/browser/guestview/adview/adview_constants.h delete mode 100644 chrome/browser/guestview/adview/adview_guest.cc delete mode 100644 chrome/browser/guestview/adview/adview_guest.h delete mode 100644 chrome/browser/guestview/guestview.cc delete mode 100644 chrome/browser/guestview/guestview.h delete mode 100644 chrome/browser/guestview/guestview_constants.cc delete mode 100644 chrome/browser/guestview/guestview_constants.h delete mode 100644 chrome/browser/guestview/webview/context_menu_content_type_webview.cc delete mode 100644 chrome/browser/guestview/webview/context_menu_content_type_webview.h delete mode 100644 chrome/browser/guestview/webview/javascript_dialog_helper.cc delete mode 100644 chrome/browser/guestview/webview/javascript_dialog_helper.h delete mode 100644 chrome/browser/guestview/webview/plugin_permission_helper.cc delete mode 100644 chrome/browser/guestview/webview/plugin_permission_helper.h delete mode 100644 chrome/browser/guestview/webview/webview_constants.cc delete mode 100644 chrome/browser/guestview/webview/webview_constants.h delete mode 100644 chrome/browser/guestview/webview/webview_find_helper.cc delete mode 100644 chrome/browser/guestview/webview/webview_find_helper.h delete mode 100644 chrome/browser/guestview/webview/webview_guest.cc delete mode 100644 chrome/browser/guestview/webview/webview_guest.h delete mode 100644 chrome/browser/guestview/webview/webview_permission_types.h diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index c0eb710..9c77726 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -41,10 +41,10 @@ #include "chrome/browser/extensions/suggest_permission_util.h" #include "chrome/browser/geolocation/chrome_access_token_store.h" #include "chrome/browser/google/google_util.h" -#include "chrome/browser/guestview/adview/adview_guest.h" -#include "chrome/browser/guestview/guestview.h" -#include "chrome/browser/guestview/guestview_constants.h" -#include "chrome/browser/guestview/webview/webview_guest.h" +#include "chrome/browser/guest_view/ad_view/ad_view_guest.h" +#include "chrome/browser/guest_view/guest_view_base.h" +#include "chrome/browser/guest_view/guest_view_constants.h" +#include "chrome/browser/guest_view/web_view/web_view_guest.h" #include "chrome/browser/media/cast_transport_host_filter.h" #include "chrome/browser/media/media_capture_devices_dispatcher.h" #include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h" @@ -770,7 +770,7 @@ void ChromeContentBrowserClient::GetStoragePartitionConfigForSite( partition_name->clear(); *in_memory = false; - bool success = GuestView::GetGuestPartitionConfigForSite( + bool success = GuestViewBase::GetGuestPartitionConfigForSite( site, partition_domain, partition_name, in_memory); if (!success && site.SchemeIs(extensions::kExtensionScheme)) { @@ -836,10 +836,11 @@ void ChromeContentBrowserClient::GuestWebContentsCreated( return; } - /// TODO(fsamuel): In the future, certain types of GuestViews won't require - // extension bindings. At that point, we should clear |extension_id| instead - // of exiting early. - if (!service->GetExtensionById(extension_id, false) && + /// TODO(fsamuel): In the future, certain types of GuestViewBases won't + // require extension bindings. At that point, we should clear |extension_id| + // instead of exiting early. + if (!extension_id.empty() && + !service->GetExtensionById(extension_id, false) && !CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserPluginForAllViewTypes)) { NOTREACHED(); @@ -847,17 +848,15 @@ void ChromeContentBrowserClient::GuestWebContentsCreated( } if (opener_web_contents) { - GuestView* guest = GuestView::FromWebContents(opener_web_contents); + GuestViewBase* guest = GuestViewBase::FromWebContents(opener_web_contents); if (!guest) { NOTREACHED(); return; } - // Create a new GuestView of the same type as the opener. - *guest_delegate = - GuestView::Create(guest_web_contents, - extension_id, - guest->GetViewType()); + // Create a new GuestViewBase of the same type as the opener. + *guest_delegate = GuestViewBase::Create( + guest_web_contents, extension_id, guest->GetViewType()); return; } @@ -872,17 +871,14 @@ void ChromeContentBrowserClient::GuestWebContentsCreated( return; *guest_delegate = - GuestView::Create(guest_web_contents, - extension_id, - GuestView::GetViewTypeFromString(api_type)); + GuestViewBase::Create(guest_web_contents, extension_id, api_type); } void ChromeContentBrowserClient::GuestWebContentsAttached( WebContents* guest_web_contents, WebContents* embedder_web_contents, const base::DictionaryValue& extra_params) { - - GuestView* guest = GuestView::FromWebContents(guest_web_contents); + GuestViewBase* guest = GuestViewBase::FromWebContents(guest_web_contents); if (!guest) { // It's ok to return here, since we could be running a browser plugin // outside an extension, and don't need to attach a @@ -947,7 +943,8 @@ void ChromeContentBrowserClient::RenderProcessWillLaunch( RendererContentSettingRules rules; if (host->IsGuest()) { - GuestView::GetDefaultContentSettingRules(&rules, profile->IsOffTheRecord()); + GuestViewBase::GetDefaultContentSettingRules(&rules, + profile->IsOffTheRecord()); } else { GetRendererContentSettingRules( profile->GetHostContentSettingsMap(), &rules); diff --git a/chrome/browser/extensions/api/declarative/declarative_api.cc b/chrome/browser/extensions/api/declarative/declarative_api.cc index 3e094ff..7a644c2 100644 --- a/chrome/browser/extensions/api/declarative/declarative_api.cc +++ b/chrome/browser/extensions/api/declarative/declarative_api.cc @@ -9,7 +9,7 @@ #include "base/task_runner_util.h" #include "base/values.h" #include "chrome/browser/extensions/api/declarative/rules_registry_service.h" -#include "chrome/browser/guestview/webview/webview_guest.h" +#include "chrome/browser/guest_view/web_view/web_view_guest.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/events.h" #include "content/public/browser/browser_thread.h" diff --git a/chrome/browser/extensions/api/webview/webview_api.h b/chrome/browser/extensions/api/webview/webview_api.h index b6e011a..b90eef7 100644 --- a/chrome/browser/extensions/api/webview/webview_api.h +++ b/chrome/browser/extensions/api/webview/webview_api.h @@ -7,8 +7,8 @@ #include "chrome/browser/extensions/api/capture_web_contents_function.h" #include "chrome/browser/extensions/api/execute_code_function.h" -#include "chrome/browser/guestview/webview/webview_find_helper.h" -#include "chrome/browser/guestview/webview/webview_guest.h" +#include "chrome/browser/guest_view/web_view/web_view_find_helper.h" +#include "chrome/browser/guest_view/web_view/web_view_guest.h" // WARNING: Webview could be loaded in an unblessed context, thus any new // APIs must extend WebviewExtensionFunction/WebviewExecuteCodeFunction which diff --git a/chrome/browser/extensions/menu_manager.cc b/chrome/browser/extensions/menu_manager.cc index 6d32916..dc71cc6 100644 --- a/chrome/browser/extensions/menu_manager.cc +++ b/chrome/browser/extensions/menu_manager.cc @@ -18,7 +18,7 @@ #include "chrome/browser/extensions/menu_manager_factory.h" #include "chrome/browser/extensions/state_store.h" #include "chrome/browser/extensions/tab_helper.h" -#include "chrome/browser/guestview/webview/webview_guest.h" +#include "chrome/browser/guest_view/web_view/web_view_guest.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/context_menus.h" #include "chrome/common/extensions/api/webview.h" diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc index 7364754..f5507c7 100644 --- a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc +++ b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc @@ -15,7 +15,7 @@ #include "chrome/browser/content_settings/permission_request_id.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" #include "chrome/browser/extensions/suggest_permission_util.h" -#include "chrome/browser/guestview/webview/webview_guest.h" +#include "chrome/browser/guest_view/web_view/web_view_guest.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" diff --git a/chrome/browser/guest_view/OWNERS b/chrome/browser/guest_view/OWNERS new file mode 100644 index 0000000..c92691f --- /dev/null +++ b/chrome/browser/guest_view/OWNERS @@ -0,0 +1 @@ +fsamuel@chromium.org diff --git a/chrome/browser/guest_view/ad_view/ad_view_constants.cc b/chrome/browser/guest_view/ad_view/ad_view_constants.cc new file mode 100644 index 0000000..d083d7e --- /dev/null +++ b/chrome/browser/guest_view/ad_view/ad_view_constants.cc @@ -0,0 +1,13 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/guest_view/ad_view/ad_view_constants.h" + +namespace adview { + +// Events. +const char kEventLoadAbort[] = "adview.onLoadAbort"; +const char kEventLoadCommit[] = "adview.onLoadCommit"; + +} // namespace adview diff --git a/chrome/browser/guest_view/ad_view/ad_view_constants.h b/chrome/browser/guest_view/ad_view/ad_view_constants.h new file mode 100644 index 0000000..c7206ff --- /dev/null +++ b/chrome/browser/guest_view/ad_view/ad_view_constants.h @@ -0,0 +1,19 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Constants used for the adview API. + +#ifndef CHROME_BROWSER_GUEST_VIEW_AD_VIEW_AD_VIEW_CONSTANTS_H_ +#define CHROME_BROWSER_GUEST_VIEW_AD_VIEW_AD_VIEW_CONSTANTS_H_ + +namespace adview { + +// Events. +extern const char kEventLoadAbort[]; +extern const char kEventLoadCommit[]; + +} // namespace adview + +#endif // CHROME_BROWSER_GUEST_VIEW_AD_VIEW_AD_VIEW_CONSTANTS_H_ + diff --git a/chrome/browser/guest_view/ad_view/ad_view_guest.cc b/chrome/browser/guest_view/ad_view/ad_view_guest.cc new file mode 100644 index 0000000..c43718a --- /dev/null +++ b/chrome/browser/guest_view/ad_view/ad_view_guest.cc @@ -0,0 +1,58 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/guest_view/ad_view/ad_view_guest.h" + +#include "base/strings/string_util.h" +#include "chrome/browser/guest_view/ad_view/ad_view_constants.h" +#include "chrome/browser/guest_view/guest_view_constants.h" +#include "content/public/browser/web_contents.h" +#include "net/base/net_errors.h" + +using content::WebContents; + +AdViewGuest::AdViewGuest(WebContents* guest_web_contents, + const std::string& extension_id) + : GuestView(guest_web_contents, extension_id), + WebContentsObserver(guest_web_contents) { +} + +// static +const std::string& AdViewGuest::Type = "adview"; + +AdViewGuest::~AdViewGuest() { +} + +void AdViewGuest::DidCommitProvisionalLoadForFrame( + int64 frame_id, + const base::string16& frame_unique_name, + bool is_main_frame, + const GURL& url, + content::PageTransition transition_type, + content::RenderViewHost* render_view_host) { + scoped_ptr args(new base::DictionaryValue()); + args->SetString(guestview::kUrl, url.spec()); + args->SetBoolean(guestview::kIsTopLevel, is_main_frame); + DispatchEvent( + new GuestViewBase::Event(adview::kEventLoadCommit, args.Pass())); +} + +void AdViewGuest::DidFailProvisionalLoad( + int64 frame_id, + const base::string16& frame_unique_name, + bool is_main_frame, + const GURL& validated_url, + int error_code, + const base::string16& error_description, + content::RenderViewHost* render_view_host) { + // Translate the |error_code| into an error string. + std::string error_type; + base::RemoveChars(net::ErrorToString(error_code), "net::", &error_type); + + scoped_ptr args(new base::DictionaryValue()); + args->SetBoolean(guestview::kIsTopLevel, is_main_frame); + args->SetString(guestview::kUrl, validated_url.spec()); + args->SetString(guestview::kReason, error_type); + DispatchEvent(new GuestViewBase::Event(adview::kEventLoadAbort, args.Pass())); +} diff --git a/chrome/browser/guest_view/ad_view/ad_view_guest.h b/chrome/browser/guest_view/ad_view/ad_view_guest.h new file mode 100644 index 0000000..2374558 --- /dev/null +++ b/chrome/browser/guest_view/ad_view/ad_view_guest.h @@ -0,0 +1,49 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GUEST_VIEW_AD_VIEW_AD_VIEW_GUEST_H_ +#define CHROME_BROWSER_GUEST_VIEW_AD_VIEW_AD_VIEW_GUEST_H_ + +#include "base/values.h" +#include "chrome/browser/guest_view/guest_view.h" +#include "content/public/browser/web_contents_observer.h" + +// An AdViewGuest is a WebContentsObserver on the guest WebContents of a +// tag. It provides the browser-side implementation of the +// API and manages the lifetime of extension events. AdViewGuest is +// created on attachment. When a guest WebContents is associated with +// a particular embedder WebContents, we call this "attachment". +// TODO(fsamuel): There might be an opportunity here to refactor and reuse code +// between AdViewGuest and WebViewGuest. +class AdViewGuest : public GuestView, + public content::WebContentsObserver { + public: + AdViewGuest(content::WebContents* guest_web_contents, + const std::string& extension_id); + + static const std::string& Type; + + private: + virtual ~AdViewGuest(); + + virtual void DidCommitProvisionalLoadForFrame( + int64 frame_id, + const base::string16& frame_unique_name, + bool is_main_frame, + const GURL& url, + content::PageTransition transition_type, + content::RenderViewHost* render_view_host) OVERRIDE; + virtual void DidFailProvisionalLoad( + int64 frame_id, + const base::string16& frame_unique_name, + bool is_main_frame, + const GURL& validated_url, + int error_code, + const base::string16& error_description, + content::RenderViewHost* render_view_host) OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(AdViewGuest); +}; + +#endif // CHROME_BROWSER_GUEST_VIEW_AD_VIEW_AD_VIEW_GUEST_H_ diff --git a/chrome/browser/guest_view/guest_view.h b/chrome/browser/guest_view/guest_view.h new file mode 100644 index 0000000..9cc0954 --- /dev/null +++ b/chrome/browser/guest_view/guest_view.h @@ -0,0 +1,38 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_H_ +#define CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_H_ + +#include "chrome/browser/guest_view/guest_view_base.h" + +template +class GuestView : public GuestViewBase { + public: + static T* From(int embedder_process_id, int guest_instance_id) { + GuestViewBase* guest = + GuestViewBase::From(embedder_process_id, guest_instance_id); + if (!guest) + return NULL; + return guest->As(); + } + + static T* FromWebContents(content::WebContents* contents) { + GuestViewBase* guest = GuestViewBase::FromWebContents(contents); + return guest ? guest->As() : NULL; + } + + // GuestViewBase implementation. + virtual const std::string& GetViewType() const OVERRIDE { return T::Type; } + + protected: + GuestView(content::WebContents* guest_web_contents, + const std::string& embedder_extension_id) + : GuestViewBase(guest_web_contents, embedder_extension_id) {} + + private: + DISALLOW_COPY_AND_ASSIGN(GuestView); +}; + +#endif // CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_H_ diff --git a/chrome/browser/guest_view/guest_view_base.cc b/chrome/browser/guest_view/guest_view_base.cc new file mode 100644 index 0000000..a6ea195 --- /dev/null +++ b/chrome/browser/guest_view/guest_view_base.cc @@ -0,0 +1,205 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/guest_view/guest_view_base.h" + +#include "base/lazy_instance.h" +#include "chrome/browser/guest_view/ad_view/ad_view_guest.h" +#include "chrome/browser/guest_view/guest_view_constants.h" +#include "chrome/browser/guest_view/web_view/web_view_guest.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/content_settings.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/url_constants.h" +#include "extensions/browser/event_router.h" +#include "net/base/escape.h" + +using content::WebContents; + +namespace { + +// => GuestViewBase* +typedef std::map, GuestViewBase*> EmbedderGuestViewMap; +static base::LazyInstance embedder_guestview_map = + LAZY_INSTANCE_INITIALIZER; + +typedef std::map WebContentsGuestViewMap; +static base::LazyInstance webcontents_guestview_map = + LAZY_INSTANCE_INITIALIZER; + +} // namespace + +GuestViewBase::Event::Event(const std::string& name, + scoped_ptr args) + : name_(name), args_(args.Pass()) { +} + +GuestViewBase::Event::~Event() { +} + +scoped_ptr GuestViewBase::Event::GetArguments() { + return args_.Pass(); +} + +GuestViewBase::GuestViewBase(WebContents* guest_web_contents, + const std::string& embedder_extension_id) + : guest_web_contents_(guest_web_contents), + embedder_web_contents_(NULL), + embedder_extension_id_(embedder_extension_id), + embedder_render_process_id_(0), + browser_context_(guest_web_contents->GetBrowserContext()), + guest_instance_id_(guest_web_contents->GetEmbeddedInstanceID()), + view_instance_id_(guestview::kInstanceIDNone), + weak_ptr_factory_(this) { + webcontents_guestview_map.Get().insert( + std::make_pair(guest_web_contents, this)); +} + +// static +GuestViewBase* GuestViewBase::Create(WebContents* guest_web_contents, + const std::string& embedder_extension_id, + const std::string& view_type) { + if (view_type == "webview") { + return new WebViewGuest(guest_web_contents, embedder_extension_id); + } else if (view_type == "adview") { + return new AdViewGuest(guest_web_contents, embedder_extension_id); + } + NOTREACHED(); + return NULL; +} + +// static +GuestViewBase* GuestViewBase::FromWebContents(WebContents* web_contents) { + WebContentsGuestViewMap* guest_map = webcontents_guestview_map.Pointer(); + WebContentsGuestViewMap::iterator it = guest_map->find(web_contents); + return it == guest_map->end() ? NULL : it->second; +} + +// static +GuestViewBase* GuestViewBase::From(int embedder_process_id, + int guest_instance_id) { + EmbedderGuestViewMap* guest_map = embedder_guestview_map.Pointer(); + EmbedderGuestViewMap::iterator it = + guest_map->find(std::make_pair(embedder_process_id, guest_instance_id)); + return it == guest_map->end() ? NULL : it->second; +} + +// static +bool GuestViewBase::GetGuestPartitionConfigForSite( + const GURL& site, + std::string* partition_domain, + std::string* partition_name, + bool* in_memory) { + if (!site.SchemeIs(content::kGuestScheme)) + return false; + + // Since guest URLs are only used for packaged apps, there must be an app + // id in the URL. + CHECK(site.has_host()); + *partition_domain = site.host(); + // Since persistence is optional, the path must either be empty or the + // literal string. + *in_memory = (site.path() != "/persist"); + // The partition name is user supplied value, which we have encoded when the + // URL was created, so it needs to be decoded. + *partition_name = + net::UnescapeURLComponent(site.query(), net::UnescapeRule::NORMAL); + return true; +} + +// static +void GuestViewBase::GetDefaultContentSettingRules( + RendererContentSettingRules* rules, + bool incognito) { + rules->image_rules.push_back( + ContentSettingPatternSource(ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTING_ALLOW, + std::string(), + incognito)); + + rules->script_rules.push_back( + ContentSettingPatternSource(ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTING_ALLOW, + std::string(), + incognito)); +} + +void GuestViewBase::Attach(content::WebContents* embedder_web_contents, + const base::DictionaryValue& args) { + embedder_web_contents_ = embedder_web_contents; + embedder_render_process_id_ = + embedder_web_contents->GetRenderProcessHost()->GetID(); + args.GetInteger(guestview::kParameterInstanceId, &view_instance_id_); + + std::pair key(embedder_render_process_id_, guest_instance_id_); + embedder_guestview_map.Get().insert(std::make_pair(key, this)); + + // GuestViewBase::Attach is called prior to initialization (and initial + // navigation) of the guest in the content layer in order to permit mapping + // the necessary associations between the <*view> element and its guest. This + // is needed by the WebRequest API to allow intercepting resource + // requests during navigation. However, queued events should be fired after + // content layer initialization in order to ensure that load events (such as + // 'loadstop') fire in embedder after the contentWindow is available. + if (!in_extension()) + return; + + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&GuestViewBase::SendQueuedEvents, + weak_ptr_factory_.GetWeakPtr())); +} + +GuestViewBase::~GuestViewBase() { + std::pair key(embedder_render_process_id_, guest_instance_id_); + embedder_guestview_map.Get().erase(key); + + webcontents_guestview_map.Get().erase(guest_web_contents()); + + pending_events_.clear(); +} + +void GuestViewBase::DispatchEvent(Event* event) { + scoped_ptr event_ptr(event); + if (!in_extension()) { + NOTREACHED(); + return; + } + + if (!attached()) { + pending_events_.push_back(linked_ptr(event_ptr.release())); + return; + } + + Profile* profile = Profile::FromBrowserContext(browser_context_); + + extensions::EventFilteringInfo info; + info.SetURL(GURL()); + info.SetInstanceID(guest_instance_id_); + scoped_ptr args(new base::ListValue()); + args->Append(event->GetArguments().release()); + + extensions::EventRouter::DispatchEvent( + embedder_web_contents_, + profile, + embedder_extension_id_, + event->name(), + args.Pass(), + extensions::EventRouter::USER_GESTURE_UNKNOWN, + info); +} + +void GuestViewBase::SendQueuedEvents() { + if (!attached()) + return; + + while (!pending_events_.empty()) { + linked_ptr event_ptr = pending_events_.front(); + pending_events_.pop_front(); + DispatchEvent(event_ptr.release()); + } +} diff --git a/chrome/browser/guest_view/guest_view_base.h b/chrome/browser/guest_view/guest_view_base.h new file mode 100644 index 0000000..4422297 --- /dev/null +++ b/chrome/browser/guest_view/guest_view_base.h @@ -0,0 +1,143 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_ +#define CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_ + +#include + +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "content/public/browser/browser_plugin_guest_delegate.h" +#include "content/public/browser/web_contents.h" + +class AdViewGuest; +class WebViewGuest; +struct RendererContentSettingRules; + +// A GuestViewBase is the base class browser-side API implementation for a +// <*view> tag. GuestViewBase maintains an association between a guest +// WebContents and an embedder WebContents. It receives events issued from +// the guest and relays them to the embedder. +class GuestViewBase : public content::BrowserPluginGuestDelegate { + public: + class Event { + public: + Event(const std::string& name, scoped_ptr args); + ~Event(); + + const std::string& name() const { return name_; } + + scoped_ptr GetArguments(); + + private: + const std::string name_; + scoped_ptr args_; + }; + + // Returns a *ViewGuest if this GuestView is of the given view type. + template + T* As() { + if (GetViewType() == T::Type) { + return static_cast(this); + } + return NULL; + } + + static GuestViewBase* Create(content::WebContents* guest_web_contents, + const std::string& embedder_extension_id, + const std::string& view_type); + + static GuestViewBase* FromWebContents(content::WebContents* web_contents); + + static GuestViewBase* From(int embedder_process_id, int instance_id); + + // For GuestViewBases, we create special guest processes, which host the + // tag content separately from the main application that embeds the tag. + // A GuestViewBase can specify both the partition name and whether the storage + // for that partition should be persisted. Each tag gets a SiteInstance with + // a specially formatted URL, based on the application it is hosted by and + // the partition requested by it. The format for that URL is: + // chrome-guest://partition_domain/persist?partition_name + static bool GetGuestPartitionConfigForSite(const GURL& site, + std::string* partition_domain, + std::string* partition_name, + bool* in_memory); + + // By default, JavaScript and images are enabled in guest content. + static void GetDefaultContentSettingRules(RendererContentSettingRules* rules, + bool incognito); + + virtual const std::string& GetViewType() const = 0; + + virtual void Attach(content::WebContents* embedder_web_contents, + const base::DictionaryValue& args); + + content::WebContents* embedder_web_contents() const { + return embedder_web_contents_; + } + + // Returns the guest WebContents. + content::WebContents* guest_web_contents() const { + return guest_web_contents_; + } + + // Returns whether this guest has an associated embedder. + bool attached() const { return !!embedder_web_contents_; } + + // Returns the instance ID of the <*view> element. + int view_instance_id() const { return view_instance_id_; } + + // Returns the instance ID of the guest WebContents. + int guest_instance_id() const { return guest_instance_id_; } + + // Returns the extension ID of the embedder. + const std::string& embedder_extension_id() const { + return embedder_extension_id_; + } + + // Returns whether this GuestView is embedded in an extension/app. + bool in_extension() const { return !embedder_extension_id_.empty(); } + + // Returns the user browser context of the embedder. + content::BrowserContext* browser_context() const { return browser_context_; } + + // Returns the embedder's process ID. + int embedder_render_process_id() const { return embedder_render_process_id_; } + + protected: + GuestViewBase(content::WebContents* guest_web_contents, + const std::string& embedder_extension_id); + virtual ~GuestViewBase(); + + // Dispatches an event |event_name| to the embedder with the |event| fields. + void DispatchEvent(Event* event); + + private: + void SendQueuedEvents(); + + content::WebContents* const guest_web_contents_; + content::WebContents* embedder_web_contents_; + const std::string embedder_extension_id_; + int embedder_render_process_id_; + content::BrowserContext* const browser_context_; + // |guest_instance_id_| is a profile-wide unique identifier for a guest + // WebContents. + const int guest_instance_id_; + // |view_instance_id_| is an identifier that's unique within a particular + // embedder RenderViewHost for a particular <*view> instance. + int view_instance_id_; + + // This is a queue of Events that are destined to be sent to the embedder once + // the guest is attached to a particular embedder. + std::deque > pending_events_; + + // This is used to ensure pending tasks will not fire after this object is + // destroyed. + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(GuestViewBase); +}; + +#endif // CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_ diff --git a/chrome/browser/guest_view/guest_view_constants.cc b/chrome/browser/guest_view/guest_view_constants.cc new file mode 100644 index 0000000..844c3e13 --- /dev/null +++ b/chrome/browser/guest_view/guest_view_constants.cc @@ -0,0 +1,22 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/guest_view/guest_view_constants.h" + +namespace guestview { + +// Parameters/properties on events. +const char kIsTopLevel[] = "isTopLevel"; +const char kReason[] = "reason"; +const char kUrl[] = "url"; +const char kUserGesture[] = "userGesture"; + +// Initialization parameters. +const char kParameterApi[] = "api"; +const char kParameterInstanceId[] = "instanceId"; + +// Other. +const int kInstanceIDNone = 0; + +} // namespace guestview diff --git a/chrome/browser/guest_view/guest_view_constants.h b/chrome/browser/guest_view/guest_view_constants.h new file mode 100644 index 0000000..dbdfb62 --- /dev/null +++ b/chrome/browser/guest_view/guest_view_constants.h @@ -0,0 +1,28 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Constants used for the WebView API. + +#ifndef CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_CONSTANTS_H_ +#define CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_CONSTANTS_H_ + +namespace guestview { + +// Parameters/properties on events. +extern const char kIsTopLevel[]; +extern const char kReason[]; +extern const char kUrl[]; +extern const char kUserGesture[]; + +// Initialization parameters. +extern const char kParameterApi[]; +extern const char kParameterInstanceId[]; + +// Other. +extern const int kInstanceIDNone; + +} // namespace guestview + +#endif // CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_CONSTANTS_H_ + diff --git a/chrome/browser/guest_view/web_view/context_menu_content_type_web_view.cc b/chrome/browser/guest_view/web_view/context_menu_content_type_web_view.cc new file mode 100644 index 0000000..fa21e10 --- /dev/null +++ b/chrome/browser/guest_view/web_view/context_menu_content_type_web_view.cc @@ -0,0 +1,32 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/guest_view/web_view/context_menu_content_type_web_view.h" + +ContextMenuContentTypeWebView::ContextMenuContentTypeWebView( + content::WebContents* web_contents, + const content::ContextMenuParams& params) + : ContextMenuContentType(web_contents, params, true) { +} + +ContextMenuContentTypeWebView::~ContextMenuContentTypeWebView() { +} + +bool ContextMenuContentTypeWebView::SupportsGroup(int group) { + switch (group) { + case ITEM_GROUP_PAGE: + case ITEM_GROUP_FRAME: + case ITEM_GROUP_LINK: + case ITEM_GROUP_SEARCH_PROVIDER: + case ITEM_GROUP_PRINT: + case ITEM_GROUP_ALL_EXTENSION: + case ITEM_GROUP_PRINT_PREVIEW: + return false; + case ITEM_GROUP_CURRENT_EXTENSION: + // Show contextMenus API items. + return true; + default: + return ContextMenuContentType::SupportsGroup(group); + } +} diff --git a/chrome/browser/guest_view/web_view/context_menu_content_type_web_view.h b/chrome/browser/guest_view/web_view/context_menu_content_type_web_view.h new file mode 100644 index 0000000..8bd2388 --- /dev/null +++ b/chrome/browser/guest_view/web_view/context_menu_content_type_web_view.h @@ -0,0 +1,31 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_CONTEXT_MENU_CONTENT_TYPE_WEB_VIEW_H_ +#define CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_CONTEXT_MENU_CONTENT_TYPE_WEB_VIEW_H_ + +#include "chrome/browser/renderer_context_menu/context_menu_content_type.h" + +// A ContextMenuContentType for guest. +// Guests are rendered inside chrome apps, but have most of the actions +// that a regular web page has. Currently actions/items that are suppressed from +// guests are: searching, printing, speech and instant. +class ContextMenuContentTypeWebView : public ContextMenuContentType { + public: + virtual ~ContextMenuContentTypeWebView(); + + // ContextMenuContentType overrides. + virtual bool SupportsGroup(int group) OVERRIDE; + + protected: + ContextMenuContentTypeWebView(content::WebContents* web_contents, + const content::ContextMenuParams& params); + + private: + friend class ContextMenuContentTypeFactory; + + DISALLOW_COPY_AND_ASSIGN(ContextMenuContentTypeWebView); +}; + +#endif // CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_CONTEXT_MENU_CONTENT_TYPE_WEB_VIEW_H_ diff --git a/chrome/browser/guest_view/web_view/javascript_dialog_helper.cc b/chrome/browser/guest_view/web_view/javascript_dialog_helper.cc new file mode 100644 index 0000000..2c198e5 --- /dev/null +++ b/chrome/browser/guest_view/web_view/javascript_dialog_helper.cc @@ -0,0 +1,104 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/guest_view/web_view/javascript_dialog_helper.h" + +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "chrome/browser/guest_view/guest_view_constants.h" +#include "chrome/browser/guest_view/web_view/web_view_constants.h" +#include "chrome/browser/guest_view/web_view/web_view_guest.h" +#include "chrome/browser/guest_view/web_view/web_view_permission_types.h" + +namespace { + +std::string JavaScriptMessageTypeToString( + content::JavaScriptMessageType message_type) { + switch (message_type) { + case content::JAVASCRIPT_MESSAGE_TYPE_ALERT: + return "alert"; + case content::JAVASCRIPT_MESSAGE_TYPE_CONFIRM: + return "confirm"; + case content::JAVASCRIPT_MESSAGE_TYPE_PROMPT: + return "prompt"; + default: + NOTREACHED() << "Unknown JavaScript Message Type."; + return "unknown"; + } +} + +} // namespace + +JavaScriptDialogHelper::JavaScriptDialogHelper(WebViewGuest* guest) + : webview_guest_(guest) { +} + +JavaScriptDialogHelper::~JavaScriptDialogHelper() { +} + +void JavaScriptDialogHelper::RunJavaScriptDialog( + content::WebContents* web_contents, + const GURL& origin_url, + const std::string& accept_lang, + content::JavaScriptMessageType javascript_message_type, + const base::string16& message_text, + const base::string16& default_prompt_text, + const DialogClosedCallback& callback, + bool* did_suppress_message) { + base::DictionaryValue request_info; + request_info.Set( + webview::kDefaultPromptText, + base::Value::CreateStringValue(base::UTF16ToUTF8(default_prompt_text))); + request_info.Set( + webview::kMessageText, + base::Value::CreateStringValue(base::UTF16ToUTF8(message_text))); + request_info.Set( + webview::kMessageType, + base::Value::CreateStringValue( + JavaScriptMessageTypeToString(javascript_message_type))); + request_info.Set( + guestview::kUrl, + base::Value::CreateStringValue(origin_url.spec())); + webview_guest_->RequestPermission( + static_cast( + WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG), + request_info, + base::Bind(&JavaScriptDialogHelper::OnPermissionResponse, + base::Unretained(this), + callback), + false /* allowed_by_default */); +} + +void JavaScriptDialogHelper::RunBeforeUnloadDialog( + content::WebContents* web_contents, + const base::string16& message_text, + bool is_reload, + const DialogClosedCallback& callback) { + // This is called if the guest has a beforeunload event handler. + // This callback allows navigation to proceed. + callback.Run(true, base::string16()); +} + +bool JavaScriptDialogHelper::HandleJavaScriptDialog( + content::WebContents* web_contents, + bool accept, + const base::string16* prompt_override) { + return false; +} + +void JavaScriptDialogHelper::CancelActiveAndPendingDialogs( + content::WebContents* web_contents) { +} + +void JavaScriptDialogHelper::WebContentsDestroyed( + content::WebContents* web_contents) { +} + +void JavaScriptDialogHelper::OnPermissionResponse( + const DialogClosedCallback& callback, + bool allow, + const std::string& user_input) { + callback.Run(allow && webview_guest_->attached(), + base::UTF8ToUTF16(user_input)); +} diff --git a/chrome/browser/guest_view/web_view/javascript_dialog_helper.h b/chrome/browser/guest_view/web_view/javascript_dialog_helper.h new file mode 100644 index 0000000..94f7374 --- /dev/null +++ b/chrome/browser/guest_view/web_view/javascript_dialog_helper.h @@ -0,0 +1,53 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_JAVASCRIPT_DIALOG_HELPER_H_ +#define CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_JAVASCRIPT_DIALOG_HELPER_H_ + +#include "content/public/browser/javascript_dialog_manager.h" + +class WebViewGuest; + +class JavaScriptDialogHelper : public content::JavaScriptDialogManager { + public: + explicit JavaScriptDialogHelper(WebViewGuest* guest); + virtual ~JavaScriptDialogHelper(); + + // JavaScriptDialogManager implementation. + virtual void RunJavaScriptDialog( + content::WebContents* web_contents, + const GURL& origin_url, + const std::string& accept_lang, + content::JavaScriptMessageType javascript_message_type, + const base::string16& message_text, + const base::string16& default_prompt_text, + const DialogClosedCallback& callback, + bool* did_suppress_message) OVERRIDE; + virtual void RunBeforeUnloadDialog( + content::WebContents* web_contents, + const base::string16& message_text, + bool is_reload, + const DialogClosedCallback& callback) OVERRIDE; + virtual bool HandleJavaScriptDialog( + content::WebContents* web_contents, + bool accept, + const base::string16* prompt_override) OVERRIDE; + virtual void CancelActiveAndPendingDialogs( + content::WebContents* web_contents) OVERRIDE; + virtual void WebContentsDestroyed( + content::WebContents* web_contents) OVERRIDE; + + private: + void OnPermissionResponse( + const DialogClosedCallback& callback, + bool allow, + const std::string& user_input); + + // Pointer to the webview that is being helped. + WebViewGuest* const webview_guest_; + + DISALLOW_COPY_AND_ASSIGN(JavaScriptDialogHelper); +}; + +#endif // CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_JAVASCRIPT_DIALOG_HELPER_H_ diff --git a/chrome/browser/guest_view/web_view/plugin_permission_helper.cc b/chrome/browser/guest_view/web_view/plugin_permission_helper.cc new file mode 100644 index 0000000..12bcc7d --- /dev/null +++ b/chrome/browser/guest_view/web_view/plugin_permission_helper.cc @@ -0,0 +1,109 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/guest_view/web_view/plugin_permission_helper.h" + +#include "chrome/browser/guest_view/web_view/web_view_guest.h" +#include "chrome/browser/guest_view/web_view/web_view_permission_types.h" +#include "chrome/browser/plugins/chrome_plugin_service_filter.h" +#include "chrome/common/render_messages.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/user_metrics.h" + +using content::BrowserPluginGuestDelegate; +using content::RenderViewHost; +using content::WebContents; + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(PluginPermissionHelper); + +PluginPermissionHelper::PluginPermissionHelper(WebContents* contents) + : content::WebContentsObserver(contents), + weak_factory_(this) { +} + +PluginPermissionHelper::~PluginPermissionHelper() { +} + +bool PluginPermissionHelper::OnMessageReceived(const IPC::Message& message) { + IPC_BEGIN_MESSAGE_MAP(PluginPermissionHelper, message) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedUnauthorizedPlugin, + OnBlockedUnauthorizedPlugin) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CouldNotLoadPlugin, + OnCouldNotLoadPlugin) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedOutdatedPlugin, + OnBlockedOutdatedPlugin) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_NPAPINotSupported, + OnNPAPINotSupported) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_OpenAboutPlugins, + OnOpenAboutPlugins) +#if defined(ENABLE_PLUGIN_INSTALLATION) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FindMissingPlugin, + OnFindMissingPlugin) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RemovePluginPlaceholderHost, + OnRemovePluginPlaceholderHost) +#endif + IPC_MESSAGE_UNHANDLED(return false) + IPC_END_MESSAGE_MAP() + + return true; +} + +void PluginPermissionHelper::OnBlockedUnauthorizedPlugin( + const base::string16& name, + const std::string& identifier) { + const char kPluginName[] = "name"; + const char kPluginIdentifier[] = "identifier"; + + WebViewGuest* webview = WebViewGuest::FromWebContents(web_contents()); + if (!webview) + return; + + base::DictionaryValue info; + info.SetString(std::string(kPluginName), name); + info.SetString(std::string(kPluginIdentifier), identifier); + webview->RequestPermission(static_cast( + WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN), + info, + base::Bind(&PluginPermissionHelper::OnPermissionResponse, + weak_factory_.GetWeakPtr(), + identifier), + true /* allowed_by_default */); + content::RecordAction( + base::UserMetricsAction("WebView.Guest.PluginLoadRequest")); +} + +void PluginPermissionHelper::OnCouldNotLoadPlugin( + const base::FilePath& plugin_path) { +} + +void PluginPermissionHelper::OnBlockedOutdatedPlugin( + int placeholder_id, + const std::string& identifier) { +} + +void PluginPermissionHelper::OnNPAPINotSupported(const std::string& id) { +} + +void PluginPermissionHelper::OnOpenAboutPlugins() { +} + +#if defined(ENABLE_PLUGIN_INSTALLATION) +void PluginPermissionHelper::OnFindMissingPlugin(int placeholder_id, + const std::string& mime_type) { + Send(new ChromeViewMsg_DidNotFindMissingPlugin(placeholder_id)); +} + +void PluginPermissionHelper::OnRemovePluginPlaceholderHost(int placeholder_id) { +} +#endif // defined(ENABLE_PLUGIN_INSTALLATION) + +void PluginPermissionHelper::OnPermissionResponse(const std::string& identifier, + bool allow, + const std::string& input) { + if (allow) { + ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins( + web_contents(), true, identifier); + } +} diff --git a/chrome/browser/guest_view/web_view/plugin_permission_helper.h b/chrome/browser/guest_view/web_view/plugin_permission_helper.h new file mode 100644 index 0000000..e937bc3 --- /dev/null +++ b/chrome/browser/guest_view/web_view/plugin_permission_helper.h @@ -0,0 +1,48 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_PLUGIN_PERMISSION_HELPER_H_ +#define CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_PLUGIN_PERMISSION_HELPER_H_ + +#include "base/memory/weak_ptr.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" + +class PluginPermissionHelper + : public content::WebContentsUserData, + public content::WebContentsObserver { + public: + virtual ~PluginPermissionHelper(); + + private: + explicit PluginPermissionHelper(content::WebContents* web_contents); + friend class content::WebContentsUserData; + + // content::WebContentsObserver implementation. + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + + // Message handlers: + void OnBlockedUnauthorizedPlugin(const base::string16& name, + const std::string& identifier); + void OnCouldNotLoadPlugin(const base::FilePath& plugin_path); + void OnBlockedOutdatedPlugin(int placeholder_id, + const std::string& identifier); + void OnNPAPINotSupported(const std::string& identifier); + void OnOpenAboutPlugins(); +#if defined(ENABLE_PLUGIN_INSTALLATION) + void OnFindMissingPlugin(int placeholder_id, const std::string& mime_type); + + void OnRemovePluginPlaceholderHost(int placeholder_id); +#endif + + void OnPermissionResponse(const std::string& identifier, + bool allow, + const std::string& user_input); + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PluginPermissionHelper); +}; + +#endif // CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_PLUGIN_PERMISSION_HELPER_H_ diff --git a/chrome/browser/guest_view/web_view/web_view_constants.cc b/chrome/browser/guest_view/web_view/web_view_constants.cc new file mode 100644 index 0000000..408d1ee --- /dev/null +++ b/chrome/browser/guest_view/web_view/web_view_constants.cc @@ -0,0 +1,83 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/guest_view/web_view/web_view_constants.h" + +namespace webview { + +// Events. +const char kEventClose[] = "webview.onClose"; +const char kEventConsoleMessage[] = "webview.onConsoleMessage"; +const char kEventContentLoad[] = "webview.onContentLoad"; +const char kEventDialog[] = "webview.onDialog"; +const char kEventExit[] = "webview.onExit"; +const char kEventFindReply[] = "webview.onFindReply"; +const char kEventLoadAbort[] = "webview.onLoadAbort"; +const char kEventLoadCommit[] = "webview.onLoadCommit"; +const char kEventLoadProgress[] = "webview.onLoadProgress"; +const char kEventLoadRedirect[] = "webview.onLoadRedirect"; +const char kEventLoadStart[] = "webview.onLoadStart"; +const char kEventLoadStop[] = "webview.onLoadStop"; +const char kEventNewWindow[] = "webview.onNewWindow"; +const char kEventPermissionRequest[] = "webview.onPermissionRequest"; +const char kEventResponsive[] = "webview.onResponsive"; +const char kEventSizeChanged[] = "webview.onSizeChanged"; +const char kEventUnresponsive[] = "webview.onUnresponsive"; +const char kEventZoomChange[] = "webview.onZoomChange"; + +// Parameters/properties on events. +const char kDefaultPromptText[] = "defaultPromptText"; +const char kFindSearchText[] = "searchText"; +const char kFindFinalUpdate[] = "finalUpdate"; +const char kLastUnlockedBySelf[] = "lastUnlockedBySelf"; +const char kLevel[] = "level"; +const char kLine[] = "line"; +const char kMessage[] = "message"; +const char kMessageText[] = "messageText"; +const char kMessageType[] = "messageType"; +const char kNewHeight[] = "newHeight"; +const char kNewURL[] = "newUrl"; +const char kNewWidth[] = "newWidth"; +const char kOldHeight[] = "oldHeight"; +const char kOldURL[] = "oldUrl"; +const char kPermission[] = "permission"; +const char kPermissionTypeDialog[] = "dialog"; +const char kPermissionTypeDownload[] = "download"; +const char kPermissionTypeGeolocation[] = "geolocation"; +const char kPermissionTypeLoadPlugin[] = "loadplugin"; +const char kPermissionTypeMedia[] = "media"; +const char kPermissionTypeNewWindow[] = "newwindow"; +const char kPermissionTypePointerLock[] = "pointerLock"; +const char kOldWidth[] = "oldWidth"; +const char kProcessId[] = "processId"; +const char kProgress[] = "progress"; +const char kReason[] = "reason"; +const char kRequestId[] = "requestId"; +const char kSourceId[] = "sourceId"; +const char kOldZoomFactor[] = "oldZoomFactor"; +const char kNewZoomFactor[] = "newZoomFactor"; + +// Internal parameters/properties on events. +const char kInternalCurrentEntryIndex[] = "currentEntryIndex"; +const char kInternalEntryCount[] = "entryCount"; +const char kInternalProcessId[] = "processId"; + +// Parameters to callback functions. +const char kFindNumberOfMatches[] = "numberOfMatches"; +const char kFindActiveMatchOrdinal[] = "activeMatchOrdinal"; +const char kFindSelectionRect[] = "selectionRect"; +const char kFindRectLeft[] = "left"; +const char kFindRectTop[] = "top"; +const char kFindRectWidth[] = "width"; +const char kFindRectHeight[] = "height"; +const char kFindCanceled[] = "canceled"; + +// Initialization parameters. +const char kParameterUserAgentOverride[] = "userAgentOverride"; + +// Miscellaneous. +const unsigned int kMaxOutstandingPermissionRequests = 1024; +const int kInvalidPermissionRequestID = 0; + +} // namespace webview diff --git a/chrome/browser/guest_view/web_view/web_view_constants.h b/chrome/browser/guest_view/web_view/web_view_constants.h new file mode 100644 index 0000000..ff50895 --- /dev/null +++ b/chrome/browser/guest_view/web_view/web_view_constants.h @@ -0,0 +1,89 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Constants used for the WebView API. + +#ifndef CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_CONSTANTS_H_ +#define CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_CONSTANTS_H_ + +namespace webview { + +// Events. +extern const char kEventClose[]; +extern const char kEventConsoleMessage[]; +extern const char kEventContentLoad[]; +extern const char kEventDialog[]; +extern const char kEventExit[]; +extern const char kEventFindReply[]; +extern const char kEventLoadAbort[]; +extern const char kEventLoadCommit[]; +extern const char kEventLoadProgress[]; +extern const char kEventLoadRedirect[]; +extern const char kEventLoadStart[]; +extern const char kEventLoadStop[]; +extern const char kEventNewWindow[]; +extern const char kEventPermissionRequest[]; +extern const char kEventResponsive[]; +extern const char kEventSizeChanged[]; +extern const char kEventUnresponsive[]; +extern const char kEventZoomChange[]; + +// Parameters/properties on events. +extern const char kDefaultPromptText[]; +extern const char kFindSearchText[]; +extern const char kFindFinalUpdate[]; +extern const char kLastUnlockedBySelf[]; +extern const char kLevel[]; +extern const char kLine[]; +extern const char kMessage[]; +extern const char kMessageText[]; +extern const char kMessageType[]; +extern const char kNewHeight[]; +extern const char kNewURL[]; +extern const char kNewWidth[]; +extern const char kOldHeight[]; +extern const char kOldURL[]; +extern const char kPermission[]; +extern const char kPermissionTypeDialog[]; +extern const char kPermissionTypeDownload[]; +extern const char kPermissionTypeGeolocation[]; +extern const char kPermissionTypeLoadPlugin[]; +extern const char kPermissionTypeMedia[]; +extern const char kPermissionTypeNewWindow[]; +extern const char kPermissionTypePointerLock[]; +extern const char kOldWidth[]; +extern const char kProcessId[]; +extern const char kProgress[]; +extern const char kReason[]; +extern const char kRequestId[]; +extern const char kSourceId[]; +extern const char kOldZoomFactor[]; +extern const char kNewZoomFactor[]; + +// Internal parameters/properties on events. +extern const char kInternalCurrentEntryIndex[]; +extern const char kInternalEntryCount[]; +extern const char kInternalProcessId[]; + +// Parameters to callback functions. +extern const char kFindNumberOfMatches[]; +extern const char kFindActiveMatchOrdinal[]; +extern const char kFindSelectionRect[]; +extern const char kFindRectLeft[]; +extern const char kFindRectTop[]; +extern const char kFindRectWidth[]; +extern const char kFindRectHeight[]; +extern const char kFindCanceled[]; +extern const char kFindDone[]; + +// Initialization parameters. +extern const char kParameterUserAgentOverride[]; + +// Miscellaneous. +extern const unsigned int kMaxOutstandingPermissionRequests; +extern const int kInvalidPermissionRequestID; + +} // namespace webview + +#endif // CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_CONSTANTS_H_ diff --git a/chrome/browser/guest_view/web_view/web_view_find_helper.cc b/chrome/browser/guest_view/web_view/web_view_find_helper.cc new file mode 100644 index 0000000..e292a50 --- /dev/null +++ b/chrome/browser/guest_view/web_view/web_view_find_helper.cc @@ -0,0 +1,279 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/guest_view/web_view/web_view_find_helper.h" + +#include + +#include "chrome/browser/extensions/api/webview/webview_api.h" +#include "chrome/browser/guest_view/web_view/web_view_constants.h" + +WebviewFindHelper::WebviewFindHelper(WebViewGuest* webview_guest) + : webview_guest_(webview_guest), + current_find_request_id_(0) { +} + +WebviewFindHelper::~WebviewFindHelper() { +} + +void WebviewFindHelper::CancelAllFindSessions() { + current_find_session_ = linked_ptr(); + while (!find_info_map_.empty()) { + find_info_map_.begin()->second->SendResponse(true /* canceled */); + find_info_map_.erase(find_info_map_.begin()); + } + if (find_update_event_.get()) + DispatchFindUpdateEvent(true /* canceled */, true /* final_update */); + find_update_event_.reset(); +} + +void WebviewFindHelper::DispatchFindUpdateEvent(bool canceled, + bool final_update) { + DCHECK(find_update_event_.get()); + scoped_ptr args(new base::DictionaryValue()); + find_update_event_->PrepareResults(args.get()); + args->SetBoolean(webview::kFindCanceled, canceled); + args->SetBoolean(webview::kFindFinalUpdate, final_update); + DCHECK(webview_guest_); + webview_guest_->DispatchEvent( + new GuestViewBase::Event(webview::kEventFindReply, args.Pass())); +} + +void WebviewFindHelper::EndFindSession(int session_request_id, bool canceled) { + FindInfoMap::iterator session_iterator = + find_info_map_.find(session_request_id); + DCHECK(session_iterator != find_info_map_.end()); + FindInfo* find_info = session_iterator->second.get(); + + // Call the callback function of the first request of the find session. + find_info->SendResponse(canceled); + + // For every subsequent find request of the find session. + for (std::vector >::iterator i = + find_info->find_next_requests_.begin(); + i != find_info->find_next_requests_.end(); ++i) { + DCHECK(i->get()); + + // Do not call callbacks for subsequent find requests that have not been + // replied to yet. These requests will get their own final updates in the + // same order as they appear in |find_next_requests_|, i.e. the order that + // the requests were made in. Once one request is found that has not been + // replied to, none that follow will be replied to either, and do not need + // to be checked. + if (!(*i)->replied_) + break; + + // Update the request's number of matches (if not canceled). + if (!canceled) { + (*i)->find_results_.number_of_matches_ = + find_info->find_results_.number_of_matches_; + } + + // Call the request's callback function with the find results, and then + // delete its map entry to free the WebviewFindFunction object. + (*i)->SendResponse(canceled); + find_info_map_.erase((*i)->request_id_); + } + + // Erase the first find request's map entry to free the WebviewFindFunction + // object. + find_info_map_.erase(session_request_id); +} + +void WebviewFindHelper::Find( + content::WebContents* guest_web_contents, + const base::string16& search_text, + const blink::WebFindOptions& options, + scoped_refptr find_function) { + // Need a new request_id for each new find request. + ++current_find_request_id_; + + // Stores the find request information by request_id so that its callback + // function can be called when the find results are available. + std::pair insert_result = + find_info_map_.insert( + std::make_pair(current_find_request_id_, + linked_ptr( + new WebviewFindHelper::FindInfo( + current_find_request_id_, + search_text, + options, + find_function)))); + // No duplicate insertions. + DCHECK(insert_result.second); + + // Find options including the implicit |findNext| field. + blink::WebFindOptions* full_options = insert_result.first->second->options(); + + // Set |findNext| implicitly. + if (current_find_session_.get()) { + const base::string16& current_search_text = + current_find_session_->search_text(); + bool current_match_case = current_find_session_->options()->matchCase; + full_options->findNext = !current_search_text.empty() && + current_search_text == search_text && + current_match_case == options.matchCase; + } else { + full_options->findNext = false; + } + + // Link find requests that are a part of the same find session. + if (full_options->findNext && current_find_session_.get()) { + DCHECK(current_find_request_id_ != current_find_session_->request_id()); + current_find_session_->AddFindNextRequest( + insert_result.first->second->AsWeakPtr()); + } + + // Update the current find session, if necessary. + if (!full_options->findNext) + current_find_session_ = insert_result.first->second; + + guest_web_contents->Find(current_find_request_id_, + search_text, *full_options); +} + +void WebviewFindHelper::FindReply(int request_id, + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update) { + FindInfoMap::iterator find_iterator = find_info_map_.find(request_id); + + // Ignore slow replies to canceled find requests. + if (find_iterator == find_info_map_.end()) + return; + + // This find request must be a part of an existing find session. + DCHECK(current_find_session_.get()); + + WebviewFindHelper::FindInfo* find_info = find_iterator->second.get(); + + // Handle canceled find requests. + if (!find_info->options()->findNext && + find_info_map_.begin()->first < request_id) { + DCHECK_NE(current_find_session_->request_id(), + find_info_map_.begin()->first); + DispatchFindUpdateEvent(true /* canceled */, true /* final_update */); + EndFindSession(find_info_map_.begin()->first, true /* canceled */); + } + + // Clears the results for |findupdate| for a new find session. + if (!find_info->replied() && !find_info->options()->findNext) + find_update_event_.reset(new FindUpdateEvent(find_info->search_text())); + + // Aggregate the find results. + find_info->AggregateResults(number_of_matches, selection_rect, + active_match_ordinal, final_update); + find_update_event_->AggregateResults(number_of_matches, selection_rect, + active_match_ordinal, final_update); + + // Propagate incremental results to the |findupdate| event. + DispatchFindUpdateEvent(false /* canceled */, final_update); + + // Call the callback functions of completed find requests. + if (final_update) + EndFindSession(request_id, false /* canceled */); +} + +WebviewFindHelper::FindResults::FindResults() + : number_of_matches_(0), + active_match_ordinal_(0) {} + +WebviewFindHelper::FindResults::~FindResults() { +} + +void WebviewFindHelper::FindResults::AggregateResults( + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update) { + if (number_of_matches != -1) + number_of_matches_ = number_of_matches; + + if (active_match_ordinal != -1) + active_match_ordinal_ = active_match_ordinal; + + if (final_update && active_match_ordinal_ == 0) { + // No match found, so the selection rectangle is empty. + selection_rect_ = gfx::Rect(); + } else if (!selection_rect.IsEmpty()) { + selection_rect_ = selection_rect; + } +} + +void WebviewFindHelper::FindResults::PrepareResults( + base::DictionaryValue* results) { + results->SetInteger(webview::kFindNumberOfMatches, number_of_matches_); + results->SetInteger(webview::kFindActiveMatchOrdinal, active_match_ordinal_); + base::DictionaryValue rect; + rect.SetInteger(webview::kFindRectLeft, selection_rect_.x()); + rect.SetInteger(webview::kFindRectTop, selection_rect_.y()); + rect.SetInteger(webview::kFindRectWidth, selection_rect_.width()); + rect.SetInteger(webview::kFindRectHeight, selection_rect_.height()); + results->Set(webview::kFindSelectionRect, rect.DeepCopy()); +} + +WebviewFindHelper::FindUpdateEvent::FindUpdateEvent( + const base::string16& search_text) : search_text_(search_text) { +} + +WebviewFindHelper::FindUpdateEvent::~FindUpdateEvent() { +} + +void WebviewFindHelper::FindUpdateEvent::AggregateResults( + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update) { + find_results_.AggregateResults(number_of_matches, selection_rect, + active_match_ordinal, final_update); +} + +void WebviewFindHelper::FindUpdateEvent::PrepareResults( + base::DictionaryValue* results) { + results->SetString(webview::kFindSearchText, search_text_); + find_results_.PrepareResults(results); +} + +WebviewFindHelper::FindInfo::FindInfo( + int request_id, + const base::string16& search_text, + const blink::WebFindOptions& options, + scoped_refptr find_function) + : request_id_(request_id), + search_text_(search_text), + options_(options), + find_function_(find_function), + replied_(false), + weak_ptr_factory_(this) { +} + +WebviewFindHelper::FindInfo::~FindInfo() { +} + +void WebviewFindHelper::FindInfo::AggregateResults( + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update) { + replied_ = true; + find_results_.AggregateResults(number_of_matches, selection_rect, + active_match_ordinal, final_update); +} + +base::WeakPtr + WebviewFindHelper::FindInfo::AsWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); +} + +void WebviewFindHelper::FindInfo::SendResponse(bool canceled) { + // Prepare the find results to pass to the callback function. + base::DictionaryValue results; + find_results_.PrepareResults(&results); + results.SetBoolean(webview::kFindCanceled, canceled); + + // Call the callback. + find_function_->SetResult(results.DeepCopy()); + find_function_->SendResponse(true); +} diff --git a/chrome/browser/guest_view/web_view/web_view_find_helper.h b/chrome/browser/guest_view/web_view/web_view_find_helper.h new file mode 100644 index 0000000..d8b26e36 --- /dev/null +++ b/chrome/browser/guest_view/web_view/web_view_find_helper.h @@ -0,0 +1,186 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_FIND_HELPER_H_ +#define CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_FIND_HELPER_H_ + +#include +#include + +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "content/public/browser/web_contents.h" +#include "third_party/WebKit/public/web/WebFindOptions.h" +#include "ui/gfx/geometry/rect.h" + +namespace extensions { +class WebviewFindFunction; +} // namespace extensions +class WebViewGuest; + +// Helper class for find requests and replies for the webview find API. +class WebviewFindHelper { + public: + explicit WebviewFindHelper(WebViewGuest* webview_guest); + ~WebviewFindHelper(); + + // Cancels all find requests in progress and calls their callback functions. + void CancelAllFindSessions(); + + // Dispatches the |findupdate| event. + void DispatchFindUpdateEvent(bool canceled, bool final_update); + + // Ends the find session with id |session_request_id| and calls the + // appropriate callbacks. + void EndFindSession(int session_request_id, bool canceled); + + // Helper function for WebViewGuest::Find(). + void Find(content::WebContents* guest_web_contents, + const base::string16& search_text, + const blink::WebFindOptions& options, + scoped_refptr find_function); + + // Helper function for WeViewGuest:FindReply(). + void FindReply(int request_id, + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update); + + private: + // A wrapper to store find results. + class FindResults { + public: + FindResults(); + ~FindResults(); + + // Aggregate the find results. + void AggregateResults(int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update); + + // Stores find results into a DictionaryValue. + void PrepareResults(base::DictionaryValue* results); + + private: + int number_of_matches_; + int active_match_ordinal_; + gfx::Rect selection_rect_; + + friend void WebviewFindHelper::EndFindSession(int session_request_id, + bool canceled); + + DISALLOW_COPY_AND_ASSIGN(FindResults); + }; + + // Stores and processes the results for the |findupdate| event. + class FindUpdateEvent { + public: + explicit FindUpdateEvent(const base::string16& search_text); + ~FindUpdateEvent(); + + // Aggregate the find results. + void AggregateResults(int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update); + + // Stores find results and other event info into a DictionaryValue. + void PrepareResults(base::DictionaryValue* results); + + private: + const base::string16 search_text_; + FindResults find_results_; + + DISALLOW_COPY_AND_ASSIGN(FindUpdateEvent); + }; + + // Handles all information about a find request and its results. + class FindInfo { + public: + FindInfo(int request_id, + const base::string16& search_text, + const blink::WebFindOptions& options, + scoped_refptr find_function); + ~FindInfo(); + + // Add another request to |find_next_requests_|. + void AddFindNextRequest(const base::WeakPtr& request) { + find_next_requests_.push_back(request); + } + + // Aggregate the find results. + void AggregateResults(int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update); + + base::WeakPtr AsWeakPtr(); + + blink::WebFindOptions* options() { + return &options_; + } + + bool replied() { + return replied_; + } + + int request_id() { + return request_id_; + } + + const base::string16& search_text() { + return search_text_; + } + + // Calls the callback function within |find_function_| with the find results + // from within |find_results_|. + void SendResponse(bool canceled); + + private: + const int request_id_; + const base::string16 search_text_; + blink::WebFindOptions options_; + scoped_refptr find_function_; + FindResults find_results_; + + // A find reply has been received for this find request. + bool replied_; + + // Stores pointers to all the find next requests if this is the first + // request of a find session. + std::vector > find_next_requests_; + + // Weak pointer used to access the find info of fin. + base::WeakPtrFactory weak_ptr_factory_; + + friend void WebviewFindHelper::EndFindSession(int session_request_id, + bool canceled); + + DISALLOW_COPY_AND_ASSIGN(FindInfo); + }; + + // Pointer to the webview that is being helped. + WebViewGuest* const webview_guest_; + + // A counter to generate a unique request id for a find request. + // We only need the ids to be unique for a given WebViewGuest. + int current_find_request_id_; + + // Stores aggregated find results and other info for the |findupdate| event. + scoped_ptr find_update_event_; + + // Pointer to the first request of the current find session. + linked_ptr current_find_session_; + + // Stores each find request's information by request_id so that its callback + // function can be called when its find results are available. + typedef std::map > FindInfoMap; + FindInfoMap find_info_map_; + + DISALLOW_COPY_AND_ASSIGN(WebviewFindHelper); +}; + +#endif // CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_FIND_HELPER_H_ diff --git a/chrome/browser/guest_view/web_view/web_view_guest.cc b/chrome/browser/guest_view/web_view/web_view_guest.cc new file mode 100644 index 0000000..5365e1b --- /dev/null +++ b/chrome/browser/guest_view/web_view/web_view_guest.cc @@ -0,0 +1,1023 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/guest_view/web_view/web_view_guest.h" + +#include "base/message_loop/message_loop.h" +#include "base/strings/stringprintf.h" +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/extensions/api/web_request/web_request_api.h" +#include "chrome/browser/extensions/api/webview/webview_api.h" +#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" +#include "chrome/browser/extensions/extension_renderer_state.h" +#include "chrome/browser/extensions/menu_manager.h" +#include "chrome/browser/extensions/script_executor.h" +#include "chrome/browser/favicon/favicon_tab_helper.h" +#include "chrome/browser/guest_view/guest_view_constants.h" +#include "chrome/browser/guest_view/web_view/web_view_constants.h" +#include "chrome/browser/guest_view/web_view/web_view_permission_types.h" +#include "chrome/common/chrome_version_info.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/geolocation_permission_context.h" +#include "content/public/browser/native_web_keyboard_event.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_source.h" +#include "content/public/browser/notification_types.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/resource_request_details.h" +#include "content/public/browser/site_instance.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/user_metrics.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/common/media_stream_request.h" +#include "content/public/common/page_zoom.h" +#include "content/public/common/result_codes.h" +#include "content/public/common/stop_find_action.h" +#include "extensions/common/constants.h" +#include "net/base/net_errors.h" +#include "third_party/WebKit/public/web/WebFindOptions.h" + +#if defined(ENABLE_PLUGINS) +#include "chrome/browser/guest_view/web_view/plugin_permission_helper.h" +#endif + +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" +#endif + +using base::UserMetricsAction; +using content::WebContents; + +namespace { + +static std::string TerminationStatusToString(base::TerminationStatus status) { + switch (status) { + case base::TERMINATION_STATUS_NORMAL_TERMINATION: + return "normal"; + case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: + case base::TERMINATION_STATUS_STILL_RUNNING: + return "abnormal"; + case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: + return "killed"; + case base::TERMINATION_STATUS_PROCESS_CRASHED: +#if defined(OS_ANDROID) + case base::TERMINATION_STATUS_OOM_PROTECTED: +#endif + return "crashed"; + case base::TERMINATION_STATUS_MAX_ENUM: + break; + } + NOTREACHED() << "Unknown Termination Status."; + return "unknown"; +} + +static std::string PermissionTypeToString(BrowserPluginPermissionType type) { + switch (type) { + case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: + return webview::kPermissionTypeNewWindow; + case BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN: + NOTREACHED(); + break; + default: { + WebViewPermissionType webview = static_cast(type); + switch (webview) { + case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: + return webview::kPermissionTypeDownload; + case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION: + return webview::kPermissionTypeGeolocation; + case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: + return webview::kPermissionTypeDialog; + case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN: + return webview::kPermissionTypeLoadPlugin; + case WEB_VIEW_PERMISSION_TYPE_MEDIA: + return webview::kPermissionTypeMedia; + case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: + return webview::kPermissionTypePointerLock; + } + NOTREACHED(); + } + } + return std::string(); +} + +void RemoveWebViewEventListenersOnIOThread( + void* profile, + const std::string& extension_id, + int embedder_process_id, + int view_instance_id) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners( + profile, + extension_id, + embedder_process_id, + view_instance_id); +} + +void AttachWebViewHelpers(WebContents* contents) { + FaviconTabHelper::CreateForWebContents(contents); + extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( + contents); +#if defined(ENABLE_PLUGINS) + PluginPermissionHelper::CreateForWebContents(contents); +#endif +} + +} // namespace + +WebViewGuest::WebViewGuest(WebContents* guest_web_contents, + const std::string& extension_id) + : GuestView(guest_web_contents, extension_id), + WebContentsObserver(guest_web_contents), + script_executor_(new extensions::ScriptExecutor(guest_web_contents, + &script_observers_)), + next_permission_request_id_(0), + is_overriding_user_agent_(false), + pending_reload_on_attachment_(false), + main_frame_id_(0), + chromevox_injected_(false), + find_helper_(this), + javascript_dialog_helper_(this) { + notification_registrar_.Add( + this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, + content::Source(guest_web_contents)); + + notification_registrar_.Add( + this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, + content::Source(guest_web_contents)); + +#if defined(OS_CHROMEOS) + chromeos::AccessibilityManager* accessibility_manager = + chromeos::AccessibilityManager::Get(); + CHECK(accessibility_manager); + accessibility_subscription_ = accessibility_manager->RegisterCallback( + base::Bind(&WebViewGuest::OnAccessibilityStatusChanged, + base::Unretained(this))); +#endif + + AttachWebViewHelpers(guest_web_contents); +} + +// static +const std::string& WebViewGuest::Type = "webview"; + +// static. +int WebViewGuest::GetViewInstanceId(WebContents* contents) { + WebViewGuest* guest = FromWebContents(contents); + if (!guest) + return guestview::kInstanceIDNone; + + return guest->view_instance_id(); +} + +// static +void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, + bool allow) { + if (allow) { + // Note that |allow| == true means the embedder explicitly allowed the + // request. For some requests they might still fail. An example of such + // scenario would be: an embedder allows geolocation request but doesn't + // have geolocation access on its own. + switch (info.permission_type) { + case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: + content::RecordAction( + UserMetricsAction("BrowserPlugin.PermissionAllow.NewWindow")); + break; + case BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN: + break; + default: { + WebViewPermissionType webview_permission_type = + static_cast(info.permission_type); + switch (webview_permission_type) { + case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: + content::RecordAction( + UserMetricsAction("WebView.PermissionAllow.Download")); + break; + case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION: + content::RecordAction( + UserMetricsAction("WebView.PermissionAllow.Geolocation")); + break; + case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: + content::RecordAction( + UserMetricsAction("WebView.PermissionAllow.JSDialog")); + break; + case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN: + content::RecordAction( + UserMetricsAction("WebView.Guest.PermissionAllow.PluginLoad")); + case WEB_VIEW_PERMISSION_TYPE_MEDIA: + content::RecordAction( + UserMetricsAction("WebView.PermissionAllow.Media")); + break; + case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: + content::RecordAction( + UserMetricsAction("WebView.PermissionAllow.PointerLock")); + break; + default: + break; + } + } + } + } else { + switch (info.permission_type) { + case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: + content::RecordAction( + UserMetricsAction("BrowserPlugin.PermissionDeny.NewWindow")); + break; + case BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN: + break; + default: { + WebViewPermissionType webview_permission_type = + static_cast(info.permission_type); + switch (webview_permission_type) { + case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: + content::RecordAction( + UserMetricsAction("WebView.PermissionDeny.Download")); + break; + case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION: + content::RecordAction( + UserMetricsAction("WebView.PermissionDeny.Geolocation")); + break; + case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: + content::RecordAction( + UserMetricsAction("WebView.PermissionDeny.JSDialog")); + break; + case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN: + content::RecordAction( + UserMetricsAction("WebView.Guest.PermissionDeny.PluginLoad")); + case WEB_VIEW_PERMISSION_TYPE_MEDIA: + content::RecordAction( + UserMetricsAction("WebView.PermissionDeny.Media")); + break; + case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: + content::RecordAction( + UserMetricsAction("WebView.PermissionDeny.PointerLock")); + break; + default: + break; + } + } + } + } +} + +void WebViewGuest::Attach(WebContents* embedder_web_contents, + const base::DictionaryValue& args) { + std::string user_agent_override; + if (args.GetString(webview::kParameterUserAgentOverride, + &user_agent_override)) { + SetUserAgentOverride(user_agent_override); + } else { + SetUserAgentOverride(""); + } + + GuestViewBase::Attach(embedder_web_contents, args); + + AddWebViewToExtensionRendererState(); +} + +void WebViewGuest::AddMessageToConsole(int32 level, + const base::string16& message, + int32 line_no, + const base::string16& source_id) { + scoped_ptr args(new base::DictionaryValue()); + // Log levels are from base/logging.h: LogSeverity. + args->SetInteger(webview::kLevel, level); + args->SetString(webview::kMessage, message); + args->SetInteger(webview::kLine, line_no); + args->SetString(webview::kSourceId, source_id); + DispatchEvent( + new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass())); +} + +void WebViewGuest::Close() { + scoped_ptr args(new base::DictionaryValue()); + DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass())); +} + +void WebViewGuest::DidAttach() { + if (pending_reload_on_attachment_) { + pending_reload_on_attachment_ = false; + guest_web_contents()->GetController().Reload(false); + } +} + +void WebViewGuest::EmbedderDestroyed() { + // TODO(fsamuel): WebRequest event listeners for should survive + // reparenting of a within a single embedder. Right now, we keep + // around the browser state for the listener for the lifetime of the embedder. + // Ideally, the lifetime of the listeners should match the lifetime of the + // DOM node. Once http://crbug.com/156219 is resolved we can move + // the call to RemoveWebViewEventListenersOnIOThread back to + // WebViewGuest::WebContentsDestroyed. + content::BrowserThread::PostTask( + content::BrowserThread::IO, + FROM_HERE, + base::Bind( + &RemoveWebViewEventListenersOnIOThread, + browser_context(), embedder_extension_id(), + embedder_render_process_id(), + view_instance_id())); +} + +void WebViewGuest::FindReply(int request_id, + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update) { + find_helper_.FindReply(request_id, number_of_matches, selection_rect, + active_match_ordinal, final_update); +} + +void WebViewGuest::GuestProcessGone(base::TerminationStatus status) { + // Cancel all find sessions in progress. + find_helper_.CancelAllFindSessions(); + + scoped_ptr args(new base::DictionaryValue()); + args->SetInteger(webview::kProcessId, + guest_web_contents()->GetRenderProcessHost()->GetID()); + args->SetString(webview::kReason, TerminationStatusToString(status)); + DispatchEvent(new GuestViewBase::Event(webview::kEventExit, args.Pass())); +} + +bool WebViewGuest::HandleKeyboardEvent( + const content::NativeWebKeyboardEvent& event) { + if (event.type != blink::WebInputEvent::RawKeyDown) + return false; + +#if defined(OS_MACOSX) + if (event.modifiers != blink::WebInputEvent::MetaKey) + return false; + + if (event.windowsKeyCode == ui::VKEY_OEM_4) { + Go(-1); + return true; + } + + if (event.windowsKeyCode == ui::VKEY_OEM_6) { + Go(1); + return true; + } +#else + if (event.windowsKeyCode == ui::VKEY_BROWSER_BACK) { + Go(-1); + return true; + } + + if (event.windowsKeyCode == ui::VKEY_BROWSER_FORWARD) { + Go(1); + return true; + } +#endif + return false; +} + +bool WebViewGuest::IsDragAndDropEnabled() { + return true; +} + +bool WebViewGuest::IsOverridingUserAgent() const { + return is_overriding_user_agent_; +} + +void WebViewGuest::LoadProgressed(double progress) { + scoped_ptr args(new base::DictionaryValue()); + args->SetString(guestview::kUrl, guest_web_contents()->GetURL().spec()); + args->SetDouble(webview::kProgress, progress); + DispatchEvent( + new GuestViewBase::Event(webview::kEventLoadProgress, args.Pass())); +} + +void WebViewGuest::LoadAbort(bool is_top_level, + const GURL& url, + const std::string& error_type) { + scoped_ptr args(new base::DictionaryValue()); + args->SetBoolean(guestview::kIsTopLevel, is_top_level); + args->SetString(guestview::kUrl, url.possibly_invalid_spec()); + args->SetString(guestview::kReason, error_type); + DispatchEvent( + new GuestViewBase::Event(webview::kEventLoadAbort, args.Pass())); +} + +// TODO(fsamuel): Find a reliable way to test the 'responsive' and +// 'unresponsive' events. +void WebViewGuest::RendererResponsive() { + scoped_ptr args(new base::DictionaryValue()); + args->SetInteger(webview::kProcessId, + guest_web_contents()->GetRenderProcessHost()->GetID()); + DispatchEvent( + new GuestViewBase::Event(webview::kEventResponsive, args.Pass())); +} + +void WebViewGuest::RendererUnresponsive() { + scoped_ptr args(new base::DictionaryValue()); + args->SetInteger(webview::kProcessId, + guest_web_contents()->GetRenderProcessHost()->GetID()); + DispatchEvent( + new GuestViewBase::Event(webview::kEventUnresponsive, args.Pass())); +} + +void WebViewGuest::RequestPermission( + BrowserPluginPermissionType permission_type, + const base::DictionaryValue& request_info, + const PermissionResponseCallback& callback, + bool allowed_by_default) { + RequestPermissionInternal(permission_type, + request_info, + callback, + allowed_by_default); +} + +void WebViewGuest::Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + switch (type) { + case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: { + DCHECK_EQ(content::Source(source).ptr(), + guest_web_contents()); + if (content::Source(source).ptr() == guest_web_contents()) + LoadHandlerCalled(); + break; + } + case content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: { + DCHECK_EQ(content::Source(source).ptr(), + guest_web_contents()); + content::ResourceRedirectDetails* resource_redirect_details = + content::Details(details).ptr(); + bool is_top_level = + resource_redirect_details->resource_type == ResourceType::MAIN_FRAME; + LoadRedirect(resource_redirect_details->url, + resource_redirect_details->new_url, + is_top_level); + break; + } + default: + NOTREACHED() << "Unexpected notification sent."; + break; + } +} + +void WebViewGuest::SetZoom(double zoom_factor) { + double zoom_level = content::ZoomFactorToZoomLevel(zoom_factor); + guest_web_contents()->SetZoomLevel(zoom_level); + + scoped_ptr args(new base::DictionaryValue()); + args->SetDouble(webview::kOldZoomFactor, current_zoom_factor_); + args->SetDouble(webview::kNewZoomFactor, zoom_factor); + DispatchEvent( + new GuestViewBase::Event(webview::kEventZoomChange, args.Pass())); + + current_zoom_factor_ = zoom_factor; +} + +double WebViewGuest::GetZoom() { + return current_zoom_factor_; +} + +void WebViewGuest::Find( + const base::string16& search_text, + const blink::WebFindOptions& options, + scoped_refptr find_function) { + find_helper_.Find(guest_web_contents(), search_text, options, find_function); +} + +void WebViewGuest::StopFinding(content::StopFindAction action) { + find_helper_.CancelAllFindSessions(); + guest_web_contents()->StopFinding(action); +} + +void WebViewGuest::Go(int relative_index) { + guest_web_contents()->GetController().GoToOffset(relative_index); +} + +void WebViewGuest::Reload() { + // TODO(fsamuel): Don't check for repost because we don't want to show + // Chromium's repost warning. We might want to implement a separate API + // for registering a callback if a repost is about to happen. + guest_web_contents()->GetController().Reload(false); +} + + +void WebViewGuest::RequestGeolocationPermission( + int bridge_id, + const GURL& requesting_frame, + bool user_gesture, + const base::Callback& callback) { + base::DictionaryValue request_info; + request_info.Set(guestview::kUrl, + base::Value::CreateStringValue(requesting_frame.spec())); + request_info.Set(guestview::kUserGesture, + base::Value::CreateBooleanValue(user_gesture)); + + // It is safe to hold an unretained pointer to WebViewGuest because this + // callback is called from WebViewGuest::SetPermission. + const PermissionResponseCallback permission_callback = + base::Bind(&WebViewGuest::OnWebViewGeolocationPermissionResponse, + base::Unretained(this), + bridge_id, + user_gesture, + callback); + int request_id = RequestPermissionInternal( + static_cast( + WEB_VIEW_PERMISSION_TYPE_GEOLOCATION), + request_info, + permission_callback, + false /* allowed_by_default */); + bridge_id_to_request_id_map_[bridge_id] = request_id; +} + +void WebViewGuest::OnWebViewGeolocationPermissionResponse( + int bridge_id, + bool user_gesture, + const base::Callback& callback, + bool allow, + const std::string& user_input) { + // The embedder has allowed the permission. We now need to make sure + // that the embedder has geolocation permission. + RemoveBridgeID(bridge_id); + + if (!allow || !attached()) { + callback.Run(false); + return; + } + + content::GeolocationPermissionContext* geolocation_context = + browser_context()->GetGeolocationPermissionContext(); + + DCHECK(geolocation_context); + geolocation_context->RequestGeolocationPermission( + embedder_web_contents()->GetRenderProcessHost()->GetID(), + embedder_web_contents()->GetRoutingID(), + // The geolocation permission request here is not initiated + // through WebGeolocationPermissionRequest. We are only interested + // in the fact whether the embedder/app has geolocation + // permission. Therefore we use an invalid |bridge_id|. + -1 /* bridge_id */, + embedder_web_contents()->GetLastCommittedURL(), + user_gesture, + callback); +} + +void WebViewGuest::CancelGeolocationPermissionRequest(int bridge_id) { + int request_id = RemoveBridgeID(bridge_id); + RequestMap::iterator request_itr = + pending_permission_requests_.find(request_id); + + if (request_itr == pending_permission_requests_.end()) + return; + + pending_permission_requests_.erase(request_itr); +} + +void WebViewGuest::OnWebViewMediaPermissionResponse( + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback, + bool allow, + const std::string& user_input) { + if (!allow || !attached()) { + // Deny the request. + callback.Run(content::MediaStreamDevices(), + content::MEDIA_DEVICE_INVALID_STATE, + scoped_ptr()); + return; + } + if (!embedder_web_contents()->GetDelegate()) + return; + + embedder_web_contents()->GetDelegate()-> + RequestMediaAccessPermission(embedder_web_contents(), request, callback); +} + +void WebViewGuest::OnWebViewDownloadPermissionResponse( + const base::Callback& callback, + bool allow, + const std::string& user_input) { + callback.Run(allow && attached()); +} + +void WebViewGuest::OnWebViewPointerLockPermissionResponse( + const base::Callback& callback, + bool allow, + const std::string& user_input) { + callback.Run(allow && attached()); +} + +WebViewGuest::SetPermissionResult WebViewGuest::SetPermission( + int request_id, + PermissionResponseAction action, + const std::string& user_input) { + RequestMap::iterator request_itr = + pending_permission_requests_.find(request_id); + + if (request_itr == pending_permission_requests_.end()) + return SET_PERMISSION_INVALID; + + const PermissionResponseInfo& info = request_itr->second; + bool allow = (action == ALLOW) || + ((action == DEFAULT) && info.allowed_by_default); + + info.callback.Run(allow, user_input); + + // Only record user initiated (i.e. non-default) actions. + if (action != DEFAULT) + RecordUserInitiatedUMA(info, allow); + + pending_permission_requests_.erase(request_itr); + + return allow ? SET_PERMISSION_ALLOWED : SET_PERMISSION_DENIED; +} + +void WebViewGuest::SetUserAgentOverride( + const std::string& user_agent_override) { + is_overriding_user_agent_ = !user_agent_override.empty(); + if (is_overriding_user_agent_) { + content::RecordAction(UserMetricsAction("WebView.Guest.OverrideUA")); + } + guest_web_contents()->SetUserAgentOverride(user_agent_override); +} + +void WebViewGuest::Stop() { + guest_web_contents()->Stop(); +} + +void WebViewGuest::Terminate() { + content::RecordAction(UserMetricsAction("WebView.Guest.Terminate")); + base::ProcessHandle process_handle = + guest_web_contents()->GetRenderProcessHost()->GetHandle(); + if (process_handle) + base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false); +} + +bool WebViewGuest::ClearData(const base::Time remove_since, + uint32 removal_mask, + const base::Closure& callback) { + content::RecordAction(UserMetricsAction("WebView.Guest.ClearData")); + content::StoragePartition* partition = + content::BrowserContext::GetStoragePartition( + guest_web_contents()->GetBrowserContext(), + guest_web_contents()->GetSiteInstance()); + + if (!partition) + return false; + + partition->ClearData( + removal_mask, + content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL, + GURL(), + content::StoragePartition::OriginMatcherFunction(), + remove_since, + base::Time::Now(), + callback); + return true; +} + +WebViewGuest::~WebViewGuest() { +} + +void WebViewGuest::DidCommitProvisionalLoadForFrame( + int64 frame_id, + const base::string16& frame_unique_name, + bool is_main_frame, + const GURL& url, + content::PageTransition transition_type, + content::RenderViewHost* render_view_host) { + find_helper_.CancelAllFindSessions(); + + scoped_ptr args(new base::DictionaryValue()); + args->SetString(guestview::kUrl, url.spec()); + args->SetBoolean(guestview::kIsTopLevel, is_main_frame); + args->SetInteger(webview::kInternalCurrentEntryIndex, + guest_web_contents()->GetController().GetCurrentEntryIndex()); + args->SetInteger(webview::kInternalEntryCount, + guest_web_contents()->GetController().GetEntryCount()); + args->SetInteger(webview::kInternalProcessId, + guest_web_contents()->GetRenderProcessHost()->GetID()); + DispatchEvent( + new GuestViewBase::Event(webview::kEventLoadCommit, args.Pass())); + + // Update the current zoom factor for the new page. + current_zoom_factor_ = content::ZoomLevelToZoomFactor( + guest_web_contents()->GetZoomLevel()); + + if (is_main_frame) { + chromevox_injected_ = false; + main_frame_id_ = frame_id; + } +} + +void WebViewGuest::DidFailProvisionalLoad( + int64 frame_id, + const base::string16& frame_unique_name, + bool is_main_frame, + const GURL& validated_url, + int error_code, + const base::string16& error_description, + content::RenderViewHost* render_view_host) { + // Translate the |error_code| into an error string. + std::string error_type; + base::RemoveChars(net::ErrorToString(error_code), "net::", &error_type); + LoadAbort(is_main_frame, validated_url, error_type); +} + +void WebViewGuest::DidStartProvisionalLoadForFrame( + int64 frame_id, + int64 parent_frame_id, + bool is_main_frame, + const GURL& validated_url, + bool is_error_page, + bool is_iframe_srcdoc, + content::RenderViewHost* render_view_host) { + scoped_ptr args(new base::DictionaryValue()); + args->SetString(guestview::kUrl, validated_url.spec()); + args->SetBoolean(guestview::kIsTopLevel, is_main_frame); + DispatchEvent( + new GuestViewBase::Event(webview::kEventLoadStart, args.Pass())); +} + +void WebViewGuest::DocumentLoadedInFrame( + int64 frame_id, + content::RenderViewHost* render_view_host) { + if (frame_id == main_frame_id_) + InjectChromeVoxIfNeeded(render_view_host); +} + +void WebViewGuest::DidStopLoading(content::RenderViewHost* render_view_host) { + scoped_ptr args(new base::DictionaryValue()); + DispatchEvent(new GuestViewBase::Event(webview::kEventLoadStop, args.Pass())); +} + +void WebViewGuest::WebContentsDestroyed(WebContents* web_contents) { + // Clean up custom context menu items for this guest. + extensions::MenuManager* menu_manager = extensions::MenuManager::Get( + Profile::FromBrowserContext(browser_context())); + menu_manager->RemoveAllContextItems(extensions::MenuItem::ExtensionKey( + embedder_extension_id(), view_instance_id())); + + RemoveWebViewFromExtensionRendererState(web_contents); +} + +void WebViewGuest::UserAgentOverrideSet(const std::string& user_agent) { + content::NavigationController& controller = + guest_web_contents()->GetController(); + content::NavigationEntry* entry = controller.GetVisibleEntry(); + if (!entry) + return; + entry->SetIsOverridingUserAgent(!user_agent.empty()); + if (!attached()) { + // We cannot reload now because all resource loads are suspended until + // attachment. + pending_reload_on_attachment_ = true; + return; + } + guest_web_contents()->GetController().Reload(false); +} + +void WebViewGuest::LoadHandlerCalled() { + scoped_ptr args(new base::DictionaryValue()); + DispatchEvent( + new GuestViewBase::Event(webview::kEventContentLoad, args.Pass())); +} + +void WebViewGuest::LoadRedirect(const GURL& old_url, + const GURL& new_url, + bool is_top_level) { + scoped_ptr args(new base::DictionaryValue()); + args->SetBoolean(guestview::kIsTopLevel, is_top_level); + args->SetString(webview::kNewURL, new_url.spec()); + args->SetString(webview::kOldURL, old_url.spec()); + DispatchEvent( + new GuestViewBase::Event(webview::kEventLoadRedirect, args.Pass())); +} + +void WebViewGuest::AddWebViewToExtensionRendererState() { + const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); + std::string partition_domain; + std::string partition_id; + bool in_memory; + if (!GetGuestPartitionConfigForSite( + site_url, &partition_domain, &partition_id, &in_memory)) { + NOTREACHED(); + return; + } + DCHECK(embedder_extension_id() == partition_domain); + + ExtensionRendererState::WebViewInfo webview_info; + webview_info.embedder_process_id = embedder_render_process_id(); + webview_info.instance_id = view_instance_id(); + webview_info.partition_id = partition_id; + webview_info.embedder_extension_id = embedder_extension_id(); + + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind( + &ExtensionRendererState::AddWebView, + base::Unretained(ExtensionRendererState::GetInstance()), + guest_web_contents()->GetRenderProcessHost()->GetID(), + guest_web_contents()->GetRoutingID(), + webview_info)); +} + +// static +void WebViewGuest::RemoveWebViewFromExtensionRendererState( + WebContents* web_contents) { + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind( + &ExtensionRendererState::RemoveWebView, + base::Unretained(ExtensionRendererState::GetInstance()), + web_contents->GetRenderProcessHost()->GetID(), + web_contents->GetRoutingID())); +} + +GURL WebViewGuest::ResolveURL(const std::string& src) { + if (!in_extension()) { + NOTREACHED(); + return GURL(src); + } + + GURL default_url(base::StringPrintf("%s://%s/", + extensions::kExtensionScheme, + embedder_extension_id().c_str())); + return default_url.Resolve(src); +} + +void WebViewGuest::SizeChanged(const gfx::Size& old_size, + const gfx::Size& new_size) { + scoped_ptr args(new base::DictionaryValue()); + args->SetInteger(webview::kOldHeight, old_size.height()); + args->SetInteger(webview::kOldWidth, old_size.width()); + args->SetInteger(webview::kNewHeight, new_size.height()); + args->SetInteger(webview::kNewWidth, new_size.width()); + DispatchEvent( + new GuestViewBase::Event(webview::kEventSizeChanged, args.Pass())); +} + +void WebViewGuest::RequestMediaAccessPermission( + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) { + base::DictionaryValue request_info; + request_info.Set( + guestview::kUrl, + base::Value::CreateStringValue(request.security_origin.spec())); + RequestPermission(static_cast( + WEB_VIEW_PERMISSION_TYPE_MEDIA), + request_info, + base::Bind(&WebViewGuest::OnWebViewMediaPermissionResponse, + base::Unretained(this), + request, + callback), + false /* allowed_by_default */); +} + +void WebViewGuest::CanDownload( + const std::string& request_method, + const GURL& url, + const base::Callback& callback) { + base::DictionaryValue request_info; + request_info.Set( + guestview::kUrl, + base::Value::CreateStringValue(url.spec())); + RequestPermission( + static_cast( + WEB_VIEW_PERMISSION_TYPE_DOWNLOAD), + request_info, + base::Bind(&WebViewGuest::OnWebViewDownloadPermissionResponse, + base::Unretained(this), + callback), + false /* allowed_by_default */); +} + +void WebViewGuest::RequestPointerLockPermission( + bool user_gesture, + bool last_unlocked_by_target, + const base::Callback& callback) { + base::DictionaryValue request_info; + request_info.Set(guestview::kUserGesture, + base::Value::CreateBooleanValue(user_gesture)); + request_info.Set(webview::kLastUnlockedBySelf, + base::Value::CreateBooleanValue(last_unlocked_by_target)); + request_info.Set(guestview::kUrl, + base::Value::CreateStringValue( + guest_web_contents()->GetLastCommittedURL().spec())); + + RequestPermission( + static_cast( + WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK), + request_info, + base::Bind(&WebViewGuest::OnWebViewPointerLockPermissionResponse, + base::Unretained(this), + callback), + false /* allowed_by_default */); +} + +content::JavaScriptDialogManager* + WebViewGuest::GetJavaScriptDialogManager() { + return &javascript_dialog_helper_; +} + +#if defined(OS_CHROMEOS) +void WebViewGuest::OnAccessibilityStatusChanged( + const chromeos::AccessibilityStatusEventDetails& details) { + if (details.notification_type == chromeos::ACCESSIBILITY_MANAGER_SHUTDOWN) { + accessibility_subscription_.reset(); + } else if (details.notification_type == + chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) { + if (details.enabled) + InjectChromeVoxIfNeeded(guest_web_contents()->GetRenderViewHost()); + else + chromevox_injected_ = false; + } +} +#endif + +void WebViewGuest::InjectChromeVoxIfNeeded( + content::RenderViewHost* render_view_host) { +#if defined(OS_CHROMEOS) + if (!chromevox_injected_) { + chromeos::AccessibilityManager* manager = + chromeos::AccessibilityManager::Get(); + if (manager && manager->IsSpokenFeedbackEnabled()) { + manager->InjectChromeVox(render_view_host); + chromevox_injected_ = true; + } + } +#endif +} + +int WebViewGuest::RemoveBridgeID(int bridge_id) { + std::map::iterator bridge_itr = + bridge_id_to_request_id_map_.find(bridge_id); + if (bridge_itr == bridge_id_to_request_id_map_.end()) + return webview::kInvalidPermissionRequestID; + + int request_id = bridge_itr->second; + bridge_id_to_request_id_map_.erase(bridge_itr); + return request_id; +} + +int WebViewGuest::RequestPermissionInternal( + BrowserPluginPermissionType permission_type, + const base::DictionaryValue& request_info, + const PermissionResponseCallback& callback, + bool allowed_by_default) { + // If there are too many pending permission requests then reject this request. + if (pending_permission_requests_.size() >= + webview::kMaxOutstandingPermissionRequests) { + // Let the stack unwind before we deny the permission request so that + // objects held by the permission request are not destroyed immediately + // after creation. This is to allow those same objects to be accessed again + // in the same scope without fear of use after freeing. + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&PermissionResponseCallback::Run, + base::Owned(new PermissionResponseCallback(callback)), + allowed_by_default, + std::string())); + return webview::kInvalidPermissionRequestID; + } + + int request_id = next_permission_request_id_++; + pending_permission_requests_[request_id] = + PermissionResponseInfo(callback, permission_type, allowed_by_default); + scoped_ptr args(request_info.DeepCopy()); + args->SetInteger(webview::kRequestId, request_id); + switch (static_cast(permission_type)) { + case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: { + DispatchEvent( + new GuestViewBase::Event(webview::kEventNewWindow, args.Pass())); + break; + } + case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: { + DispatchEvent( + new GuestViewBase::Event(webview::kEventDialog, args.Pass())); + break; + } + default: { + args->SetString(webview::kPermission, + PermissionTypeToString(permission_type)); + DispatchEvent(new GuestViewBase::Event(webview::kEventPermissionRequest, + args.Pass())); + break; + } + } + return request_id; +} + +WebViewGuest::PermissionResponseInfo::PermissionResponseInfo() + : permission_type(BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN), + allowed_by_default(false) { +} + +WebViewGuest::PermissionResponseInfo::PermissionResponseInfo( + const PermissionResponseCallback& callback, + BrowserPluginPermissionType permission_type, + bool allowed_by_default) + : callback(callback), + permission_type(permission_type), + allowed_by_default(allowed_by_default) { +} + +WebViewGuest::PermissionResponseInfo::~PermissionResponseInfo() { +} diff --git a/chrome/browser/guest_view/web_view/web_view_guest.h b/chrome/browser/guest_view/web_view/web_view_guest.h new file mode 100644 index 0000000..98c2e31 --- /dev/null +++ b/chrome/browser/guest_view/web_view/web_view_guest.h @@ -0,0 +1,323 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_ +#define CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_ + +#include "base/observer_list.h" +#include "chrome/browser/extensions/tab_helper.h" +#include "chrome/browser/guest_view/guest_view.h" +#include "chrome/browser/guest_view/web_view/javascript_dialog_helper.h" +#include "chrome/browser/guest_view/web_view/web_view_find_helper.h" +#include "content/public/browser/javascript_dialog_manager.h" +#include "content/public/browser/notification_registrar.h" +#include "content/public/browser/web_contents_observer.h" +#include "third_party/WebKit/public/web/WebFindOptions.h" + +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" +#endif + +namespace extensions { +class ScriptExecutor; +class WebviewFindFunction; +} // namespace extensions + +// A WebViewGuest is a WebContentsObserver on the guest WebContents of a +// tag. It provides the browser-side implementation of the +// API and manages the lifetime of extension events. WebViewGuest is +// created on attachment. That is, when a guest WebContents is associated with +// a particular embedder WebContents. This happens on either initial navigation +// or through the use of the New Window API, when a new window is attached to +// a particular . +class WebViewGuest : public GuestView, + public content::NotificationObserver, + public content::WebContentsObserver { + public: + WebViewGuest(content::WebContents* guest_web_contents, + const std::string& embedder_extension_id); + + // Returns guestview::kInstanceIDNone if |contents| does not correspond to a + // WebViewGuest. + static int GetViewInstanceId(content::WebContents* contents); + static const std::string& Type; + + // GuestViewBase implementation. + virtual void Attach(content::WebContents* embedder_web_contents, + const base::DictionaryValue& args) OVERRIDE; + + // GuestDelegate implementation. + virtual void AddMessageToConsole(int32 level, + const base::string16& message, + int32 line_no, + const base::string16& source_id) OVERRIDE; + virtual void LoadProgressed(double progress) OVERRIDE; + virtual void Close() OVERRIDE; + virtual void DidAttach() OVERRIDE; + virtual void EmbedderDestroyed() OVERRIDE; + virtual void FindReply(int request_id, + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update) OVERRIDE; + virtual void GuestProcessGone(base::TerminationStatus status) OVERRIDE; + virtual bool HandleKeyboardEvent( + const content::NativeWebKeyboardEvent& event) OVERRIDE; + virtual bool IsDragAndDropEnabled() OVERRIDE; + virtual bool IsOverridingUserAgent() const OVERRIDE; + virtual void LoadAbort(bool is_top_level, + const GURL& url, + const std::string& error_type) OVERRIDE; + virtual void RendererResponsive() OVERRIDE; + virtual void RendererUnresponsive() OVERRIDE; + virtual void RequestPermission( + BrowserPluginPermissionType permission_type, + const base::DictionaryValue& request_info, + const PermissionResponseCallback& callback, + bool allowed_by_default) OVERRIDE; + virtual GURL ResolveURL(const std::string& src) OVERRIDE; + virtual void SizeChanged(const gfx::Size& old_size, const gfx::Size& new_size) + OVERRIDE; + virtual void RequestMediaAccessPermission( + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) OVERRIDE; + virtual void CanDownload(const std::string& request_method, + const GURL& url, + const base::Callback& callback) OVERRIDE; + virtual void RequestPointerLockPermission( + bool user_gesture, + bool last_unlocked_by_target, + const base::Callback& callback) OVERRIDE; + virtual content::JavaScriptDialogManager* + GetJavaScriptDialogManager() OVERRIDE; + + // NotificationObserver implementation. + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + + // Set the zoom factor. + virtual void SetZoom(double zoom_factor) OVERRIDE; + + // Returns the current zoom factor. + double GetZoom(); + + // Begin or continue a find request. + void Find(const base::string16& search_text, + const blink::WebFindOptions& options, + scoped_refptr find_function); + + // Conclude a find request to clear highlighting. + void StopFinding(content::StopFindAction); + + // If possible, navigate the guest to |relative_index| entries away from the + // current navigation entry. + void Go(int relative_index); + + // Reload the guest. + void Reload(); + + // Requests Geolocation Permission from the embedder. + void RequestGeolocationPermission(int bridge_id, + const GURL& requesting_frame, + bool user_gesture, + const base::Callback& callback); + + void OnWebViewGeolocationPermissionResponse( + int bridge_id, + bool user_gesture, + const base::Callback& callback, + bool allow, + const std::string& user_input); + + void CancelGeolocationPermissionRequest(int bridge_id); + + void OnWebViewMediaPermissionResponse( + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback, + bool allow, + const std::string& user_input); + + void OnWebViewDownloadPermissionResponse( + const base::Callback& callback, + bool allow, + const std::string& user_input); + + void OnWebViewPointerLockPermissionResponse( + const base::Callback& callback, + bool allow, + const std::string& user_input); + + enum PermissionResponseAction { + DENY, + ALLOW, + DEFAULT + }; + + enum SetPermissionResult { + SET_PERMISSION_INVALID, + SET_PERMISSION_ALLOWED, + SET_PERMISSION_DENIED + }; + + // Responds to the permission request |request_id| with |action| and + // |user_input|. Returns whether there was a pending request for the provided + // |request_id|. + SetPermissionResult SetPermission(int request_id, + PermissionResponseAction action, + const std::string& user_input); + + // Overrides the user agent for this guest. + // This affects subsequent guest navigations. + void SetUserAgentOverride(const std::string& user_agent_override); + + // Stop loading the guest. + void Stop(); + + // Kill the guest process. + void Terminate(); + + // Clears data in the storage partition of this guest. + // + // Partition data that are newer than |removal_since| will be removed. + // |removal_mask| corresponds to bitmask in StoragePartition::RemoveDataMask. + bool ClearData(const base::Time remove_since, + uint32 removal_mask, + const base::Closure& callback); + + extensions::ScriptExecutor* script_executor() { + return script_executor_.get(); + } + + private: + virtual ~WebViewGuest(); + + // A map to store the callback for a request keyed by the request's id. + struct PermissionResponseInfo { + PermissionResponseCallback callback; + BrowserPluginPermissionType permission_type; + bool allowed_by_default; + PermissionResponseInfo(); + PermissionResponseInfo(const PermissionResponseCallback& callback, + BrowserPluginPermissionType permission_type, + bool allowed_by_default); + ~PermissionResponseInfo(); + }; + + static void RecordUserInitiatedUMA(const PermissionResponseInfo& info, + bool allow); + // WebContentsObserver implementation. + virtual void DidCommitProvisionalLoadForFrame( + int64 frame_id, + const base::string16& frame_unique_name, + bool is_main_frame, + const GURL& url, + content::PageTransition transition_type, + content::RenderViewHost* render_view_host) OVERRIDE; + virtual void DidFailProvisionalLoad( + int64 frame_id, + const base::string16& frame_unique_name, + bool is_main_frame, + const GURL& validated_url, + int error_code, + const base::string16& error_description, + content::RenderViewHost* render_view_host) OVERRIDE; + virtual void DidStartProvisionalLoadForFrame( + int64 frame_id, + int64 parent_frame_id, + bool is_main_frame, + const GURL& validated_url, + bool is_error_page, + bool is_iframe_srcdoc, + content::RenderViewHost* render_view_host) OVERRIDE; + virtual void DocumentLoadedInFrame( + int64 frame_id, + content::RenderViewHost* render_view_host) OVERRIDE; + virtual void DidStopLoading( + content::RenderViewHost* render_view_host) OVERRIDE; + virtual void WebContentsDestroyed( + content::WebContents* web_contents) OVERRIDE; + virtual void UserAgentOverrideSet(const std::string& user_agent) OVERRIDE; + + // Called after the load handler is called in the guest's main frame. + void LoadHandlerCalled(); + + // Called when a redirect notification occurs. + void LoadRedirect(const GURL& old_url, + const GURL& new_url, + bool is_top_level); + + void AddWebViewToExtensionRendererState(); + static void RemoveWebViewFromExtensionRendererState( + content::WebContents* web_contents); + +#if defined(OS_CHROMEOS) + // Notification of a change in the state of an accessibility setting. + void OnAccessibilityStatusChanged( + const chromeos::AccessibilityStatusEventDetails& details); +#endif + + void InjectChromeVoxIfNeeded(content::RenderViewHost* render_view_host); + + // Bridge IDs correspond to a geolocation request. This method will remove + // the bookkeeping for a particular geolocation request associated with the + // provided |bridge_id|. It returns the request ID of the geolocation request. + int RemoveBridgeID(int bridge_id); + + int RequestPermissionInternal( + BrowserPluginPermissionType permission_type, + const base::DictionaryValue& request_info, + const PermissionResponseCallback& callback, + bool allowed_by_default); + + ObserverList + script_observers_; + scoped_ptr script_executor_; + + content::NotificationRegistrar notification_registrar_; + + // A counter to generate a unique request id for a permission request. + // We only need the ids to be unique for a given WebViewGuest. + int next_permission_request_id_; + + typedef std::map RequestMap; + RequestMap pending_permission_requests_; + + // True if the user agent is overridden. + bool is_overriding_user_agent_; + + // Indicates that the page needs to be reloaded once it has been attached to + // an embedder. + bool pending_reload_on_attachment_; + + // Main frame ID of last committed page. + int64 main_frame_id_; + + // Set to |true| if ChromeVox was already injected in main frame. + bool chromevox_injected_; + + // Stores the current zoom factor. + double current_zoom_factor_; + + // Handles find requests and replies for the webview find API. + WebviewFindHelper find_helper_; + + // Handles the JavaScript dialog requests. + JavaScriptDialogHelper javascript_dialog_helper_; + + friend void WebviewFindHelper::DispatchFindUpdateEvent(bool canceled, + bool final_update); + +#if defined(OS_CHROMEOS) + // Subscription to receive notifications on changes to a11y settings. + scoped_ptr + accessibility_subscription_; +#endif + + std::map bridge_id_to_request_id_map_; + + DISALLOW_COPY_AND_ASSIGN(WebViewGuest); +}; + +#endif // CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_ diff --git a/chrome/browser/guest_view/web_view/web_view_permission_types.h b/chrome/browser/guest_view/web_view/web_view_permission_types.h new file mode 100644 index 0000000..11df574 --- /dev/null +++ b/chrome/browser/guest_view/web_view/web_view_permission_types.h @@ -0,0 +1,30 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_PERMISSION_TYPES_H_ +#define CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_PERMISSION_TYPES_H_ + +#include "content/public/common/browser_plugin_permission_type.h" + +enum WebViewPermissionType { + WEB_VIEW_PERMISSION_TYPE_DOWNLOAD = + BROWSER_PLUGIN_PERMISSION_TYPE_CONTENT_END + 1, + + WEB_VIEW_PERMISSION_TYPE_GEOLOCATION, + + // JavaScript Dialogs: prompt, alert, confirm + // Note: Even through dialogs do not use the permission API, the dialog API + // is sufficiently similiar that it's convenient to consider it a permission + // type for code reuse. + WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG, + + WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN, + + // Media access (audio/video) permission request type. + WEB_VIEW_PERMISSION_TYPE_MEDIA, + + WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK +}; + +#endif // CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_PERMISSION_TYPES_H_ diff --git a/chrome/browser/guestview/OWNERS b/chrome/browser/guestview/OWNERS deleted file mode 100644 index c92691f..0000000 --- a/chrome/browser/guestview/OWNERS +++ /dev/null @@ -1 +0,0 @@ -fsamuel@chromium.org diff --git a/chrome/browser/guestview/adview/adview_constants.cc b/chrome/browser/guestview/adview/adview_constants.cc deleted file mode 100644 index 8ba709c..0000000 --- a/chrome/browser/guestview/adview/adview_constants.cc +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/guestview/adview/adview_constants.h" - -namespace adview { - -// Events. -const char kEventLoadAbort[] = "adview.onLoadAbort"; -const char kEventLoadCommit[] = "adview.onLoadCommit"; - -} // namespace adview diff --git a/chrome/browser/guestview/adview/adview_constants.h b/chrome/browser/guestview/adview/adview_constants.h deleted file mode 100644 index 5bb5490..0000000 --- a/chrome/browser/guestview/adview/adview_constants.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Constants used for the adview API. - -#ifndef CHROME_BROWSER_GUESTVIEW_ADVIEW_ADVIEW_CONSTANTS_H_ -#define CHROME_BROWSER_GUESTVIEW_ADVIEW_ADVIEW_CONSTANTS_H_ - -namespace adview { - -// Events. -extern const char kEventLoadAbort[]; -extern const char kEventLoadCommit[]; - -} // namespace adview - -#endif // CHROME_BROWSER_GUESTVIEW_ADVIEW_ADVIEW_CONSTANTS_H_ - diff --git a/chrome/browser/guestview/adview/adview_guest.cc b/chrome/browser/guestview/adview/adview_guest.cc deleted file mode 100644 index 6b0de6f..0000000 --- a/chrome/browser/guestview/adview/adview_guest.cc +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/guestview/adview/adview_guest.h" - -#include "base/strings/string_util.h" -#include "chrome/browser/guestview/adview/adview_constants.h" -#include "chrome/browser/guestview/guestview_constants.h" -#include "content/public/browser/web_contents.h" -#include "net/base/net_errors.h" - -using content::WebContents; - -AdViewGuest::AdViewGuest(WebContents* guest_web_contents, - const std::string& extension_id) - : GuestView(guest_web_contents, extension_id), - WebContentsObserver(guest_web_contents) { -} - -// static -AdViewGuest* AdViewGuest::From(int embedder_process_id, - int guest_instance_id) { - GuestView* guest = GuestView::From(embedder_process_id, guest_instance_id); - if (!guest) - return NULL; - return guest->AsAdView(); -} - -GuestView::Type AdViewGuest::GetViewType() const { - return GuestView::ADVIEW; -} - -WebViewGuest* AdViewGuest::AsWebView() { - return NULL; -} - -AdViewGuest* AdViewGuest::AsAdView() { - return this; -} - -AdViewGuest::~AdViewGuest() { -} - -void AdViewGuest::DidCommitProvisionalLoadForFrame( - int64 frame_id, - const base::string16& frame_unique_name, - bool is_main_frame, - const GURL& url, - content::PageTransition transition_type, - content::RenderViewHost* render_view_host) { - scoped_ptr args(new base::DictionaryValue()); - args->SetString(guestview::kUrl, url.spec()); - args->SetBoolean(guestview::kIsTopLevel, is_main_frame); - DispatchEvent(new GuestView::Event(adview::kEventLoadCommit, args.Pass())); -} - -void AdViewGuest::DidFailProvisionalLoad( - int64 frame_id, - const base::string16& frame_unique_name, - bool is_main_frame, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - content::RenderViewHost* render_view_host) { - // Translate the |error_code| into an error string. - std::string error_type; - base::RemoveChars(net::ErrorToString(error_code), "net::", &error_type); - - scoped_ptr args(new base::DictionaryValue()); - args->SetBoolean(guestview::kIsTopLevel, is_main_frame); - args->SetString(guestview::kUrl, validated_url.spec()); - args->SetString(guestview::kReason, error_type); - DispatchEvent(new GuestView::Event(adview::kEventLoadAbort, args.Pass())); -} diff --git a/chrome/browser/guestview/adview/adview_guest.h b/chrome/browser/guestview/adview/adview_guest.h deleted file mode 100644 index aaefe00..0000000 --- a/chrome/browser/guestview/adview/adview_guest.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_GUESTVIEW_ADVIEW_ADVIEW_GUEST_H_ -#define CHROME_BROWSER_GUESTVIEW_ADVIEW_ADVIEW_GUEST_H_ - -#include "base/values.h" -#include "chrome/browser/guestview/guestview.h" -#include "content/public/browser/web_contents_observer.h" - -// An AdViewGuest is a WebContentsObserver on the guest WebContents of a -// tag. It provides the browser-side implementation of the -// API and manages the lifetime of extension events. AdViewGuest is -// created on attachment. When a guest WebContents is associated with -// a particular embedder WebContents, we call this "attachment". -// TODO(fsamuel): There might be an opportunity here to refactor and reuse code -// between AdViewGuest and WebViewGuest. -class AdViewGuest : public GuestView, - public content::WebContentsObserver { - public: - AdViewGuest(content::WebContents* guest_web_contents, - const std::string& extension_id); - - static AdViewGuest* From(int embedder_process_id, int instance_id); - - // GuestView implementation. - virtual GuestView::Type GetViewType() const OVERRIDE; - virtual WebViewGuest* AsWebView() OVERRIDE; - virtual AdViewGuest* AsAdView() OVERRIDE; - - private: - virtual ~AdViewGuest(); - - virtual void DidCommitProvisionalLoadForFrame( - int64 frame_id, - const base::string16& frame_unique_name, - bool is_main_frame, - const GURL& url, - content::PageTransition transition_type, - content::RenderViewHost* render_view_host) OVERRIDE; - virtual void DidFailProvisionalLoad( - int64 frame_id, - const base::string16& frame_unique_name, - bool is_main_frame, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - content::RenderViewHost* render_view_host) OVERRIDE; - - DISALLOW_COPY_AND_ASSIGN(AdViewGuest); -}; - -#endif // CHROME_BROWSER_GUESTVIEW_ADVIEW_ADVIEW_GUEST_H_ diff --git a/chrome/browser/guestview/guestview.cc b/chrome/browser/guestview/guestview.cc deleted file mode 100644 index 7cd6c59b..0000000 --- a/chrome/browser/guestview/guestview.cc +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/guestview/guestview.h" - -#include "base/lazy_instance.h" -#include "chrome/browser/guestview/adview/adview_guest.h" -#include "chrome/browser/guestview/guestview_constants.h" -#include "chrome/browser/guestview/webview/webview_guest.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/content_settings.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/url_constants.h" -#include "extensions/browser/event_router.h" -#include "net/base/escape.h" - -using content::WebContents; - -namespace { - -// => GuestView* -typedef std::map, GuestView*> EmbedderGuestViewMap; -static base::LazyInstance embedder_guestview_map = - LAZY_INSTANCE_INITIALIZER; - -typedef std::map WebContentsGuestViewMap; -static base::LazyInstance webcontents_guestview_map = - LAZY_INSTANCE_INITIALIZER; - -} // namespace - -GuestView::Event::Event(const std::string& name, - scoped_ptr args) - : name_(name), - args_(args.Pass()) { -} - -GuestView::Event::~Event() { -} - -scoped_ptr GuestView::Event::GetArguments() { - return args_.Pass(); -} - -GuestView::GuestView(WebContents* guest_web_contents, - const std::string& embedder_extension_id) - : guest_web_contents_(guest_web_contents), - embedder_web_contents_(NULL), - embedder_extension_id_(embedder_extension_id), - embedder_render_process_id_(0), - browser_context_(guest_web_contents->GetBrowserContext()), - guest_instance_id_(guest_web_contents->GetEmbeddedInstanceID()), - view_instance_id_(guestview::kInstanceIDNone), - weak_ptr_factory_(this) { - webcontents_guestview_map.Get().insert( - std::make_pair(guest_web_contents, this)); -} - -// static -GuestView::Type GuestView::GetViewTypeFromString(const std::string& api_type) { - if (api_type == "adview") { - return GuestView::ADVIEW; - } else if (api_type == "webview") { - return GuestView::WEBVIEW; - } - return GuestView::UNKNOWN; -} - -// static -GuestView* GuestView::Create(WebContents* guest_web_contents, - const std::string& embedder_extension_id, - GuestView::Type view_type) { - switch (view_type) { - case GuestView::WEBVIEW: - return new WebViewGuest(guest_web_contents, embedder_extension_id); - case GuestView::ADVIEW: - return new AdViewGuest(guest_web_contents, embedder_extension_id); - default: - NOTREACHED(); - return NULL; - } -} - -// static -GuestView* GuestView::FromWebContents(WebContents* web_contents) { - WebContentsGuestViewMap* guest_map = webcontents_guestview_map.Pointer(); - WebContentsGuestViewMap::iterator it = guest_map->find(web_contents); - return it == guest_map->end() ? NULL : it->second; -} - -// static -GuestView* GuestView::From(int embedder_process_id, int guest_instance_id) { - EmbedderGuestViewMap* guest_map = embedder_guestview_map.Pointer(); - EmbedderGuestViewMap::iterator it = guest_map->find( - std::make_pair(embedder_process_id, guest_instance_id)); - return it == guest_map->end() ? NULL : it->second; -} - -// static -bool GuestView::GetGuestPartitionConfigForSite(const GURL& site, - std::string* partition_domain, - std::string* partition_name, - bool* in_memory) { - if (!site.SchemeIs(content::kGuestScheme)) - return false; - - // Since guest URLs are only used for packaged apps, there must be an app - // id in the URL. - CHECK(site.has_host()); - *partition_domain = site.host(); - // Since persistence is optional, the path must either be empty or the - // literal string. - *in_memory = (site.path() != "/persist"); - // The partition name is user supplied value, which we have encoded when the - // URL was created, so it needs to be decoded. - *partition_name = net::UnescapeURLComponent(site.query(), - net::UnescapeRule::NORMAL); - return true; -} - -// static -void GuestView::GetDefaultContentSettingRules( - RendererContentSettingRules* rules, bool incognito) { - rules->image_rules.push_back(ContentSettingPatternSource( - ContentSettingsPattern::Wildcard(), - ContentSettingsPattern::Wildcard(), - CONTENT_SETTING_ALLOW, - std::string(), - incognito)); - - rules->script_rules.push_back(ContentSettingPatternSource( - ContentSettingsPattern::Wildcard(), - ContentSettingsPattern::Wildcard(), - CONTENT_SETTING_ALLOW, - std::string(), - incognito)); -} - -void GuestView::Attach(content::WebContents* embedder_web_contents, - const base::DictionaryValue& args) { - embedder_web_contents_ = embedder_web_contents; - embedder_render_process_id_ = - embedder_web_contents->GetRenderProcessHost()->GetID(); - args.GetInteger(guestview::kParameterInstanceId, &view_instance_id_); - - std::pair key(embedder_render_process_id_, guest_instance_id_); - embedder_guestview_map.Get().insert(std::make_pair(key, this)); - - // GuestView::Attach is called prior to initialization (and initial - // navigation) of the guest in the content layer in order to permit mapping - // the necessary associations between the <*view> element and its guest. This - // is needed by the WebRequest API to allow intercepting resource - // requests during navigation. However, queued events should be fired after - // content layer initialization in order to ensure that load events (such as - // 'loadstop') fire in embedder after the contentWindow is available. - if (!in_extension()) - return; - - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&GuestView::SendQueuedEvents, - weak_ptr_factory_.GetWeakPtr())); -} - -GuestView::Type GuestView::GetViewType() const { - return GuestView::UNKNOWN; -} - -WebViewGuest* GuestView::AsWebView() { - return NULL; -} - -AdViewGuest* GuestView::AsAdView() { - return NULL; -} - -GuestView::~GuestView() { - std::pair key(embedder_render_process_id_, guest_instance_id_); - embedder_guestview_map.Get().erase(key); - - webcontents_guestview_map.Get().erase(guest_web_contents()); - - pending_events_.clear(); -} - -void GuestView::DispatchEvent(Event* event) { - scoped_ptr event_ptr(event); - if (!in_extension()) { - NOTREACHED(); - return; - } - - if (!attached()) { - pending_events_.push_back(linked_ptr(event_ptr.release())); - return; - } - - Profile* profile = Profile::FromBrowserContext(browser_context_); - - extensions::EventFilteringInfo info; - info.SetURL(GURL()); - info.SetInstanceID(guest_instance_id_); - scoped_ptr args(new base::ListValue()); - args->Append(event->GetArguments().release()); - - extensions::EventRouter::DispatchEvent( - embedder_web_contents_, profile, embedder_extension_id_, - event->name(), args.Pass(), - extensions::EventRouter::USER_GESTURE_UNKNOWN, info); -} - -void GuestView::SendQueuedEvents() { - if (!attached()) - return; - - while (!pending_events_.empty()) { - linked_ptr event_ptr = pending_events_.front(); - pending_events_.pop_front(); - DispatchEvent(event_ptr.release()); - } -} diff --git a/chrome/browser/guestview/guestview.h b/chrome/browser/guestview/guestview.h deleted file mode 100644 index 3ff23f4..0000000 --- a/chrome/browser/guestview/guestview.h +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_GUESTVIEW_GUESTVIEW_H_ -#define CHROME_BROWSER_GUESTVIEW_GUESTVIEW_H_ - -#include - -#include "base/memory/weak_ptr.h" -#include "base/values.h" -#include "content/public/browser/browser_plugin_guest_delegate.h" -#include "content/public/browser/web_contents.h" - -class AdViewGuest; -class WebViewGuest; -struct RendererContentSettingRules; - -// A GuestView is the base class browser-side API implementation for a <*view> -// tag. GuestView maintains an association between a guest WebContents and an -// embedder WebContents. It receives events issued from the guest and relays -// them to the embedder. -class GuestView : public content::BrowserPluginGuestDelegate { - public: - enum Type { - WEBVIEW, - ADVIEW, - UNKNOWN - }; - - class Event { - public: - Event(const std::string& name, scoped_ptr args); - ~Event(); - - const std::string& name() const { return name_; } - - scoped_ptr GetArguments(); - - private: - const std::string name_; - scoped_ptr args_; - }; - - static Type GetViewTypeFromString(const std::string& api_type); - - static GuestView* Create(content::WebContents* guest_web_contents, - const std::string& embedder_extension_id, - Type view_type); - - static GuestView* FromWebContents(content::WebContents* web_contents); - - static GuestView* From(int embedder_process_id, int instance_id); - - // For GuestViews, we create special guest processes, which host the - // tag content separately from the main application that embeds the tag. - // A GuestView can specify both the partition name and whether the storage - // for that partition should be persisted. Each tag gets a SiteInstance with - // a specially formatted URL, based on the application it is hosted by and - // the partition requested by it. The format for that URL is: - // chrome-guest://partition_domain/persist?partition_name - static bool GetGuestPartitionConfigForSite(const GURL& site, - std::string* partition_domain, - std::string* partition_name, - bool* in_memory); - - // By default, JavaScript and images are enabled in guest content. - static void GetDefaultContentSettingRules( - RendererContentSettingRules* rules, bool incognito); - - virtual void Attach(content::WebContents* embedder_web_contents, - const base::DictionaryValue& args); - - content::WebContents* embedder_web_contents() const { - return embedder_web_contents_; - } - - // Returns the guest WebContents. - content::WebContents* guest_web_contents() const { - return guest_web_contents_; - } - - virtual Type GetViewType() const; - - // Returns a WebViewGuest if this GuestView belongs to a . - virtual WebViewGuest* AsWebView() = 0; - - // Returns an AdViewGuest if the GuestView belongs to an . - virtual AdViewGuest* AsAdView() = 0; - - // Returns whether this guest has an associated embedder. - bool attached() const { return !!embedder_web_contents_; } - - // Returns the instance ID of the <*view> element. - int view_instance_id() const { return view_instance_id_; } - - // Returns the instance ID of the guest WebContents. - int guest_instance_id() const { return guest_instance_id_; } - - // Returns the extension ID of the embedder. - const std::string& embedder_extension_id() const { - return embedder_extension_id_; - } - - // Returns whether this GuestView is embedded in an extension/app. - bool in_extension() const { - return !embedder_extension_id_.empty(); - } - - // Returns the user browser context of the embedder. - content::BrowserContext* browser_context() const { return browser_context_; } - - // Returns the embedder's process ID. - int embedder_render_process_id() const { return embedder_render_process_id_; } - - protected: - GuestView(content::WebContents* guest_web_contents, - const std::string& embedder_extension_id); - virtual ~GuestView(); - - // Dispatches an event |event_name| to the embedder with the |event| fields. - void DispatchEvent(Event* event); - - private: - void SendQueuedEvents(); - - content::WebContents* const guest_web_contents_; - content::WebContents* embedder_web_contents_; - const std::string embedder_extension_id_; - int embedder_render_process_id_; - content::BrowserContext* const browser_context_; - // |guest_instance_id_| is a profile-wide unique identifier for a guest - // WebContents. - const int guest_instance_id_; - // |view_instance_id_| is an identifier that's unique within a particular - // embedder RenderViewHost for a particular <*view> instance. - int view_instance_id_; - - // This is a queue of Events that are destined to be sent to the embedder once - // the guest is attached to a particular embedder. - std::deque > pending_events_; - - // This is used to ensure pending tasks will not fire after this object is - // destroyed. - base::WeakPtrFactory weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(GuestView); -}; - -#endif // CHROME_BROWSER_GUESTVIEW_GUESTVIEW_H_ diff --git a/chrome/browser/guestview/guestview_constants.cc b/chrome/browser/guestview/guestview_constants.cc deleted file mode 100644 index d1d9e82..0000000 --- a/chrome/browser/guestview/guestview_constants.cc +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/guestview/guestview_constants.h" - -namespace guestview { - -// Parameters/properties on events. -const char kIsTopLevel[] = "isTopLevel"; -const char kReason[] = "reason"; -const char kUrl[] = "url"; -const char kUserGesture[] = "userGesture"; - -// Initialization parameters. -const char kParameterApi[] = "api"; -const char kParameterInstanceId[] = "instanceId"; - -// Other. -const int kInstanceIDNone = 0; - -} // namespace guestview diff --git a/chrome/browser/guestview/guestview_constants.h b/chrome/browser/guestview/guestview_constants.h deleted file mode 100644 index 7f1e03e..0000000 --- a/chrome/browser/guestview/guestview_constants.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Constants used for the WebView API. - -#ifndef CHROME_BROWSER_GUESTVIEW_GUESTVIEW_CONSTANTS_H_ -#define CHROME_BROWSER_GUESTVIEW_GUESTVIEW_CONSTANTS_H_ - -namespace guestview { - -// Parameters/properties on events. -extern const char kIsTopLevel[]; -extern const char kReason[]; -extern const char kUrl[]; -extern const char kUserGesture[]; - -// Initialization parameters. -extern const char kParameterApi[]; -extern const char kParameterInstanceId[]; - -// Other. -extern const int kInstanceIDNone; - -} // namespace guestview - -#endif // CHROME_BROWSER_GUESTVIEW_GUESTVIEW_CONSTANTS_H_ - diff --git a/chrome/browser/guestview/webview/context_menu_content_type_webview.cc b/chrome/browser/guestview/webview/context_menu_content_type_webview.cc deleted file mode 100644 index 4db0e80..0000000 --- a/chrome/browser/guestview/webview/context_menu_content_type_webview.cc +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/guestview/webview/context_menu_content_type_webview.h" - -ContextMenuContentTypeWebView::ContextMenuContentTypeWebView( - content::WebContents* web_contents, - const content::ContextMenuParams& params) - : ContextMenuContentType(web_contents, params, true) { -} - -ContextMenuContentTypeWebView::~ContextMenuContentTypeWebView() { -} - -bool ContextMenuContentTypeWebView::SupportsGroup(int group) { - switch (group) { - case ITEM_GROUP_PAGE: - case ITEM_GROUP_FRAME: - case ITEM_GROUP_LINK: - case ITEM_GROUP_SEARCH_PROVIDER: - case ITEM_GROUP_PRINT: - case ITEM_GROUP_ALL_EXTENSION: - case ITEM_GROUP_PRINT_PREVIEW: - return false; - case ITEM_GROUP_CURRENT_EXTENSION: - // Show contextMenus API items. - return true; - default: - return ContextMenuContentType::SupportsGroup(group); - } -} diff --git a/chrome/browser/guestview/webview/context_menu_content_type_webview.h b/chrome/browser/guestview/webview/context_menu_content_type_webview.h deleted file mode 100644 index 9c87334..0000000 --- a/chrome/browser/guestview/webview/context_menu_content_type_webview.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_GUESTVIEW_WEBVIEW_CONTEXT_MENU_CONTENT_TYPE_WEBVIEW_H_ -#define CHROME_BROWSER_GUESTVIEW_WEBVIEW_CONTEXT_MENU_CONTENT_TYPE_WEBVIEW_H_ - -#include "chrome/browser/renderer_context_menu/context_menu_content_type.h" - -// A ContextMenuContentType for guest. -// Guests are rendered inside chrome apps, but have most of the actions -// that a regular web page has. Currently actions/items that are suppressed from -// guests are: searching, printing, speech and instant. -class ContextMenuContentTypeWebView : public ContextMenuContentType { - public: - virtual ~ContextMenuContentTypeWebView(); - - // ContextMenuContentType overrides. - virtual bool SupportsGroup(int group) OVERRIDE; - - protected: - ContextMenuContentTypeWebView(content::WebContents* web_contents, - const content::ContextMenuParams& params); - - private: - friend class ContextMenuContentTypeFactory; - - DISALLOW_COPY_AND_ASSIGN(ContextMenuContentTypeWebView); -}; - -#endif // CHROME_BROWSER_GUESTVIEW_WEBVIEW_CONTEXT_MENU_CONTENT_TYPE_WEBVIEW_H_ diff --git a/chrome/browser/guestview/webview/javascript_dialog_helper.cc b/chrome/browser/guestview/webview/javascript_dialog_helper.cc deleted file mode 100644 index 8173f06..0000000 --- a/chrome/browser/guestview/webview/javascript_dialog_helper.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/guestview/webview/javascript_dialog_helper.h" - -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/guestview/guestview_constants.h" -#include "chrome/browser/guestview/webview/webview_constants.h" -#include "chrome/browser/guestview/webview/webview_guest.h" -#include "chrome/browser/guestview/webview/webview_permission_types.h" - -namespace { - -std::string JavaScriptMessageTypeToString( - content::JavaScriptMessageType message_type) { - switch (message_type) { - case content::JAVASCRIPT_MESSAGE_TYPE_ALERT: - return "alert"; - case content::JAVASCRIPT_MESSAGE_TYPE_CONFIRM: - return "confirm"; - case content::JAVASCRIPT_MESSAGE_TYPE_PROMPT: - return "prompt"; - default: - NOTREACHED() << "Unknown JavaScript Message Type."; - return "unknown"; - } -} - -} // namespace - -JavaScriptDialogHelper::JavaScriptDialogHelper(WebViewGuest* guest) - : webview_guest_(guest) { -} - -JavaScriptDialogHelper::~JavaScriptDialogHelper() { -} - -void JavaScriptDialogHelper::RunJavaScriptDialog( - content::WebContents* web_contents, - const GURL& origin_url, - const std::string& accept_lang, - content::JavaScriptMessageType javascript_message_type, - const base::string16& message_text, - const base::string16& default_prompt_text, - const DialogClosedCallback& callback, - bool* did_suppress_message) { - base::DictionaryValue request_info; - request_info.Set( - webview::kDefaultPromptText, - base::Value::CreateStringValue(base::UTF16ToUTF8(default_prompt_text))); - request_info.Set( - webview::kMessageText, - base::Value::CreateStringValue(base::UTF16ToUTF8(message_text))); - request_info.Set( - webview::kMessageType, - base::Value::CreateStringValue( - JavaScriptMessageTypeToString(javascript_message_type))); - request_info.Set( - guestview::kUrl, - base::Value::CreateStringValue(origin_url.spec())); - webview_guest_->RequestPermission( - static_cast( - WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG), - request_info, - base::Bind(&JavaScriptDialogHelper::OnPermissionResponse, - base::Unretained(this), - callback), - false /* allowed_by_default */); -} - -void JavaScriptDialogHelper::RunBeforeUnloadDialog( - content::WebContents* web_contents, - const base::string16& message_text, - bool is_reload, - const DialogClosedCallback& callback) { - // This is called if the guest has a beforeunload event handler. - // This callback allows navigation to proceed. - callback.Run(true, base::string16()); -} - -bool JavaScriptDialogHelper::HandleJavaScriptDialog( - content::WebContents* web_contents, - bool accept, - const base::string16* prompt_override) { - return false; -} - -void JavaScriptDialogHelper::CancelActiveAndPendingDialogs( - content::WebContents* web_contents) { -} - -void JavaScriptDialogHelper::WebContentsDestroyed( - content::WebContents* web_contents) { -} - -void JavaScriptDialogHelper::OnPermissionResponse( - const DialogClosedCallback& callback, - bool allow, - const std::string& user_input) { - callback.Run(allow && webview_guest_->attached(), - base::UTF8ToUTF16(user_input)); -} diff --git a/chrome/browser/guestview/webview/javascript_dialog_helper.h b/chrome/browser/guestview/webview/javascript_dialog_helper.h deleted file mode 100644 index 4f536bd..0000000 --- a/chrome/browser/guestview/webview/javascript_dialog_helper.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_GUESTVIEW_WEBVIEW_JAVASCRIPT_DIALOG_HELPER_H_ -#define CHROME_BROWSER_GUESTVIEW_WEBVIEW_JAVASCRIPT_DIALOG_HELPER_H_ - -#include "content/public/browser/javascript_dialog_manager.h" - -class WebViewGuest; - -class JavaScriptDialogHelper : public content::JavaScriptDialogManager { - public: - explicit JavaScriptDialogHelper(WebViewGuest* guest); - virtual ~JavaScriptDialogHelper(); - - // JavaScriptDialogManager implementation. - virtual void RunJavaScriptDialog( - content::WebContents* web_contents, - const GURL& origin_url, - const std::string& accept_lang, - content::JavaScriptMessageType javascript_message_type, - const base::string16& message_text, - const base::string16& default_prompt_text, - const DialogClosedCallback& callback, - bool* did_suppress_message) OVERRIDE; - virtual void RunBeforeUnloadDialog( - content::WebContents* web_contents, - const base::string16& message_text, - bool is_reload, - const DialogClosedCallback& callback) OVERRIDE; - virtual bool HandleJavaScriptDialog( - content::WebContents* web_contents, - bool accept, - const base::string16* prompt_override) OVERRIDE; - virtual void CancelActiveAndPendingDialogs( - content::WebContents* web_contents) OVERRIDE; - virtual void WebContentsDestroyed( - content::WebContents* web_contents) OVERRIDE; - - private: - void OnPermissionResponse( - const DialogClosedCallback& callback, - bool allow, - const std::string& user_input); - - // Pointer to the webview that is being helped. - WebViewGuest* const webview_guest_; - - DISALLOW_COPY_AND_ASSIGN(JavaScriptDialogHelper); -}; - -#endif // CHROME_BROWSER_GUESTVIEW_WEBVIEW_JAVASCRIPT_DIALOG_HELPER_H_ diff --git a/chrome/browser/guestview/webview/plugin_permission_helper.cc b/chrome/browser/guestview/webview/plugin_permission_helper.cc deleted file mode 100644 index a4fd5d4..0000000 --- a/chrome/browser/guestview/webview/plugin_permission_helper.cc +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/guestview/webview/plugin_permission_helper.h" - -#include "chrome/browser/guestview/webview/webview_guest.h" -#include "chrome/browser/guestview/webview/webview_permission_types.h" -#include "chrome/browser/plugins/chrome_plugin_service_filter.h" -#include "chrome/common/render_messages.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/user_metrics.h" - -using content::BrowserPluginGuestDelegate; -using content::RenderViewHost; -using content::WebContents; - -DEFINE_WEB_CONTENTS_USER_DATA_KEY(PluginPermissionHelper); - -PluginPermissionHelper::PluginPermissionHelper(WebContents* contents) - : content::WebContentsObserver(contents), - weak_factory_(this) { -} - -PluginPermissionHelper::~PluginPermissionHelper() { -} - -bool PluginPermissionHelper::OnMessageReceived(const IPC::Message& message) { - IPC_BEGIN_MESSAGE_MAP(PluginPermissionHelper, message) - IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedUnauthorizedPlugin, - OnBlockedUnauthorizedPlugin) - IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CouldNotLoadPlugin, - OnCouldNotLoadPlugin) - IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedOutdatedPlugin, - OnBlockedOutdatedPlugin) - IPC_MESSAGE_HANDLER(ChromeViewHostMsg_NPAPINotSupported, - OnNPAPINotSupported) - IPC_MESSAGE_HANDLER(ChromeViewHostMsg_OpenAboutPlugins, - OnOpenAboutPlugins) -#if defined(ENABLE_PLUGIN_INSTALLATION) - IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FindMissingPlugin, - OnFindMissingPlugin) - IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RemovePluginPlaceholderHost, - OnRemovePluginPlaceholderHost) -#endif - IPC_MESSAGE_UNHANDLED(return false) - IPC_END_MESSAGE_MAP() - - return true; -} - -void PluginPermissionHelper::OnBlockedUnauthorizedPlugin( - const base::string16& name, - const std::string& identifier) { - const char kPluginName[] = "name"; - const char kPluginIdentifier[] = "identifier"; - - WebViewGuest* webview = WebViewGuest::FromWebContents(web_contents()); - if (!webview) - return; - - base::DictionaryValue info; - info.SetString(std::string(kPluginName), name); - info.SetString(std::string(kPluginIdentifier), identifier); - webview->RequestPermission(static_cast( - WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN), - info, - base::Bind(&PluginPermissionHelper::OnPermissionResponse, - weak_factory_.GetWeakPtr(), - identifier), - true /* allowed_by_default */); - content::RecordAction( - base::UserMetricsAction("WebView.Guest.PluginLoadRequest")); -} - -void PluginPermissionHelper::OnCouldNotLoadPlugin( - const base::FilePath& plugin_path) { -} - -void PluginPermissionHelper::OnBlockedOutdatedPlugin( - int placeholder_id, - const std::string& identifier) { -} - -void PluginPermissionHelper::OnNPAPINotSupported(const std::string& id) { -} - -void PluginPermissionHelper::OnOpenAboutPlugins() { -} - -#if defined(ENABLE_PLUGIN_INSTALLATION) -void PluginPermissionHelper::OnFindMissingPlugin(int placeholder_id, - const std::string& mime_type) { - Send(new ChromeViewMsg_DidNotFindMissingPlugin(placeholder_id)); -} - -void PluginPermissionHelper::OnRemovePluginPlaceholderHost(int placeholder_id) { -} -#endif // defined(ENABLE_PLUGIN_INSTALLATION) - -void PluginPermissionHelper::OnPermissionResponse(const std::string& identifier, - bool allow, - const std::string& input) { - if (allow) { - ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins( - web_contents(), true, identifier); - } -} diff --git a/chrome/browser/guestview/webview/plugin_permission_helper.h b/chrome/browser/guestview/webview/plugin_permission_helper.h deleted file mode 100644 index 0c280e9..0000000 --- a/chrome/browser/guestview/webview/plugin_permission_helper.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_GUESTVIEW_WEBVIEW_PLUGIN_PERMISSION_HELPER_H_ -#define CHROME_BROWSER_GUESTVIEW_WEBVIEW_PLUGIN_PERMISSION_HELPER_H_ - -#include "base/memory/weak_ptr.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" - -class PluginPermissionHelper - : public content::WebContentsUserData, - public content::WebContentsObserver { - public: - virtual ~PluginPermissionHelper(); - - private: - explicit PluginPermissionHelper(content::WebContents* web_contents); - friend class content::WebContentsUserData; - - // content::WebContentsObserver implementation. - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - - // Message handlers: - void OnBlockedUnauthorizedPlugin(const base::string16& name, - const std::string& identifier); - void OnCouldNotLoadPlugin(const base::FilePath& plugin_path); - void OnBlockedOutdatedPlugin(int placeholder_id, - const std::string& identifier); - void OnNPAPINotSupported(const std::string& identifier); - void OnOpenAboutPlugins(); -#if defined(ENABLE_PLUGIN_INSTALLATION) - void OnFindMissingPlugin(int placeholder_id, const std::string& mime_type); - - void OnRemovePluginPlaceholderHost(int placeholder_id); -#endif - - void OnPermissionResponse(const std::string& identifier, - bool allow, - const std::string& user_input); - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(PluginPermissionHelper); -}; - -#endif // CHROME_BROWSER_GUESTVIEW_WEBVIEW_PLUGIN_PERMISSION_HELPER_H_ diff --git a/chrome/browser/guestview/webview/webview_constants.cc b/chrome/browser/guestview/webview/webview_constants.cc deleted file mode 100644 index 2bd5e69..0000000 --- a/chrome/browser/guestview/webview/webview_constants.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/guestview/webview/webview_constants.h" - -namespace webview { - -// Events. -const char kEventClose[] = "webview.onClose"; -const char kEventConsoleMessage[] = "webview.onConsoleMessage"; -const char kEventContentLoad[] = "webview.onContentLoad"; -const char kEventDialog[] = "webview.onDialog"; -const char kEventExit[] = "webview.onExit"; -const char kEventFindReply[] = "webview.onFindReply"; -const char kEventLoadAbort[] = "webview.onLoadAbort"; -const char kEventLoadCommit[] = "webview.onLoadCommit"; -const char kEventLoadProgress[] = "webview.onLoadProgress"; -const char kEventLoadRedirect[] = "webview.onLoadRedirect"; -const char kEventLoadStart[] = "webview.onLoadStart"; -const char kEventLoadStop[] = "webview.onLoadStop"; -const char kEventNewWindow[] = "webview.onNewWindow"; -const char kEventPermissionRequest[] = "webview.onPermissionRequest"; -const char kEventResponsive[] = "webview.onResponsive"; -const char kEventSizeChanged[] = "webview.onSizeChanged"; -const char kEventUnresponsive[] = "webview.onUnresponsive"; -const char kEventZoomChange[] = "webview.onZoomChange"; - -// Parameters/properties on events. -const char kDefaultPromptText[] = "defaultPromptText"; -const char kFindSearchText[] = "searchText"; -const char kFindFinalUpdate[] = "finalUpdate"; -const char kLastUnlockedBySelf[] = "lastUnlockedBySelf"; -const char kLevel[] = "level"; -const char kLine[] = "line"; -const char kMessage[] = "message"; -const char kMessageText[] = "messageText"; -const char kMessageType[] = "messageType"; -const char kNewHeight[] = "newHeight"; -const char kNewURL[] = "newUrl"; -const char kNewWidth[] = "newWidth"; -const char kOldHeight[] = "oldHeight"; -const char kOldURL[] = "oldUrl"; -const char kPermission[] = "permission"; -const char kPermissionTypeDialog[] = "dialog"; -const char kPermissionTypeDownload[] = "download"; -const char kPermissionTypeGeolocation[] = "geolocation"; -const char kPermissionTypeLoadPlugin[] = "loadplugin"; -const char kPermissionTypeMedia[] = "media"; -const char kPermissionTypeNewWindow[] = "newwindow"; -const char kPermissionTypePointerLock[] = "pointerLock"; -const char kOldWidth[] = "oldWidth"; -const char kProcessId[] = "processId"; -const char kProgress[] = "progress"; -const char kReason[] = "reason"; -const char kRequestId[] = "requestId"; -const char kSourceId[] = "sourceId"; -const char kOldZoomFactor[] = "oldZoomFactor"; -const char kNewZoomFactor[] = "newZoomFactor"; - -// Internal parameters/properties on events. -const char kInternalCurrentEntryIndex[] = "currentEntryIndex"; -const char kInternalEntryCount[] = "entryCount"; -const char kInternalProcessId[] = "processId"; - -// Parameters to callback functions. -const char kFindNumberOfMatches[] = "numberOfMatches"; -const char kFindActiveMatchOrdinal[] = "activeMatchOrdinal"; -const char kFindSelectionRect[] = "selectionRect"; -const char kFindRectLeft[] = "left"; -const char kFindRectTop[] = "top"; -const char kFindRectWidth[] = "width"; -const char kFindRectHeight[] = "height"; -const char kFindCanceled[] = "canceled"; - -// Initialization parameters. -const char kParameterUserAgentOverride[] = "userAgentOverride"; - -// Miscellaneous. -const unsigned int kMaxOutstandingPermissionRequests = 1024; -const int kInvalidPermissionRequestID = 0; - -} // namespace webview diff --git a/chrome/browser/guestview/webview/webview_constants.h b/chrome/browser/guestview/webview/webview_constants.h deleted file mode 100644 index a05c9b903..0000000 --- a/chrome/browser/guestview/webview/webview_constants.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Constants used for the WebView API. - -#ifndef CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_CONSTANTS_H_ -#define CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_CONSTANTS_H_ - -namespace webview { - -// Events. -extern const char kEventClose[]; -extern const char kEventConsoleMessage[]; -extern const char kEventContentLoad[]; -extern const char kEventDialog[]; -extern const char kEventExit[]; -extern const char kEventFindReply[]; -extern const char kEventLoadAbort[]; -extern const char kEventLoadCommit[]; -extern const char kEventLoadProgress[]; -extern const char kEventLoadRedirect[]; -extern const char kEventLoadStart[]; -extern const char kEventLoadStop[]; -extern const char kEventNewWindow[]; -extern const char kEventPermissionRequest[]; -extern const char kEventResponsive[]; -extern const char kEventSizeChanged[]; -extern const char kEventUnresponsive[]; -extern const char kEventZoomChange[]; - -// Parameters/properties on events. -extern const char kDefaultPromptText[]; -extern const char kFindSearchText[]; -extern const char kFindFinalUpdate[]; -extern const char kLastUnlockedBySelf[]; -extern const char kLevel[]; -extern const char kLine[]; -extern const char kMessage[]; -extern const char kMessageText[]; -extern const char kMessageType[]; -extern const char kNewHeight[]; -extern const char kNewURL[]; -extern const char kNewWidth[]; -extern const char kOldHeight[]; -extern const char kOldURL[]; -extern const char kPermission[]; -extern const char kPermissionTypeDialog[]; -extern const char kPermissionTypeDownload[]; -extern const char kPermissionTypeGeolocation[]; -extern const char kPermissionTypeLoadPlugin[]; -extern const char kPermissionTypeMedia[]; -extern const char kPermissionTypeNewWindow[]; -extern const char kPermissionTypePointerLock[]; -extern const char kOldWidth[]; -extern const char kProcessId[]; -extern const char kProgress[]; -extern const char kReason[]; -extern const char kRequestId[]; -extern const char kSourceId[]; -extern const char kOldZoomFactor[]; -extern const char kNewZoomFactor[]; - -// Internal parameters/properties on events. -extern const char kInternalCurrentEntryIndex[]; -extern const char kInternalEntryCount[]; -extern const char kInternalProcessId[]; - -// Parameters to callback functions. -extern const char kFindNumberOfMatches[]; -extern const char kFindActiveMatchOrdinal[]; -extern const char kFindSelectionRect[]; -extern const char kFindRectLeft[]; -extern const char kFindRectTop[]; -extern const char kFindRectWidth[]; -extern const char kFindRectHeight[]; -extern const char kFindCanceled[]; -extern const char kFindDone[]; - -// Initialization parameters. -extern const char kParameterUserAgentOverride[]; - -// Miscellaneous. -extern const unsigned int kMaxOutstandingPermissionRequests; -extern const int kInvalidPermissionRequestID; - -} // namespace webview - -#endif // CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_CONSTANTS_H_ diff --git a/chrome/browser/guestview/webview/webview_find_helper.cc b/chrome/browser/guestview/webview/webview_find_helper.cc deleted file mode 100644 index d636a78..0000000 --- a/chrome/browser/guestview/webview/webview_find_helper.cc +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/guestview/webview/webview_find_helper.h" - -#include - -#include "chrome/browser/extensions/api/webview/webview_api.h" -#include "chrome/browser/guestview/webview/webview_constants.h" - -WebviewFindHelper::WebviewFindHelper(WebViewGuest* webview_guest) - : webview_guest_(webview_guest), - current_find_request_id_(0) { -} - -WebviewFindHelper::~WebviewFindHelper() { -} - -void WebviewFindHelper::CancelAllFindSessions() { - current_find_session_ = linked_ptr(); - while (!find_info_map_.empty()) { - find_info_map_.begin()->second->SendResponse(true /* canceled */); - find_info_map_.erase(find_info_map_.begin()); - } - if (find_update_event_.get()) - DispatchFindUpdateEvent(true /* canceled */, true /* final_update */); - find_update_event_.reset(); -} - -void WebviewFindHelper::DispatchFindUpdateEvent(bool canceled, - bool final_update) { - DCHECK(find_update_event_.get()); - scoped_ptr args(new base::DictionaryValue()); - find_update_event_->PrepareResults(args.get()); - args->SetBoolean(webview::kFindCanceled, canceled); - args->SetBoolean(webview::kFindFinalUpdate, final_update); - DCHECK(webview_guest_); - webview_guest_->DispatchEvent(new GuestView::Event(webview::kEventFindReply, - args.Pass())); -} - -void WebviewFindHelper::EndFindSession(int session_request_id, bool canceled) { - FindInfoMap::iterator session_iterator = - find_info_map_.find(session_request_id); - DCHECK(session_iterator != find_info_map_.end()); - FindInfo* find_info = session_iterator->second.get(); - - // Call the callback function of the first request of the find session. - find_info->SendResponse(canceled); - - // For every subsequent find request of the find session. - for (std::vector >::iterator i = - find_info->find_next_requests_.begin(); - i != find_info->find_next_requests_.end(); ++i) { - DCHECK(i->get()); - - // Do not call callbacks for subsequent find requests that have not been - // replied to yet. These requests will get their own final updates in the - // same order as they appear in |find_next_requests_|, i.e. the order that - // the requests were made in. Once one request is found that has not been - // replied to, none that follow will be replied to either, and do not need - // to be checked. - if (!(*i)->replied_) - break; - - // Update the request's number of matches (if not canceled). - if (!canceled) { - (*i)->find_results_.number_of_matches_ = - find_info->find_results_.number_of_matches_; - } - - // Call the request's callback function with the find results, and then - // delete its map entry to free the WebviewFindFunction object. - (*i)->SendResponse(canceled); - find_info_map_.erase((*i)->request_id_); - } - - // Erase the first find request's map entry to free the WebviewFindFunction - // object. - find_info_map_.erase(session_request_id); -} - -void WebviewFindHelper::Find( - content::WebContents* guest_web_contents, - const base::string16& search_text, - const blink::WebFindOptions& options, - scoped_refptr find_function) { - // Need a new request_id for each new find request. - ++current_find_request_id_; - - // Stores the find request information by request_id so that its callback - // function can be called when the find results are available. - std::pair insert_result = - find_info_map_.insert( - std::make_pair(current_find_request_id_, - linked_ptr( - new WebviewFindHelper::FindInfo( - current_find_request_id_, - search_text, - options, - find_function)))); - // No duplicate insertions. - DCHECK(insert_result.second); - - // Find options including the implicit |findNext| field. - blink::WebFindOptions* full_options = insert_result.first->second->options(); - - // Set |findNext| implicitly. - if (current_find_session_.get()) { - const base::string16& current_search_text = - current_find_session_->search_text(); - bool current_match_case = current_find_session_->options()->matchCase; - full_options->findNext = !current_search_text.empty() && - current_search_text == search_text && - current_match_case == options.matchCase; - } else { - full_options->findNext = false; - } - - // Link find requests that are a part of the same find session. - if (full_options->findNext && current_find_session_.get()) { - DCHECK(current_find_request_id_ != current_find_session_->request_id()); - current_find_session_->AddFindNextRequest( - insert_result.first->second->AsWeakPtr()); - } - - // Update the current find session, if necessary. - if (!full_options->findNext) - current_find_session_ = insert_result.first->second; - - guest_web_contents->Find(current_find_request_id_, - search_text, *full_options); -} - -void WebviewFindHelper::FindReply(int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - FindInfoMap::iterator find_iterator = find_info_map_.find(request_id); - - // Ignore slow replies to canceled find requests. - if (find_iterator == find_info_map_.end()) - return; - - // This find request must be a part of an existing find session. - DCHECK(current_find_session_.get()); - - WebviewFindHelper::FindInfo* find_info = find_iterator->second.get(); - - // Handle canceled find requests. - if (!find_info->options()->findNext && - find_info_map_.begin()->first < request_id) { - DCHECK_NE(current_find_session_->request_id(), - find_info_map_.begin()->first); - DispatchFindUpdateEvent(true /* canceled */, true /* final_update */); - EndFindSession(find_info_map_.begin()->first, true /* canceled */); - } - - // Clears the results for |findupdate| for a new find session. - if (!find_info->replied() && !find_info->options()->findNext) - find_update_event_.reset(new FindUpdateEvent(find_info->search_text())); - - // Aggregate the find results. - find_info->AggregateResults(number_of_matches, selection_rect, - active_match_ordinal, final_update); - find_update_event_->AggregateResults(number_of_matches, selection_rect, - active_match_ordinal, final_update); - - // Propagate incremental results to the |findupdate| event. - DispatchFindUpdateEvent(false /* canceled */, final_update); - - // Call the callback functions of completed find requests. - if (final_update) - EndFindSession(request_id, false /* canceled */); -} - -WebviewFindHelper::FindResults::FindResults() - : number_of_matches_(0), - active_match_ordinal_(0) {} - -WebviewFindHelper::FindResults::~FindResults() { -} - -void WebviewFindHelper::FindResults::AggregateResults( - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - if (number_of_matches != -1) - number_of_matches_ = number_of_matches; - - if (active_match_ordinal != -1) - active_match_ordinal_ = active_match_ordinal; - - if (final_update && active_match_ordinal_ == 0) { - // No match found, so the selection rectangle is empty. - selection_rect_ = gfx::Rect(); - } else if (!selection_rect.IsEmpty()) { - selection_rect_ = selection_rect; - } -} - -void WebviewFindHelper::FindResults::PrepareResults( - base::DictionaryValue* results) { - results->SetInteger(webview::kFindNumberOfMatches, number_of_matches_); - results->SetInteger(webview::kFindActiveMatchOrdinal, active_match_ordinal_); - base::DictionaryValue rect; - rect.SetInteger(webview::kFindRectLeft, selection_rect_.x()); - rect.SetInteger(webview::kFindRectTop, selection_rect_.y()); - rect.SetInteger(webview::kFindRectWidth, selection_rect_.width()); - rect.SetInteger(webview::kFindRectHeight, selection_rect_.height()); - results->Set(webview::kFindSelectionRect, rect.DeepCopy()); -} - -WebviewFindHelper::FindUpdateEvent::FindUpdateEvent( - const base::string16& search_text) : search_text_(search_text) { -} - -WebviewFindHelper::FindUpdateEvent::~FindUpdateEvent() { -} - -void WebviewFindHelper::FindUpdateEvent::AggregateResults( - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - find_results_.AggregateResults(number_of_matches, selection_rect, - active_match_ordinal, final_update); -} - -void WebviewFindHelper::FindUpdateEvent::PrepareResults( - base::DictionaryValue* results) { - results->SetString(webview::kFindSearchText, search_text_); - find_results_.PrepareResults(results); -} - -WebviewFindHelper::FindInfo::FindInfo( - int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options, - scoped_refptr find_function) - : request_id_(request_id), - search_text_(search_text), - options_(options), - find_function_(find_function), - replied_(false), - weak_ptr_factory_(this) { -} - -WebviewFindHelper::FindInfo::~FindInfo() { -} - -void WebviewFindHelper::FindInfo::AggregateResults( - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - replied_ = true; - find_results_.AggregateResults(number_of_matches, selection_rect, - active_match_ordinal, final_update); -} - -base::WeakPtr - WebviewFindHelper::FindInfo::AsWeakPtr() { - return weak_ptr_factory_.GetWeakPtr(); -} - -void WebviewFindHelper::FindInfo::SendResponse(bool canceled) { - // Prepare the find results to pass to the callback function. - base::DictionaryValue results; - find_results_.PrepareResults(&results); - results.SetBoolean(webview::kFindCanceled, canceled); - - // Call the callback. - find_function_->SetResult(results.DeepCopy()); - find_function_->SendResponse(true); -} diff --git a/chrome/browser/guestview/webview/webview_find_helper.h b/chrome/browser/guestview/webview/webview_find_helper.h deleted file mode 100644 index a9a2889..0000000 --- a/chrome/browser/guestview/webview/webview_find_helper.h +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_FIND_HELPER_H_ -#define CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_FIND_HELPER_H_ - -#include -#include - -#include "base/memory/weak_ptr.h" -#include "base/values.h" -#include "content/public/browser/web_contents.h" -#include "third_party/WebKit/public/web/WebFindOptions.h" -#include "ui/gfx/geometry/rect.h" - -namespace extensions { -class WebviewFindFunction; -} // namespace extensions -class WebViewGuest; - -// Helper class for find requests and replies for the webview find API. -class WebviewFindHelper { - public: - explicit WebviewFindHelper(WebViewGuest* webview_guest); - ~WebviewFindHelper(); - - // Cancels all find requests in progress and calls their callback functions. - void CancelAllFindSessions(); - - // Dispatches the |findupdate| event. - void DispatchFindUpdateEvent(bool canceled, bool final_update); - - // Ends the find session with id |session_request_id| and calls the - // appropriate callbacks. - void EndFindSession(int session_request_id, bool canceled); - - // Helper function for WebViewGuest::Find(). - void Find(content::WebContents* guest_web_contents, - const base::string16& search_text, - const blink::WebFindOptions& options, - scoped_refptr find_function); - - // Helper function for WeViewGuest:FindReply(). - void FindReply(int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update); - - private: - // A wrapper to store find results. - class FindResults { - public: - FindResults(); - ~FindResults(); - - // Aggregate the find results. - void AggregateResults(int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update); - - // Stores find results into a DictionaryValue. - void PrepareResults(base::DictionaryValue* results); - - private: - int number_of_matches_; - int active_match_ordinal_; - gfx::Rect selection_rect_; - - friend void WebviewFindHelper::EndFindSession(int session_request_id, - bool canceled); - - DISALLOW_COPY_AND_ASSIGN(FindResults); - }; - - // Stores and processes the results for the |findupdate| event. - class FindUpdateEvent { - public: - explicit FindUpdateEvent(const base::string16& search_text); - ~FindUpdateEvent(); - - // Aggregate the find results. - void AggregateResults(int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update); - - // Stores find results and other event info into a DictionaryValue. - void PrepareResults(base::DictionaryValue* results); - - private: - const base::string16 search_text_; - FindResults find_results_; - - DISALLOW_COPY_AND_ASSIGN(FindUpdateEvent); - }; - - // Handles all information about a find request and its results. - class FindInfo { - public: - FindInfo(int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options, - scoped_refptr find_function); - ~FindInfo(); - - // Add another request to |find_next_requests_|. - void AddFindNextRequest(const base::WeakPtr& request) { - find_next_requests_.push_back(request); - } - - // Aggregate the find results. - void AggregateResults(int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update); - - base::WeakPtr AsWeakPtr(); - - blink::WebFindOptions* options() { - return &options_; - } - - bool replied() { - return replied_; - } - - int request_id() { - return request_id_; - } - - const base::string16& search_text() { - return search_text_; - } - - // Calls the callback function within |find_function_| with the find results - // from within |find_results_|. - void SendResponse(bool canceled); - - private: - const int request_id_; - const base::string16 search_text_; - blink::WebFindOptions options_; - scoped_refptr find_function_; - FindResults find_results_; - - // A find reply has been received for this find request. - bool replied_; - - // Stores pointers to all the find next requests if this is the first - // request of a find session. - std::vector > find_next_requests_; - - // Weak pointer used to access the find info of fin. - base::WeakPtrFactory weak_ptr_factory_; - - friend void WebviewFindHelper::EndFindSession(int session_request_id, - bool canceled); - - DISALLOW_COPY_AND_ASSIGN(FindInfo); - }; - - // Pointer to the webview that is being helped. - WebViewGuest* const webview_guest_; - - // A counter to generate a unique request id for a find request. - // We only need the ids to be unique for a given WebViewGuest. - int current_find_request_id_; - - // Stores aggregated find results and other info for the |findupdate| event. - scoped_ptr find_update_event_; - - // Pointer to the first request of the current find session. - linked_ptr current_find_session_; - - // Stores each find request's information by request_id so that its callback - // function can be called when its find results are available. - typedef std::map > FindInfoMap; - FindInfoMap find_info_map_; - - DISALLOW_COPY_AND_ASSIGN(WebviewFindHelper); -}; - -#endif // CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_FIND_HELPER_H_ diff --git a/chrome/browser/guestview/webview/webview_guest.cc b/chrome/browser/guestview/webview/webview_guest.cc deleted file mode 100644 index 9a14b4f..0000000 --- a/chrome/browser/guestview/webview/webview_guest.cc +++ /dev/null @@ -1,1038 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/guestview/webview/webview_guest.h" - -#include "base/message_loop/message_loop.h" -#include "base/strings/stringprintf.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/extensions/api/web_request/web_request_api.h" -#include "chrome/browser/extensions/api/webview/webview_api.h" -#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" -#include "chrome/browser/extensions/extension_renderer_state.h" -#include "chrome/browser/extensions/menu_manager.h" -#include "chrome/browser/extensions/script_executor.h" -#include "chrome/browser/favicon/favicon_tab_helper.h" -#include "chrome/browser/guestview/guestview_constants.h" -#include "chrome/browser/guestview/webview/webview_constants.h" -#include "chrome/browser/guestview/webview/webview_permission_types.h" -#include "chrome/common/chrome_version_info.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/geolocation_permission_context.h" -#include "content/public/browser/native_web_keyboard_event.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/resource_request_details.h" -#include "content/public/browser/site_instance.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/browser/user_metrics.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_delegate.h" -#include "content/public/common/media_stream_request.h" -#include "content/public/common/page_zoom.h" -#include "content/public/common/result_codes.h" -#include "content/public/common/stop_find_action.h" -#include "extensions/common/constants.h" -#include "net/base/net_errors.h" -#include "third_party/WebKit/public/web/WebFindOptions.h" - -#if defined(ENABLE_PLUGINS) -#include "chrome/browser/guestview/webview/plugin_permission_helper.h" -#endif - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" -#endif - -using base::UserMetricsAction; -using content::WebContents; - -namespace { - -static std::string TerminationStatusToString(base::TerminationStatus status) { - switch (status) { - case base::TERMINATION_STATUS_NORMAL_TERMINATION: - return "normal"; - case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: - case base::TERMINATION_STATUS_STILL_RUNNING: - return "abnormal"; - case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: - return "killed"; - case base::TERMINATION_STATUS_PROCESS_CRASHED: -#if defined(OS_ANDROID) - case base::TERMINATION_STATUS_OOM_PROTECTED: -#endif - return "crashed"; - case base::TERMINATION_STATUS_MAX_ENUM: - break; - } - NOTREACHED() << "Unknown Termination Status."; - return "unknown"; -} - -static std::string PermissionTypeToString(BrowserPluginPermissionType type) { - switch (type) { - case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: - return webview::kPermissionTypeNewWindow; - case BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN: - NOTREACHED(); - break; - default: { - WebViewPermissionType webview = static_cast(type); - switch (webview) { - case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: - return webview::kPermissionTypeDownload; - case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION: - return webview::kPermissionTypeGeolocation; - case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: - return webview::kPermissionTypeDialog; - case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN: - return webview::kPermissionTypeLoadPlugin; - case WEB_VIEW_PERMISSION_TYPE_MEDIA: - return webview::kPermissionTypeMedia; - case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: - return webview::kPermissionTypePointerLock; - } - NOTREACHED(); - } - } - return std::string(); -} - -void RemoveWebViewEventListenersOnIOThread( - void* profile, - const std::string& extension_id, - int embedder_process_id, - int view_instance_id) { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners( - profile, - extension_id, - embedder_process_id, - view_instance_id); -} - -void AttachWebViewHelpers(WebContents* contents) { - FaviconTabHelper::CreateForWebContents(contents); - extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( - contents); -#if defined(ENABLE_PLUGINS) - PluginPermissionHelper::CreateForWebContents(contents); -#endif -} - -} // namespace - -WebViewGuest::WebViewGuest(WebContents* guest_web_contents, - const std::string& extension_id) - : GuestView(guest_web_contents, extension_id), - WebContentsObserver(guest_web_contents), - script_executor_(new extensions::ScriptExecutor(guest_web_contents, - &script_observers_)), - next_permission_request_id_(0), - is_overriding_user_agent_(false), - pending_reload_on_attachment_(false), - main_frame_id_(0), - chromevox_injected_(false), - find_helper_(this), - javascript_dialog_helper_(this) { - notification_registrar_.Add( - this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, - content::Source(guest_web_contents)); - - notification_registrar_.Add( - this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, - content::Source(guest_web_contents)); - -#if defined(OS_CHROMEOS) - chromeos::AccessibilityManager* accessibility_manager = - chromeos::AccessibilityManager::Get(); - CHECK(accessibility_manager); - accessibility_subscription_ = accessibility_manager->RegisterCallback( - base::Bind(&WebViewGuest::OnAccessibilityStatusChanged, - base::Unretained(this))); -#endif - - AttachWebViewHelpers(guest_web_contents); -} - -// static -WebViewGuest* WebViewGuest::From(int embedder_process_id, - int guest_instance_id) { - GuestView* guest = GuestView::From(embedder_process_id, guest_instance_id); - if (!guest) - return NULL; - return guest->AsWebView(); -} - -// static -WebViewGuest* WebViewGuest::FromWebContents(WebContents* contents) { - GuestView* guest = GuestView::FromWebContents(contents); - return guest ? guest->AsWebView() : NULL; -} - -// static. -int WebViewGuest::GetViewInstanceId(WebContents* contents) { - WebViewGuest* guest = FromWebContents(contents); - if (!guest) - return guestview::kInstanceIDNone; - - return guest->view_instance_id(); -} - -// static -void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, - bool allow) { - if (allow) { - // Note that |allow| == true means the embedder explicitly allowed the - // request. For some requests they might still fail. An example of such - // scenario would be: an embedder allows geolocation request but doesn't - // have geolocation access on its own. - switch (info.permission_type) { - case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: - content::RecordAction( - UserMetricsAction("BrowserPlugin.PermissionAllow.NewWindow")); - break; - case BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN: - break; - default: { - WebViewPermissionType webview_permission_type = - static_cast(info.permission_type); - switch (webview_permission_type) { - case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: - content::RecordAction( - UserMetricsAction("WebView.PermissionAllow.Download")); - break; - case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION: - content::RecordAction( - UserMetricsAction("WebView.PermissionAllow.Geolocation")); - break; - case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: - content::RecordAction( - UserMetricsAction("WebView.PermissionAllow.JSDialog")); - break; - case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN: - content::RecordAction( - UserMetricsAction("WebView.Guest.PermissionAllow.PluginLoad")); - case WEB_VIEW_PERMISSION_TYPE_MEDIA: - content::RecordAction( - UserMetricsAction("WebView.PermissionAllow.Media")); - break; - case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: - content::RecordAction( - UserMetricsAction("WebView.PermissionAllow.PointerLock")); - break; - default: - break; - } - } - } - } else { - switch (info.permission_type) { - case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: - content::RecordAction( - UserMetricsAction("BrowserPlugin.PermissionDeny.NewWindow")); - break; - case BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN: - break; - default: { - WebViewPermissionType webview_permission_type = - static_cast(info.permission_type); - switch (webview_permission_type) { - case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: - content::RecordAction( - UserMetricsAction("WebView.PermissionDeny.Download")); - break; - case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION: - content::RecordAction( - UserMetricsAction("WebView.PermissionDeny.Geolocation")); - break; - case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: - content::RecordAction( - UserMetricsAction("WebView.PermissionDeny.JSDialog")); - break; - case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN: - content::RecordAction( - UserMetricsAction("WebView.Guest.PermissionDeny.PluginLoad")); - case WEB_VIEW_PERMISSION_TYPE_MEDIA: - content::RecordAction( - UserMetricsAction("WebView.PermissionDeny.Media")); - break; - case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: - content::RecordAction( - UserMetricsAction("WebView.PermissionDeny.PointerLock")); - break; - default: - break; - } - } - } - } -} - -void WebViewGuest::Attach(WebContents* embedder_web_contents, - const base::DictionaryValue& args) { - std::string user_agent_override; - if (args.GetString(webview::kParameterUserAgentOverride, - &user_agent_override)) { - SetUserAgentOverride(user_agent_override); - } else { - SetUserAgentOverride(""); - } - - GuestView::Attach(embedder_web_contents, args); - - AddWebViewToExtensionRendererState(); -} - -GuestView::Type WebViewGuest::GetViewType() const { - return GuestView::WEBVIEW; -} - -WebViewGuest* WebViewGuest::AsWebView() { - return this; -} - -AdViewGuest* WebViewGuest::AsAdView() { - return NULL; -} - -void WebViewGuest::AddMessageToConsole(int32 level, - const base::string16& message, - int32 line_no, - const base::string16& source_id) { - scoped_ptr args(new base::DictionaryValue()); - // Log levels are from base/logging.h: LogSeverity. - args->SetInteger(webview::kLevel, level); - args->SetString(webview::kMessage, message); - args->SetInteger(webview::kLine, line_no); - args->SetString(webview::kSourceId, source_id); - DispatchEvent( - new GuestView::Event(webview::kEventConsoleMessage, args.Pass())); -} - -void WebViewGuest::Close() { - scoped_ptr args(new base::DictionaryValue()); - DispatchEvent(new GuestView::Event(webview::kEventClose, args.Pass())); -} - -void WebViewGuest::DidAttach() { - if (pending_reload_on_attachment_) { - pending_reload_on_attachment_ = false; - guest_web_contents()->GetController().Reload(false); - } -} - -void WebViewGuest::EmbedderDestroyed() { - // TODO(fsamuel): WebRequest event listeners for should survive - // reparenting of a within a single embedder. Right now, we keep - // around the browser state for the listener for the lifetime of the embedder. - // Ideally, the lifetime of the listeners should match the lifetime of the - // DOM node. Once http://crbug.com/156219 is resolved we can move - // the call to RemoveWebViewEventListenersOnIOThread back to - // WebViewGuest::WebContentsDestroyed. - content::BrowserThread::PostTask( - content::BrowserThread::IO, - FROM_HERE, - base::Bind( - &RemoveWebViewEventListenersOnIOThread, - browser_context(), embedder_extension_id(), - embedder_render_process_id(), - view_instance_id())); -} - -void WebViewGuest::FindReply(int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - find_helper_.FindReply(request_id, number_of_matches, selection_rect, - active_match_ordinal, final_update); -} - -void WebViewGuest::GuestProcessGone(base::TerminationStatus status) { - // Cancel all find sessions in progress. - find_helper_.CancelAllFindSessions(); - - scoped_ptr args(new base::DictionaryValue()); - args->SetInteger(webview::kProcessId, - guest_web_contents()->GetRenderProcessHost()->GetID()); - args->SetString(webview::kReason, TerminationStatusToString(status)); - DispatchEvent( - new GuestView::Event(webview::kEventExit, args.Pass())); -} - -bool WebViewGuest::HandleKeyboardEvent( - const content::NativeWebKeyboardEvent& event) { - if (event.type != blink::WebInputEvent::RawKeyDown) - return false; - -#if defined(OS_MACOSX) - if (event.modifiers != blink::WebInputEvent::MetaKey) - return false; - - if (event.windowsKeyCode == ui::VKEY_OEM_4) { - Go(-1); - return true; - } - - if (event.windowsKeyCode == ui::VKEY_OEM_6) { - Go(1); - return true; - } -#else - if (event.windowsKeyCode == ui::VKEY_BROWSER_BACK) { - Go(-1); - return true; - } - - if (event.windowsKeyCode == ui::VKEY_BROWSER_FORWARD) { - Go(1); - return true; - } -#endif - return false; -} - -bool WebViewGuest::IsDragAndDropEnabled() { - return true; -} - -bool WebViewGuest::IsOverridingUserAgent() const { - return is_overriding_user_agent_; -} - -void WebViewGuest::LoadProgressed(double progress) { - scoped_ptr args(new base::DictionaryValue()); - args->SetString(guestview::kUrl, guest_web_contents()->GetURL().spec()); - args->SetDouble(webview::kProgress, progress); - DispatchEvent(new GuestView::Event(webview::kEventLoadProgress, args.Pass())); -} - -void WebViewGuest::LoadAbort(bool is_top_level, - const GURL& url, - const std::string& error_type) { - scoped_ptr args(new base::DictionaryValue()); - args->SetBoolean(guestview::kIsTopLevel, is_top_level); - args->SetString(guestview::kUrl, url.possibly_invalid_spec()); - args->SetString(guestview::kReason, error_type); - DispatchEvent(new GuestView::Event(webview::kEventLoadAbort, args.Pass())); -} - -// TODO(fsamuel): Find a reliable way to test the 'responsive' and -// 'unresponsive' events. -void WebViewGuest::RendererResponsive() { - scoped_ptr args(new base::DictionaryValue()); - args->SetInteger(webview::kProcessId, - guest_web_contents()->GetRenderProcessHost()->GetID()); - DispatchEvent(new GuestView::Event(webview::kEventResponsive, args.Pass())); -} - -void WebViewGuest::RendererUnresponsive() { - scoped_ptr args(new base::DictionaryValue()); - args->SetInteger(webview::kProcessId, - guest_web_contents()->GetRenderProcessHost()->GetID()); - DispatchEvent(new GuestView::Event(webview::kEventUnresponsive, args.Pass())); -} - -void WebViewGuest::RequestPermission( - BrowserPluginPermissionType permission_type, - const base::DictionaryValue& request_info, - const PermissionResponseCallback& callback, - bool allowed_by_default) { - RequestPermissionInternal(permission_type, - request_info, - callback, - allowed_by_default); -} - -void WebViewGuest::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: { - DCHECK_EQ(content::Source(source).ptr(), - guest_web_contents()); - if (content::Source(source).ptr() == guest_web_contents()) - LoadHandlerCalled(); - break; - } - case content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: { - DCHECK_EQ(content::Source(source).ptr(), - guest_web_contents()); - content::ResourceRedirectDetails* resource_redirect_details = - content::Details(details).ptr(); - bool is_top_level = - resource_redirect_details->resource_type == ResourceType::MAIN_FRAME; - LoadRedirect(resource_redirect_details->url, - resource_redirect_details->new_url, - is_top_level); - break; - } - default: - NOTREACHED() << "Unexpected notification sent."; - break; - } -} - -void WebViewGuest::SetZoom(double zoom_factor) { - double zoom_level = content::ZoomFactorToZoomLevel(zoom_factor); - guest_web_contents()->SetZoomLevel(zoom_level); - - scoped_ptr args(new base::DictionaryValue()); - args->SetDouble(webview::kOldZoomFactor, current_zoom_factor_); - args->SetDouble(webview::kNewZoomFactor, zoom_factor); - DispatchEvent(new GuestView::Event(webview::kEventZoomChange, args.Pass())); - - current_zoom_factor_ = zoom_factor; -} - -double WebViewGuest::GetZoom() { - return current_zoom_factor_; -} - -void WebViewGuest::Find( - const base::string16& search_text, - const blink::WebFindOptions& options, - scoped_refptr find_function) { - find_helper_.Find(guest_web_contents(), search_text, options, find_function); -} - -void WebViewGuest::StopFinding(content::StopFindAction action) { - find_helper_.CancelAllFindSessions(); - guest_web_contents()->StopFinding(action); -} - -void WebViewGuest::Go(int relative_index) { - guest_web_contents()->GetController().GoToOffset(relative_index); -} - -void WebViewGuest::Reload() { - // TODO(fsamuel): Don't check for repost because we don't want to show - // Chromium's repost warning. We might want to implement a separate API - // for registering a callback if a repost is about to happen. - guest_web_contents()->GetController().Reload(false); -} - - -void WebViewGuest::RequestGeolocationPermission( - int bridge_id, - const GURL& requesting_frame, - bool user_gesture, - const base::Callback& callback) { - base::DictionaryValue request_info; - request_info.Set(guestview::kUrl, - base::Value::CreateStringValue(requesting_frame.spec())); - request_info.Set(guestview::kUserGesture, - base::Value::CreateBooleanValue(user_gesture)); - - // It is safe to hold an unretained pointer to WebViewGuest because this - // callback is called from WebViewGuest::SetPermission. - const PermissionResponseCallback permission_callback = - base::Bind(&WebViewGuest::OnWebViewGeolocationPermissionResponse, - base::Unretained(this), - bridge_id, - user_gesture, - callback); - int request_id = RequestPermissionInternal( - static_cast( - WEB_VIEW_PERMISSION_TYPE_GEOLOCATION), - request_info, - permission_callback, - false /* allowed_by_default */); - bridge_id_to_request_id_map_[bridge_id] = request_id; -} - -void WebViewGuest::OnWebViewGeolocationPermissionResponse( - int bridge_id, - bool user_gesture, - const base::Callback& callback, - bool allow, - const std::string& user_input) { - // The embedder has allowed the permission. We now need to make sure - // that the embedder has geolocation permission. - RemoveBridgeID(bridge_id); - - if (!allow || !attached()) { - callback.Run(false); - return; - } - - content::GeolocationPermissionContext* geolocation_context = - browser_context()->GetGeolocationPermissionContext(); - - DCHECK(geolocation_context); - geolocation_context->RequestGeolocationPermission( - embedder_web_contents()->GetRenderProcessHost()->GetID(), - embedder_web_contents()->GetRoutingID(), - // The geolocation permission request here is not initiated - // through WebGeolocationPermissionRequest. We are only interested - // in the fact whether the embedder/app has geolocation - // permission. Therefore we use an invalid |bridge_id|. - -1 /* bridge_id */, - embedder_web_contents()->GetLastCommittedURL(), - user_gesture, - callback); -} - -void WebViewGuest::CancelGeolocationPermissionRequest(int bridge_id) { - int request_id = RemoveBridgeID(bridge_id); - RequestMap::iterator request_itr = - pending_permission_requests_.find(request_id); - - if (request_itr == pending_permission_requests_.end()) - return; - - pending_permission_requests_.erase(request_itr); -} - -void WebViewGuest::OnWebViewMediaPermissionResponse( - const content::MediaStreamRequest& request, - const content::MediaResponseCallback& callback, - bool allow, - const std::string& user_input) { - if (!allow || !attached()) { - // Deny the request. - callback.Run(content::MediaStreamDevices(), - content::MEDIA_DEVICE_INVALID_STATE, - scoped_ptr()); - return; - } - if (!embedder_web_contents()->GetDelegate()) - return; - - embedder_web_contents()->GetDelegate()-> - RequestMediaAccessPermission(embedder_web_contents(), request, callback); -} - -void WebViewGuest::OnWebViewDownloadPermissionResponse( - const base::Callback& callback, - bool allow, - const std::string& user_input) { - callback.Run(allow && attached()); -} - -void WebViewGuest::OnWebViewPointerLockPermissionResponse( - const base::Callback& callback, - bool allow, - const std::string& user_input) { - callback.Run(allow && attached()); -} - -WebViewGuest::SetPermissionResult WebViewGuest::SetPermission( - int request_id, - PermissionResponseAction action, - const std::string& user_input) { - RequestMap::iterator request_itr = - pending_permission_requests_.find(request_id); - - if (request_itr == pending_permission_requests_.end()) - return SET_PERMISSION_INVALID; - - const PermissionResponseInfo& info = request_itr->second; - bool allow = (action == ALLOW) || - ((action == DEFAULT) && info.allowed_by_default); - - info.callback.Run(allow, user_input); - - // Only record user initiated (i.e. non-default) actions. - if (action != DEFAULT) - RecordUserInitiatedUMA(info, allow); - - pending_permission_requests_.erase(request_itr); - - return allow ? SET_PERMISSION_ALLOWED : SET_PERMISSION_DENIED; -} - -void WebViewGuest::SetUserAgentOverride( - const std::string& user_agent_override) { - is_overriding_user_agent_ = !user_agent_override.empty(); - if (is_overriding_user_agent_) { - content::RecordAction(UserMetricsAction("WebView.Guest.OverrideUA")); - } - guest_web_contents()->SetUserAgentOverride(user_agent_override); -} - -void WebViewGuest::Stop() { - guest_web_contents()->Stop(); -} - -void WebViewGuest::Terminate() { - content::RecordAction(UserMetricsAction("WebView.Guest.Terminate")); - base::ProcessHandle process_handle = - guest_web_contents()->GetRenderProcessHost()->GetHandle(); - if (process_handle) - base::KillProcess(process_handle, content::RESULT_CODE_KILLED, false); -} - -bool WebViewGuest::ClearData(const base::Time remove_since, - uint32 removal_mask, - const base::Closure& callback) { - content::RecordAction(UserMetricsAction("WebView.Guest.ClearData")); - content::StoragePartition* partition = - content::BrowserContext::GetStoragePartition( - guest_web_contents()->GetBrowserContext(), - guest_web_contents()->GetSiteInstance()); - - if (!partition) - return false; - - partition->ClearData( - removal_mask, - content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL, - GURL(), - content::StoragePartition::OriginMatcherFunction(), - remove_since, - base::Time::Now(), - callback); - return true; -} - -WebViewGuest::~WebViewGuest() { -} - -void WebViewGuest::DidCommitProvisionalLoadForFrame( - int64 frame_id, - const base::string16& frame_unique_name, - bool is_main_frame, - const GURL& url, - content::PageTransition transition_type, - content::RenderViewHost* render_view_host) { - find_helper_.CancelAllFindSessions(); - - scoped_ptr args(new base::DictionaryValue()); - args->SetString(guestview::kUrl, url.spec()); - args->SetBoolean(guestview::kIsTopLevel, is_main_frame); - args->SetInteger(webview::kInternalCurrentEntryIndex, - guest_web_contents()->GetController().GetCurrentEntryIndex()); - args->SetInteger(webview::kInternalEntryCount, - guest_web_contents()->GetController().GetEntryCount()); - args->SetInteger(webview::kInternalProcessId, - guest_web_contents()->GetRenderProcessHost()->GetID()); - DispatchEvent(new GuestView::Event(webview::kEventLoadCommit, args.Pass())); - - // Update the current zoom factor for the new page. - current_zoom_factor_ = content::ZoomLevelToZoomFactor( - guest_web_contents()->GetZoomLevel()); - - if (is_main_frame) { - chromevox_injected_ = false; - main_frame_id_ = frame_id; - } -} - -void WebViewGuest::DidFailProvisionalLoad( - int64 frame_id, - const base::string16& frame_unique_name, - bool is_main_frame, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - content::RenderViewHost* render_view_host) { - // Translate the |error_code| into an error string. - std::string error_type; - base::RemoveChars(net::ErrorToString(error_code), "net::", &error_type); - LoadAbort(is_main_frame, validated_url, error_type); -} - -void WebViewGuest::DidStartProvisionalLoadForFrame( - int64 frame_id, - int64 parent_frame_id, - bool is_main_frame, - const GURL& validated_url, - bool is_error_page, - bool is_iframe_srcdoc, - content::RenderViewHost* render_view_host) { - scoped_ptr args(new base::DictionaryValue()); - args->SetString(guestview::kUrl, validated_url.spec()); - args->SetBoolean(guestview::kIsTopLevel, is_main_frame); - DispatchEvent(new GuestView::Event(webview::kEventLoadStart, args.Pass())); -} - -void WebViewGuest::DocumentLoadedInFrame( - int64 frame_id, - content::RenderViewHost* render_view_host) { - if (frame_id == main_frame_id_) - InjectChromeVoxIfNeeded(render_view_host); -} - -void WebViewGuest::DidStopLoading(content::RenderViewHost* render_view_host) { - scoped_ptr args(new base::DictionaryValue()); - DispatchEvent(new GuestView::Event(webview::kEventLoadStop, args.Pass())); -} - -void WebViewGuest::WebContentsDestroyed(WebContents* web_contents) { - // Clean up custom context menu items for this guest. - extensions::MenuManager* menu_manager = extensions::MenuManager::Get( - Profile::FromBrowserContext(browser_context())); - menu_manager->RemoveAllContextItems(extensions::MenuItem::ExtensionKey( - embedder_extension_id(), view_instance_id())); - - RemoveWebViewFromExtensionRendererState(web_contents); -} - -void WebViewGuest::UserAgentOverrideSet(const std::string& user_agent) { - content::NavigationController& controller = - guest_web_contents()->GetController(); - content::NavigationEntry* entry = controller.GetVisibleEntry(); - if (!entry) - return; - entry->SetIsOverridingUserAgent(!user_agent.empty()); - if (!attached()) { - // We cannot reload now because all resource loads are suspended until - // attachment. - pending_reload_on_attachment_ = true; - return; - } - guest_web_contents()->GetController().Reload(false); -} - -void WebViewGuest::LoadHandlerCalled() { - scoped_ptr args(new base::DictionaryValue()); - DispatchEvent(new GuestView::Event(webview::kEventContentLoad, args.Pass())); -} - -void WebViewGuest::LoadRedirect(const GURL& old_url, - const GURL& new_url, - bool is_top_level) { - scoped_ptr args(new base::DictionaryValue()); - args->SetBoolean(guestview::kIsTopLevel, is_top_level); - args->SetString(webview::kNewURL, new_url.spec()); - args->SetString(webview::kOldURL, old_url.spec()); - DispatchEvent(new GuestView::Event(webview::kEventLoadRedirect, args.Pass())); -} - -void WebViewGuest::AddWebViewToExtensionRendererState() { - const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); - std::string partition_domain; - std::string partition_id; - bool in_memory; - if (!GetGuestPartitionConfigForSite( - site_url, &partition_domain, &partition_id, &in_memory)) { - NOTREACHED(); - return; - } - DCHECK(embedder_extension_id() == partition_domain); - - ExtensionRendererState::WebViewInfo webview_info; - webview_info.embedder_process_id = embedder_render_process_id(); - webview_info.instance_id = view_instance_id(); - webview_info.partition_id = partition_id; - webview_info.embedder_extension_id = embedder_extension_id(); - - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::Bind( - &ExtensionRendererState::AddWebView, - base::Unretained(ExtensionRendererState::GetInstance()), - guest_web_contents()->GetRenderProcessHost()->GetID(), - guest_web_contents()->GetRoutingID(), - webview_info)); -} - -// static -void WebViewGuest::RemoveWebViewFromExtensionRendererState( - WebContents* web_contents) { - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::Bind( - &ExtensionRendererState::RemoveWebView, - base::Unretained(ExtensionRendererState::GetInstance()), - web_contents->GetRenderProcessHost()->GetID(), - web_contents->GetRoutingID())); -} - -GURL WebViewGuest::ResolveURL(const std::string& src) { - if (!in_extension()) { - NOTREACHED(); - return GURL(src); - } - - GURL default_url(base::StringPrintf("%s://%s/", - extensions::kExtensionScheme, - embedder_extension_id().c_str())); - return default_url.Resolve(src); -} - -void WebViewGuest::SizeChanged(const gfx::Size& old_size, - const gfx::Size& new_size) { - scoped_ptr args(new base::DictionaryValue()); - args->SetInteger(webview::kOldHeight, old_size.height()); - args->SetInteger(webview::kOldWidth, old_size.width()); - args->SetInteger(webview::kNewHeight, new_size.height()); - args->SetInteger(webview::kNewWidth, new_size.width()); - DispatchEvent(new GuestView::Event(webview::kEventSizeChanged, args.Pass())); -} - -void WebViewGuest::RequestMediaAccessPermission( - const content::MediaStreamRequest& request, - const content::MediaResponseCallback& callback) { - base::DictionaryValue request_info; - request_info.Set( - guestview::kUrl, - base::Value::CreateStringValue(request.security_origin.spec())); - RequestPermission(static_cast( - WEB_VIEW_PERMISSION_TYPE_MEDIA), - request_info, - base::Bind(&WebViewGuest::OnWebViewMediaPermissionResponse, - base::Unretained(this), - request, - callback), - false /* allowed_by_default */); -} - -void WebViewGuest::CanDownload( - const std::string& request_method, - const GURL& url, - const base::Callback& callback) { - base::DictionaryValue request_info; - request_info.Set( - guestview::kUrl, - base::Value::CreateStringValue(url.spec())); - RequestPermission( - static_cast( - WEB_VIEW_PERMISSION_TYPE_DOWNLOAD), - request_info, - base::Bind(&WebViewGuest::OnWebViewDownloadPermissionResponse, - base::Unretained(this), - callback), - false /* allowed_by_default */); -} - -void WebViewGuest::RequestPointerLockPermission( - bool user_gesture, - bool last_unlocked_by_target, - const base::Callback& callback) { - base::DictionaryValue request_info; - request_info.Set(guestview::kUserGesture, - base::Value::CreateBooleanValue(user_gesture)); - request_info.Set(webview::kLastUnlockedBySelf, - base::Value::CreateBooleanValue(last_unlocked_by_target)); - request_info.Set(guestview::kUrl, - base::Value::CreateStringValue( - guest_web_contents()->GetLastCommittedURL().spec())); - - RequestPermission( - static_cast( - WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK), - request_info, - base::Bind(&WebViewGuest::OnWebViewPointerLockPermissionResponse, - base::Unretained(this), - callback), - false /* allowed_by_default */); -} - -content::JavaScriptDialogManager* - WebViewGuest::GetJavaScriptDialogManager() { - return &javascript_dialog_helper_; -} - -#if defined(OS_CHROMEOS) -void WebViewGuest::OnAccessibilityStatusChanged( - const chromeos::AccessibilityStatusEventDetails& details) { - if (details.notification_type == chromeos::ACCESSIBILITY_MANAGER_SHUTDOWN) { - accessibility_subscription_.reset(); - } else if (details.notification_type == - chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) { - if (details.enabled) - InjectChromeVoxIfNeeded(guest_web_contents()->GetRenderViewHost()); - else - chromevox_injected_ = false; - } -} -#endif - -void WebViewGuest::InjectChromeVoxIfNeeded( - content::RenderViewHost* render_view_host) { -#if defined(OS_CHROMEOS) - if (!chromevox_injected_) { - chromeos::AccessibilityManager* manager = - chromeos::AccessibilityManager::Get(); - if (manager && manager->IsSpokenFeedbackEnabled()) { - manager->InjectChromeVox(render_view_host); - chromevox_injected_ = true; - } - } -#endif -} - -int WebViewGuest::RemoveBridgeID(int bridge_id) { - std::map::iterator bridge_itr = - bridge_id_to_request_id_map_.find(bridge_id); - if (bridge_itr == bridge_id_to_request_id_map_.end()) - return webview::kInvalidPermissionRequestID; - - int request_id = bridge_itr->second; - bridge_id_to_request_id_map_.erase(bridge_itr); - return request_id; -} - -int WebViewGuest::RequestPermissionInternal( - BrowserPluginPermissionType permission_type, - const base::DictionaryValue& request_info, - const PermissionResponseCallback& callback, - bool allowed_by_default) { - // If there are too many pending permission requests then reject this request. - if (pending_permission_requests_.size() >= - webview::kMaxOutstandingPermissionRequests) { - // Let the stack unwind before we deny the permission request so that - // objects held by the permission request are not destroyed immediately - // after creation. This is to allow those same objects to be accessed again - // in the same scope without fear of use after freeing. - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&PermissionResponseCallback::Run, - base::Owned(new PermissionResponseCallback(callback)), - allowed_by_default, - std::string())); - return webview::kInvalidPermissionRequestID; - } - - int request_id = next_permission_request_id_++; - pending_permission_requests_[request_id] = - PermissionResponseInfo(callback, permission_type, allowed_by_default); - scoped_ptr args(request_info.DeepCopy()); - args->SetInteger(webview::kRequestId, request_id); - switch (static_cast(permission_type)) { - case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: { - DispatchEvent(new GuestView::Event(webview::kEventNewWindow, - args.Pass())); - break; - } - case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: { - DispatchEvent(new GuestView::Event(webview::kEventDialog, - args.Pass())); - break; - } - default: { - args->SetString(webview::kPermission, - PermissionTypeToString(permission_type)); - DispatchEvent(new GuestView::Event(webview::kEventPermissionRequest, - args.Pass())); - break; - } - } - return request_id; -} - -WebViewGuest::PermissionResponseInfo::PermissionResponseInfo() - : permission_type(BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN), - allowed_by_default(false) { -} - -WebViewGuest::PermissionResponseInfo::PermissionResponseInfo( - const PermissionResponseCallback& callback, - BrowserPluginPermissionType permission_type, - bool allowed_by_default) - : callback(callback), - permission_type(permission_type), - allowed_by_default(allowed_by_default) { -} - -WebViewGuest::PermissionResponseInfo::~PermissionResponseInfo() { -} diff --git a/chrome/browser/guestview/webview/webview_guest.h b/chrome/browser/guestview/webview/webview_guest.h deleted file mode 100644 index 53e2f5a..0000000 --- a/chrome/browser/guestview/webview/webview_guest.h +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_GUEST_H_ -#define CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_GUEST_H_ - -#include "base/observer_list.h" -#include "chrome/browser/extensions/tab_helper.h" -#include "chrome/browser/guestview/guestview.h" -#include "chrome/browser/guestview/webview/javascript_dialog_helper.h" -#include "chrome/browser/guestview/webview/webview_find_helper.h" -#include "content/public/browser/javascript_dialog_manager.h" -#include "content/public/browser/notification_registrar.h" -#include "content/public/browser/web_contents_observer.h" -#include "third_party/WebKit/public/web/WebFindOptions.h" - -#if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" -#endif - -namespace extensions { -class ScriptExecutor; -class WebviewFindFunction; -} // namespace extensions - -// A WebViewGuest is a WebContentsObserver on the guest WebContents of a -// tag. It provides the browser-side implementation of the -// API and manages the lifetime of extension events. WebViewGuest is -// created on attachment. That is, when a guest WebContents is associated with -// a particular embedder WebContents. This happens on either initial navigation -// or through the use of the New Window API, when a new window is attached to -// a particular . -class WebViewGuest : public GuestView, - public content::NotificationObserver, - public content::WebContentsObserver { - public: - WebViewGuest(content::WebContents* guest_web_contents, - const std::string& embedder_extension_id); - - static WebViewGuest* From(int embedder_process_id, int instance_id); - static WebViewGuest* FromWebContents(content::WebContents* contents); - // Returns guestview::kInstanceIDNone if |contents| does not correspond to a - // WebViewGuest. - static int GetViewInstanceId(content::WebContents* contents); - - // GuestView implementation. - virtual void Attach(content::WebContents* embedder_web_contents, - const base::DictionaryValue& args) OVERRIDE; - virtual GuestView::Type GetViewType() const OVERRIDE; - virtual WebViewGuest* AsWebView() OVERRIDE; - virtual AdViewGuest* AsAdView() OVERRIDE; - - // GuestDelegate implementation. - virtual void AddMessageToConsole(int32 level, - const base::string16& message, - int32 line_no, - const base::string16& source_id) OVERRIDE; - virtual void LoadProgressed(double progress) OVERRIDE; - virtual void Close() OVERRIDE; - virtual void DidAttach() OVERRIDE; - virtual void EmbedderDestroyed() OVERRIDE; - virtual void FindReply(int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) OVERRIDE; - virtual void GuestProcessGone(base::TerminationStatus status) OVERRIDE; - virtual bool HandleKeyboardEvent( - const content::NativeWebKeyboardEvent& event) OVERRIDE; - virtual bool IsDragAndDropEnabled() OVERRIDE; - virtual bool IsOverridingUserAgent() const OVERRIDE; - virtual void LoadAbort(bool is_top_level, - const GURL& url, - const std::string& error_type) OVERRIDE; - virtual void RendererResponsive() OVERRIDE; - virtual void RendererUnresponsive() OVERRIDE; - virtual void RequestPermission( - BrowserPluginPermissionType permission_type, - const base::DictionaryValue& request_info, - const PermissionResponseCallback& callback, - bool allowed_by_default) OVERRIDE; - virtual GURL ResolveURL(const std::string& src) OVERRIDE; - virtual void SizeChanged(const gfx::Size& old_size, const gfx::Size& new_size) - OVERRIDE; - virtual void RequestMediaAccessPermission( - const content::MediaStreamRequest& request, - const content::MediaResponseCallback& callback) OVERRIDE; - virtual void CanDownload(const std::string& request_method, - const GURL& url, - const base::Callback& callback) OVERRIDE; - virtual void RequestPointerLockPermission( - bool user_gesture, - bool last_unlocked_by_target, - const base::Callback& callback) OVERRIDE; - virtual content::JavaScriptDialogManager* - GetJavaScriptDialogManager() OVERRIDE; - - // NotificationObserver implementation. - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) OVERRIDE; - - // Set the zoom factor. - virtual void SetZoom(double zoom_factor) OVERRIDE; - - // Returns the current zoom factor. - double GetZoom(); - - // Begin or continue a find request. - void Find(const base::string16& search_text, - const blink::WebFindOptions& options, - scoped_refptr find_function); - - // Conclude a find request to clear highlighting. - void StopFinding(content::StopFindAction); - - // If possible, navigate the guest to |relative_index| entries away from the - // current navigation entry. - void Go(int relative_index); - - // Reload the guest. - void Reload(); - - // Requests Geolocation Permission from the embedder. - void RequestGeolocationPermission(int bridge_id, - const GURL& requesting_frame, - bool user_gesture, - const base::Callback& callback); - - void OnWebViewGeolocationPermissionResponse( - int bridge_id, - bool user_gesture, - const base::Callback& callback, - bool allow, - const std::string& user_input); - - void CancelGeolocationPermissionRequest(int bridge_id); - - void OnWebViewMediaPermissionResponse( - const content::MediaStreamRequest& request, - const content::MediaResponseCallback& callback, - bool allow, - const std::string& user_input); - - void OnWebViewDownloadPermissionResponse( - const base::Callback& callback, - bool allow, - const std::string& user_input); - - void OnWebViewPointerLockPermissionResponse( - const base::Callback& callback, - bool allow, - const std::string& user_input); - - enum PermissionResponseAction { - DENY, - ALLOW, - DEFAULT - }; - - enum SetPermissionResult { - SET_PERMISSION_INVALID, - SET_PERMISSION_ALLOWED, - SET_PERMISSION_DENIED - }; - - // Responds to the permission request |request_id| with |action| and - // |user_input|. Returns whether there was a pending request for the provided - // |request_id|. - SetPermissionResult SetPermission(int request_id, - PermissionResponseAction action, - const std::string& user_input); - - // Overrides the user agent for this guest. - // This affects subsequent guest navigations. - void SetUserAgentOverride(const std::string& user_agent_override); - - // Stop loading the guest. - void Stop(); - - // Kill the guest process. - void Terminate(); - - // Clears data in the storage partition of this guest. - // - // Partition data that are newer than |removal_since| will be removed. - // |removal_mask| corresponds to bitmask in StoragePartition::RemoveDataMask. - bool ClearData(const base::Time remove_since, - uint32 removal_mask, - const base::Closure& callback); - - extensions::ScriptExecutor* script_executor() { - return script_executor_.get(); - } - - private: - virtual ~WebViewGuest(); - - // A map to store the callback for a request keyed by the request's id. - struct PermissionResponseInfo { - PermissionResponseCallback callback; - BrowserPluginPermissionType permission_type; - bool allowed_by_default; - PermissionResponseInfo(); - PermissionResponseInfo(const PermissionResponseCallback& callback, - BrowserPluginPermissionType permission_type, - bool allowed_by_default); - ~PermissionResponseInfo(); - }; - - static void RecordUserInitiatedUMA(const PermissionResponseInfo& info, - bool allow); - // WebContentsObserver implementation. - virtual void DidCommitProvisionalLoadForFrame( - int64 frame_id, - const base::string16& frame_unique_name, - bool is_main_frame, - const GURL& url, - content::PageTransition transition_type, - content::RenderViewHost* render_view_host) OVERRIDE; - virtual void DidFailProvisionalLoad( - int64 frame_id, - const base::string16& frame_unique_name, - bool is_main_frame, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - content::RenderViewHost* render_view_host) OVERRIDE; - virtual void DidStartProvisionalLoadForFrame( - int64 frame_id, - int64 parent_frame_id, - bool is_main_frame, - const GURL& validated_url, - bool is_error_page, - bool is_iframe_srcdoc, - content::RenderViewHost* render_view_host) OVERRIDE; - virtual void DocumentLoadedInFrame( - int64 frame_id, - content::RenderViewHost* render_view_host) OVERRIDE; - virtual void DidStopLoading( - content::RenderViewHost* render_view_host) OVERRIDE; - virtual void WebContentsDestroyed( - content::WebContents* web_contents) OVERRIDE; - virtual void UserAgentOverrideSet(const std::string& user_agent) OVERRIDE; - - // Called after the load handler is called in the guest's main frame. - void LoadHandlerCalled(); - - // Called when a redirect notification occurs. - void LoadRedirect(const GURL& old_url, - const GURL& new_url, - bool is_top_level); - - void AddWebViewToExtensionRendererState(); - static void RemoveWebViewFromExtensionRendererState( - content::WebContents* web_contents); - -#if defined(OS_CHROMEOS) - // Notification of a change in the state of an accessibility setting. - void OnAccessibilityStatusChanged( - const chromeos::AccessibilityStatusEventDetails& details); -#endif - - void InjectChromeVoxIfNeeded(content::RenderViewHost* render_view_host); - - // Bridge IDs correspond to a geolocation request. This method will remove - // the bookkeeping for a particular geolocation request associated with the - // provided |bridge_id|. It returns the request ID of the geolocation request. - int RemoveBridgeID(int bridge_id); - - int RequestPermissionInternal( - BrowserPluginPermissionType permission_type, - const base::DictionaryValue& request_info, - const PermissionResponseCallback& callback, - bool allowed_by_default); - - ObserverList - script_observers_; - scoped_ptr script_executor_; - - content::NotificationRegistrar notification_registrar_; - - // A counter to generate a unique request id for a permission request. - // We only need the ids to be unique for a given WebViewGuest. - int next_permission_request_id_; - - typedef std::map RequestMap; - RequestMap pending_permission_requests_; - - // True if the user agent is overridden. - bool is_overriding_user_agent_; - - // Indicates that the page needs to be reloaded once it has been attached to - // an embedder. - bool pending_reload_on_attachment_; - - // Main frame ID of last committed page. - int64 main_frame_id_; - - // Set to |true| if ChromeVox was already injected in main frame. - bool chromevox_injected_; - - // Stores the current zoom factor. - double current_zoom_factor_; - - // Handles find requests and replies for the webview find API. - WebviewFindHelper find_helper_; - - // Handles the JavaScript dialog requests. - JavaScriptDialogHelper javascript_dialog_helper_; - - friend void WebviewFindHelper::DispatchFindUpdateEvent(bool canceled, - bool final_update); - -#if defined(OS_CHROMEOS) - // Subscription to receive notifications on changes to a11y settings. - scoped_ptr - accessibility_subscription_; -#endif - - std::map bridge_id_to_request_id_map_; - - DISALLOW_COPY_AND_ASSIGN(WebViewGuest); -}; - -#endif // CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_GUEST_H_ diff --git a/chrome/browser/guestview/webview/webview_permission_types.h b/chrome/browser/guestview/webview/webview_permission_types.h deleted file mode 100644 index a532036..0000000 --- a/chrome/browser/guestview/webview/webview_permission_types.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_PERMISSION_TYPES_H_ -#define CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_PERMISSION_TYPES_H_ - -#include "content/public/common/browser_plugin_permission_type.h" - -enum WebViewPermissionType { - WEB_VIEW_PERMISSION_TYPE_DOWNLOAD = - BROWSER_PLUGIN_PERMISSION_TYPE_CONTENT_END + 1, - - WEB_VIEW_PERMISSION_TYPE_GEOLOCATION, - - // JavaScript Dialogs: prompt, alert, confirm - // Note: Even through dialogs do not use the permission API, the dialog API - // is sufficiently similiar that it's convenient to consider it a permission - // type for code reuse. - WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG, - - WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN, - - // Media access (audio/video) permission request type. - WEB_VIEW_PERMISSION_TYPE_MEDIA, - - WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK -}; - -#endif // CHROME_BROWSER_GUESTVIEW_WEBVIEW_WEBVIEW_PERMISSION_TYPES_H_ diff --git a/chrome/browser/renderer_context_menu/context_menu_content_type_factory.cc b/chrome/browser/renderer_context_menu/context_menu_content_type_factory.cc index dfbb878..5641a00 100644 --- a/chrome/browser/renderer_context_menu/context_menu_content_type_factory.cc +++ b/chrome/browser/renderer_context_menu/context_menu_content_type_factory.cc @@ -5,8 +5,8 @@ #include "chrome/browser/renderer_context_menu/context_menu_content_type_factory.h" #include "chrome/browser/app_mode/app_mode_utils.h" -#include "chrome/browser/guestview/webview/context_menu_content_type_webview.h" -#include "chrome/browser/guestview/webview/webview_guest.h" +#include "chrome/browser/guest_view/web_view/context_menu_content_type_web_view.h" +#include "chrome/browser/guest_view/web_view/web_view_guest.h" #include "chrome/browser/renderer_context_menu/context_menu_content_type.h" #include "chrome/browser/renderer_context_menu/context_menu_content_type_app_mode.h" #include "chrome/browser/renderer_context_menu/context_menu_content_type_extension_popup.h" diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 735c456..a2d8ec2 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc @@ -35,7 +35,7 @@ #include "chrome/browser/extensions/devtools_util.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/google/google_util.h" -#include "chrome/browser/guestview/webview/webview_guest.h" +#include "chrome/browser/guest_view/web_view/web_view_guest.h" #include "chrome/browser/plugins/chrome_plugin_service_filter.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/profiles/profile.h" diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 6ee7fa8..52ea8e4 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -730,27 +730,28 @@ 'browser/gpu/gpu_feature_checker.h', 'browser/gpu/gpu_mode_manager.cc', 'browser/gpu/gpu_mode_manager.h', - 'browser/guestview/adview/adview_constants.cc', - 'browser/guestview/adview/adview_constants.h', - 'browser/guestview/adview/adview_guest.cc', - 'browser/guestview/adview/adview_guest.h', - 'browser/guestview/guestview_constants.cc', - 'browser/guestview/guestview_constants.h', - 'browser/guestview/guestview.cc', - 'browser/guestview/guestview.h', - 'browser/guestview/webview/context_menu_content_type_webview.cc', - 'browser/guestview/webview/context_menu_content_type_webview.h', - 'browser/guestview/webview/javascript_dialog_helper.cc', - 'browser/guestview/webview/javascript_dialog_helper.h', - 'browser/guestview/webview/plugin_permission_helper.cc', - 'browser/guestview/webview/plugin_permission_helper.h', - 'browser/guestview/webview/webview_constants.cc', - 'browser/guestview/webview/webview_constants.h', - 'browser/guestview/webview/webview_find_helper.cc', - 'browser/guestview/webview/webview_find_helper.h', - 'browser/guestview/webview/webview_guest.cc', - 'browser/guestview/webview/webview_guest.h', - 'browser/guestview/webview/webview_permission_types.h', + 'browser/guest_view/ad_view/ad_view_constants.cc', + 'browser/guest_view/ad_view/ad_view_constants.h', + 'browser/guest_view/ad_view/ad_view_guest.cc', + 'browser/guest_view/ad_view/ad_view_guest.h', + 'browser/guest_view/guest_view_constants.cc', + 'browser/guest_view/guest_view_constants.h', + 'browser/guest_view/guest_view_base.cc', + 'browser/guest_view/guest_view_base.h', + 'browser/guest_view/guest_view.h', + 'browser/guest_view/web_view/context_menu_content_type_web_view.cc', + 'browser/guest_view/web_view/context_menu_content_type_web_view.h', + 'browser/guest_view/web_view/javascript_dialog_helper.cc', + 'browser/guest_view/web_view/javascript_dialog_helper.h', + 'browser/guest_view/web_view/plugin_permission_helper.cc', + 'browser/guest_view/web_view/plugin_permission_helper.h', + 'browser/guest_view/web_view/web_view_constants.cc', + 'browser/guest_view/web_view/web_view_constants.h', + 'browser/guest_view/web_view/web_view_find_helper.cc', + 'browser/guest_view/web_view/web_view_find_helper.h', + 'browser/guest_view/web_view/web_view_guest.cc', + 'browser/guest_view/web_view/web_view_guest.h', + 'browser/guest_view/web_view/web_view_permission_types.h', 'browser/hang_monitor/hang_crash_dump_win.cc', 'browser/hang_monitor/hang_crash_dump_win.h', 'browser/hang_monitor/hung_plugin_action.cc', @@ -2841,7 +2842,7 @@ ], }, { # enable_plugins==0 'sources/': [ - ['exclude', '^browser/guestview/webview/plugin_permission_helper'], + ['exclude', '^browser/guest_view/web_view/plugin_permission_helper'], ['exclude', '^browser/pepper_'], ['exclude', '^browser/plugins/'], ['exclude', '^browser/renderer_host/pepper/'], -- cgit v1.1