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

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: Add period at the end of sentence. 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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 props[browser_plugin::kURL] = new base::StringValue(url.spec()); 520 props[browser_plugin::kURL] = new base::StringValue(url.spec());
502 props[browser_plugin::kIsTopLevel] = new base::FundamentalValue(is_top_level); 521 props[browser_plugin::kIsTopLevel] = new base::FundamentalValue(is_top_level);
503 522
504 TriggerEvent(browser_plugin::kEventLoadStart, &props); 523 TriggerEvent(browser_plugin::kEventLoadStart, &props);
505 } 524 }
506 525
507 void BrowserPlugin::OnLoadStop(int instance_id) { 526 void BrowserPlugin::OnLoadStop(int instance_id) {
508 TriggerEvent(browser_plugin::kEventLoadStop, NULL); 527 TriggerEvent(browser_plugin::kEventLoadStop, NULL);
509 } 528 }
510 529
530 void BrowserPlugin::OnRequestPermission(
531 int instance_id,
532 const std::string& permission_type,
533 int request_id,
534 const base::DictionaryValue& request_info) {
535 if (permission_type == browser_plugin::kPermissionTypeMedia)
536 RequestMediaPermission(request_id, request_info);
537 }
538
511 void BrowserPlugin::OnSetCursor(int instance_id, const WebCursor& cursor) { 539 void BrowserPlugin::OnSetCursor(int instance_id, const WebCursor& cursor) {
512 cursor_ = cursor; 540 cursor_ = cursor;
513 } 541 }
514 542
515 void BrowserPlugin::OnShouldAcceptTouchEvents(int instance_id, bool accept) { 543 void BrowserPlugin::OnShouldAcceptTouchEvents(int instance_id, bool accept) {
516 if (container()) { 544 if (container()) {
517 container()->requestTouchEventType(accept ? 545 container()->requestTouchEventType(accept ?
518 WebKit::WebPluginContainer::TouchEventRequestTypeRaw : 546 WebKit::WebPluginContainer::TouchEventRequestTypeRaw :
519 WebKit::WebPluginContainer::TouchEventRequestTypeNone); 547 WebKit::WebPluginContainer::TouchEventRequestTypeNone);
520 } 548 }
521 } 549 }
522 550
523 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) { 551 void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) {
524 UpdateDOMAttribute(browser_plugin::kAttributeName, name); 552 UpdateDOMAttribute(browser_plugin::kAttributeName, name);
525 } 553 }
526 554
555 void BrowserPlugin::RequestMediaPermission(
556 int request_id, const base::DictionaryValue& request_info) {
557 if (!HasEventListeners(browser_plugin::kEventRequestPermission)) {
558 // Automatically deny the request if there are no event listeners for
559 // permissionrequest.
560 AllowPermission(BrowserPlugin::MEDIA, request_id, false /* allow */);
561 return;
562 }
563 DCHECK(!pending_permission_requests_.count(request_id));
564 pending_permission_requests_.insert(
565 std::make_pair(request_id,
566 std::make_pair(request_id, BrowserPlugin::MEDIA)));
567
568 std::map<std::string, base::Value*> props;
569 props[browser_plugin::kPermission] =
570 base::Value::CreateStringValue(browser_plugin::kPermissionTypeMedia);
571 props[browser_plugin::kRequestId] =
572 base::Value::CreateIntegerValue(request_id);
573
574 // Fill in the info provided by the browser.
575 for (DictionaryValue::Iterator iter(request_info); !iter.IsAtEnd();
576 iter.Advance()) {
577 props[iter.key()] = iter.value().DeepCopy();
578 }
579 TriggerEvent(browser_plugin::kEventRequestPermission, &props);
580 }
581
582 bool BrowserPlugin::HasEventListeners(const std::string& event_name) {
583 if (!container())
584 return false;
585
586 for (size_t i = 0; i < ancestors_.size(); ++i) {
587 if (ancestors_[i].hasEventListeners(
588 WebKit::WebString::fromUTF8(event_name))) {
589 return true;
590 }
591 }
592 return false;
593 }
594
527 void BrowserPlugin::OnUpdateRect( 595 void BrowserPlugin::OnUpdateRect(
528 int instance_id, 596 int instance_id,
529 const BrowserPluginMsg_UpdateRect_Params& params) { 597 const BrowserPluginMsg_UpdateRect_Params& params) {
530 bool use_new_damage_buffer = !backing_store_; 598 bool use_new_damage_buffer = !backing_store_;
531 BrowserPluginHostMsg_AutoSize_Params auto_size_params; 599 BrowserPluginHostMsg_AutoSize_Params auto_size_params;
532 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; 600 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params;
533 // If we have a pending damage buffer, and the guest has begun to use the 601 // If we have a pending damage buffer, and the guest has begun to use the
534 // damage buffer then we know the guest will no longer use the current 602 // damage buffer then we know the guest will no longer use the current
535 // damage buffer. At this point, we drop the current damage buffer, and 603 // damage buffer. At this point, we drop the current damage buffer, and
536 // mark the pending damage buffer as the current damage buffer. 604 // mark the pending damage buffer as the current damage buffer.
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 // wrapper/shim (e.g. <webview> tag) should receive these events, and expose a 832 // wrapper/shim (e.g. <webview> tag) should receive these events, and expose a
765 // more appropriate (and stable) event to the consumers as part of the API. 833 // more appropriate (and stable) event to the consumers as part of the API.
766 event.initCustomEvent( 834 event.initCustomEvent(
767 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())), 835 WebKit::WebString::fromUTF8(GetInternalEventName(event_name.c_str())),
768 false, false, 836 false, false,
769 WebKit::WebSerializedScriptValue::serialize( 837 WebKit::WebSerializedScriptValue::serialize(
770 v8::String::New(json_string.c_str(), json_string.size()))); 838 v8::String::New(json_string.c_str(), json_string.size())));
771 container()->element().dispatchEvent(event); 839 container()->element().dispatchEvent(event);
772 } 840 }
773 841
842 void BrowserPlugin::OnRequestObjectGarbageCollected(int request_id) {
843 // Remove from alive objects.
844 std::map<int, AliveV8PermissionRequestItem*>::iterator iter =
845 alive_v8_permission_request_objects.find(request_id);
846 if (iter != alive_v8_permission_request_objects.end()) {
847 DCHECK(iter->second->first == request_id);
848 alive_v8_permission_request_objects.erase(iter);
849 }
850
851 // If a decision has not been made for this request yet, deny it.
852 AllowPermissionIfRequestIsPending(request_id, false /*allow*/);
853 }
854
855 void BrowserPlugin::PersistRequestObject(
856 const NPVariant* request, const std::string& type, int id) {
857 DCHECK(alive_v8_permission_request_objects.find(id) ==
858 alive_v8_permission_request_objects.end());
859 if (alive_v8_permission_request_objects.find(id) !=
860 alive_v8_permission_request_objects.end()) {
861 return;
abarth-chromium 2013/02/14 18:56:53 Why do you both DCHECK and handle this case? It s
lazyboy 2013/02/14 21:47:20 The if () {...} part is what we want, so a request
862 }
863 if (pending_permission_requests_.find(id) ==
864 pending_permission_requests_.end()) {
865 return;
866 }
867
868 v8::Persistent<v8::Value> weak_request =
869 v8::Persistent<v8::Value>::New(WebKit::WebBindings::toV8Value(request));
870
871 AliveV8PermissionRequestItem* new_item =
872 new std::pair<int, base::WeakPtr<BrowserPlugin> >(
873 id, weak_ptr_factory_.GetWeakPtr());
874
875 std::pair<std::map<int, AliveV8PermissionRequestItem*>::iterator, bool>
876 result = alive_v8_permission_request_objects.insert(
877 std::make_pair(id, new_item));
878 DCHECK(result.second); // Inserted in the map.
879 if (result.second) {
abarth-chromium 2013/02/14 18:56:53 Again, you're handling the case of the DCHECK fail
lazyboy 2013/02/14 21:47:20 CHECK is good here. Done.
880 AliveV8PermissionRequestItem* request_item = result.first->second;
881 weak_request.MakeWeak(request_item, WeakCallbackForPersistObject);
882 }
883 }
884
885 // static
886 void BrowserPlugin::WeakCallbackForPersistObject(
887 v8::Persistent<v8::Value> object, void* param) {
888 v8::Persistent<v8::Object> persistent_object =
889 v8::Persistent<v8::Object>::Cast(object);
890
891 AliveV8PermissionRequestItem* item_ptr =
892 static_cast<AliveV8PermissionRequestItem*>(param);
893 int request_id = item_ptr->first;
894 base::WeakPtr<BrowserPlugin> plugin = item_ptr->second;
895 if (plugin)
896 plugin->OnRequestObjectGarbageCollected(request_id);
897 delete item_ptr;
898
899 persistent_object.Dispose();
abarth-chromium 2013/02/14 18:56:53 We usually call Clear() too. I'm not sure if that
lazyboy 2013/02/14 21:47:20 Added Clear(). Made OnRequestObjectGarbaggeCollect
900 }
901
774 void BrowserPlugin::Back() { 902 void BrowserPlugin::Back() {
775 if (!navigate_src_sent_) 903 if (!navigate_src_sent_)
776 return; 904 return;
777 browser_plugin_manager()->Send( 905 browser_plugin_manager()->Send(
778 new BrowserPluginHostMsg_Go(render_view_routing_id_, 906 new BrowserPluginHostMsg_Go(render_view_routing_id_,
779 instance_id_, -1)); 907 instance_id_, -1));
780 } 908 }
781 909
782 void BrowserPlugin::Forward() { 910 void BrowserPlugin::Forward() {
783 if (!navigate_src_sent_) 911 if (!navigate_src_sent_)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 bool embedder_focused = false; 962 bool embedder_focused = false;
835 if (render_view_) 963 if (render_view_)
836 embedder_focused = render_view_->has_focus(); 964 embedder_focused = render_view_->has_focus();
837 return plugin_focused_ && embedder_focused; 965 return plugin_focused_ && embedder_focused;
838 } 966 }
839 967
840 WebKit::WebPluginContainer* BrowserPlugin::container() const { 968 WebKit::WebPluginContainer* BrowserPlugin::container() const {
841 return container_; 969 return container_;
842 } 970 }
843 971
972 void BrowserPlugin::AllowPermission(
973 BrowserPlugin::PermissionRequestType type, int request_id, bool allow) {
974 switch (type) {
975 case BrowserPlugin::MEDIA:
976 browser_plugin_manager()->Send(
977 new BrowserPluginHostMsg_AllowPermission(
978 render_view_->GetRoutingID(), instance_id_,
979 browser_plugin::kPermissionTypeMedia, request_id, allow));
980 break;
981 case BrowserPlugin::INVALID:
982 default:
983 LOG(INFO) << "Not a valid permission type";
984 break;
985 }
986 }
987
988 void BrowserPlugin::AllowPermissionIfRequestIsPending(
989 int request_id, bool allow) {
990 PendingPermissionRequests::iterator iter =
991 pending_permission_requests_.find(request_id);
992 if (iter == pending_permission_requests_.end())
993 return;
994
995 BrowserPlugin::PermissionRequestType type = iter->second.second;
996 pending_permission_requests_.erase(iter);
997 AllowPermission(type, request_id, allow);
998 }
999
1000 void BrowserPlugin::OnEmbedderDecidedPermission(int request_id, bool allow) {
1001 AllowPermissionIfRequestIsPending(request_id, allow);
1002 }
1003
844 bool BrowserPlugin::initialize(WebPluginContainer* container) { 1004 bool BrowserPlugin::initialize(WebPluginContainer* container) {
845 container_ = container; 1005 container_ = container;
846 container_->setWantsWheelEvents(true); 1006 container_->setWantsWheelEvents(true);
1007 // This ancestor set is valid for the lifetime of BrowserPlugin as this object
1008 // does not survive reparenting in the DOM tree.
1009 PopulateAncestorList();
847 ParseAttributes(); 1010 ParseAttributes();
848 return true; 1011 return true;
849 } 1012 }
850 1013
851 void BrowserPlugin::EnableCompositing(bool enable) { 1014 void BrowserPlugin::EnableCompositing(bool enable) {
852 if (compositing_enabled_ == enable) 1015 if (compositing_enabled_ == enable)
853 return; 1016 return;
854 1017
855 compositing_enabled_ = enable; 1018 compositing_enabled_ = enable;
856 if (enable) { 1019 if (enable) {
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 void* notify_data) { 1320 void* notify_data) {
1158 } 1321 }
1159 1322
1160 void BrowserPlugin::didFailLoadingFrameRequest( 1323 void BrowserPlugin::didFailLoadingFrameRequest(
1161 const WebKit::WebURL& url, 1324 const WebKit::WebURL& url,
1162 void* notify_data, 1325 void* notify_data,
1163 const WebKit::WebURLError& error) { 1326 const WebKit::WebURLError& error) {
1164 } 1327 }
1165 1328
1166 } // namespace content 1329 } // 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