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

Side by Side Diff: extensions/renderer/guest_view/extensions_guest_view_container.cc

Issue 765843003: Refactor GuestViewContainer::AttachRequest to allow for other request types (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Avoid a new static 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/extensions_guest_view_container.h" 5 #include "extensions/renderer/guest_view/extensions_guest_view_container.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 "content/public/renderer/render_view.h"
9 #include "extensions/common/extension_messages.h" 9 #include "extensions/common/extension_messages.h"
10 #include "extensions/common/guest_view/guest_view_constants.h" 10 #include "extensions/common/guest_view/guest_view_constants.h"
11 #include "third_party/WebKit/public/web/WebLocalFrame.h" 11 #include "third_party/WebKit/public/web/WebLocalFrame.h"
12 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" 12 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
13 #include "third_party/WebKit/public/web/WebView.h" 13 #include "third_party/WebKit/public/web/WebView.h"
14 14
15 namespace { 15 namespace {
16 typedef std::pair<int, int> GuestViewID; 16 typedef std::map<int, extensions::ExtensionsGuestViewContainer*>
17 typedef std::map<GuestViewID, extensions::ExtensionsGuestViewContainer*>
18 ExtensionsGuestViewContainerMap; 17 ExtensionsGuestViewContainerMap;
19 static base::LazyInstance<ExtensionsGuestViewContainerMap> 18 static base::LazyInstance<ExtensionsGuestViewContainerMap>
20 g_guest_view_container_map = LAZY_INSTANCE_INITIALIZER; 19 g_guest_view_container_map = LAZY_INSTANCE_INITIALIZER;
21 } // namespace 20 } // namespace
22 21
23 namespace extensions { 22 namespace extensions {
24 23
24 ExtensionsGuestViewContainer::Request::Request(
25 GuestViewContainer* container,
26 v8::Handle<v8::Function> callback,
27 v8::Isolate* isolate)
28 : container_(container),
29 callback_(callback),
30 isolate_(isolate) {
31 }
32
33 ExtensionsGuestViewContainer::Request::~Request() {
34 }
35
36 bool ExtensionsGuestViewContainer::Request::HasCallback() const {
37 return !callback_.IsEmpty();
38 }
39
40 v8::Handle<v8::Function>
41 ExtensionsGuestViewContainer::Request::GetCallback() const {
42 return callback_.NewHandle(isolate_);
43 }
44
25 ExtensionsGuestViewContainer::AttachRequest::AttachRequest( 45 ExtensionsGuestViewContainer::AttachRequest::AttachRequest(
26 int element_instance_id, 46 GuestViewContainer* container,
27 int guest_instance_id, 47 int guest_instance_id,
28 scoped_ptr<base::DictionaryValue> params, 48 scoped_ptr<base::DictionaryValue> params,
29 v8::Handle<v8::Function> callback, 49 v8::Handle<v8::Function> callback,
30 v8::Isolate* isolate) 50 v8::Isolate* isolate)
31 : element_instance_id_(element_instance_id), 51 : Request(container, callback, isolate),
32 guest_instance_id_(guest_instance_id), 52 guest_instance_id_(guest_instance_id),
33 params_(params.Pass()), 53 params_(params.Pass()) {
34 callback_(callback),
35 isolate_(isolate) {
36 } 54 }
37 55
38 ExtensionsGuestViewContainer::AttachRequest::~AttachRequest() { 56 ExtensionsGuestViewContainer::AttachRequest::~AttachRequest() {
39 } 57 }
40 58
41 bool ExtensionsGuestViewContainer::AttachRequest::HasCallback() const { 59 void ExtensionsGuestViewContainer::AttachRequest::PerformRequest() {
42 return !callback_.IsEmpty(); 60 // Step 1, send the attach params to extensions/.
61 container()->render_frame()->Send(
62 new ExtensionHostMsg_AttachGuest(container()->render_view_routing_id(),
63 container()->element_instance_id(),
64 guest_instance_id_,
65 *params_));
66
67 // Step 2, attach plugin through content/.
68 container()->render_frame()->AttachGuest(container()->element_instance_id());
43 } 69 }
44 70
45 v8::Handle<v8::Function> 71 void ExtensionsGuestViewContainer::AttachRequest::HandleResponse(
46 ExtensionsGuestViewContainer::AttachRequest::GetCallback() const { 72 const IPC::Message& message) {
47 return callback_.NewHandle(isolate_); 73 ExtensionMsg_GuestAttached::Param param;
74 if (!ExtensionMsg_GuestAttached::Read(&message, &param))
75 return;
76
77 // If we don't have a callback then there's nothing more to do.
78 if (!HasCallback())
79 return;
80
81 content::RenderView* guest_proxy_render_view =
82 content::RenderView::FromRoutingID(param.b);
83 // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing?
84 if (!guest_proxy_render_view)
85 return;
86
87 v8::HandleScope handle_scope(isolate());
88 v8::Handle<v8::Function> callback = GetCallback();
89 v8::Handle<v8::Context> context = callback->CreationContext();
90 if (context.IsEmpty())
91 return;
92
93 blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame();
94 v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global();
95
96 const int argc = 1;
97 v8::Handle<v8::Value> argv[argc] = { window };
98
99 v8::Context::Scope context_scope(context);
100 blink::WebScopedMicrotaskSuppression suppression;
101
102 // Call the AttachGuest API's callback with the guest proxy as the first
103 // parameter.
104 callback->Call(context->Global(), argc, argv);
48 } 105 }
49 106
50 ExtensionsGuestViewContainer::ExtensionsGuestViewContainer( 107 ExtensionsGuestViewContainer::ExtensionsGuestViewContainer(
51 content::RenderFrame* render_frame) 108 content::RenderFrame* render_frame)
52 : GuestViewContainer(render_frame), 109 : GuestViewContainer(render_frame),
53 ready_(false) { 110 ready_(false) {
54 } 111 }
55 112
56 ExtensionsGuestViewContainer::~ExtensionsGuestViewContainer() { 113 ExtensionsGuestViewContainer::~ExtensionsGuestViewContainer() {
57 if (element_instance_id() != guestview::kInstanceIDNone) { 114 if (element_instance_id() != guestview::kInstanceIDNone) {
58 g_guest_view_container_map.Get().erase( 115 g_guest_view_container_map.Get().erase(element_instance_id());
59 GuestViewID(render_view_routing_id(), element_instance_id()));
60 } 116 }
61 } 117 }
62 118
63 ExtensionsGuestViewContainer* ExtensionsGuestViewContainer::FromID( 119 ExtensionsGuestViewContainer* ExtensionsGuestViewContainer::FromID(
64 int render_view_routing_id,
65 int element_instance_id) { 120 int element_instance_id) {
66 ExtensionsGuestViewContainerMap* guest_view_containers = 121 ExtensionsGuestViewContainerMap* guest_view_containers =
67 g_guest_view_container_map.Pointer(); 122 g_guest_view_container_map.Pointer();
68 ExtensionsGuestViewContainerMap::iterator it = guest_view_containers->find( 123 ExtensionsGuestViewContainerMap::iterator it =
69 GuestViewID(render_view_routing_id, element_instance_id)); 124 guest_view_containers->find(element_instance_id);
70 return it == guest_view_containers->end() ? NULL : it->second; 125 return it == guest_view_containers->end() ? NULL : it->second;
71 } 126 }
72 127
73 void ExtensionsGuestViewContainer::AttachGuest( 128 void ExtensionsGuestViewContainer::IssueRequest(linked_ptr<Request> request) {
74 linked_ptr<AttachRequest> request) { 129 EnqueueRequest(request);
75 EnqueueAttachRequest(request); 130 PerformPendingRequest();
76 PerformPendingAttachRequest();
77 } 131 }
78 132
79 void ExtensionsGuestViewContainer::SetElementInstanceID( 133 void ExtensionsGuestViewContainer::SetElementInstanceID(
80 int element_instance_id) { 134 int element_instance_id) {
81 GuestViewContainer::SetElementInstanceID(element_instance_id); 135 GuestViewContainer::SetElementInstanceID(element_instance_id);
82 136
83 GuestViewID guest_view_id(render_view_routing_id(), element_instance_id); 137 DCHECK(g_guest_view_container_map.Get().find(element_instance_id) ==
84 DCHECK(g_guest_view_container_map.Get().find(guest_view_id) ==
85 g_guest_view_container_map.Get().end()); 138 g_guest_view_container_map.Get().end());
86 g_guest_view_container_map.Get().insert(std::make_pair(guest_view_id, this)); 139 g_guest_view_container_map.Get().insert(
140 std::make_pair(element_instance_id, this));
87 } 141 }
88 142
89 void ExtensionsGuestViewContainer::Ready() { 143 void ExtensionsGuestViewContainer::Ready() {
90 ready_ = true; 144 ready_ = true;
91 CHECK(!pending_response_.get()); 145 CHECK(!pending_response_.get());
92 PerformPendingAttachRequest(); 146 PerformPendingRequest();
93 } 147 }
94 148
95 bool ExtensionsGuestViewContainer::HandlesMessage(const IPC::Message& message) { 149 bool ExtensionsGuestViewContainer::HandlesMessage(const IPC::Message& message) {
96 return message.type() == ExtensionMsg_GuestAttached::ID; 150 return (message.type() == ExtensionMsg_GuestAttached::ID);
97 } 151 }
98 152
99 bool ExtensionsGuestViewContainer::OnMessage(const IPC::Message& message) { 153 bool ExtensionsGuestViewContainer::OnMessage(const IPC::Message& message) {
100 bool handled = false; 154 if (message.type() == ExtensionMsg_GuestAttached::ID) {
101 IPC_BEGIN_MESSAGE_MAP(ExtensionsGuestViewContainer, message) 155 OnHandleCallback(message);
102 IPC_MESSAGE_HANDLER(ExtensionMsg_GuestAttached, OnGuestAttached) 156 return true;
103 IPC_MESSAGE_UNHANDLED(handled = false) 157 }
104 IPC_END_MESSAGE_MAP() 158 return false;
105 return handled;
106 } 159 }
107 160
108 void ExtensionsGuestViewContainer::OnGuestAttached(int /* unused */, 161 void ExtensionsGuestViewContainer::OnHandleCallback(
109 int guest_proxy_routing_id) { 162 const IPC::Message& message) {
110 // Handle the callback for the current request with a pending response. 163 // Handle the callback for the current request with a pending response.
111 HandlePendingResponseCallback(guest_proxy_routing_id); 164 HandlePendingResponseCallback(message);
112 // Perform the subsequent attach request if one exists. 165 // Perform the subsequent attach request if one exists.
113 PerformPendingAttachRequest(); 166 PerformPendingRequest();
114 } 167 }
115 168
116 void ExtensionsGuestViewContainer::AttachGuestInternal( 169 void ExtensionsGuestViewContainer::EnqueueRequest(linked_ptr<Request> request) {
117 linked_ptr<AttachRequest> request) {
118 CHECK(!pending_response_.get());
119 // Step 1, send the attach params to chrome/.
120 render_frame()->Send(
121 new ExtensionHostMsg_AttachGuest(render_view_routing_id(),
122 request->element_instance_id(),
123 request->guest_instance_id(),
124 *request->attach_params()));
125
126 // Step 2, attach plugin through content/.
127 render_frame()->AttachGuest(request->element_instance_id());
128
129 pending_response_ = request;
130 }
131
132 void ExtensionsGuestViewContainer::EnqueueAttachRequest(
133 linked_ptr<AttachRequest> request) {
134 pending_requests_.push_back(request); 170 pending_requests_.push_back(request);
135 } 171 }
136 172
137 void ExtensionsGuestViewContainer::PerformPendingAttachRequest() { 173 void ExtensionsGuestViewContainer::PerformPendingRequest() {
138 if (!ready_ || pending_requests_.empty() || pending_response_.get()) 174 if (!ready_ || pending_requests_.empty() || pending_response_.get())
139 return; 175 return;
140 176
141 linked_ptr<AttachRequest> pending_request = pending_requests_.front(); 177 linked_ptr<Request> pending_request = pending_requests_.front();
142 pending_requests_.pop_front(); 178 pending_requests_.pop_front();
143 AttachGuestInternal(pending_request); 179 pending_request->PerformRequest();
180 pending_response_ = pending_request;
144 } 181 }
145 182
146 void ExtensionsGuestViewContainer::HandlePendingResponseCallback( 183 void ExtensionsGuestViewContainer::HandlePendingResponseCallback(
147 int guest_proxy_routing_id) { 184 const IPC::Message& message) {
148 CHECK(pending_response_.get()); 185 CHECK(pending_response_.get());
149 linked_ptr<AttachRequest> pending_response(pending_response_.release()); 186 linked_ptr<Request> pending_response(pending_response_.release());
150 187 pending_response->HandleResponse(message);
151 // If we don't have a callback then there's nothing more to do.
152 if (!pending_response->HasCallback())
153 return;
154
155 content::RenderView* guest_proxy_render_view =
156 content::RenderView::FromRoutingID(guest_proxy_routing_id);
157 // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing?
158 if (!guest_proxy_render_view)
159 return;
160
161 v8::HandleScope handle_scope(pending_response->isolate());
162 v8::Handle<v8::Function> callback = pending_response->GetCallback();
163 v8::Handle<v8::Context> context = callback->CreationContext();
164 if (context.IsEmpty())
165 return;
166
167 blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame();
168 v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global();
169
170 const int argc = 1;
171 v8::Handle<v8::Value> argv[argc] = { window };
172
173 v8::Context::Scope context_scope(context);
174 blink::WebScopedMicrotaskSuppression suppression;
175
176 // Call the AttachGuest API's callback with the guest proxy as the first
177 // parameter.
178 callback->Call(context->Global(), argc, argv);
179 } 188 }
180 189
181 } // namespace extensions 190 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698