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

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 cdn@, use enums for permission_type. 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() {
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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 props[browser_plugin::kURL] = new base::StringValue(url.spec()); 524 props[browser_plugin::kURL] = new base::StringValue(url.spec());
506 props[browser_plugin::kIsTopLevel] = new base::FundamentalValue(is_top_level); 525 props[browser_plugin::kIsTopLevel] = new base::FundamentalValue(is_top_level);
507 526
508 TriggerEvent(browser_plugin::kEventLoadStart, &props); 527 TriggerEvent(browser_plugin::kEventLoadStart, &props);
509 } 528 }
510 529
511 void BrowserPlugin::OnLoadStop(int instance_id) { 530 void BrowserPlugin::OnLoadStop(int instance_id) {
512 TriggerEvent(browser_plugin::kEventLoadStop, NULL); 531 TriggerEvent(browser_plugin::kEventLoadStop, NULL);
513 } 532 }
514 533
534 void BrowserPlugin::OnRequestPermission(
535 int instance_id,
536 int permission_type,
537 int request_id,
538 const base::DictionaryValue& request_info) {
539 if (permission_type == BrowserPluginPermissionTypeMedia)
540 RequestMediaPermission(request_id, request_info);
541 }
542
515 void BrowserPlugin::OnSetCursor(int instance_id, const WebCursor& cursor) { 543 void BrowserPlugin::OnSetCursor(int instance_id, const WebCursor& cursor) {
516 cursor_ = cursor; 544 cursor_ = cursor;
517 } 545 }
518 546
519 void BrowserPlugin::OnShouldAcceptTouchEvents(int instance_id, bool accept) { 547 void BrowserPlugin::OnShouldAcceptTouchEvents(int instance_id, bool accept) {
520 if (container()) { 548 if (container()) {
521 container()->requestTouchEventType(accept ? 549 container()->requestTouchEventType(accept ?
522 WebKit::WebPluginContainer::TouchEventRequestTypeRaw : 550 WebKit::WebPluginContainer::TouchEventRequestTypeRaw :
523 WebKit::WebPluginContainer::TouchEventRequestTypeNone); 551 WebKit::WebPluginContainer::TouchEventRequestTypeNone);
524 } 552 }
525 } 553 }
526 554
527 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) { 555 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) {
528 UpdateDOMAttribute(browser_plugin::kAttributeName, name); 556 UpdateDOMAttribute(browser_plugin::kAttributeName, name);
529 } 557 }
530 558
559 void BrowserPlugin::RequestMediaPermission(
560 int request_id, const base::DictionaryValue& request_info) {
561 if (!HasEventListeners(browser_plugin::kEventRequestPermission)) {
562 // Automatically deny the request if there are no event listeners for
563 // permissionrequest.
564 AllowPermission(
565 BrowserPluginPermissionTypeMedia, request_id, false /* allow */);
566 return;
567 }
568 DCHECK(!pending_permission_requests_.count(request_id));
569 pending_permission_requests_.insert(
570 std::make_pair(request_id,
571 std::make_pair(request_id,
572 BrowserPluginPermissionTypeMedia)));
573
574 std::map<std::string, base::Value*> props;
575 props[browser_plugin::kPermission] =
576 base::Value::CreateStringValue(browser_plugin::kPermissionTypeMedia);
577 props[browser_plugin::kRequestId] =
578 base::Value::CreateIntegerValue(request_id);
579
580 // Fill in the info provided by the browser.
581 for (DictionaryValue::Iterator iter(request_info); !iter.IsAtEnd();
582 iter.Advance()) {
583 props[iter.key()] = iter.value().DeepCopy();
584 }
585 TriggerEvent(browser_plugin::kEventRequestPermission, &props);
586 }
587
588 bool BrowserPlugin::HasEventListeners(const std::string& event_name) {
589 if (!container())
590 return false;
591
592 for (size_t i = 0; i < ancestors_.size(); ++i) {
593 if (ancestors_[i].hasEventListeners(
594 WebKit::WebString::fromUTF8(event_name))) {
595 return true;
596 }
597 }
598 return false;
599 }
600
531 void BrowserPlugin::OnUpdateRect( 601 void BrowserPlugin::OnUpdateRect(
532 int instance_id, 602 int instance_id,
533 const BrowserPluginMsg_UpdateRect_Params& params) { 603 const BrowserPluginMsg_UpdateRect_Params& params) {
534 bool use_new_damage_buffer = !backing_store_; 604 bool use_new_damage_buffer = !backing_store_;
535 BrowserPluginHostMsg_AutoSize_Params auto_size_params; 605 BrowserPluginHostMsg_AutoSize_Params auto_size_params;
536 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; 606 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params;
537 // If we have a pending damage buffer, and the guest has begun to use the 607 // 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 608 // 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 609 // damage buffer. At this point, we drop the current damage buffer, and
540 // mark the pending damage buffer as the current damage buffer. 610 // 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 838 // 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. 839 // more appropriate (and stable) event to the consumers as part of the API.
770 event.initCustomEvent( 840 event.initCustomEvent(
771 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())), 841 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())),
772 false, false, 842 false, false,
773 WebKit::WebSerializedScriptValue::serialize( 843 WebKit::WebSerializedScriptValue::serialize(
774 v8::String::New(json_string.c_str(), json_string.size()))); 844 v8::String::New(json_string.c_str(), json_string.size())));
775 container()->element().dispatchEvent(event); 845 container()->element().dispatchEvent(event);
776 } 846 }
777 847
848 void BrowserPlugin::OnRequestObjectGarbageCollected(int request_id) {
849 // Remove from alive objects.
850 std::map<int, AliveV8PermissionRequestItem*>::iterator iter =
851 alive_v8_permission_request_objects_.find(request_id);
852 if (iter != alive_v8_permission_request_objects_.end()) {
853 DCHECK(iter->second->first == request_id);
854 alive_v8_permission_request_objects_.erase(iter);
855 }
856
857 // If a decision has not been made for this request yet, deny it.
858 AllowPermissionIfRequestIsPending(request_id, false /*allow*/);
859 }
860
861 void BrowserPlugin::PersistRequestObject(
862 const NPVariant* request, const std::string& type, int id) {
863 DCHECK(alive_v8_permission_request_objects_.find(id) ==
864 alive_v8_permission_request_objects_.end());
865 if (alive_v8_permission_request_objects_.find(id) !=
866 alive_v8_permission_request_objects_.end()) {
867 return;
868 }
869 if (pending_permission_requests_.find(id) ==
870 pending_permission_requests_.end()) {
871 return;
872 }
873
874 v8::Persistent<v8::Value> weak_request =
875 v8::Persistent<v8::Value>::New(WebKit::WebBindings::toV8Value(request));
876
877 AliveV8PermissionRequestItem* new_item =
878 new std::pair<int, base::WeakPtr<BrowserPlugin> >(
879 id, weak_ptr_factory_.GetWeakPtr());
880
881 std::pair<std::map<int, AliveV8PermissionRequestItem*>::iterator, bool>
882 result = alive_v8_permission_request_objects_.insert(
883 std::make_pair(id, new_item));
884 CHECK(result.second); // Inserted in the map.
885 AliveV8PermissionRequestItem* request_item = result.first->second;
886 weak_request.MakeWeak(request_item, WeakCallbackForPersistObject);
887 }
888
889 // static
890 void BrowserPlugin::WeakCallbackForPersistObject(
891 v8::Persistent<v8::Value> object, void* param) {
892 v8::Persistent<v8::Object> persistent_object =
893 v8::Persistent<v8::Object>::Cast(object);
894
895 AliveV8PermissionRequestItem* item_ptr =
896 static_cast<AliveV8PermissionRequestItem*>(param);
897 int request_id = item_ptr->first;
898 base::WeakPtr<BrowserPlugin> plugin = item_ptr->second;
899 delete item_ptr;
900
901 persistent_object.Dispose();
902 persistent_object.Clear();
903
904 if (plugin) {
905 // Asynchronously remove item from |alive_v8_permission_request_objects_|.
906 // Note that we are using weak pointer for the following PostTask, so we
907 // don't need to worry about BrowserPlugin going away.
908 MessageLoop::current()->PostTask(
909 FROM_HERE,
910 base::Bind(&BrowserPlugin::OnRequestObjectGarbageCollected,
911 plugin, request_id));
912 }
913 }
914
778 void BrowserPlugin::Back() { 915 void BrowserPlugin::Back() {
779 if (!navigate_src_sent_) 916 if (!navigate_src_sent_)
780 return; 917 return;
781 browser_plugin_manager()->Send( 918 browser_plugin_manager()->Send(
782 new BrowserPluginHostMsg_Go(render_view_routing_id_, 919 new BrowserPluginHostMsg_Go(render_view_routing_id_,
783 instance_id_, -1)); 920 instance_id_, -1));
784 } 921 }
785 922
786 void BrowserPlugin::Forward() { 923 void BrowserPlugin::Forward() {
787 if (!navigate_src_sent_) 924 if (!navigate_src_sent_)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 bool embedder_focused = false; 975 bool embedder_focused = false;
839 if (render_view_) 976 if (render_view_)
840 embedder_focused = render_view_->has_focus(); 977 embedder_focused = render_view_->has_focus();
841 return plugin_focused_ && embedder_focused; 978 return plugin_focused_ && embedder_focused;
842 } 979 }
843 980
844 WebKit::WebPluginContainer* BrowserPlugin::container() const { 981 WebKit::WebPluginContainer* BrowserPlugin::container() const {
845 return container_; 982 return container_;
846 } 983 }
847 984
985 void BrowserPlugin::AllowPermission(
986 int permission_type, int request_id, bool allow) {
987 switch (permission_type) {
988 case BrowserPluginPermissionTypeMedia:
989 browser_plugin_manager()->Send(
990 new BrowserPluginHostMsg_AllowPermission(
991 render_view_->GetRoutingID(), instance_id_,
992 BrowserPluginPermissionTypeMedia, request_id, allow));
993 break;
994 default:
995 LOG(INFO) << "Not a valid permission type";
996 break;
997 }
998 }
999
1000 void BrowserPlugin::AllowPermissionIfRequestIsPending(
1001 int request_id, bool allow) {
1002 PendingPermissionRequests::iterator iter =
1003 pending_permission_requests_.find(request_id);
1004 if (iter == pending_permission_requests_.end())
1005 return;
1006
1007 int type = iter->second.second;
1008 pending_permission_requests_.erase(iter);
1009 AllowPermission(type, request_id, allow);
1010 }
1011
1012 void BrowserPlugin::OnEmbedderDecidedPermission(int request_id, bool allow) {
1013 AllowPermissionIfRequestIsPending(request_id, allow);
1014 }
1015
848 bool BrowserPlugin::initialize(WebPluginContainer* container) { 1016 bool BrowserPlugin::initialize(WebPluginContainer* container) {
849 container_ = container; 1017 container_ = container;
850 container_->setWantsWheelEvents(true); 1018 container_->setWantsWheelEvents(true);
1019 // This ancestor set is valid for the lifetime of BrowserPlugin as this object
1020 // does not survive reparenting in the DOM tree.
1021 PopulateAncestorList();
851 ParseAttributes(); 1022 ParseAttributes();
852 return true; 1023 return true;
853 } 1024 }
854 1025
855 void BrowserPlugin::EnableCompositing(bool enable) { 1026 void BrowserPlugin::EnableCompositing(bool enable) {
856 if (compositing_enabled_ == enable) 1027 if (compositing_enabled_ == enable)
857 return; 1028 return;
858 1029
859 compositing_enabled_ = enable; 1030 compositing_enabled_ = enable;
860 if (enable) { 1031 if (enable) {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 void* notify_data) { 1335 void* notify_data) {
1165 } 1336 }
1166 1337
1167 void BrowserPlugin::didFailLoadingFrameRequest( 1338 void BrowserPlugin::didFailLoadingFrameRequest(
1168 const WebKit::WebURL& url, 1339 const WebKit::WebURL& url,
1169 void* notify_data, 1340 void* notify_data,
1170 const WebKit::WebURLError& error) { 1341 const WebKit::WebURLError& error) {
1171 } 1342 }
1172 1343
1173 } // namespace content 1344 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698