Chromium Code Reviews| Index: extensions/renderer/guest_view/guest_view_container.cc |
| diff --git a/extensions/renderer/guest_view/guest_view_container.cc b/extensions/renderer/guest_view/guest_view_container.cc |
| index 8ef8054ae714ce18059109e5f2029960d9d28113..5563df87f2850dd3a732be31f7a4f29d33eb5932 100644 |
| --- a/extensions/renderer/guest_view/guest_view_container.cc |
| +++ b/extensions/renderer/guest_view/guest_view_container.cc |
| @@ -23,6 +23,32 @@ static base::LazyInstance<GuestViewContainerMap> g_guest_view_container_map = |
| namespace extensions { |
| +GuestViewContainer::AttachRequest::AttachRequest( |
| + int element_instance_id, |
| + int guest_instance_id, |
| + scoped_ptr<base::DictionaryValue> params, |
| + v8::Handle<v8::Function> callback, |
| + v8::Isolate* isolate) |
| + : element_instance_id_(element_instance_id), |
| + guest_instance_id_(guest_instance_id), |
| + params_(params.Pass()), |
| + callback_(callback), |
| + isolate_(isolate) { |
| +} |
| + |
| +GuestViewContainer::AttachRequest::~AttachRequest() { |
| +} |
| + |
| + |
|
lazyboy
2014/10/03 22:10:19
nit: remove empty line.
Fady Samuel
2014/10/03 22:23:59
Done.
|
| +bool GuestViewContainer::AttachRequest::HasCallback() const { |
| + return !callback_.IsEmpty(); |
| +} |
| + |
| +v8::Handle<v8::Function> |
| +GuestViewContainer::AttachRequest::GetCallback() const { |
| + return callback_.NewHandle(isolate_); |
| +} |
| + |
| GuestViewContainer::GuestViewContainer( |
| content::RenderFrame* render_frame, |
| const std::string& mime_type) |
| @@ -32,8 +58,7 @@ GuestViewContainer::GuestViewContainer( |
| element_instance_id_(guestview::kInstanceIDNone), |
| render_view_routing_id_(render_frame->GetRenderView()->GetRoutingID()), |
| attached_(false), |
| - attach_pending_(false), |
| - isolate_(NULL) { |
| + ready_(false) { |
| } |
| GuestViewContainer::~GuestViewContainer() { |
| @@ -52,29 +77,9 @@ GuestViewContainer* GuestViewContainer::FromID(int render_view_routing_id, |
| return it == guest_view_containers->end() ? NULL : it->second; |
| } |
| - |
| -void GuestViewContainer::AttachGuest(int element_instance_id, |
| - int guest_instance_id, |
| - scoped_ptr<base::DictionaryValue> params, |
| - v8::Handle<v8::Function> callback, |
| - v8::Isolate* isolate) { |
| - // GuestViewContainer supports reattachment (i.e. attached_ == true) but not |
| - // while a current attach process is pending. |
| - if (attach_pending_) |
| - return; |
| - |
| - // Step 1, send the attach params to chrome/. |
| - render_frame()->Send(new ExtensionHostMsg_AttachGuest(render_view_routing_id_, |
| - element_instance_id, |
| - guest_instance_id, |
| - *params)); |
| - |
| - // Step 2, attach plugin through content/. |
| - render_frame()->AttachGuest(element_instance_id); |
| - |
| - callback_.reset(callback); |
| - isolate_ = isolate; |
| - attach_pending_ = true; |
| +void GuestViewContainer::AttachGuest(linked_ptr<AttachRequest> request) { |
| + EnqueueAttachRequest(request); |
| + PerformPendingAttachRequest(); |
| } |
| void GuestViewContainer::SetElementInstanceID(int element_instance_id) { |
| @@ -100,6 +105,12 @@ void GuestViewContainer::DidReceiveData(const char* data, int data_length) { |
| html_string_ += value; |
| } |
| +void GuestViewContainer::Ready() { |
| + ready_ = true; |
| + CHECK(!pending_response_.get()); |
| + PerformPendingAttachRequest(); |
| +} |
| + |
| void GuestViewContainer::OnDestruct() { |
| // GuestViewContainer's lifetime is managed by BrowserPlugin so don't let |
| // RenderFrameObserver self-destruct here. |
| @@ -137,24 +148,34 @@ void GuestViewContainer::OnCreateMimeHandlerViewGuestACK( |
| void GuestViewContainer::OnGuestAttached(int element_instance_id, |
| int guest_routing_id) { |
| + CHECK(pending_response_.get()); |
| + |
| attached_ = true; |
| - attach_pending_ = false; |
| // If we don't have a callback then there's nothing more to do. |
| - if (callback_.IsEmpty()) |
| + if (!pending_response_->HasCallback()) { |
| + pending_response_.reset(); |
| + PerformPendingAttachRequest(); |
| return; |
| + } |
| content::RenderView* guest_proxy_render_view = |
| content::RenderView::FromRoutingID(guest_routing_id); |
| // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing? |
| - if (!guest_proxy_render_view) |
| + if (!guest_proxy_render_view) { |
| + pending_response_.reset(); |
| + PerformPendingAttachRequest(); |
| return; |
| + } |
| - v8::HandleScope handle_scope(isolate_); |
| - v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_); |
| + v8::HandleScope handle_scope(pending_response_->isolate()); |
| + v8::Handle<v8::Function> callback = pending_response_->GetCallback(); |
| v8::Handle<v8::Context> context = callback->CreationContext(); |
| - if (context.IsEmpty()) |
| + if (context.IsEmpty()) { |
| + pending_response_.reset(); |
| + PerformPendingAttachRequest(); |
| return; |
| + } |
| blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame(); |
| v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global(); |
| @@ -168,7 +189,39 @@ void GuestViewContainer::OnGuestAttached(int element_instance_id, |
| // Call the AttachGuest API's callback with the guest proxy as the first |
| // parameter. |
| callback->Call(context->Global(), argc, argv); |
| - callback_.reset(); |
| + |
| + pending_response_.reset(); |
|
lazyboy
2014/10/03 22:10:19
The repetitive pattern (4 times) suggests we would
Fady Samuel
2014/10/03 22:23:59
Done.
|
| + PerformPendingAttachRequest(); |
| +} |
| + |
| +void GuestViewContainer::AttachGuestInternal( |
| + linked_ptr<AttachRequest> request) { |
| + CHECK(!pending_response_.get()); |
| + // Step 1, send the attach params to chrome/. |
| + render_frame()->Send( |
| + new ExtensionHostMsg_AttachGuest(render_view_routing_id_, |
| + request->element_instance_id(), |
| + request->guest_instance_id(), |
| + *request->attach_params())); |
| + |
| + // Step 2, attach plugin through content/. |
| + render_frame()->AttachGuest(request->element_instance_id()); |
| + |
| + pending_response_ = request; |
| +} |
| + |
| +void GuestViewContainer::EnqueueAttachRequest( |
| + linked_ptr<AttachRequest> request) { |
| + pending_requests_.push_back(request); |
| +} |
| + |
| +void GuestViewContainer::PerformPendingAttachRequest() { |
| + if (!ready_ || pending_requests_.empty() || pending_response_.get()) |
| + return; |
| + |
| + linked_ptr<AttachRequest> pending_request = pending_requests_.front(); |
| + pending_requests_.pop_front(); |
| + AttachGuestInternal(pending_request); |
| } |
| // static |