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

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: Address comments from fsamuel@ Created 8 years, 2 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 adde725e61b83c614b638541935b9a737c56661b..cc894ed70b8c13d8662b25680042f0073f56c20d 100644
--- a/content/renderer/browser_plugin/browser_plugin.cc
+++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -42,7 +42,10 @@ using WebKit::WebVector;
namespace content {
namespace {
+const char kAllowMediaAccessCallbackName[] = "allow";
const char kCrashEventName[] = "crash";
+const char kDenyMediaAccessCallbackName[] = "deny";
+const char kInstanceIdKey[] = "instance_id";
const char kIsTopLevel[] = "isTopLevel";
const char kLoadAbortEventName[] = "loadAbort";
const char kLoadRedirectEventName[] = "loadRedirect";
@@ -52,9 +55,43 @@ const char kNewURL[] = "newUrl";
const char kOldURL[] = "oldUrl";
const char kPartitionAttribute[] = "partition";
const char kPersistPrefix[] = "persist:";
+const char kPermissionRequestEventName[] = "permissionRequest";
Charlie Reis 2012/10/17 06:18:45 nit: permission < persist
lazyboy 2012/10/17 09:09:53 Done.
+const char kPermissionTypeMedia[] = "media";
+const char kRequestIdKey[] = "request_id";
const char kSrcAttribute[] = "src";
const char kType[] = "type";
const char kURL[] = "url";
+
+void SetMediaAccessPermission(bool allow, const v8::Arguments& args) {
+ int instance_id = -1;
+ int request_id = -1;
+ v8::Local<v8::Value> instance_id_value =
+ args.Callee()->GetHiddenValue(v8::String::New(kInstanceIdKey));
+ v8::Local<v8::Value> request_id_value =
+ args.Callee()->GetHiddenValue(v8::String::New(kRequestIdKey));
+ if (instance_id_value->IsInt32())
+ instance_id = instance_id_value->ToInt32()->Value();
+ if (request_id_value->IsInt32())
+ request_id = request_id_value->ToInt32()->Value();
+
+ DCHECK_NE(instance_id, -1);
+ DCHECK_NE(request_id, -1);
+ BrowserPlugin* plugin =
+ BrowserPluginManager::Get()->GetBrowserPlugin(instance_id);
+ if (plugin)
+ plugin->AllowMediaAccess(request_id, allow);
+}
+
+v8::Handle<v8::Value> OnJsAllowMediaAccess(const v8::Arguments& args) {
+ SetMediaAccessPermission(true /* allow */, args);
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> OnJsDenyMediaAccess(const v8::Arguments& args) {
+ SetMediaAccessPermission(false /* allow */, args);
+ return v8::Undefined();
+}
+
}
BrowserPlugin::BrowserPlugin(
@@ -477,6 +514,75 @@ void BrowserPlugin::SetAcceptTouchEvents(bool accept) {
container()->setIsAcceptingTouchEvents(accept);
}
+void BrowserPlugin::RequestMediaAccess(int request_id) {
+ if (!HasListeners(kPermissionRequestEventName)) {
+ // TODO(lazyboy): Automatically deny request when there is no listener.
Charlie Reis 2012/10/17 06:18:45 Can we go ahead and do this?
lazyboy 2012/10/17 09:09:53 Ah, it is easy to do so now. Done.
+ return;
+ }
+ EventListeners& listeners = event_listener_map_[kPermissionRequestEventName];
+ EventListeners::iterator it = listeners.begin();
+
+ WebKit::WebElement plugin = container()->element();
+ v8::HandleScope handle_scope;
+ v8::Context::Scope context_scope(
+ plugin.document().frame()->mainWorldScriptContext());
+
+ // Set callbacks.
+ // We also save the |instance_id_| and |request_id| in these callbacks. This
+ // is so that we know where to route the callback to when js calls the
+ // callback.
+ //
+ // Javascript:
+ // browser.addEventListener('permissionRequest', function(e) {
+ // e.allow(); // Calls OnJsAllowMediaAccess().
+ // e.deny(); // Calls OnJsDenyMediaAccess().
+ // });
+
+ // Allow callback.
+ v8::Local<v8::Function> allow_function =
+ v8::FunctionTemplate::New(OnJsAllowMediaAccess)->GetFunction();
+ allow_function->SetHiddenValue(v8::String::New(kInstanceIdKey),
+ v8::Int32::New(instance_id_));
+ allow_function->SetHiddenValue(v8::String::New(kRequestIdKey),
+ v8::Int32::New(request_id));
+ // Deny callback.
+ v8::Local<v8::Function> deny_function =
+ v8::FunctionTemplate::New(OnJsDenyMediaAccess)->GetFunction();
+ deny_function->SetHiddenValue(v8::String::New(kInstanceIdKey),
+ v8::Int32::New(instance_id_));
+ deny_function->SetHiddenValue(v8::String::New(kRequestIdKey),
+ v8::Int32::New(request_id));
+
+ // Event object.
+ v8::Local<v8::Value> event =
+ v8::Local<v8::Object>::New(v8::Object::New());
+ // TODO(lazyboy): Also set permission details. Permission details would
+ // include: whether the request was for audio(microphone)/video(webcam)/both.
+ v8::Local<v8::Object>::Cast(event)->Set(
+ v8::String::New(kType), v8::String::New(kPermissionTypeMedia));
+ v8::Local<v8::Object>::Cast(event)->Set(
+ v8::String::New(kAllowMediaAccessCallbackName), allow_function);
+ v8::Local<v8::Object>::Cast(event)->Set(
+ v8::String::New(kDenyMediaAccessCallbackName), deny_function);
+
+ for (; it != listeners.end(); ++it) {
+ // Fire the event listener.
+ container()->element().document().frame()->
+ callFunctionEvenIfScriptDisabled(*it,
+ v8::Object::New(),
+ 1,
+ &event);
+ }
+}
+
+void BrowserPlugin::AllowMediaAccess(int request_id, bool allow) {
+ BrowserPluginManager::Get()->Send(
+ new BrowserPluginHostMsg_AllowMediaAccess(render_view_->GetRoutingID(),
+ instance_id_,
+ request_id,
+ allow));
+}
+
bool BrowserPlugin::HasListeners(const std::string& event_name) {
return event_listener_map_.find(event_name) != event_listener_map_.end();
}

Powered by Google App Engine
This is Rietveld 408576698