| OLD | NEW |
| 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/guest_view/guest_view_constants.h" | 9 #include "extensions/common/guest_view/guest_view_constants.h" |
| 10 #include "extensions/common/guest_view/guest_view_messages.h" | 10 #include "extensions/common/guest_view/guest_view_messages.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::map<int, extensions::ExtensionsGuestViewContainer*> | 16 typedef std::map<int, extensions::ExtensionsGuestViewContainer*> |
| 17 ExtensionsGuestViewContainerMap; | 17 ExtensionsGuestViewContainerMap; |
| 18 static base::LazyInstance<ExtensionsGuestViewContainerMap> | 18 static base::LazyInstance<ExtensionsGuestViewContainerMap> |
| 19 g_guest_view_container_map = LAZY_INSTANCE_INITIALIZER; | 19 g_guest_view_container_map = LAZY_INSTANCE_INITIALIZER; |
| 20 } // namespace | 20 } // namespace |
| 21 | 21 |
| 22 namespace extensions { | 22 namespace extensions { |
| 23 | 23 |
| 24 ExtensionsGuestViewContainer::Request::Request( | 24 ExtensionsGuestViewContainer::Request::Request(GuestViewContainer* container, |
| 25 GuestViewContainer* container, | 25 v8::Local<v8::Function> callback, |
| 26 v8::Handle<v8::Function> callback, | 26 v8::Isolate* isolate) |
| 27 v8::Isolate* isolate) | |
| 28 : container_(container), callback_(isolate, callback), isolate_(isolate) { | 27 : container_(container), callback_(isolate, callback), isolate_(isolate) { |
| 29 } | 28 } |
| 30 | 29 |
| 31 ExtensionsGuestViewContainer::Request::~Request() { | 30 ExtensionsGuestViewContainer::Request::~Request() { |
| 32 } | 31 } |
| 33 | 32 |
| 34 bool ExtensionsGuestViewContainer::Request::HasCallback() const { | 33 bool ExtensionsGuestViewContainer::Request::HasCallback() const { |
| 35 return !callback_.IsEmpty(); | 34 return !callback_.IsEmpty(); |
| 36 } | 35 } |
| 37 | 36 |
| 38 v8::Handle<v8::Function> | 37 v8::Local<v8::Function> ExtensionsGuestViewContainer::Request::GetCallback() |
| 39 ExtensionsGuestViewContainer::Request::GetCallback() const { | 38 const { |
| 40 return v8::Local<v8::Function>::New(isolate_, callback_); | 39 return v8::Local<v8::Function>::New(isolate_, callback_); |
| 41 } | 40 } |
| 42 | 41 |
| 43 void ExtensionsGuestViewContainer::Request::ExecuteCallbackIfAvailable( | 42 void ExtensionsGuestViewContainer::Request::ExecuteCallbackIfAvailable( |
| 44 int argc, scoped_ptr<v8::Handle<v8::Value>[]> argv) { | 43 int argc, |
| 44 scoped_ptr<v8::Local<v8::Value>[]> argv) { |
| 45 if (!HasCallback()) | 45 if (!HasCallback()) |
| 46 return; | 46 return; |
| 47 | 47 |
| 48 v8::HandleScope handle_scope(isolate()); | 48 v8::HandleScope handle_scope(isolate()); |
| 49 v8::Handle<v8::Function> callback = GetCallback(); | 49 v8::Local<v8::Function> callback = GetCallback(); |
| 50 v8::Handle<v8::Context> context = callback->CreationContext(); | 50 v8::Local<v8::Context> context = callback->CreationContext(); |
| 51 if (context.IsEmpty()) | 51 if (context.IsEmpty()) |
| 52 return; | 52 return; |
| 53 | 53 |
| 54 v8::Context::Scope context_scope(context); | 54 v8::Context::Scope context_scope(context); |
| 55 blink::WebScopedMicrotaskSuppression suppression; | 55 blink::WebScopedMicrotaskSuppression suppression; |
| 56 | 56 |
| 57 // Call the AttachGuest API's callback with the guest proxy as the first | 57 // Call the AttachGuest API's callback with the guest proxy as the first |
| 58 // parameter. | 58 // parameter. |
| 59 callback->Call(context->Global(), argc, argv.get()); | 59 callback->Call(context->Global(), argc, argv.get()); |
| 60 } | 60 } |
| 61 | 61 |
| 62 ExtensionsGuestViewContainer::AttachRequest::AttachRequest( | 62 ExtensionsGuestViewContainer::AttachRequest::AttachRequest( |
| 63 GuestViewContainer* container, | 63 GuestViewContainer* container, |
| 64 int guest_instance_id, | 64 int guest_instance_id, |
| 65 scoped_ptr<base::DictionaryValue> params, | 65 scoped_ptr<base::DictionaryValue> params, |
| 66 v8::Handle<v8::Function> callback, | 66 v8::Local<v8::Function> callback, |
| 67 v8::Isolate* isolate) | 67 v8::Isolate* isolate) |
| 68 : Request(container, callback, isolate), | 68 : Request(container, callback, isolate), |
| 69 guest_instance_id_(guest_instance_id), | 69 guest_instance_id_(guest_instance_id), |
| 70 params_(params.Pass()) { | 70 params_(params.Pass()) { |
| 71 } | 71 } |
| 72 | 72 |
| 73 ExtensionsGuestViewContainer::AttachRequest::~AttachRequest() { | 73 ExtensionsGuestViewContainer::AttachRequest::~AttachRequest() { |
| 74 } | 74 } |
| 75 | 75 |
| 76 void ExtensionsGuestViewContainer::AttachRequest::PerformRequest() { | 76 void ExtensionsGuestViewContainer::AttachRequest::PerformRequest() { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 97 content::RenderView::FromRoutingID(get<1>(param)); | 97 content::RenderView::FromRoutingID(get<1>(param)); |
| 98 // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing? | 98 // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing? |
| 99 if (!guest_proxy_render_view) | 99 if (!guest_proxy_render_view) |
| 100 return; | 100 return; |
| 101 | 101 |
| 102 v8::HandleScope handle_scope(isolate()); | 102 v8::HandleScope handle_scope(isolate()); |
| 103 blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame(); | 103 blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame(); |
| 104 v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global(); | 104 v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global(); |
| 105 | 105 |
| 106 const int argc = 1; | 106 const int argc = 1; |
| 107 scoped_ptr<v8::Handle<v8::Value>[]> argv(new v8::Handle<v8::Value>[argc]); | 107 scoped_ptr<v8::Local<v8::Value>[]> argv(new v8::Local<v8::Value>[argc]); |
| 108 argv[0] = window; | 108 argv[0] = window; |
| 109 | 109 |
| 110 ExecuteCallbackIfAvailable(argc, argv.Pass()); | 110 ExecuteCallbackIfAvailable(argc, argv.Pass()); |
| 111 } | 111 } |
| 112 | 112 |
| 113 ExtensionsGuestViewContainer::DetachRequest::DetachRequest( | 113 ExtensionsGuestViewContainer::DetachRequest::DetachRequest( |
| 114 GuestViewContainer* container, | 114 GuestViewContainer* container, |
| 115 v8::Handle<v8::Function> callback, | 115 v8::Local<v8::Function> callback, |
| 116 v8::Isolate* isolate) | 116 v8::Isolate* isolate) |
| 117 : Request(container, callback, isolate) { | 117 : Request(container, callback, isolate) { |
| 118 } | 118 } |
| 119 | 119 |
| 120 ExtensionsGuestViewContainer::DetachRequest::~DetachRequest() { | 120 ExtensionsGuestViewContainer::DetachRequest::~DetachRequest() { |
| 121 } | 121 } |
| 122 | 122 |
| 123 void ExtensionsGuestViewContainer::DetachRequest::PerformRequest() { | 123 void ExtensionsGuestViewContainer::DetachRequest::PerformRequest() { |
| 124 if (!container()->render_frame()) | 124 if (!container()->render_frame()) |
| 125 return; | 125 return; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 151 while (pending_requests_.size() > 0) { | 151 while (pending_requests_.size() > 0) { |
| 152 linked_ptr<Request> pending_request = pending_requests_.front(); | 152 linked_ptr<Request> pending_request = pending_requests_.front(); |
| 153 pending_requests_.pop_front(); | 153 pending_requests_.pop_front(); |
| 154 // Call the JavaScript callbacks with no arguments which implies an error. | 154 // Call the JavaScript callbacks with no arguments which implies an error. |
| 155 pending_request->ExecuteCallbackIfAvailable(0 /* argc */, nullptr); | 155 pending_request->ExecuteCallbackIfAvailable(0 /* argc */, nullptr); |
| 156 } | 156 } |
| 157 | 157 |
| 158 // Call the destruction callback, if one is registered. | 158 // Call the destruction callback, if one is registered. |
| 159 if (!destruction_callback_.IsEmpty()) { | 159 if (!destruction_callback_.IsEmpty()) { |
| 160 v8::HandleScope handle_scope(destruction_isolate_); | 160 v8::HandleScope handle_scope(destruction_isolate_); |
| 161 v8::Handle<v8::Function> callback = | 161 v8::Local<v8::Function> callback = v8::Local<v8::Function>::New( |
| 162 v8::Local<v8::Function>::New(destruction_isolate_, | 162 destruction_isolate_, destruction_callback_); |
| 163 destruction_callback_); | 163 v8::Local<v8::Context> context = callback->CreationContext(); |
| 164 v8::Handle<v8::Context> context = callback->CreationContext(); | |
| 165 if (context.IsEmpty()) | 164 if (context.IsEmpty()) |
| 166 return; | 165 return; |
| 167 | 166 |
| 168 v8::Context::Scope context_scope(context); | 167 v8::Context::Scope context_scope(context); |
| 169 blink::WebScopedMicrotaskSuppression suppression; | 168 blink::WebScopedMicrotaskSuppression suppression; |
| 170 | 169 |
| 171 callback->Call(context->Global(), 0 /* argc */, nullptr); | 170 callback->Call(context->Global(), 0 /* argc */, nullptr); |
| 172 } | 171 } |
| 173 } | 172 } |
| 174 | 173 |
| 175 ExtensionsGuestViewContainer* ExtensionsGuestViewContainer::FromID( | 174 ExtensionsGuestViewContainer* ExtensionsGuestViewContainer::FromID( |
| 176 int element_instance_id) { | 175 int element_instance_id) { |
| 177 ExtensionsGuestViewContainerMap* guest_view_containers = | 176 ExtensionsGuestViewContainerMap* guest_view_containers = |
| 178 g_guest_view_container_map.Pointer(); | 177 g_guest_view_container_map.Pointer(); |
| 179 auto it = guest_view_containers->find(element_instance_id); | 178 auto it = guest_view_containers->find(element_instance_id); |
| 180 return it == guest_view_containers->end() ? nullptr : it->second; | 179 return it == guest_view_containers->end() ? nullptr : it->second; |
| 181 } | 180 } |
| 182 | 181 |
| 183 void ExtensionsGuestViewContainer::IssueRequest(linked_ptr<Request> request) { | 182 void ExtensionsGuestViewContainer::IssueRequest(linked_ptr<Request> request) { |
| 184 EnqueueRequest(request); | 183 EnqueueRequest(request); |
| 185 PerformPendingRequest(); | 184 PerformPendingRequest(); |
| 186 } | 185 } |
| 187 | 186 |
| 188 void ExtensionsGuestViewContainer::RegisterDestructionCallback( | 187 void ExtensionsGuestViewContainer::RegisterDestructionCallback( |
| 189 v8::Handle<v8::Function> callback, | 188 v8::Local<v8::Function> callback, |
| 190 v8::Isolate* isolate) { | 189 v8::Isolate* isolate) { |
| 191 destruction_callback_.Reset(isolate, callback); | 190 destruction_callback_.Reset(isolate, callback); |
| 192 destruction_isolate_ = isolate; | 191 destruction_isolate_ = isolate; |
| 193 } | 192 } |
| 194 | 193 |
| 195 void ExtensionsGuestViewContainer::RegisterElementResizeCallback( | 194 void ExtensionsGuestViewContainer::RegisterElementResizeCallback( |
| 196 v8::Handle<v8::Function> callback, | 195 v8::Local<v8::Function> callback, |
| 197 v8::Isolate* isolate) { | 196 v8::Isolate* isolate) { |
| 198 element_resize_callback_.Reset(isolate, callback); | 197 element_resize_callback_.Reset(isolate, callback); |
| 199 element_resize_isolate_ = isolate; | 198 element_resize_isolate_ = isolate; |
| 200 } | 199 } |
| 201 | 200 |
| 202 void ExtensionsGuestViewContainer::DidResizeElement(const gfx::Size& old_size, | 201 void ExtensionsGuestViewContainer::DidResizeElement(const gfx::Size& old_size, |
| 203 const gfx::Size& new_size) { | 202 const gfx::Size& new_size) { |
| 204 // Call the element resize callback, if one is registered. | 203 // Call the element resize callback, if one is registered. |
| 205 if (element_resize_callback_.IsEmpty()) | 204 if (element_resize_callback_.IsEmpty()) |
| 206 return; | 205 return; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 // Handle the callback for the current request with a pending response. | 237 // Handle the callback for the current request with a pending response. |
| 239 HandlePendingResponseCallback(message); | 238 HandlePendingResponseCallback(message); |
| 240 // Perform the subsequent attach request if one exists. | 239 // Perform the subsequent attach request if one exists. |
| 241 PerformPendingRequest(); | 240 PerformPendingRequest(); |
| 242 } | 241 } |
| 243 | 242 |
| 244 void ExtensionsGuestViewContainer::CallElementResizeCallback( | 243 void ExtensionsGuestViewContainer::CallElementResizeCallback( |
| 245 const gfx::Size& old_size, | 244 const gfx::Size& old_size, |
| 246 const gfx::Size& new_size) { | 245 const gfx::Size& new_size) { |
| 247 v8::HandleScope handle_scope(element_resize_isolate_); | 246 v8::HandleScope handle_scope(element_resize_isolate_); |
| 248 v8::Handle<v8::Function> callback = v8::Local<v8::Function>::New( | 247 v8::Local<v8::Function> callback = v8::Local<v8::Function>::New( |
| 249 element_resize_isolate_, element_resize_callback_); | 248 element_resize_isolate_, element_resize_callback_); |
| 250 v8::Handle<v8::Context> context = callback->CreationContext(); | 249 v8::Local<v8::Context> context = callback->CreationContext(); |
| 251 if (context.IsEmpty()) | 250 if (context.IsEmpty()) |
| 252 return; | 251 return; |
| 253 | 252 |
| 254 const int argc = 4; | 253 const int argc = 4; |
| 255 v8::Handle<v8::Value> argv[argc] = { | 254 v8::Local<v8::Value> argv[argc] = { |
| 256 v8::Integer::New(element_resize_isolate_, old_size.width()), | 255 v8::Integer::New(element_resize_isolate_, old_size.width()), |
| 257 v8::Integer::New(element_resize_isolate_, old_size.height()), | 256 v8::Integer::New(element_resize_isolate_, old_size.height()), |
| 258 v8::Integer::New(element_resize_isolate_, new_size.width()), | 257 v8::Integer::New(element_resize_isolate_, new_size.width()), |
| 259 v8::Integer::New(element_resize_isolate_, new_size.height())}; | 258 v8::Integer::New(element_resize_isolate_, new_size.height())}; |
| 260 | 259 |
| 261 v8::Context::Scope context_scope(context); | 260 v8::Context::Scope context_scope(context); |
| 262 blink::WebScopedMicrotaskSuppression suppression; | 261 blink::WebScopedMicrotaskSuppression suppression; |
| 263 | 262 |
| 264 callback->Call(context->Global(), argc, argv); | 263 callback->Call(context->Global(), argc, argv); |
| 265 } | 264 } |
| 266 | 265 |
| 267 void ExtensionsGuestViewContainer::EnqueueRequest(linked_ptr<Request> request) { | 266 void ExtensionsGuestViewContainer::EnqueueRequest(linked_ptr<Request> request) { |
| 268 pending_requests_.push_back(request); | 267 pending_requests_.push_back(request); |
| 269 } | 268 } |
| 270 | 269 |
| 271 void ExtensionsGuestViewContainer::PerformPendingRequest() { | 270 void ExtensionsGuestViewContainer::PerformPendingRequest() { |
| 272 if (!ready_ || pending_requests_.empty() || pending_response_.get()) | 271 if (!ready_ || pending_requests_.empty() || pending_response_.get()) |
| 273 return; | 272 return; |
| 274 | 273 |
| 275 linked_ptr<Request> pending_request = pending_requests_.front(); | 274 linked_ptr<Request> pending_request = pending_requests_.front(); |
| 276 pending_requests_.pop_front(); | 275 pending_requests_.pop_front(); |
| 277 pending_request->PerformRequest(); | 276 pending_request->PerformRequest(); |
| 278 pending_response_ = pending_request; | 277 pending_response_ = pending_request; |
| 279 } | 278 } |
| 280 | 279 |
| 281 void ExtensionsGuestViewContainer::HandlePendingResponseCallback( | 280 void ExtensionsGuestViewContainer::HandlePendingResponseCallback( |
| 282 const IPC::Message& message) { | 281 const IPC::Message& message) { |
| 283 CHECK(pending_response_.get()); | 282 CHECK(pending_response_.get()); |
| 284 linked_ptr<Request> pending_response(pending_response_.release()); | 283 linked_ptr<Request> pending_response(pending_response_.release()); |
| 285 pending_response->HandleResponse(message); | 284 pending_response->HandleResponse(message); |
| 286 } | 285 } |
| 287 | 286 |
| 288 } // namespace extensions | 287 } // namespace extensions |
| OLD | NEW |