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

Side by Side Diff: content/renderer/browser_plugin/browser_plugin.cc

Issue 11093080: <webview>: First stab at implementing media permission request for guests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments from creis@ Created 7 years, 10 months 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 | Annotate | Revision Log
OLDNEW
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
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 bindings_.reset(new BrowserPluginBindings(this)); 104 bindings_.reset(new BrowserPluginBindings(this));
103 } 105 }
104 106
105 BrowserPlugin::~BrowserPlugin() { 107 BrowserPlugin::~BrowserPlugin() {
106 // If the BrowserPlugin has never navigated then the browser process and 108 // If the BrowserPlugin has never navigated then the browser process and
107 // BrowserPluginManager don't know about it and so there is nothing to do 109 // BrowserPluginManager don't know about it and so there is nothing to do
108 // here. 110 // here.
109 if (!navigate_src_sent_) 111 if (!navigate_src_sent_)
110 return; 112 return;
111 browser_plugin_manager()->RemoveBrowserPlugin(instance_id_); 113 browser_plugin_manager()->RemoveBrowserPlugin(instance_id_);
(...skipping 10 matching lines...) Expand all
122 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestContentWindowReady, 124 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestContentWindowReady,
123 OnGuestContentWindowReady) 125 OnGuestContentWindowReady)
124 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone, OnGuestGone) 126 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone, OnGuestGone)
125 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestResponsive, OnGuestResponsive) 127 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestResponsive, OnGuestResponsive)
126 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestUnresponsive, OnGuestUnresponsive) 128 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestUnresponsive, OnGuestUnresponsive)
127 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadAbort, OnLoadAbort) 129 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadAbort, OnLoadAbort)
128 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadCommit, OnLoadCommit) 130 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadCommit, OnLoadCommit)
129 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadRedirect, OnLoadRedirect) 131 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadRedirect, OnLoadRedirect)
130 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStart, OnLoadStart) 132 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStart, OnLoadStart)
131 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStop, OnLoadStop) 133 IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStop, OnLoadStop)
134 IPC_MESSAGE_HANDLER(BrowserPluginMsg_RequestPermission, OnRequestPermission)
132 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor) 135 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor)
133 IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents, 136 IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents,
134 OnShouldAcceptTouchEvents) 137 OnShouldAcceptTouchEvents)
135 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdatedName, OnUpdatedName) 138 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdatedName, OnUpdatedName)
136 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdateRect, OnUpdateRect) 139 IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdateRect, OnUpdateRect)
137 IPC_MESSAGE_UNHANDLED(handled = false) 140 IPC_MESSAGE_UNHANDLED(handled = false)
138 IPC_END_MESSAGE_MAP() 141 IPC_END_MESSAGE_MAP()
139 return handled; 142 return handled;
140 } 143 }
141 144
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 container()->requestTouchEventType(accept ? 531 container()->requestTouchEventType(accept ?
529 WebKit::WebPluginContainer::TouchEventRequestTypeRaw : 532 WebKit::WebPluginContainer::TouchEventRequestTypeRaw :
530 WebKit::WebPluginContainer::TouchEventRequestTypeNone); 533 WebKit::WebPluginContainer::TouchEventRequestTypeNone);
531 } 534 }
532 } 535 }
533 536
534 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) { 537 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) {
535 UpdateDOMAttribute(browser_plugin::kAttributeName, name); 538 UpdateDOMAttribute(browser_plugin::kAttributeName, name);
536 } 539 }
537 540
541 void BrowserPlugin::OnRequestPermission(
Fady Samuel 2013/02/12 16:13:20 Alphabetize with other message handlers.
lazyboy 2013/02/12 18:57:51 Done.
542 int instance_id,
543 const std::string& permission_type,
544 int request_id,
545 const base::DictionaryValue& request_info) {
546 if (permission_type == "media")
547 OnRequestMediaPermission(request_id, request_info);
Fady Samuel 2013/02/12 16:13:20 How about just RequestMedia permission?
lazyboy 2013/02/12 18:57:51 Done.
548 }
549
550 void BrowserPlugin::OnRequestMediaPermission(
551 int request_id, const base::DictionaryValue& request_info) {
552 if (!HasEventListeners(browser_plugin::kEventRequestPermission)) {
553 // Automatically deny the request if there are no event listeners for
554 // permissionrequest.
555 RespondPermission(BrowserPlugin::MEDIA, request_id, false /* allow */);
556 return;
557 }
558 DCHECK(!pending_permission_request_ids_.count(request_id));
559 pending_permission_request_ids_.insert(request_id);
Fady Samuel 2013/02/12 16:13:20 I'm confused. Why do we have a pending_permission_
lazyboy 2013/02/12 18:57:51 Merged them, thanks.
560 pending_request_id_to_type_.insert(
561 std::make_pair(request_id, BrowserPlugin::MEDIA));
562
563 std::map<std::string, base::Value*> props;
564 props[browser_plugin::kPermission] =
565 base::Value::CreateStringValue(browser_plugin::kPermissionTypeMedia);
566 props[browser_plugin::kRequestId] =
567 base::Value::CreateIntegerValue(request_id);
568
569 // Fill in the info provided by the browser.
570 for (DictionaryValue::Iterator iter(request_info); !iter.IsAtEnd();
571 iter.Advance()) {
572 props[iter.key()] = iter.value().DeepCopy();
573 }
574 TriggerEvent(browser_plugin::kEventRequestPermission, &props);
575 }
576
577 bool BrowserPlugin::HasEventListeners(const std::string& event_name) {
578 if (!container())
579 return false;
580
581 // TODO(lazyboy): Fix before submitting: use ancestor list instead similar to
Fady Samuel 2013/02/12 16:13:20 You can probably copy and paste my code in the win
lazyboy 2013/02/12 18:57:51 Done.
582 // window.open CL, so bubbling is supported.
583 WebKit::WebNode parent = container()->element().parentNode();
584 if (!parent.isNull() && !parent.shadowHost().isNull()) {
585 WebKit::WebElement shadow_host = parent.shadowHost();
586 return shadow_host.hasEventListeners(
587 WebKit::WebString::fromUTF8(event_name));
588 }
589 return false;
590 }
591
538 void BrowserPlugin::OnUpdateRect( 592 void BrowserPlugin::OnUpdateRect(
539 int instance_id, 593 int instance_id,
540 const BrowserPluginMsg_UpdateRect_Params& params) { 594 const BrowserPluginMsg_UpdateRect_Params& params) {
541 bool use_new_damage_buffer = !backing_store_; 595 bool use_new_damage_buffer = !backing_store_;
542 BrowserPluginHostMsg_AutoSize_Params auto_size_params; 596 BrowserPluginHostMsg_AutoSize_Params auto_size_params;
543 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; 597 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params;
544 // If we have a pending damage buffer, and the guest has begun to use the 598 // 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 599 // 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 600 // damage buffer. At this point, we drop the current damage buffer, and
547 // mark the pending damage buffer as the current damage buffer. 601 // mark the pending damage buffer as the current damage buffer.
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 // wrapper/shim (e.g. <webview> tag) should receive these events, and expose a 829 // 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. 830 // more appropriate (and stable) event to the consumers as part of the API.
777 event.initCustomEvent( 831 event.initCustomEvent(
778 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())), 832 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())),
779 false, false, 833 false, false,
780 WebKit::WebSerializedScriptValue::serialize( 834 WebKit::WebSerializedScriptValue::serialize(
781 v8::String::New(json_string.c_str(), json_string.size()))); 835 v8::String::New(json_string.c_str(), json_string.size())));
782 container()->element().dispatchEvent(event); 836 container()->element().dispatchEvent(event);
783 } 837 }
784 838
839 void BrowserPlugin::OnRequestObjectGarbageCollected(int request_id) {
840 // Remove from alive objects.
841 std::map<int, AliveV8PermissionRequestItem*>::iterator iter =
842 alive_v8_permission_request_objects.find(request_id);
Fady Samuel 2013/02/12 16:13:20 I feel like fundamentally, we want a map that's:
lazyboy 2013/02/12 18:57:51 The V8_*_requests container is not parallel to the
843 if (iter != alive_v8_permission_request_objects.end()) {
844 DCHECK(iter->second->first == request_id);
845 alive_v8_permission_request_objects.erase(iter);
846 }
847
848 // If a decision has not been made for this request yet, deny it.
849 RespondPermissionIfPending(request_id, false /*allow*/);
850 }
851
852 void BrowserPlugin::PersistRequestObject(
853 const NPVariant* request, const std::string& type, int id) {
854 DCHECK(alive_v8_permission_request_objects.find(id) ==
855 alive_v8_permission_request_objects.end());
856 if (alive_v8_permission_request_objects.find(id) ==
Fady Samuel 2013/02/12 16:13:20 Early exit preferred. if (alive_v8_permission_req
lazyboy 2013/02/12 18:57:51 Done.
857 alive_v8_permission_request_objects.end()) {
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 DCHECK(result.second); // Inserted in the map.
869 if (result.second) {
870 AliveV8PermissionRequestItem* request_item = result.first->second;
871 weak_request.MakeWeak(request_item, WeakCallbackForPersistObject);
872 }
873 }
874 }
875
876 void BrowserPlugin::WeakCallbackForPersistObject(
Fady Samuel 2013/02/12 16:13:20 // static
lazyboy 2013/02/12 18:57:51 Done.
877 v8::Persistent<v8::Value> object, void* param) {
878 v8::Persistent<v8::Object> persistent_object =
879 v8::Persistent<v8::Object>::Cast(object);
880
881 AliveV8PermissionRequestItem* item_ptr =
882 static_cast<AliveV8PermissionRequestItem*>(param);
883 int request_id = item_ptr->first;
884 base::WeakPtr<BrowserPlugin> plugin = item_ptr->second;
885 if (plugin)
886 plugin->OnRequestObjectGarbageCollected(request_id);
887 delete item_ptr;
888
889 persistent_object.Dispose();
890 }
891
785 void BrowserPlugin::Back() { 892 void BrowserPlugin::Back() {
786 if (!navigate_src_sent_) 893 if (!navigate_src_sent_)
787 return; 894 return;
788 browser_plugin_manager()->Send( 895 browser_plugin_manager()->Send(
789 new BrowserPluginHostMsg_Go(render_view_routing_id_, 896 new BrowserPluginHostMsg_Go(render_view_routing_id_,
790 instance_id_, -1)); 897 instance_id_, -1));
791 } 898 }
792 899
793 void BrowserPlugin::Forward() { 900 void BrowserPlugin::Forward() {
794 if (!navigate_src_sent_) 901 if (!navigate_src_sent_)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 bool embedder_focused = false; 952 bool embedder_focused = false;
846 if (render_view_) 953 if (render_view_)
847 embedder_focused = render_view_->has_focus(); 954 embedder_focused = render_view_->has_focus();
848 return plugin_focused_ && embedder_focused; 955 return plugin_focused_ && embedder_focused;
849 } 956 }
850 957
851 WebKit::WebPluginContainer* BrowserPlugin::container() const { 958 WebKit::WebPluginContainer* BrowserPlugin::container() const {
852 return container_; 959 return container_;
853 } 960 }
854 961
962 void BrowserPlugin::RespondPermission(
963 BrowserPlugin::PermissionRequestType type, int request_id, bool allow) {
964 if (type == BrowserPlugin::INVALID) {
Fady Samuel 2013/02/12 16:13:20 This can probably be a switch statement. Only two
lazyboy 2013/02/12 18:57:51 Done.
965 LOG(INFO) << "Not a valid permission type";
966 return;
967 }
968
969 if (type == BrowserPlugin::MEDIA) {
970 browser_plugin_manager()->Send(
971 new BrowserPluginHostMsg_AllowPermission(
972 render_view_->GetRoutingID(), instance_id_,
973 browser_plugin::kPermissionTypeMedia, request_id, allow));
974 }
975 }
976
977 void BrowserPlugin::RespondPermissionIfPending(int request_id, bool allow) {
978 PendingPermissionRequestIds::iterator iter =
979 pending_permission_request_ids_.find(request_id);
980 std::map<int, BrowserPlugin::PermissionRequestType>::iterator type_iter =
981 pending_request_id_to_type_.find(request_id);
982
983 if (iter == pending_permission_request_ids_.end()) {
984 DCHECK(type_iter == pending_request_id_to_type_.end());
985 return;
986 }
987
988 BrowserPlugin::PermissionRequestType type = type_iter->second;
989 pending_permission_request_ids_.erase(iter);
990 pending_request_id_to_type_.erase(request_id);
991 RespondPermission(type, request_id, allow);
992 }
993
994 void BrowserPlugin::OnEmbedderDecidedPermission(int request_id, bool allow) {
Fady Samuel 2013/02/12 16:13:20 I'm not too keen on the On* method names for thing
lazyboy 2013/02/12 18:57:51 I see. But I think this name makes it clearer to u
995 RespondPermissionIfPending(request_id, allow);
996 }
997
855 bool BrowserPlugin::initialize(WebPluginContainer* container) { 998 bool BrowserPlugin::initialize(WebPluginContainer* container) {
856 container_ = container; 999 container_ = container;
857 container_->setWantsWheelEvents(true); 1000 container_->setWantsWheelEvents(true);
858 ParseAttributes(); 1001 ParseAttributes();
859 return true; 1002 return true;
860 } 1003 }
861 1004
862 void BrowserPlugin::EnableCompositing(bool enable) { 1005 void BrowserPlugin::EnableCompositing(bool enable) {
863 if (compositing_enabled_ == enable) 1006 if (compositing_enabled_ == enable)
864 return; 1007 return;
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 void* notify_data) { 1311 void* notify_data) {
1169 } 1312 }
1170 1313
1171 void BrowserPlugin::didFailLoadingFrameRequest( 1314 void BrowserPlugin::didFailLoadingFrameRequest(
1172 const WebKit::WebURL& url, 1315 const WebKit::WebURL& url,
1173 void* notify_data, 1316 void* notify_data,
1174 const WebKit::WebURLError& error) { 1317 const WebKit::WebURLError& error) {
1175 } 1318 }
1176 1319
1177 } // namespace content 1320 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698