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

Unified 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: Remove hanging request on garbage collection, yay! 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/browser_plugin/browser_plugin.cc
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc
index 0dbc53fe80a50dc306b41a135f9f866d77bab3ff..73a6a828e1153b590cc210511f7b753434bbd5ee 100644
--- a/content/renderer/browser_plugin/browser_plugin.cc
+++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -134,6 +134,8 @@ bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) {
OnShouldAcceptTouchEvents)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdatedName, OnUpdatedName)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdateRect, OnUpdateRect)
+ IPC_MESSAGE_HANDLER(BrowserPluginMsg_RequestMediaAccess,
+ OnRequestMediaAccess)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -535,6 +537,43 @@ void BrowserPlugin::OnUpdatedName(int instance_id, const std::string& name) {
UpdateDOMAttribute(browser_plugin::kAttributeName, name);
}
+void BrowserPlugin::OnRequestMediaAccess(int instance_id,
+ int request_id,
+ const GURL& security_origin) {
+ if (!HasEventListeners(browser_plugin::kEventRequestPermission)) {
+ // Automatically deny the request if there are no event listeners for
+ // permissionrequest.
+ RespondMediaAccess(request_id, false /* allow */);
+ return;
+ }
+ DCHECK(!media_access_pending_request_ids_.count(request_id));
+ media_access_pending_request_ids_.insert(request_id);
+
+ std::map<std::string, base::Value*> props;
+ props[browser_plugin::kPermission] =
+ base::Value::CreateStringValue(browser_plugin::kPermissionTypeMedia);
+ props[browser_plugin::kRequestId] =
+ base::Value::CreateIntegerValue(request_id);
+ props[browser_plugin::kURL] =
+ base::Value::CreateStringValue(security_origin.spec());
+ TriggerEvent(browser_plugin::kEventRequestPermission, &props);
+}
+
+bool BrowserPlugin::HasEventListeners(const std::string& event_name) {
+ if (!container())
+ return false;
+
+ // TODO(lazyboy): Fix before submitting: use ancestor list instead similar to
+ // window.open CL, so bubbling is supported.
+ WebKit::WebNode parent = container()->element().parentNode();
+ if (!parent.isNull() && !parent.shadowHost().isNull()) {
+ WebKit::WebElement shadow_host = parent.shadowHost();
+ return shadow_host.hasEventListeners(
+ WebKit::WebString::fromUTF8(event_name));
+ }
+ return false;
+}
+
void BrowserPlugin::OnUpdateRect(
int instance_id,
const BrowserPluginMsg_UpdateRect_Params& params) {
@@ -782,6 +821,51 @@ void BrowserPlugin::TriggerEvent(const std::string& event_name,
container()->element().dispatchEvent(event);
}
+void BrowserPlugin::OnMediaRequestGarbageCollected(int request_id) {
+ // Remove from alive objects.
+ std::map<int, MediaAccessAliveV8RequestItem*>::iterator iter =
+ media_access_alive_v8_request_objects_.find(request_id);
+ if (iter != media_access_alive_v8_request_objects_.end()) {
+ MediaAccessAliveV8RequestItem* item = iter->second;
+ DCHECK(*item->first == request_id);
+ media_access_alive_v8_request_objects_.erase(iter);
+ delete item->first;
+ }
+
+ // If a decision has not been made for this request yet, deny it.
+ RespondMediaAccessIfPending(request_id, false /* allow */);
+}
+
+void BrowserPlugin::PersistRequestObject(const NPVariant* request, int id) {
Fady Samuel 2013/02/07 15:40:34 Can we make this more general to allow for window.
lazyboy 2013/02/07 21:24:41 We need a centralized id generation in that case,
+ v8::Persistent<v8::Value> weak_request =
+ v8::Persistent<v8::Value>::New(WebKit::WebBindings::toV8Value(request));
+ int *new_request_id = new int(id);
Fady Samuel 2013/02/07 15:40:34 why are you allocating memory on the heap here? We
lazyboy 2013/02/07 21:24:41 I thought reference to map element is not guarante
+ std::pair<int*, BrowserPlugin*>* req =
+ new std::pair<int*, BrowserPlugin*>(
+ std::make_pair(new_request_id, this));
+ DCHECK(media_access_alive_v8_request_objects_.find(id) ==
+ media_access_alive_v8_request_objects_.end());
+ if (media_access_alive_v8_request_objects_.find(id) ==
+ media_access_alive_v8_request_objects_.end()) {
+ media_access_alive_v8_request_objects_[*new_request_id] = req;
+ weak_request.MakeWeak(req, WeakCallbackForPersistObject);
+ }
+}
+
+void BrowserPlugin::WeakCallbackForPersistObject(
+ v8::Persistent<v8::Value> object, void* param) {
+ v8::Persistent<v8::Object> persistent_object =
+ v8::Persistent<v8::Object>::Cast(object);
+
+ MediaAccessAliveV8RequestItem* item_ptr =
+ static_cast<std::pair<int*, BrowserPlugin*>*>(param);
Fady Samuel 2013/02/07 15:40:34 We're leaking memory here. Seem my suggestion abov
lazyboy 2013/02/07 21:24:41 See above, fixed hopefully.
+ int request_id = *(item_ptr->first);
+ BrowserPlugin* plugin = item_ptr->second;
+ plugin->OnMediaRequestGarbageCollected(request_id);
+
+ persistent_object.Dispose();
+}
+
void BrowserPlugin::Back() {
if (!navigate_src_sent_)
return;
@@ -852,6 +936,25 @@ WebKit::WebPluginContainer* BrowserPlugin::container() const {
return container_;
}
+void BrowserPlugin::RespondMediaAccess(int request_id, bool allow) {
+ browser_plugin_manager()->Send(
+ new BrowserPluginHostMsg_AllowMediaAccess(
Fady Samuel 2013/02/07 15:40:34 Given the review overhead for introducing new IPCs
lazyboy 2013/02/07 21:24:41 This part should be straight forward. Done.
+ render_view_->GetRoutingID(), instance_id_, request_id, allow));
+}
+
+void BrowserPlugin::RespondMediaAccessIfPending(int request_id, bool allow) {
+ MediaAccessPendingRequestIds::iterator iter =
+ media_access_pending_request_ids_.find(request_id);
+ if (iter == media_access_pending_request_ids_.end())
+ return;
+ media_access_pending_request_ids_.erase(iter);
+ RespondMediaAccess(request_id, allow);
+}
+
+void BrowserPlugin::OnListenerCallMediaAccess(int request_id, bool allow) {
+ RespondMediaAccessIfPending(request_id, allow);
+}
+
bool BrowserPlugin::initialize(WebPluginContainer* container) {
container_ = container;
container_->setWantsWheelEvents(true);

Powered by Google App Engine
This is Rietveld 408576698