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

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 abarth@ 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 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 props[browser_plugin::kURL] = new base::StringValue(url.spec()); 508 props[browser_plugin::kURL] = new base::StringValue(url.spec());
506 props[browser_plugin::kIsTopLevel] = new base::FundamentalValue(is_top_level); 509 props[browser_plugin::kIsTopLevel] = new base::FundamentalValue(is_top_level);
507 510
508 TriggerEvent(browser_plugin::kEventLoadStart, &props); 511 TriggerEvent(browser_plugin::kEventLoadStart, &props);
509 } 512 }
510 513
511 void BrowserPlugin::OnLoadStop(int instance_id) { 514 void BrowserPlugin::OnLoadStop(int instance_id) {
512 TriggerEvent(browser_plugin::kEventLoadStop, NULL); 515 TriggerEvent(browser_plugin::kEventLoadStop, NULL);
513 } 516 }
514 517
518 void BrowserPlugin::OnRequestPermission(
519 int instance_id,
520 BrowserPluginPermissionType permission_type,
521 int request_id,
522 const base::DictionaryValue& request_info) {
523 if (permission_type == BrowserPluginPermissionTypeMedia)
524 RequestMediaPermission(request_id, request_info);
525 }
526
515 void BrowserPlugin::OnSetCursor(int instance_id, const WebCursor& cursor) { 527 void BrowserPlugin::OnSetCursor(int instance_id, const WebCursor& cursor) {
516 cursor_ = cursor; 528 cursor_ = cursor;
517 } 529 }
518 530
519 void BrowserPlugin::OnShouldAcceptTouchEvents(int instance_id, bool accept) { 531 void BrowserPlugin::OnShouldAcceptTouchEvents(int instance_id, bool accept) {
520 if (container()) { 532 if (container()) {
521 container()->requestTouchEventType(accept ? 533 container()->requestTouchEventType(accept ?
522 WebKit::WebPluginContainer::TouchEventRequestTypeRaw : 534 WebKit::WebPluginContainer::TouchEventRequestTypeRaw :
523 WebKit::WebPluginContainer::TouchEventRequestTypeNone); 535 WebKit::WebPluginContainer::TouchEventRequestTypeNone);
524 } 536 }
525 } 537 }
526 538
527 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) { 539 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) {
528 UpdateDOMAttribute(browser_plugin::kAttributeName, name); 540 UpdateDOMAttribute(browser_plugin::kAttributeName, name);
529 } 541 }
530 542
543 void BrowserPlugin::RequestMediaPermission(
544 int request_id, const base::DictionaryValue& request_info) {
545 if (!HasEventListeners(browser_plugin::kEventRequestPermission)) {
546 // Automatically deny the request if there are no event listeners for
547 // permissionrequest.
548 RespondPermission(
549 BrowserPluginPermissionTypeMedia, request_id, false /* allow */);
550 return;
551 }
552 DCHECK(!pending_permission_requests_.count(request_id));
553 pending_permission_requests_.insert(
554 std::make_pair(request_id,
555 std::make_pair(request_id,
556 BrowserPluginPermissionTypeMedia)));
557
558 std::map<std::string, base::Value*> props;
559 props[browser_plugin::kPermission] =
560 base::Value::CreateStringValue(browser_plugin::kPermissionTypeMedia);
561 props[browser_plugin::kRequestId] =
562 base::Value::CreateIntegerValue(request_id);
563
564 // Fill in the info provided by the browser.
565 for (DictionaryValue::Iterator iter(request_info); !iter.IsAtEnd();
566 iter.Advance()) {
567 props[iter.key()] = iter.value().DeepCopy();
568 }
569 TriggerEvent(browser_plugin::kEventRequestPermission, &props);
570 }
571
572 bool BrowserPlugin::HasEventListeners(const std::string& event_name) {
573 if (!container())
574 return false;
575
576 WebKit::WebNode node = container()->element();
577 // Escape the <webview> shim if this BrowserPlugin has one.
578 WebKit::WebElement shim = node.shadowHost();
579 if (!shim.isNull())
580 node = shim;
581
582 const WebKit::WebString& web_event_name =
583 WebKit::WebString::fromUTF8(event_name);
584 while (!node.isNull()) {
585 if (node.hasEventListeners(web_event_name))
586 return true;
587 node = node.parentNode();
588 }
589 return false;
590 }
591
531 void BrowserPlugin::OnUpdateRect( 592 void BrowserPlugin::OnUpdateRect(
532 int instance_id, 593 int instance_id,
533 const BrowserPluginMsg_UpdateRect_Params& params) { 594 const BrowserPluginMsg_UpdateRect_Params& params) {
534 bool use_new_damage_buffer = !backing_store_; 595 bool use_new_damage_buffer = !backing_store_;
535 BrowserPluginHostMsg_AutoSize_Params auto_size_params; 596 BrowserPluginHostMsg_AutoSize_Params auto_size_params;
536 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; 597 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params;
537 // 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
538 // 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
539 // 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
540 // 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
768 // 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
769 // 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.
770 event.initCustomEvent( 831 event.initCustomEvent(
771 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())), 832 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())),
772 false, false, 833 false, false,
773 WebKit::WebSerializedScriptValue::serialize( 834 WebKit::WebSerializedScriptValue::serialize(
774 v8::String::New(json_string.c_str(), json_string.size()))); 835 v8::String::New(json_string.c_str(), json_string.size())));
775 container()->element().dispatchEvent(event); 836 container()->element().dispatchEvent(event);
776 } 837 }
777 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);
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 RespondPermissionIfRequestIsPending(request_id, false /*allow*/);
850 }
851
852 void BrowserPlugin::PersistRequestObject(
853 const NPVariant* request, const std::string& type, int id) {
854 CHECK(alive_v8_permission_request_objects_.find(id) ==
855 alive_v8_permission_request_objects_.end());
856 if (pending_permission_requests_.find(id) ==
857 pending_permission_requests_.end()) {
858 return;
859 }
860
861 v8::Persistent<v8::Value> weak_request =
862 v8::Persistent<v8::Value>::New(WebKit::WebBindings::toV8Value(request));
863
864 AliveV8PermissionRequestItem* new_item =
865 new std::pair<int, base::WeakPtr<BrowserPlugin> >(
866 id, weak_ptr_factory_.GetWeakPtr());
867
868 std::pair<std::map<int, AliveV8PermissionRequestItem*>::iterator, bool>
869 result = alive_v8_permission_request_objects_.insert(
870 std::make_pair(id, new_item));
871 CHECK(result.second); // Inserted in the map.
872 AliveV8PermissionRequestItem* request_item = result.first->second;
873 weak_request.MakeWeak(request_item, WeakCallbackForPersistObject);
874 }
875
876 // static
877 void BrowserPlugin::WeakCallbackForPersistObject(
878 v8::Persistent<v8::Value> object, void* param) {
879 v8::Persistent<v8::Object> persistent_object =
880 v8::Persistent<v8::Object>::Cast(object);
881
882 AliveV8PermissionRequestItem* item_ptr =
883 static_cast<AliveV8PermissionRequestItem*>(param);
884 int request_id = item_ptr->first;
885 base::WeakPtr<BrowserPlugin> plugin = item_ptr->second;
886 delete item_ptr;
887
888 persistent_object.Dispose();
889 persistent_object.Clear();
890
891 if (plugin) {
Fady Samuel 2013/02/22 18:39:51 What's the point of the if statement given the com
lazyboy 2013/02/22 19:14:43 If the weak pointer is pointing to invalid Browser
892 // Asynchronously remove item from |alive_v8_permission_request_objects_|.
893 // Note that we are using weak pointer for the following PostTask, so we
894 // don't need to worry about BrowserPlugin going away.
895 MessageLoop::current()->PostTask(
896 FROM_HERE,
897 base::Bind(&BrowserPlugin::OnRequestObjectGarbageCollected,
898 plugin, request_id));
899 }
900 }
901
778 void BrowserPlugin::Back() { 902 void BrowserPlugin::Back() {
779 if (!navigate_src_sent_) 903 if (!navigate_src_sent_)
780 return; 904 return;
781 browser_plugin_manager()->Send( 905 browser_plugin_manager()->Send(
782 new BrowserPluginHostMsg_Go(render_view_routing_id_, 906 new BrowserPluginHostMsg_Go(render_view_routing_id_,
783 instance_id_, -1)); 907 instance_id_, -1));
784 } 908 }
785 909
786 void BrowserPlugin::Forward() { 910 void BrowserPlugin::Forward() {
787 if (!navigate_src_sent_) 911 if (!navigate_src_sent_)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 bool embedder_focused = false; 962 bool embedder_focused = false;
839 if (render_view_) 963 if (render_view_)
840 embedder_focused = render_view_->has_focus(); 964 embedder_focused = render_view_->has_focus();
841 return plugin_focused_ && embedder_focused; 965 return plugin_focused_ && embedder_focused;
842 } 966 }
843 967
844 WebKit::WebPluginContainer* BrowserPlugin::container() const { 968 WebKit::WebPluginContainer* BrowserPlugin::container() const {
845 return container_; 969 return container_;
846 } 970 }
847 971
972 void BrowserPlugin::RespondPermission(
973 BrowserPluginPermissionType permission_type, int request_id, bool allow) {
974 switch (permission_type) {
975 case BrowserPluginPermissionTypeMedia:
976 browser_plugin_manager()->Send(
977 new BrowserPluginHostMsg_RespondPermission(
978 render_view_->GetRoutingID(), instance_id_,
979 BrowserPluginPermissionTypeMedia, request_id, allow));
980 break;
981 case BrowserPluginPermissionTypeUnknown:
982 default:
983 // Not a valid permission type.
984 NOTREACHED();
985 break;
986 }
987 }
988
989 void BrowserPlugin::RespondPermissionIfRequestIsPending(
990 int request_id, bool allow) {
991 PendingPermissionRequests::iterator iter =
992 pending_permission_requests_.find(request_id);
993 if (iter == pending_permission_requests_.end())
994 return;
995
996 BrowserPluginPermissionType permission_type = iter->second.second;
997 pending_permission_requests_.erase(iter);
998 RespondPermission(permission_type, request_id, allow);
999 }
1000
1001 void BrowserPlugin::OnEmbedderDecidedPermission(int request_id, bool allow) {
1002 RespondPermissionIfRequestIsPending(request_id, allow);
1003 }
1004
848 bool BrowserPlugin::initialize(WebPluginContainer* container) { 1005 bool BrowserPlugin::initialize(WebPluginContainer* container) {
849 container_ = container; 1006 container_ = container;
850 container_->setWantsWheelEvents(true); 1007 container_->setWantsWheelEvents(true);
851 ParseAttributes(); 1008 ParseAttributes();
852 return true; 1009 return true;
853 } 1010 }
854 1011
855 void BrowserPlugin::EnableCompositing(bool enable) { 1012 void BrowserPlugin::EnableCompositing(bool enable) {
856 if (compositing_enabled_ == enable) 1013 if (compositing_enabled_ == enable)
857 return; 1014 return;
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 void* notify_data) { 1321 void* notify_data) {
1165 } 1322 }
1166 1323
1167 void BrowserPlugin::didFailLoadingFrameRequest( 1324 void BrowserPlugin::didFailLoadingFrameRequest(
1168 const WebKit::WebURL& url, 1325 const WebKit::WebURL& url,
1169 void* notify_data, 1326 void* notify_data,
1170 const WebKit::WebURLError& error) { 1327 const WebKit::WebURLError& error) {
1171 } 1328 }
1172 1329
1173 } // namespace content 1330 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/browser_plugin/browser_plugin.h ('k') | content/renderer/browser_plugin/browser_plugin_bindings.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698