Index: content/child/permissions/permission_dispatcher.cc |
diff --git a/content/child/permissions/permission_dispatcher.cc b/content/child/permissions/permission_dispatcher.cc |
index 3e7912697678e10f1cf1141b283f63280607a138..c9a67781a741d6600f8f2208af49c4daf98c270c 100644 |
--- a/content/child/permissions/permission_dispatcher.cc |
+++ b/content/child/permissions/permission_dispatcher.cc |
@@ -102,6 +102,14 @@ void PermissionDispatcher::requestPermission( |
type, origin.string().utf8(), callback, kNoWorkerThread); |
} |
+void PermissionDispatcher::requestPermissions( |
+ const blink::WebVector<blink::WebPermissionType>& types, |
+ const blink::WebURL& origin, |
+ blink::WebPermissionsCallback* callback) { |
+ RequestPermissionsInternal( |
+ types, origin.string().utf8(), callback, kNoWorkerThread); |
+} |
+ |
void PermissionDispatcher::revokePermission( |
blink::WebPermissionType type, |
const blink::WebURL& origin, |
@@ -151,6 +159,14 @@ void PermissionDispatcher::RequestPermissionForWorker( |
RequestPermissionInternal(type, origin, callback, worker_thread_id); |
} |
+void PermissionDispatcher::RequestPermissionsForWorker( |
+ const blink::WebVector<blink::WebPermissionType>& types, |
+ const std::string& origin, |
+ blink::WebPermissionsCallback* callback, |
+ int worker_thread_id) { |
+ RequestPermissionsInternal(types, origin, callback, worker_thread_id); |
+} |
+ |
void PermissionDispatcher::RevokePermissionForWorker( |
blink::WebPermissionType type, |
const std::string& origin, |
@@ -202,6 +218,13 @@ void PermissionDispatcher::RunCallbackOnWorkerThread( |
delete callback; |
} |
+void PermissionDispatcher::RunMultiCallbackOnWorkerThread( |
+ blink::WebPermissionsCallback* callback, |
+ scoped_ptr<blink::WebVector<blink::WebPermissionStatus>> statuses) { |
+ callback->onSuccess(blink::adoptWebPtr(statuses.release())); |
+ delete callback; |
+} |
+ |
PermissionServicePtr& PermissionDispatcher::GetPermissionServicePtr() { |
if (!permission_service_.get()) { |
service_registry_->ConnectToRemoteService( |
@@ -255,6 +278,33 @@ void PermissionDispatcher::RequestPermissionInternal( |
callback_key)); |
} |
+void PermissionDispatcher::RequestPermissionsInternal( |
+ const blink::WebVector<blink::WebPermissionType>& types, |
+ const std::string& origin, |
+ blink::WebPermissionsCallback* callback, |
+ int worker_thread_id) { |
+ // We need to save the |callback| in an ScopedVector so if |this| gets |
+ // deleted, the callback will not leak. In the case of |this| gets deleted, |
+ // the |permission_service_| pipe will be destroyed too so OnQueryPermission |
+ // will not be called. |
+ uintptr_t callback_key = reinterpret_cast<uintptr_t>(callback); |
+ batch_pending_callbacks_.add(callback_key, |
+ scoped_ptr<blink::WebPermissionsCallback>(callback)); |
+ |
+ mojo::Array<PermissionName> names(types.size()); |
+ for (size_t i = 0; i < types.size(); ++i) |
+ names[i] = GetPermissionName(types[i]); |
+ |
+ GetPermissionServicePtr()->RequestBatchPermission( |
+ names.Pass(), |
+ origin, |
+ blink::WebUserGestureIndicator::isProcessingUserGesture(), |
+ base::Bind(&PermissionDispatcher::OnPermissionsResponse, |
+ base::Unretained(this), |
+ worker_thread_id, |
+ callback_key)); |
+} |
+ |
void PermissionDispatcher::RevokePermissionInternal( |
blink::WebPermissionType type, |
const std::string& origin, |
@@ -303,6 +353,35 @@ void PermissionDispatcher::OnPermissionResponse( |
pending_callbacks_.erase(callback_key); |
} |
+void PermissionDispatcher::OnPermissionsResponse( |
+ int worker_thread_id, |
+ uintptr_t callback_key, |
+ const mojo::Array<PermissionStatus>& result) { |
+ blink::WebPermissionsCallback* callback = |
+ batch_pending_callbacks_.get(callback_key); |
+ scoped_ptr<blink::WebVector<blink::WebPermissionStatus>> statuses( |
+ new blink::WebVector<blink::WebPermissionStatus>(result.size())); |
+ |
+ for (size_t i = 0; i < result.size(); i++) |
+ statuses->operator[](i) = GetWebPermissionStatus(result[i]); |
+ |
+ if (worker_thread_id != kNoWorkerThread) { |
+ batch_pending_callbacks_.take_and_erase(callback_key); |
+ |
+ // If the worker is no longer running, ::PostTask() will return false and |
+ // gracefully fail, destroying the callback too. |
+ WorkerTaskRunner::Instance()->PostTask( |
+ worker_thread_id, |
+ base::Bind(&PermissionDispatcher::RunMultiCallbackOnWorkerThread, |
+ base::Unretained(callback), |
+ base::Passed(&statuses))); |
+ return; |
+ } |
+ |
+ callback->onSuccess(blink::adoptWebPtr(statuses.release())); |
+ batch_pending_callbacks_.erase(callback_key); |
+} |
+ |
void PermissionDispatcher::OnPermissionChanged( |
blink::WebPermissionType type, |
const std::string& origin, |