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

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: Fix file name in chrome_renderer.gypi Created 7 years, 9 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 } 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
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
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
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
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
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