Chromium Code Reviews| 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 033330beb599edd8573bef41fd3c71d384f2c2a9..f1e8f8f267a1f43b4307b88e48d1a9e7d7162771 100644 |
| --- a/content/renderer/browser_plugin/browser_plugin.cc |
| +++ b/content/renderer/browser_plugin/browser_plugin.cc |
| @@ -54,6 +54,7 @@ const char kEventLoadCommit[] = "loadcommit"; |
| const char kEventLoadRedirect[] = "loadredirect"; |
| const char kEventLoadStart[] = "loadstart"; |
| const char kEventLoadStop[] = "loadstop"; |
| +const char kEventRequestPermission[] = "permissionrequest"; |
| const char kEventResponsive[] = "responsive"; |
| const char kEventSizeChanged[] = "sizechanged"; |
| const char kEventUnresponsive[] = "unresponsive"; |
| @@ -67,9 +68,12 @@ const char kOldURL[] = "oldUrl"; |
| const char kOldHeight[] = "oldHeight"; |
| const char kOldWidth[] = "oldWidth"; |
| const char kPartition[] = "partition"; |
| +const char kPermission[] = "permission"; |
| +const char kPermissionTypeMedia[] = "media"; |
| const char kPersistPrefix[] = "persist:"; |
| const char kProcessId[] = "processId"; |
| const char kReason[] = "reason"; |
| +const char kRequestId[] = "request_id"; |
| const char kSrc[] = "src"; |
| const char kURL[] = "url"; |
| @@ -678,6 +682,41 @@ void BrowserPlugin::LoadAbort(const GURL& url, |
| TriggerEvent(kEventLoadAbort, &props); |
| } |
| +void BrowserPlugin::RequestMediaAccess(int request_id, |
| + const GURL& security_origin) { |
| + size_t num_listeners = GetNumberOfEventListeners(kEventRequestPermission); |
| + if (!num_listeners) { |
| + // Automatically deny the request if there are no event listeners for |
| + // permissionrequest. |
| + RespondMediaAccess(request_id, false /* allow */); |
| + return; |
| + } |
| + DCHECK(media_access_pending_counts_.find(request_id) == |
| + media_access_pending_counts_.end()); |
| + media_access_pending_counts_[request_id] = num_listeners; |
| + |
| + std::map<std::string, base::Value*> props; |
| + props[kPermission] = base::Value::CreateStringValue(kPermissionTypeMedia); |
| + props[kRequestId] = base::Value::CreateIntegerValue(request_id); |
| + props[kURL] = base::Value::CreateStringValue(security_origin.spec()); |
| + TriggerEvent(kEventRequestPermission, &props); |
| +} |
| + |
| +size_t BrowserPlugin::GetNumberOfEventListeners(const std::string& event_name) { |
| + if (!container()) |
| + return 0; |
| + |
| + WebKit::WebNode parent = container()->element().parentNode(); |
| + if (!parent.isNull() && parent.isShadowRoot()) { |
| + WebKit::WebElement shadow_host = parent.shadowHost(); |
| + if (!shadow_host.isNull()) { |
| + return shadow_host.numberOfEventListeners( |
| + WebKit::WebString::fromUTF8(event_name)); |
| + } |
| + } |
| + return 0; |
| +} |
| + |
| void BrowserPlugin::LoadRedirect(const GURL& old_url, |
| const GURL& new_url, |
| bool is_top_level) { |
| @@ -731,6 +770,34 @@ void BrowserPlugin::SetAcceptTouchEvents(bool accept) { |
| } |
| } |
| +void BrowserPlugin::RespondMediaAccess(int request_id, bool allow) { |
| + browser_plugin_manager()->Send( |
| + new BrowserPluginHostMsg_AllowMediaAccess(render_view_->GetRoutingID(), |
| + instance_id_, |
| + request_id, |
| + allow)); |
| +} |
| + |
| +void BrowserPlugin::OnListenerCallMediaAccess(int request_id, bool allow) { |
| + MediaAccessPendingCountsMap::iterator iter = |
| + media_access_pending_counts_.find(request_id); |
| + if (iter == media_access_pending_counts_.end()) |
| + return; |
| + DCHECK(iter->second > 0); |
| + // If there were n listeners registered for media access permissionrequest, we |
| + // require n allow() calls to allow the request. |
| + // TODO(lazyboy): Figure out a way to track that each listener calls allow() |
| + // at least once. Right now we only check for total number of allow() calls, |
| + // which means a single listener calling allow() enough/multiple times can |
| + // incorrectly allow the request. |
|
Charlie Reis
2012/12/17 22:28:09
Yeah, that's no good. Ideally there would be some
|
| + if (!allow || iter->second == 1) { |
| + media_access_pending_counts_.erase(iter); |
| + RespondMediaAccess(request_id, allow); |
| + } else { |
| + iter->second--; |
| + } |
| +} |
| + |
| WebKit::WebPluginContainer* BrowserPlugin::container() const { |
| return container_; |
| } |