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

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 Fady. 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 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 new BrowserPluginHostMsg_CreateGuest(render_view_routing_id_, 383 new BrowserPluginHostMsg_CreateGuest(render_view_routing_id_,
381 instance_id_, 384 instance_id_,
382 create_guest_params)); 385 create_guest_params));
383 386
384 // Record that we sent a navigation request to the browser process. 387 // Record that we sent a navigation request to the browser process.
385 // Once this instance has navigated, the storage partition cannot be changed, 388 // Once this instance has navigated, the storage partition cannot be changed,
386 // so this value is used for enforcing this. 389 // so this value is used for enforcing this.
387 navigate_src_sent_ = true; 390 navigate_src_sent_ = true;
388 } 391 }
389 392
393 void BrowserPlugin::PopulateAncestorList() {
Charlie Reis 2013/02/13 01:44:47 Please have a WebKit expert (perhaps abarth) revie
lazyboy 2013/02/13 04:07:48 Yes, I'll do that once you're OK with the CL.
394 if (!container())
395 return;
396
397 WebKit::WebNode ancestor = container()->element();
398 // Escape the <webview> shim if this BrowserPlugin has one.
399 WebKit::WebElement shim = ancestor.shadowHost();
400 if (!shim.isNull())
401 ancestor = shim;
402 ancestors_.clear();
403 while (!ancestor.isNull()) {
404 ancestors_.push_back(ancestor);
405 ancestor = ancestor.parentNode();
406 }
407 }
408
390 void BrowserPlugin::OnAdvanceFocus(int instance_id, bool reverse) { 409 void BrowserPlugin::OnAdvanceFocus(int instance_id, bool reverse) {
391 DCHECK(render_view_); 410 DCHECK(render_view_);
392 render_view_->GetWebView()->advanceFocus(reverse); 411 render_view_->GetWebView()->advanceFocus(reverse);
393 } 412 }
394 413
395 void BrowserPlugin::OnBuffersSwapped(int instance_id, 414 void BrowserPlugin::OnBuffersSwapped(int instance_id,
396 const gfx::Size& size, 415 const gfx::Size& size,
397 std::string mailbox_name, 416 std::string mailbox_name,
398 int gpu_route_id, 417 int gpu_route_id,
399 int gpu_host_id) { 418 int gpu_host_id) {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 props[browser_plugin::kIsTopLevel] = 531 props[browser_plugin::kIsTopLevel] =
513 base::Value::CreateBooleanValue(is_top_level); 532 base::Value::CreateBooleanValue(is_top_level);
514 533
515 TriggerEvent(browser_plugin::kEventLoadStart, &props); 534 TriggerEvent(browser_plugin::kEventLoadStart, &props);
516 } 535 }
517 536
518 void BrowserPlugin::OnLoadStop(int instance_id) { 537 void BrowserPlugin::OnLoadStop(int instance_id) {
519 TriggerEvent(browser_plugin::kEventLoadStop, NULL); 538 TriggerEvent(browser_plugin::kEventLoadStop, NULL);
520 } 539 }
521 540
541 void BrowserPlugin::OnRequestPermission(
542 int instance_id,
543 const std::string& permission_type,
544 int request_id,
545 const base::DictionaryValue& request_info) {
546 if (permission_type == browser_plugin::kPermissionTypeMedia)
547 RequestMediaPermission(request_id, request_info);
548 }
549
522 void BrowserPlugin::OnSetCursor(int instance_id, const WebCursor& cursor) { 550 void BrowserPlugin::OnSetCursor(int instance_id, const WebCursor& cursor) {
523 cursor_ = cursor; 551 cursor_ = cursor;
524 } 552 }
525 553
526 void BrowserPlugin::OnShouldAcceptTouchEvents(int instance_id, bool accept) { 554 void BrowserPlugin::OnShouldAcceptTouchEvents(int instance_id, bool accept) {
527 if (container()) { 555 if (container()) {
528 container()->requestTouchEventType(accept ? 556 container()->requestTouchEventType(accept ?
529 WebKit::WebPluginContainer::TouchEventRequestTypeRaw : 557 WebKit::WebPluginContainer::TouchEventRequestTypeRaw :
530 WebKit::WebPluginContainer::TouchEventRequestTypeNone); 558 WebKit::WebPluginContainer::TouchEventRequestTypeNone);
531 } 559 }
532 } 560 }
533 561
534 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) { 562 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) {
535 UpdateDOMAttribute(browser_plugin::kAttributeName, name); 563 UpdateDOMAttribute(browser_plugin::kAttributeName, name);
536 } 564 }
537 565
566 void BrowserPlugin::RequestMediaPermission(
567 int request_id, const base::DictionaryValue& request_info) {
568 if (!HasEventListeners(browser_plugin::kEventRequestPermission)) {
569 // Automatically deny the request if there are no event listeners for
570 // permissionrequest.
571 RespondPermission(BrowserPlugin::MEDIA, request_id, false /* allow */);
572 return;
573 }
574 DCHECK(!pending_permission_requests_.count(request_id));
575 pending_permission_requests_.insert(
576 std::make_pair(request_id,
577 std::make_pair(request_id, BrowserPlugin::MEDIA)));
578
579 std::map<std::string, base::Value*> props;
580 props[browser_plugin::kPermission] =
581 base::Value::CreateStringValue(browser_plugin::kPermissionTypeMedia);
582 props[browser_plugin::kRequestId] =
583 base::Value::CreateIntegerValue(request_id);
584
585 // Fill in the info provided by the browser.
586 for (DictionaryValue::Iterator iter(request_info); !iter.IsAtEnd();
587 iter.Advance()) {
588 props[iter.key()] = iter.value().DeepCopy();
589 }
590 TriggerEvent(browser_plugin::kEventRequestPermission, &props);
591 }
592
593 bool BrowserPlugin::HasEventListeners(const std::string& event_name) {
594 if (!container())
595 return false;
596
597 for (size_t i = 0; i < ancestors_.size(); ++i) {
598 if (ancestors_[i].hasEventListeners(
599 WebKit::WebString::fromUTF8(event_name))) {
600 return true;
601 }
602 }
603 return false;
604 }
605
538 void BrowserPlugin::OnUpdateRect( 606 void BrowserPlugin::OnUpdateRect(
539 int instance_id, 607 int instance_id,
540 const BrowserPluginMsg_UpdateRect_Params& params) { 608 const BrowserPluginMsg_UpdateRect_Params& params) {
541 bool use_new_damage_buffer = !backing_store_; 609 bool use_new_damage_buffer = !backing_store_;
542 BrowserPluginHostMsg_AutoSize_Params auto_size_params; 610 BrowserPluginHostMsg_AutoSize_Params auto_size_params;
543 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; 611 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params;
544 // If we have a pending damage buffer, and the guest has begun to use the 612 // 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 613 // 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 614 // damage buffer. At this point, we drop the current damage buffer, and
547 // mark the pending damage buffer as the current damage buffer. 615 // 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 843 // 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. 844 // more appropriate (and stable) event to the consumers as part of the API.
777 event.initCustomEvent( 845 event.initCustomEvent(
778 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())), 846 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())),
779 false, false, 847 false, false,
780 WebKit::WebSerializedScriptValue::serialize( 848 WebKit::WebSerializedScriptValue::serialize(
781 v8::String::New(json_string.c_str(), json_string.size()))); 849 v8::String::New(json_string.c_str(), json_string.size())));
782 container()->element().dispatchEvent(event); 850 container()->element().dispatchEvent(event);
783 } 851 }
784 852
853 void BrowserPlugin::OnRequestObjectGarbageCollected(int request_id) {
854 // Remove from alive objects.
855 std::map<int, AliveV8PermissionRequestItem*>::iterator iter =
856 alive_v8_permission_request_objects.find(request_id);
857 if (iter != alive_v8_permission_request_objects.end()) {
858 DCHECK(iter->second->first == request_id);
859 alive_v8_permission_request_objects.erase(iter);
860 }
861
862 // If a decision has not been made for this request yet, deny it.
863 RespondPermissionIfPending(request_id, false /*allow*/);
864 }
865
866 void BrowserPlugin::PersistRequestObject(
867 const NPVariant* request, const std::string& type, int id) {
868 DCHECK(alive_v8_permission_request_objects.find(id) ==
869 alive_v8_permission_request_objects.end());
870 if (alive_v8_permission_request_objects.find(id) !=
871 alive_v8_permission_request_objects.end()) {
872 return;
873 }
874 if (pending_permission_requests_.find(id) ==
875 pending_permission_requests_.end()) {
876 return;
877 }
878
879 v8::Persistent<v8::Value> weak_request =
880 v8::Persistent<v8::Value>::New(WebKit::WebBindings::toV8Value(request));
881
882 AliveV8PermissionRequestItem* new_item =
883 new std::pair<int, base::WeakPtr<BrowserPlugin> >(
884 id, weak_ptr_factory_.GetWeakPtr());
885
886 std::pair<std::map<int, AliveV8PermissionRequestItem*>::iterator, bool>
887 result = alive_v8_permission_request_objects.insert(
888 std::make_pair(id, new_item));
889 DCHECK(result.second); // Inserted in the map.
890 if (result.second) {
891 AliveV8PermissionRequestItem* request_item = result.first->second;
892 weak_request.MakeWeak(request_item, WeakCallbackForPersistObject);
893 }
894 }
895
896 // static
897 void BrowserPlugin::WeakCallbackForPersistObject(
898 v8::Persistent<v8::Value> object, void* param) {
899 v8::Persistent<v8::Object> persistent_object =
900 v8::Persistent<v8::Object>::Cast(object);
901
902 AliveV8PermissionRequestItem* item_ptr =
903 static_cast<AliveV8PermissionRequestItem*>(param);
904 int request_id = item_ptr->first;
905 base::WeakPtr<BrowserPlugin> plugin = item_ptr->second;
906 if (plugin)
907 plugin->OnRequestObjectGarbageCollected(request_id);
908 delete item_ptr;
909
910 persistent_object.Dispose();
911 }
912
785 void BrowserPlugin::Back() { 913 void BrowserPlugin::Back() {
786 if (!navigate_src_sent_) 914 if (!navigate_src_sent_)
787 return; 915 return;
788 browser_plugin_manager()->Send( 916 browser_plugin_manager()->Send(
789 new BrowserPluginHostMsg_Go(render_view_routing_id_, 917 new BrowserPluginHostMsg_Go(render_view_routing_id_,
790 instance_id_, -1)); 918 instance_id_, -1));
791 } 919 }
792 920
793 void BrowserPlugin::Forward() { 921 void BrowserPlugin::Forward() {
794 if (!navigate_src_sent_) 922 if (!navigate_src_sent_)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 bool embedder_focused = false; 973 bool embedder_focused = false;
846 if (render_view_) 974 if (render_view_)
847 embedder_focused = render_view_->has_focus(); 975 embedder_focused = render_view_->has_focus();
848 return plugin_focused_ && embedder_focused; 976 return plugin_focused_ && embedder_focused;
849 } 977 }
850 978
851 WebKit::WebPluginContainer* BrowserPlugin::container() const { 979 WebKit::WebPluginContainer* BrowserPlugin::container() const {
852 return container_; 980 return container_;
853 } 981 }
854 982
983 void BrowserPlugin::RespondPermission(
984 BrowserPlugin::PermissionRequestType type, int request_id, bool allow) {
985 switch (type) {
986 case BrowserPlugin::MEDIA:
987 browser_plugin_manager()->Send(
988 new BrowserPluginHostMsg_AllowPermission(
989 render_view_->GetRoutingID(), instance_id_,
990 browser_plugin::kPermissionTypeMedia, request_id, allow));
991 break;
992 case BrowserPlugin::INVALID:
993 default:
994 LOG(INFO) << "Not a valid permission type";
995 break;
996 }
997 }
998
999 void BrowserPlugin::RespondPermissionIfPending(int request_id, bool allow) {
1000 PendingPermissionRequests::iterator iter =
1001 pending_permission_requests_.find(request_id);
1002 if (iter == pending_permission_requests_.end())
1003 return;
1004
1005 BrowserPlugin::PermissionRequestType type = iter->second.second;
1006 pending_permission_requests_.erase(iter);
1007 RespondPermission(type, request_id, allow);
1008 }
1009
1010 void BrowserPlugin::OnEmbedderDecidedPermission(int request_id, bool allow) {
1011 RespondPermissionIfPending(request_id, allow);
1012 }
1013
855 bool BrowserPlugin::initialize(WebPluginContainer* container) { 1014 bool BrowserPlugin::initialize(WebPluginContainer* container) {
856 container_ = container; 1015 container_ = container;
857 container_->setWantsWheelEvents(true); 1016 container_->setWantsWheelEvents(true);
1017 // This ancestor set is valid for the lifetime of BrowserPlugin as this object
1018 // does not survive reparenting in the DOM tree.
1019 PopulateAncestorList();
858 ParseAttributes(); 1020 ParseAttributes();
859 return true; 1021 return true;
860 } 1022 }
861 1023
862 void BrowserPlugin::EnableCompositing(bool enable) { 1024 void BrowserPlugin::EnableCompositing(bool enable) {
863 if (compositing_enabled_ == enable) 1025 if (compositing_enabled_ == enable)
864 return; 1026 return;
865 1027
866 compositing_enabled_ = enable; 1028 compositing_enabled_ = enable;
867 if (enable) { 1029 if (enable) {
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 void* notify_data) { 1330 void* notify_data) {
1169 } 1331 }
1170 1332
1171 void BrowserPlugin::didFailLoadingFrameRequest( 1333 void BrowserPlugin::didFailLoadingFrameRequest(
1172 const WebKit::WebURL& url, 1334 const WebKit::WebURL& url,
1173 void* notify_data, 1335 void* notify_data,
1174 const WebKit::WebURLError& error) { 1336 const WebKit::WebURLError& error) {
1175 } 1337 }
1176 1338
1177 } // namespace content 1339 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698