| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 persist_storage_(false), | 91 persist_storage_(false), |
| 92 valid_partition_id_(true), | 92 valid_partition_id_(true), |
| 93 content_window_routing_id_(MSG_ROUTING_NONE), | 93 content_window_routing_id_(MSG_ROUTING_NONE), |
| 94 plugin_focused_(false), | 94 plugin_focused_(false), |
| 95 visible_(true), | 95 visible_(true), |
| 96 size_changed_in_flight_(false), | 96 size_changed_in_flight_(false), |
| 97 allocate_instance_id_sent_(false), | 97 allocate_instance_id_sent_(false), |
| 98 browser_plugin_manager_(render_view->browser_plugin_manager()), | 98 browser_plugin_manager_(render_view->browser_plugin_manager()), |
| 99 current_nav_entry_index_(0), | 99 current_nav_entry_index_(0), |
| 100 nav_entry_count_(0), | 100 nav_entry_count_(0), |
| 101 compositing_enabled_(false) { | 101 compositing_enabled_(false), |
| 102 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 103 weak_ptr_factory_(this)) { |
| 102 } | 104 } |
| 103 | 105 |
| 104 BrowserPlugin::~BrowserPlugin() { | 106 BrowserPlugin::~BrowserPlugin() { |
| 105 // If the BrowserPlugin has never navigated then the browser process and | 107 // If the BrowserPlugin has never navigated then the browser process and |
| 106 // BrowserPluginManager don't know about it and so there is nothing to do | 108 // BrowserPluginManager don't know about it and so there is nothing to do |
| 107 // here. | 109 // here. |
| 108 if (!navigate_src_sent_) | 110 if (!navigate_src_sent_) |
| 109 return; | 111 return; |
| 110 browser_plugin_manager()->RemoveBrowserPlugin(instance_id_); | 112 browser_plugin_manager()->RemoveBrowserPlugin(instance_id_); |
| 111 browser_plugin_manager()->Send( | 113 browser_plugin_manager()->Send( |
| 112 new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_, | 114 new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_, |
| 113 instance_id_)); | 115 instance_id_)); |
| 114 } | 116 } |
| 115 | 117 |
| 116 bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) { | 118 bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) { |
| 117 bool handled = true; | 119 bool handled = true; |
| 118 IPC_BEGIN_MESSAGE_MAP(BrowserPlugin, message) | 120 IPC_BEGIN_MESSAGE_MAP(BrowserPlugin, message) |
| 119 IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus) | 121 IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus) |
| 120 IPC_MESSAGE_HANDLER(BrowserPluginMsg_BuffersSwapped, OnBuffersSwapped) | 122 IPC_MESSAGE_HANDLER(BrowserPluginMsg_BuffersSwapped, OnBuffersSwapped) |
| 121 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestContentWindowReady, | 123 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestContentWindowReady, |
| 122 OnGuestContentWindowReady) | 124 OnGuestContentWindowReady) |
| 123 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone, OnGuestGone) | 125 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone, OnGuestGone) |
| 124 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestResponsive, OnGuestResponsive) | 126 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestResponsive, OnGuestResponsive) |
| 125 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestUnresponsive, OnGuestUnresponsive) | 127 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestUnresponsive, OnGuestUnresponsive) |
| 126 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadAbort, OnLoadAbort) | 128 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadAbort, OnLoadAbort) |
| 127 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadCommit, OnLoadCommit) | 129 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadCommit, OnLoadCommit) |
| 128 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadRedirect, OnLoadRedirect) | 130 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadRedirect, OnLoadRedirect) |
| 129 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStart, OnLoadStart) | 131 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStart, OnLoadStart) |
| 130 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStop, OnLoadStop) | 132 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStop, OnLoadStop) |
| 133 IPC_MESSAGE_HANDLER(BrowserPluginMsg_RequestPermission, OnRequestPermission) |
| 131 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor) | 134 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor) |
| 132 IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents, | 135 IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents, |
| 133 OnShouldAcceptTouchEvents) | 136 OnShouldAcceptTouchEvents) |
| 134 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdatedName, OnUpdatedName) | 137 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdatedName, OnUpdatedName) |
| 135 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdateRect, OnUpdateRect) | 138 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdateRect, OnUpdateRect) |
| 136 IPC_MESSAGE_UNHANDLED(handled = false) | 139 IPC_MESSAGE_UNHANDLED(handled = false) |
| 137 IPC_END_MESSAGE_MAP() | 140 IPC_END_MESSAGE_MAP() |
| 138 return handled; | 141 return handled; |
| 139 } | 142 } |
| 140 | 143 |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 props[browser_plugin::kURL] = new base::StringValue(url.spec()); | 507 props[browser_plugin::kURL] = new base::StringValue(url.spec()); |
| 505 props[browser_plugin::kIsTopLevel] = new base::FundamentalValue(is_top_level); | 508 props[browser_plugin::kIsTopLevel] = new base::FundamentalValue(is_top_level); |
| 506 | 509 |
| 507 TriggerEvent(browser_plugin::kEventLoadStart, &props); | 510 TriggerEvent(browser_plugin::kEventLoadStart, &props); |
| 508 } | 511 } |
| 509 | 512 |
| 510 void BrowserPlugin::OnLoadStop(int instance_id) { | 513 void BrowserPlugin::OnLoadStop(int instance_id) { |
| 511 TriggerEvent(browser_plugin::kEventLoadStop, NULL); | 514 TriggerEvent(browser_plugin::kEventLoadStop, NULL); |
| 512 } | 515 } |
| 513 | 516 |
| 517 void BrowserPlugin::OnRequestPermission( |
| 518 int instance_id, |
| 519 BrowserPluginPermissionType permission_type, |
| 520 int request_id, |
| 521 const base::DictionaryValue& request_info) { |
| 522 if (permission_type == BrowserPluginPermissionTypeMedia) |
| 523 RequestMediaPermission(request_id, request_info); |
| 524 } |
| 525 |
| 514 void BrowserPlugin::OnSetCursor(int instance_id, const WebCursor& cursor) { | 526 void BrowserPlugin::OnSetCursor(int instance_id, const WebCursor& cursor) { |
| 515 cursor_ = cursor; | 527 cursor_ = cursor; |
| 516 } | 528 } |
| 517 | 529 |
| 518 void BrowserPlugin::OnShouldAcceptTouchEvents(int instance_id, bool accept) { | 530 void BrowserPlugin::OnShouldAcceptTouchEvents(int instance_id, bool accept) { |
| 519 if (container()) { | 531 if (container()) { |
| 520 container()->requestTouchEventType(accept ? | 532 container()->requestTouchEventType(accept ? |
| 521 WebKit::WebPluginContainer::TouchEventRequestTypeRaw : | 533 WebKit::WebPluginContainer::TouchEventRequestTypeRaw : |
| 522 WebKit::WebPluginContainer::TouchEventRequestTypeNone); | 534 WebKit::WebPluginContainer::TouchEventRequestTypeNone); |
| 523 } | 535 } |
| 524 } | 536 } |
| 525 | 537 |
| 526 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) { | 538 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) { |
| 527 UpdateDOMAttribute(browser_plugin::kAttributeName, name); | 539 UpdateDOMAttribute(browser_plugin::kAttributeName, name); |
| 528 } | 540 } |
| 529 | 541 |
| 542 void BrowserPlugin::RequestMediaPermission( |
| 543 int request_id, const base::DictionaryValue& request_info) { |
| 544 if (!HasEventListeners(browser_plugin::kEventRequestPermission)) { |
| 545 // Automatically deny the request if there are no event listeners for |
| 546 // permissionrequest. |
| 547 RespondPermission( |
| 548 BrowserPluginPermissionTypeMedia, request_id, false /* allow */); |
| 549 return; |
| 550 } |
| 551 DCHECK(!pending_permission_requests_.count(request_id)); |
| 552 pending_permission_requests_.insert( |
| 553 std::make_pair(request_id, |
| 554 std::make_pair(request_id, |
| 555 BrowserPluginPermissionTypeMedia))); |
| 556 |
| 557 std::map<std::string, base::Value*> props; |
| 558 props[browser_plugin::kPermission] = |
| 559 base::Value::CreateStringValue(browser_plugin::kPermissionTypeMedia); |
| 560 props[browser_plugin::kRequestId] = |
| 561 base::Value::CreateIntegerValue(request_id); |
| 562 |
| 563 // Fill in the info provided by the browser. |
| 564 for (DictionaryValue::Iterator iter(request_info); !iter.IsAtEnd(); |
| 565 iter.Advance()) { |
| 566 props[iter.key()] = iter.value().DeepCopy(); |
| 567 } |
| 568 TriggerEvent(browser_plugin::kEventRequestPermission, &props); |
| 569 } |
| 570 |
| 571 bool BrowserPlugin::HasEventListeners(const std::string& event_name) { |
| 572 if (!container()) |
| 573 return false; |
| 574 |
| 575 WebKit::WebNode node = container()->element(); |
| 576 // Escape the <webview> shim if this BrowserPlugin has one. |
| 577 WebKit::WebElement shim = node.shadowHost(); |
| 578 if (!shim.isNull()) |
| 579 node = shim; |
| 580 |
| 581 const WebKit::WebString& web_event_name = |
| 582 WebKit::WebString::fromUTF8(event_name); |
| 583 while (!node.isNull()) { |
| 584 if (node.hasEventListeners(web_event_name)) |
| 585 return true; |
| 586 node = node.parentNode(); |
| 587 } |
| 588 return false; |
| 589 } |
| 590 |
| 530 void BrowserPlugin::OnUpdateRect( | 591 void BrowserPlugin::OnUpdateRect( |
| 531 int instance_id, | 592 int instance_id, |
| 532 const BrowserPluginMsg_UpdateRect_Params& params) { | 593 const BrowserPluginMsg_UpdateRect_Params& params) { |
| 533 bool use_new_damage_buffer = !backing_store_; | 594 bool use_new_damage_buffer = !backing_store_; |
| 534 BrowserPluginHostMsg_AutoSize_Params auto_size_params; | 595 BrowserPluginHostMsg_AutoSize_Params auto_size_params; |
| 535 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; | 596 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; |
| 536 // If we have a pending damage buffer, and the guest has begun to use the | 597 // If we have a pending damage buffer, and the guest has begun to use the |
| 537 // damage buffer then we know the guest will no longer use the current | 598 // damage buffer then we know the guest will no longer use the current |
| 538 // damage buffer. At this point, we drop the current damage buffer, and | 599 // damage buffer. At this point, we drop the current damage buffer, and |
| 539 // mark the pending damage buffer as the current damage buffer. | 600 // mark the pending damage buffer as the current damage buffer. |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 // wrapper/shim (e.g. <webview> tag) should receive these events, and expose a | 828 // wrapper/shim (e.g. <webview> tag) should receive these events, and expose a |
| 768 // more appropriate (and stable) event to the consumers as part of the API. | 829 // more appropriate (and stable) event to the consumers as part of the API. |
| 769 event.initCustomEvent( | 830 event.initCustomEvent( |
| 770 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())), | 831 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())), |
| 771 false, false, | 832 false, false, |
| 772 WebKit::WebSerializedScriptValue::serialize( | 833 WebKit::WebSerializedScriptValue::serialize( |
| 773 v8::String::New(json_string.c_str(), json_string.size()))); | 834 v8::String::New(json_string.c_str(), json_string.size()))); |
| 774 container()->element().dispatchEvent(event); | 835 container()->element().dispatchEvent(event); |
| 775 } | 836 } |
| 776 | 837 |
| 838 void BrowserPlugin::OnRequestObjectGarbageCollected(int request_id) { |
| 839 // Remove from alive objects. |
| 840 std::map<int, AliveV8PermissionRequestItem*>::iterator iter = |
| 841 alive_v8_permission_request_objects_.find(request_id); |
| 842 if (iter != alive_v8_permission_request_objects_.end()) |
| 843 alive_v8_permission_request_objects_.erase(iter); |
| 844 |
| 845 // If a decision has not been made for this request yet, deny it. |
| 846 RespondPermissionIfRequestIsPending(request_id, false /*allow*/); |
| 847 } |
| 848 |
| 849 void BrowserPlugin::PersistRequestObject( |
| 850 const NPVariant* request, const std::string& type, int id) { |
| 851 CHECK(alive_v8_permission_request_objects_.find(id) == |
| 852 alive_v8_permission_request_objects_.end()); |
| 853 if (pending_permission_requests_.find(id) == |
| 854 pending_permission_requests_.end()) { |
| 855 return; |
| 856 } |
| 857 |
| 858 v8::Persistent<v8::Value> weak_request = |
| 859 v8::Persistent<v8::Value>::New(WebKit::WebBindings::toV8Value(request)); |
| 860 |
| 861 AliveV8PermissionRequestItem* new_item = |
| 862 new std::pair<int, base::WeakPtr<BrowserPlugin> >( |
| 863 id, weak_ptr_factory_.GetWeakPtr()); |
| 864 |
| 865 std::pair<std::map<int, AliveV8PermissionRequestItem*>::iterator, bool> |
| 866 result = alive_v8_permission_request_objects_.insert( |
| 867 std::make_pair(id, new_item)); |
| 868 CHECK(result.second); // Inserted in the map. |
| 869 AliveV8PermissionRequestItem* request_item = result.first->second; |
| 870 weak_request.MakeWeak(request_item, WeakCallbackForPersistObject); |
| 871 } |
| 872 |
| 873 // static |
| 874 void BrowserPlugin::WeakCallbackForPersistObject( |
| 875 v8::Persistent<v8::Value> object, void* param) { |
| 876 v8::Persistent<v8::Object> persistent_object = |
| 877 v8::Persistent<v8::Object>::Cast(object); |
| 878 |
| 879 AliveV8PermissionRequestItem* item_ptr = |
| 880 static_cast<AliveV8PermissionRequestItem*>(param); |
| 881 int request_id = item_ptr->first; |
| 882 base::WeakPtr<BrowserPlugin> plugin = item_ptr->second; |
| 883 delete item_ptr; |
| 884 |
| 885 persistent_object.Dispose(); |
| 886 persistent_object.Clear(); |
| 887 |
| 888 if (plugin) { |
| 889 // Asynchronously remove item from |alive_v8_permission_request_objects_|. |
| 890 // Note that we are using weak pointer for the following PostTask, so we |
| 891 // don't need to worry about BrowserPlugin going away. |
| 892 MessageLoop::current()->PostTask( |
| 893 FROM_HERE, |
| 894 base::Bind(&BrowserPlugin::OnRequestObjectGarbageCollected, |
| 895 plugin, request_id)); |
| 896 } |
| 897 } |
| 898 |
| 777 void BrowserPlugin::Back() { | 899 void BrowserPlugin::Back() { |
| 778 if (!navigate_src_sent_) | 900 if (!navigate_src_sent_) |
| 779 return; | 901 return; |
| 780 browser_plugin_manager()->Send( | 902 browser_plugin_manager()->Send( |
| 781 new BrowserPluginHostMsg_Go(render_view_routing_id_, | 903 new BrowserPluginHostMsg_Go(render_view_routing_id_, |
| 782 instance_id_, -1)); | 904 instance_id_, -1)); |
| 783 } | 905 } |
| 784 | 906 |
| 785 void BrowserPlugin::Forward() { | 907 void BrowserPlugin::Forward() { |
| 786 if (!navigate_src_sent_) | 908 if (!navigate_src_sent_) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 bool embedder_focused = false; | 959 bool embedder_focused = false; |
| 838 if (render_view_) | 960 if (render_view_) |
| 839 embedder_focused = render_view_->has_focus(); | 961 embedder_focused = render_view_->has_focus(); |
| 840 return plugin_focused_ && embedder_focused; | 962 return plugin_focused_ && embedder_focused; |
| 841 } | 963 } |
| 842 | 964 |
| 843 WebKit::WebPluginContainer* BrowserPlugin::container() const { | 965 WebKit::WebPluginContainer* BrowserPlugin::container() const { |
| 844 return container_; | 966 return container_; |
| 845 } | 967 } |
| 846 | 968 |
| 969 void BrowserPlugin::RespondPermission( |
| 970 BrowserPluginPermissionType permission_type, int request_id, bool allow) { |
| 971 switch (permission_type) { |
| 972 case BrowserPluginPermissionTypeMedia: |
| 973 browser_plugin_manager()->Send( |
| 974 new BrowserPluginHostMsg_RespondPermission( |
| 975 render_view_->GetRoutingID(), instance_id_, |
| 976 BrowserPluginPermissionTypeMedia, request_id, allow)); |
| 977 break; |
| 978 case BrowserPluginPermissionTypeUnknown: |
| 979 default: |
| 980 // Not a valid permission type. |
| 981 NOTREACHED(); |
| 982 break; |
| 983 } |
| 984 } |
| 985 |
| 986 void BrowserPlugin::RespondPermissionIfRequestIsPending( |
| 987 int request_id, bool allow) { |
| 988 PendingPermissionRequests::iterator iter = |
| 989 pending_permission_requests_.find(request_id); |
| 990 if (iter == pending_permission_requests_.end()) |
| 991 return; |
| 992 |
| 993 BrowserPluginPermissionType permission_type = iter->second.second; |
| 994 pending_permission_requests_.erase(iter); |
| 995 RespondPermission(permission_type, request_id, allow); |
| 996 } |
| 997 |
| 998 void BrowserPlugin::OnEmbedderDecidedPermission(int request_id, bool allow) { |
| 999 RespondPermissionIfRequestIsPending(request_id, allow); |
| 1000 } |
| 1001 |
| 847 bool BrowserPlugin::initialize(WebPluginContainer* container) { | 1002 bool BrowserPlugin::initialize(WebPluginContainer* container) { |
| 848 if (!container) | 1003 if (!container) |
| 849 return false; | 1004 return false; |
| 850 | 1005 |
| 851 if (!GetContentClient()->renderer()->AllowBrowserPlugin(container)) | 1006 if (!GetContentClient()->renderer()->AllowBrowserPlugin(container)) |
| 852 return false; | 1007 return false; |
| 853 | 1008 |
| 854 bindings_.reset(new BrowserPluginBindings(this)); | 1009 bindings_.reset(new BrowserPluginBindings(this)); |
| 855 container_ = container; | 1010 container_ = container; |
| 856 container_->setWantsWheelEvents(true); | 1011 container_->setWantsWheelEvents(true); |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 void* notify_data) { | 1328 void* notify_data) { |
| 1174 } | 1329 } |
| 1175 | 1330 |
| 1176 void BrowserPlugin::didFailLoadingFrameRequest( | 1331 void BrowserPlugin::didFailLoadingFrameRequest( |
| 1177 const WebKit::WebURL& url, | 1332 const WebKit::WebURL& url, |
| 1178 void* notify_data, | 1333 void* notify_data, |
| 1179 const WebKit::WebURLError& error) { | 1334 const WebKit::WebURLError& error) { |
| 1180 } | 1335 } |
| 1181 | 1336 |
| 1182 } // namespace content | 1337 } // namespace content |
| OLD | NEW |