Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/renderer/browser_plugin/browser_plugin.h" | 5 #include "content/renderer/browser_plugin/browser_plugin.h" |
| 6 | 6 |
| 7 #include "base/json/json_string_value_serializer.h" | 7 #include "base/json/json_string_value_serializer.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadAbort, OnLoadAbort) | 127 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadAbort, OnLoadAbort) |
| 128 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadCommit, OnLoadCommit) | 128 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadCommit, OnLoadCommit) |
| 129 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadRedirect, OnLoadRedirect) | 129 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadRedirect, OnLoadRedirect) |
| 130 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStart, OnLoadStart) | 130 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStart, OnLoadStart) |
| 131 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStop, OnLoadStop) | 131 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStop, OnLoadStop) |
| 132 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor) | 132 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor) |
| 133 IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents, | 133 IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents, |
| 134 OnShouldAcceptTouchEvents) | 134 OnShouldAcceptTouchEvents) |
| 135 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdatedName, OnUpdatedName) | 135 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdatedName, OnUpdatedName) |
| 136 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdateRect, OnUpdateRect) | 136 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdateRect, OnUpdateRect) |
| 137 IPC_MESSAGE_HANDLER(BrowserPluginMsg_RequestMediaAccess, | |
| 138 OnRequestMediaAccess) | |
| 137 IPC_MESSAGE_UNHANDLED(handled = false) | 139 IPC_MESSAGE_UNHANDLED(handled = false) |
| 138 IPC_END_MESSAGE_MAP() | 140 IPC_END_MESSAGE_MAP() |
| 139 return handled; | 141 return handled; |
| 140 } | 142 } |
| 141 | 143 |
| 142 void BrowserPlugin::UpdateDOMAttribute(const std::string& attribute_name, | 144 void BrowserPlugin::UpdateDOMAttribute(const std::string& attribute_name, |
| 143 const std::string& attribute_value) { | 145 const std::string& attribute_value) { |
| 144 if (!container()) | 146 if (!container()) |
| 145 return; | 147 return; |
| 146 | 148 |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 528 container()->requestTouchEventType(accept ? | 530 container()->requestTouchEventType(accept ? |
| 529 WebKit::WebPluginContainer::TouchEventRequestTypeRaw : | 531 WebKit::WebPluginContainer::TouchEventRequestTypeRaw : |
| 530 WebKit::WebPluginContainer::TouchEventRequestTypeNone); | 532 WebKit::WebPluginContainer::TouchEventRequestTypeNone); |
| 531 } | 533 } |
| 532 } | 534 } |
| 533 | 535 |
| 534 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) { | 536 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) { |
| 535 UpdateDOMAttribute(browser_plugin::kAttributeName, name); | 537 UpdateDOMAttribute(browser_plugin::kAttributeName, name); |
| 536 } | 538 } |
| 537 | 539 |
| 540 void BrowserPlugin::OnRequestMediaAccess(int instance_id, | |
| 541 int request_id, | |
| 542 const GURL& security_origin) { | |
| 543 if (!HasEventListeners(browser_plugin::kEventRequestPermission)) { | |
| 544 // Automatically deny the request if there are no event listeners for | |
| 545 // permissionrequest. | |
| 546 RespondMediaAccess(request_id, false /* allow */); | |
| 547 return; | |
| 548 } | |
| 549 DCHECK(!media_access_pending_request_ids_.count(request_id)); | |
| 550 media_access_pending_request_ids_.insert(request_id); | |
| 551 | |
| 552 std::map<std::string, base::Value*> props; | |
| 553 props[browser_plugin::kPermission] = | |
| 554 base::Value::CreateStringValue(browser_plugin::kPermissionTypeMedia); | |
| 555 props[browser_plugin::kRequestId] = | |
| 556 base::Value::CreateIntegerValue(request_id); | |
| 557 props[browser_plugin::kURL] = | |
| 558 base::Value::CreateStringValue(security_origin.spec()); | |
| 559 TriggerEvent(browser_plugin::kEventRequestPermission, &props); | |
| 560 } | |
| 561 | |
| 562 bool BrowserPlugin::HasEventListeners(const std::string& event_name) { | |
| 563 if (!container()) | |
| 564 return false; | |
| 565 | |
| 566 // TODO(lazyboy): Fix before submitting: use ancestor list instead similar to | |
| 567 // window.open CL, so bubbling is supported. | |
| 568 WebKit::WebNode parent = container()->element().parentNode(); | |
| 569 if (!parent.isNull() && !parent.shadowHost().isNull()) { | |
| 570 WebKit::WebElement shadow_host = parent.shadowHost(); | |
| 571 return shadow_host.hasEventListeners( | |
| 572 WebKit::WebString::fromUTF8(event_name)); | |
| 573 } | |
| 574 return false; | |
| 575 } | |
| 576 | |
| 538 void BrowserPlugin::OnUpdateRect( | 577 void BrowserPlugin::OnUpdateRect( |
| 539 int instance_id, | 578 int instance_id, |
| 540 const BrowserPluginMsg_UpdateRect_Params& params) { | 579 const BrowserPluginMsg_UpdateRect_Params& params) { |
| 541 bool use_new_damage_buffer = !backing_store_; | 580 bool use_new_damage_buffer = !backing_store_; |
| 542 BrowserPluginHostMsg_AutoSize_Params auto_size_params; | 581 BrowserPluginHostMsg_AutoSize_Params auto_size_params; |
| 543 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; | 582 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; |
| 544 // If we have a pending damage buffer, and the guest has begun to use the | 583 // If we have a pending damage buffer, and the guest has begun to use the |
| 545 // damage buffer then we know the guest will no longer use the current | 584 // damage buffer then we know the guest will no longer use the current |
| 546 // damage buffer. At this point, we drop the current damage buffer, and | 585 // damage buffer. At this point, we drop the current damage buffer, and |
| 547 // mark the pending damage buffer as the current damage buffer. | 586 // mark the pending damage buffer as the current damage buffer. |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 775 // wrapper/shim (e.g. <webview> tag) should receive these events, and expose a | 814 // wrapper/shim (e.g. <webview> tag) should receive these events, and expose a |
| 776 // more appropriate (and stable) event to the consumers as part of the API. | 815 // more appropriate (and stable) event to the consumers as part of the API. |
| 777 event.initCustomEvent( | 816 event.initCustomEvent( |
| 778 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())), | 817 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())), |
| 779 false, false, | 818 false, false, |
| 780 WebKit::WebSerializedScriptValue::serialize( | 819 WebKit::WebSerializedScriptValue::serialize( |
| 781 v8::String::New(json_string.c_str(), json_string.size()))); | 820 v8::String::New(json_string.c_str(), json_string.size()))); |
| 782 container()->element().dispatchEvent(event); | 821 container()->element().dispatchEvent(event); |
| 783 } | 822 } |
| 784 | 823 |
| 824 void BrowserPlugin::OnMediaRequestGarbageCollected(int request_id) { | |
| 825 // Remove from alive objects. | |
| 826 std::map<int, MediaAccessAliveV8RequestItem>::iterator iter = | |
| 827 media_access_alive_v8_request_objects_.find(request_id); | |
| 828 if (iter != media_access_alive_v8_request_objects_.end()) { | |
| 829 DCHECK(iter->second.first == request_id); | |
| 830 media_access_alive_v8_request_objects_.erase(iter); | |
| 831 } | |
| 832 | |
| 833 // If a decision has not been made for this request yet, deny it. | |
| 834 RespondMediaAccessIfPending(request_id, false /* allow */); | |
| 835 } | |
| 836 | |
| 837 void BrowserPlugin::PersistRequestObject(const NPVariant* request, int id) { | |
| 838 DCHECK(media_access_alive_v8_request_objects_.find(id) == | |
| 839 media_access_alive_v8_request_objects_.end()); | |
| 840 if (media_access_alive_v8_request_objects_.find(id) == | |
| 841 media_access_alive_v8_request_objects_.end()) { | |
| 842 v8::Persistent<v8::Value> weak_request = | |
| 843 v8::Persistent<v8::Value>::New(WebKit::WebBindings::toV8Value(request)); | |
| 844 | |
| 845 std::pair<std::map<int, MediaAccessAliveV8RequestItem>::iterator, bool> | |
| 846 result = media_access_alive_v8_request_objects_.insert( | |
| 847 std::make_pair(id, std::make_pair(id, this))); | |
| 848 DCHECK(result.second); // Inserted in the map. | |
| 849 if (result.second) { | |
| 850 MediaAccessAliveV8RequestItem* request_item = &result.first->second; | |
| 851 weak_request.MakeWeak(request_item, WeakCallbackForPersistObject); | |
| 852 } | |
| 853 } | |
| 854 } | |
| 855 | |
| 856 void BrowserPlugin::WeakCallbackForPersistObject( | |
|
Fady Samuel
2013/02/07 21:41:24
It just occurred to me: what happens if BrowserPlu
lazyboy
2013/02/07 22:59:27
Good catch here.
Using WeakPtr and allocating map
| |
| 857 v8::Persistent<v8::Value> object, void* param) { | |
| 858 v8::Persistent<v8::Object> persistent_object = | |
| 859 v8::Persistent<v8::Object>::Cast(object); | |
| 860 | |
| 861 MediaAccessAliveV8RequestItem* item_ptr = | |
| 862 static_cast<MediaAccessAliveV8RequestItem*>(param); | |
| 863 int request_id = item_ptr->first; | |
| 864 BrowserPlugin* plugin = item_ptr->second; | |
| 865 plugin->OnMediaRequestGarbageCollected(request_id); | |
| 866 | |
| 867 persistent_object.Dispose(); | |
| 868 } | |
| 869 | |
| 785 void BrowserPlugin::Back() { | 870 void BrowserPlugin::Back() { |
| 786 if (!navigate_src_sent_) | 871 if (!navigate_src_sent_) |
| 787 return; | 872 return; |
| 788 browser_plugin_manager()->Send( | 873 browser_plugin_manager()->Send( |
| 789 new BrowserPluginHostMsg_Go(render_view_routing_id_, | 874 new BrowserPluginHostMsg_Go(render_view_routing_id_, |
| 790 instance_id_, -1)); | 875 instance_id_, -1)); |
| 791 } | 876 } |
| 792 | 877 |
| 793 void BrowserPlugin::Forward() { | 878 void BrowserPlugin::Forward() { |
| 794 if (!navigate_src_sent_) | 879 if (!navigate_src_sent_) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 845 bool embedder_focused = false; | 930 bool embedder_focused = false; |
| 846 if (render_view_) | 931 if (render_view_) |
| 847 embedder_focused = render_view_->has_focus(); | 932 embedder_focused = render_view_->has_focus(); |
| 848 return plugin_focused_ && embedder_focused; | 933 return plugin_focused_ && embedder_focused; |
| 849 } | 934 } |
| 850 | 935 |
| 851 WebKit::WebPluginContainer* BrowserPlugin::container() const { | 936 WebKit::WebPluginContainer* BrowserPlugin::container() const { |
| 852 return container_; | 937 return container_; |
| 853 } | 938 } |
| 854 | 939 |
| 940 void BrowserPlugin::RespondMediaAccess(int request_id, bool allow) { | |
| 941 browser_plugin_manager()->Send( | |
| 942 new BrowserPluginHostMsg_AllowPermissionAccess( | |
| 943 render_view_->GetRoutingID(), instance_id_, | |
| 944 browser_plugin::kPermissionTypeMedia, request_id, allow)); | |
| 945 } | |
| 946 | |
| 947 void BrowserPlugin::RespondMediaAccessIfPending(int request_id, bool allow) { | |
| 948 MediaAccessPendingRequestIds::iterator iter = | |
| 949 media_access_pending_request_ids_.find(request_id); | |
| 950 if (iter == media_access_pending_request_ids_.end()) | |
| 951 return; | |
| 952 media_access_pending_request_ids_.erase(iter); | |
| 953 RespondMediaAccess(request_id, allow); | |
| 954 } | |
| 955 | |
| 956 void BrowserPlugin::OnListenerCallMediaAccess(int request_id, bool allow) { | |
| 957 RespondMediaAccessIfPending(request_id, allow); | |
| 958 } | |
| 959 | |
| 855 bool BrowserPlugin::initialize(WebPluginContainer* container) { | 960 bool BrowserPlugin::initialize(WebPluginContainer* container) { |
| 856 container_ = container; | 961 container_ = container; |
| 857 container_->setWantsWheelEvents(true); | 962 container_->setWantsWheelEvents(true); |
| 858 ParseAttributes(); | 963 ParseAttributes(); |
| 859 return true; | 964 return true; |
| 860 } | 965 } |
| 861 | 966 |
| 862 void BrowserPlugin::EnableCompositing(bool enable) { | 967 void BrowserPlugin::EnableCompositing(bool enable) { |
| 863 if (compositing_enabled_ == enable) | 968 if (compositing_enabled_ == enable) |
| 864 return; | 969 return; |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1167 void* notify_data) { | 1272 void* notify_data) { |
| 1168 } | 1273 } |
| 1169 | 1274 |
| 1170 void BrowserPlugin::didFailLoadingFrameRequest( | 1275 void BrowserPlugin::didFailLoadingFrameRequest( |
| 1171 const WebKit::WebURL& url, | 1276 const WebKit::WebURL& url, |
| 1172 void* notify_data, | 1277 void* notify_data, |
| 1173 const WebKit::WebURLError& error) { | 1278 const WebKit::WebURLError& error) { |
| 1174 } | 1279 } |
| 1175 | 1280 |
| 1176 } // namespace content | 1281 } // namespace content |
| OLD | NEW |