Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc

Issue 729333002: Add PostMessage support for MimeHandlerView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_con tainer.h" 5 #include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_con tainer.h"
6 6
7 #include "content/public/renderer/render_frame.h" 7 #include "content/public/renderer/render_frame.h"
8 #include "content/public/renderer/render_view.h"
8 #include "extensions/common/extension_messages.h" 9 #include "extensions/common/extension_messages.h"
9 #include "extensions/common/guest_view/guest_view_constants.h" 10 #include "extensions/common/guest_view/guest_view_constants.h"
11 #include "gin/arguments.h"
12 #include "gin/handle.h"
13 #include "gin/interceptor.h"
14 #include "gin/object_template_builder.h"
15 #include "gin/wrappable.h"
10 #include "third_party/WebKit/public/web/WebDocument.h" 16 #include "third_party/WebKit/public/web/WebDocument.h"
11 #include "third_party/WebKit/public/web/WebLocalFrame.h" 17 #include "third_party/WebKit/public/web/WebLocalFrame.h"
18 #include "third_party/WebKit/public/web/WebView.h"
12 19
13 namespace extensions { 20 namespace extensions {
14 21
22 namespace {
23
24 const char kPostMessageName[] = "postMessage";
25
26 // The gin-backed scriptable object which is exposed by the BrowserPlugin for
27 // MimeHandlerViewContainer. This currently only implements "postMessage".
28 class ScriptableObject : public gin::Wrappable<ScriptableObject>,
29 public gin::NamedPropertyInterceptor {
30 public:
31 static gin::WrapperInfo kWrapperInfo;
32
33 static v8::Handle<v8::Object> Create(
34 v8::Isolate* isolate,
35 base::WeakPtr<MimeHandlerViewContainer> container) {
36 ScriptableObject* scriptable_object =
37 new ScriptableObject(isolate, container);
38 return gin::CreateHandle(isolate, scriptable_object).ToV8()->ToObject();
39 }
40
41 // gin::NamedPropertyInterceptor
42 v8::Local<v8::Value> GetNamedProperty(
43 v8::Isolate* isolate,
44 const std::string& identifier) override {
45 if (identifier == kPostMessageName) {
46 return gin::CreateFunctionTemplate(isolate,
47 base::Bind(&MimeHandlerViewContainer::PostMessage,
48 container_, isolate))->GetFunction();
49 }
50 return v8::Local<v8::Value>();
51 }
52
53 private:
54 ScriptableObject(v8::Isolate* isolate,
55 base::WeakPtr<MimeHandlerViewContainer> container)
56 : gin::NamedPropertyInterceptor(isolate, this),
57 container_(container) {}
58 virtual ~ScriptableObject() {}
59
60 // gin::Wrappable
61 virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
62 v8::Isolate* isolate) override {
63 return gin::Wrappable<ScriptableObject>::GetObjectTemplateBuilder(isolate)
64 .AddNamedPropertyInterceptor();
Sam McNally 2014/12/18 05:36:47 2 more spaces?
raymes 2014/12/19 00:00:16 Done.
65 }
66
67 base::WeakPtr<MimeHandlerViewContainer> container_;
68 };
69
70 // static
71 gin::WrapperInfo ScriptableObject::kWrapperInfo = { gin::kEmbedderNativeGin };
72
73 } // namespace
74
15 MimeHandlerViewContainer::MimeHandlerViewContainer( 75 MimeHandlerViewContainer::MimeHandlerViewContainer(
16 content::RenderFrame* render_frame, 76 content::RenderFrame* render_frame,
17 const std::string& mime_type, 77 const std::string& mime_type,
18 const GURL& original_url) 78 const GURL& original_url)
19 : GuestViewContainer(render_frame), 79 : GuestViewContainer(render_frame),
20 mime_type_(mime_type), 80 mime_type_(mime_type),
21 original_url_(original_url) { 81 original_url_(original_url),
82 guest_proxy_routing_id_(-1),
83 weak_factory_(this) {
22 DCHECK(!mime_type_.empty()); 84 DCHECK(!mime_type_.empty());
23 is_embedded_ = !render_frame->GetWebFrame()->document().isPluginDocument(); 85 is_embedded_ = !render_frame->GetWebFrame()->document().isPluginDocument();
24 } 86 }
25 87
26 MimeHandlerViewContainer::~MimeHandlerViewContainer() { 88 MimeHandlerViewContainer::~MimeHandlerViewContainer() {
27 if (loader_) 89 if (loader_)
28 loader_->cancel(); 90 loader_->cancel();
29 } 91 }
30 92
31 void MimeHandlerViewContainer::DidFinishLoading() {
32 DCHECK(!is_embedded_);
33 CreateMimeHandlerViewGuest();
34 }
35
36 void MimeHandlerViewContainer::DidReceiveData(const char* data,
37 int data_length) {
38 html_string_ += std::string(data, data_length);
39 }
40
41 void MimeHandlerViewContainer::Ready() { 93 void MimeHandlerViewContainer::Ready() {
42 blink::WebFrame* frame = render_frame()->GetWebFrame(); 94 blink::WebFrame* frame = render_frame()->GetWebFrame();
43 blink::WebURLLoaderOptions options; 95 blink::WebURLLoaderOptions options;
44 // The embedded plugin is allowed to be cross-origin. 96 // The embedded plugin is allowed to be cross-origin.
45 options.crossOriginRequestPolicy = 97 options.crossOriginRequestPolicy =
46 blink::WebURLLoaderOptions::CrossOriginRequestPolicyAllow; 98 blink::WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
47 DCHECK(!loader_); 99 DCHECK(!loader_);
48 loader_.reset(frame->createAssociatedURLLoader(options)); 100 loader_.reset(frame->createAssociatedURLLoader(options));
49 101
50 blink::WebURLRequest request(original_url_); 102 blink::WebURLRequest request(original_url_);
51 request.setRequestContext(blink::WebURLRequest::RequestContextObject); 103 request.setRequestContext(blink::WebURLRequest::RequestContextObject);
52 loader_->loadAsynchronously(request, this); 104 loader_->loadAsynchronously(request, this);
53 } 105 }
54 106
107 void MimeHandlerViewContainer::DidFinishLoading() {
108 DCHECK(!is_embedded_);
109 CreateMimeHandlerViewGuest();
110 }
111
112 void MimeHandlerViewContainer::DidReceiveData(const char* data,
113 int data_length) {
114 html_string_ += std::string(data, data_length);
115 }
116
117 v8::Local<v8::Object> MimeHandlerViewContainer::v8ScriptableObject(
118 v8::Isolate* isolate) {
119 if (scriptable_object_.IsEmpty()) {
120 v8::Local<v8::Object> object =
121 ScriptableObject::Create(isolate, weak_factory_.GetWeakPtr());
122 scriptable_object_.reset(object);
123 }
124 return scriptable_object_.NewHandle(isolate);
125 }
126
55 bool MimeHandlerViewContainer::HandlesMessage(const IPC::Message& message) { 127 bool MimeHandlerViewContainer::HandlesMessage(const IPC::Message& message) {
56 return message.type() == ExtensionMsg_CreateMimeHandlerViewGuestACK::ID; 128 return message.type() == ExtensionMsg_CreateMimeHandlerViewGuestACK::ID ||
129 message.type() == ExtensionMsg_GuestAttached::ID;
57 } 130 }
58 131
59 bool MimeHandlerViewContainer::OnMessage(const IPC::Message& message) { 132 bool MimeHandlerViewContainer::OnMessage(const IPC::Message& message) {
60 bool handled = true; 133 bool handled = true;
61 IPC_BEGIN_MESSAGE_MAP(MimeHandlerViewContainer, message) 134 IPC_BEGIN_MESSAGE_MAP(MimeHandlerViewContainer, message)
62 IPC_MESSAGE_HANDLER(ExtensionMsg_CreateMimeHandlerViewGuestACK, 135 IPC_MESSAGE_HANDLER(ExtensionMsg_CreateMimeHandlerViewGuestACK,
63 OnCreateMimeHandlerViewGuestACK) 136 OnCreateMimeHandlerViewGuestACK)
137 IPC_MESSAGE_HANDLER(ExtensionMsg_GuestAttached, OnGuestAttached)
64 IPC_MESSAGE_UNHANDLED(handled = false) 138 IPC_MESSAGE_UNHANDLED(handled = false)
65 IPC_END_MESSAGE_MAP() 139 IPC_END_MESSAGE_MAP()
66 return handled; 140 return handled;
67 } 141 }
68 142
69 void MimeHandlerViewContainer::didReceiveData(blink::WebURLLoader* /* unused */, 143 void MimeHandlerViewContainer::didReceiveData(blink::WebURLLoader* /* unused */,
70 const char* data, 144 const char* data,
71 int data_length, 145 int data_length,
72 int /* unused */) { 146 int /* unused */) {
73 html_string_ += std::string(data, data_length); 147 html_string_ += std::string(data, data_length);
74 } 148 }
75 149
76 void MimeHandlerViewContainer::didFinishLoading( 150 void MimeHandlerViewContainer::didFinishLoading(
77 blink::WebURLLoader* /* unused */, 151 blink::WebURLLoader* /* unused */,
78 double /* unused */, 152 double /* unused */,
79 int64_t /* unused */) { 153 int64_t /* unused */) {
80 DCHECK(is_embedded_); 154 DCHECK(is_embedded_);
81 CreateMimeHandlerViewGuest(); 155 CreateMimeHandlerViewGuest();
82 } 156 }
83 157
158 void MimeHandlerViewContainer::PostMessage(v8::Isolate* isolate,
159 v8::Handle<v8::Value> message) {
160 content::RenderView* guest_proxy_render_view =
161 content::RenderView::FromRoutingID(guest_proxy_routing_id_);
162 if (!guest_proxy_render_view)
163 return;
164 blink::WebFrame* guest_proxy_frame =
165 guest_proxy_render_view->GetWebView()->mainFrame();
166 if (!guest_proxy_frame)
167 return;
168
169 v8::Local<v8::Object> guest_proxy_window =
Sam McNally 2014/12/18 05:36:47 I think this would be nicer if it used a gin::Dict
raymes 2014/12/19 00:00:16 Done.
170 guest_proxy_frame->mainWorldScriptContext()->Global();
171 std::string post_message_name(kPostMessageName);
172 v8::Handle<v8::String> post_message_string = v8::String::NewFromUtf8(
173 isolate, post_message_name.c_str(), v8::String::kNormalString,
174 post_message_name.size());
175 v8::Handle<v8::Value> post_message =
176 guest_proxy_window->Get(post_message_string);
177 if (post_message.IsEmpty() || !post_message->IsFunction())
178 return;
179
180 v8::Handle<v8::Value> args[] = {
181 message,
182 // Post the message to any domain inside the browser plugin. The embedder
183 // should already know what is embedded.
184 v8::String::NewFromUtf8(isolate, "*", v8::String::kNormalString, 1)
Sam McNally 2014/12/18 05:36:47 gin::StringToV8?
raymes 2014/12/19 00:00:16 Done.
185 };
186 post_message.As<v8::Function>()->Call(
187 guest_proxy_window, arraysize(args), args);
188 }
189
84 void MimeHandlerViewContainer::OnCreateMimeHandlerViewGuestACK( 190 void MimeHandlerViewContainer::OnCreateMimeHandlerViewGuestACK(
85 int element_instance_id) { 191 int element_instance_id) {
86 DCHECK_NE(this->element_instance_id(), guestview::kInstanceIDNone); 192 DCHECK_NE(this->element_instance_id(), guestview::kInstanceIDNone);
87 DCHECK_EQ(this->element_instance_id(), element_instance_id); 193 DCHECK_EQ(this->element_instance_id(), element_instance_id);
88 render_frame()->AttachGuest(element_instance_id); 194 render_frame()->AttachGuest(element_instance_id);
89 } 195 }
90 196
197 void MimeHandlerViewContainer::OnGuestAttached(int /* unused */,
198 int guest_proxy_routing_id) {
199 guest_proxy_routing_id_ = guest_proxy_routing_id;
200 }
201
91 void MimeHandlerViewContainer::CreateMimeHandlerViewGuest() { 202 void MimeHandlerViewContainer::CreateMimeHandlerViewGuest() {
92 // The loader has completed loading |html_string_| so we can dispose it. 203 // The loader has completed loading |html_string_| so we can dispose it.
93 loader_.reset(); 204 loader_.reset();
94 205
95 // Parse the stream URL to ensure it's valid. 206 // Parse the stream URL to ensure it's valid.
96 GURL stream_url(html_string_); 207 GURL stream_url(html_string_);
97 208
98 DCHECK_NE(element_instance_id(), guestview::kInstanceIDNone); 209 DCHECK_NE(element_instance_id(), guestview::kInstanceIDNone);
99 render_frame()->Send(new ExtensionHostMsg_CreateMimeHandlerViewGuest( 210 render_frame()->Send(new ExtensionHostMsg_CreateMimeHandlerViewGuest(
100 routing_id(), stream_url.spec(), original_url_.spec(), mime_type_, 211 routing_id(), stream_url.spec(), original_url_.spec(), mime_type_,
101 element_instance_id())); 212 element_instance_id()));
102 } 213 }
103 214
104 } // namespace extensions 215 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698