Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / guest_view / guest_view_base.cc
blob80526d55b6ae2ea7ef132b5933ba98b8e57b9da1
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/guest_view/guest_view_base.h"
7 #include "base/lazy_instance.h"
8 #include "chrome/browser/guest_view/ad_view/ad_view_guest.h"
9 #include "chrome/browser/guest_view/guest_view_constants.h"
10 #include "chrome/browser/guest_view/guest_view_manager.h"
11 #include "chrome/browser/guest_view/web_view/web_view_guest.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/common/content_settings.h"
14 #include "content/public/browser/render_process_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/common/url_constants.h"
17 #include "extensions/browser/event_router.h"
18 #include "net/base/escape.h"
20 using content::WebContents;
22 namespace {
24 typedef std::map<WebContents*, GuestViewBase*> WebContentsGuestViewMap;
25 static base::LazyInstance<WebContentsGuestViewMap> webcontents_guestview_map =
26 LAZY_INSTANCE_INITIALIZER;
28 } // namespace
30 GuestViewBase::Event::Event(const std::string& name,
31 scoped_ptr<base::DictionaryValue> args)
32 : name_(name), args_(args.Pass()) {
35 GuestViewBase::Event::~Event() {
38 scoped_ptr<base::DictionaryValue> GuestViewBase::Event::GetArguments() {
39 return args_.Pass();
42 GuestViewBase::GuestViewBase(WebContents* guest_web_contents,
43 const std::string& embedder_extension_id,
44 const base::WeakPtr<GuestViewBase>& opener)
45 : guest_web_contents_(guest_web_contents),
46 embedder_web_contents_(NULL),
47 embedder_extension_id_(embedder_extension_id),
48 embedder_render_process_id_(0),
49 browser_context_(guest_web_contents->GetBrowserContext()),
50 guest_instance_id_(guest_web_contents->GetEmbeddedInstanceID()),
51 view_instance_id_(guestview::kInstanceIDNone),
52 opener_(opener),
53 weak_ptr_factory_(this) {
54 webcontents_guestview_map.Get().insert(
55 std::make_pair(guest_web_contents, this));
58 // static
59 GuestViewBase* GuestViewBase::Create(
60 WebContents* guest_web_contents,
61 const std::string& embedder_extension_id,
62 const std::string& view_type,
63 const base::WeakPtr<GuestViewBase>& opener) {
64 if (view_type == "webview") {
65 return new WebViewGuest(guest_web_contents, embedder_extension_id, opener);
66 } else if (view_type == "adview") {
67 return new AdViewGuest(guest_web_contents, embedder_extension_id);
69 NOTREACHED();
70 return NULL;
73 // static
74 GuestViewBase* GuestViewBase::FromWebContents(WebContents* web_contents) {
75 WebContentsGuestViewMap* guest_map = webcontents_guestview_map.Pointer();
76 WebContentsGuestViewMap::iterator it = guest_map->find(web_contents);
77 return it == guest_map->end() ? NULL : it->second;
80 // static
81 GuestViewBase* GuestViewBase::From(int embedder_process_id,
82 int guest_instance_id) {
83 content::RenderProcessHost* host =
84 content::RenderProcessHost::FromID(embedder_process_id);
85 if (!host)
86 return NULL;
88 content::WebContents* guest_web_contents =
89 GuestViewManager::FromBrowserContext(host->GetBrowserContext())->
90 GetGuestByInstanceID(guest_instance_id, embedder_process_id);
91 if (!guest_web_contents)
92 return NULL;
94 return GuestViewBase::FromWebContents(guest_web_contents);
97 // static
98 bool GuestViewBase::GetGuestPartitionConfigForSite(
99 const GURL& site,
100 std::string* partition_domain,
101 std::string* partition_name,
102 bool* in_memory) {
103 if (!site.SchemeIs(content::kGuestScheme))
104 return false;
106 // Since guest URLs are only used for packaged apps, there must be an app
107 // id in the URL.
108 CHECK(site.has_host());
109 *partition_domain = site.host();
110 // Since persistence is optional, the path must either be empty or the
111 // literal string.
112 *in_memory = (site.path() != "/persist");
113 // The partition name is user supplied value, which we have encoded when the
114 // URL was created, so it needs to be decoded.
115 *partition_name =
116 net::UnescapeURLComponent(site.query(), net::UnescapeRule::NORMAL);
117 return true;
120 // static
121 void GuestViewBase::GetDefaultContentSettingRules(
122 RendererContentSettingRules* rules,
123 bool incognito) {
124 rules->image_rules.push_back(
125 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
126 ContentSettingsPattern::Wildcard(),
127 CONTENT_SETTING_ALLOW,
128 std::string(),
129 incognito));
131 rules->script_rules.push_back(
132 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
133 ContentSettingsPattern::Wildcard(),
134 CONTENT_SETTING_ALLOW,
135 std::string(),
136 incognito));
139 base::WeakPtr<GuestViewBase> GuestViewBase::AsWeakPtr() {
140 return weak_ptr_factory_.GetWeakPtr();
143 void GuestViewBase::Attach(content::WebContents* embedder_web_contents,
144 const base::DictionaryValue& args) {
145 embedder_web_contents_ = embedder_web_contents;
146 embedder_render_process_id_ =
147 embedder_web_contents->GetRenderProcessHost()->GetID();
148 args.GetInteger(guestview::kParameterInstanceId, &view_instance_id_);
150 std::pair<int, int> key(embedder_render_process_id_, guest_instance_id_);
152 // GuestViewBase::Attach is called prior to initialization (and initial
153 // navigation) of the guest in the content layer in order to permit mapping
154 // the necessary associations between the <*view> element and its guest. This
155 // is needed by the <webview> WebRequest API to allow intercepting resource
156 // requests during navigation. However, queued events should be fired after
157 // content layer initialization in order to ensure that load events (such as
158 // 'loadstop') fire in embedder after the contentWindow is available.
159 if (!in_extension())
160 return;
162 base::MessageLoop::current()->PostTask(
163 FROM_HERE,
164 base::Bind(&GuestViewBase::SendQueuedEvents,
165 weak_ptr_factory_.GetWeakPtr()));
168 WebContents* GuestViewBase::GetOpener() const {
169 if (!opener_)
170 return NULL;
171 return opener_->guest_web_contents();
174 void GuestViewBase::SetOpener(WebContents* web_contents) {
175 GuestViewBase* guest = FromWebContents(web_contents);
176 if (guest && guest->IsViewType(GetViewType())) {
177 opener_ = guest->AsWeakPtr();
178 return;
180 opener_ = base::WeakPtr<GuestViewBase>();
183 GuestViewBase::~GuestViewBase() {
184 std::pair<int, int> key(embedder_render_process_id_, guest_instance_id_);
186 webcontents_guestview_map.Get().erase(guest_web_contents());
188 pending_events_.clear();
191 void GuestViewBase::DispatchEvent(Event* event) {
192 scoped_ptr<Event> event_ptr(event);
193 if (!in_extension()) {
194 NOTREACHED();
195 return;
198 if (!attached()) {
199 pending_events_.push_back(linked_ptr<Event>(event_ptr.release()));
200 return;
203 Profile* profile = Profile::FromBrowserContext(browser_context_);
205 extensions::EventFilteringInfo info;
206 info.SetURL(GURL());
207 info.SetInstanceID(guest_instance_id_);
208 scoped_ptr<base::ListValue> args(new base::ListValue());
209 args->Append(event->GetArguments().release());
211 extensions::EventRouter::DispatchEvent(
212 embedder_web_contents_,
213 profile,
214 embedder_extension_id_,
215 event->name(),
216 args.Pass(),
217 extensions::EventRouter::USER_GESTURE_UNKNOWN,
218 info);
221 void GuestViewBase::SendQueuedEvents() {
222 if (!attached())
223 return;
225 while (!pending_events_.empty()) {
226 linked_ptr<Event> event_ptr = pending_events_.front();
227 pending_events_.pop_front();
228 DispatchEvent(event_ptr.release());