Index: content/browser/permissions/permission_service_impl.cc |
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc |
index 795c93b471f24bd7970086f75932463501b7e01f..e14db59381f91229127f7ed183c5f0384b86a32b 100644 |
--- a/content/browser/permissions/permission_service_impl.cc |
+++ b/content/browser/permissions/permission_service_impl.cc |
@@ -5,6 +5,8 @@ |
#include "content/browser/permissions/permission_service_impl.h" |
#include "base/bind.h" |
+#include "content/browser/permissions/permission_pending_multiple_request.h" |
+#include "content/browser/permissions/permission_pending_single_request.h" |
#include "content/public/browser/browser_context.h" |
#include "content/public/browser/permission_manager.h" |
#include "content/public/browser/permission_type.h" |
@@ -33,20 +35,6 @@ PermissionType PermissionNameToPermissionType(PermissionName name) { |
} // anonymous namespace |
-PermissionServiceImpl::PendingRequest::PendingRequest( |
- PermissionType permission, |
- const GURL& origin, |
- const PermissionStatusCallback& callback) |
- : permission(permission), |
- origin(origin), |
- callback(callback) { |
-} |
- |
-PermissionServiceImpl::PendingRequest::~PendingRequest() { |
- if (!callback.is_null()) |
- callback.Run(PERMISSION_STATUS_ASK); |
-} |
- |
PermissionServiceImpl::PendingSubscription::PendingSubscription( |
PermissionType permission, |
const GURL& origin, |
@@ -109,8 +97,11 @@ void PermissionServiceImpl::RequestPermission( |
} |
PermissionType permission_type = PermissionNameToPermissionType(permission); |
- int request_id = pending_requests_.Add( |
- new PendingRequest(permission_type, GURL(origin), callback)); |
+ |
+ PermissionPendingSingleRequest* request = |
+ new PermissionPendingSingleRequest( |
+ permission_type, GURL(origin), callback); |
+ int request_id = pending_requests_.Add(request); |
browser_context->GetPermissionManager()->RequestPermission( |
permission_type, |
@@ -120,19 +111,95 @@ void PermissionServiceImpl::RequestPermission( |
user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) |
base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, |
weak_factory_.GetWeakPtr(), |
- request_id)); |
+ request_id, |
+ request)); |
+} |
+ |
+void PermissionServiceImpl::RequestPermissions( |
+ mojo::Array<PermissionName> permissions, |
+ const mojo::String& origin, |
+ bool user_gesture, |
+ const PermissionsStatusCallback& callback) { |
+ if (permissions.is_null()) { |
+ callback.Run(mojo::Array<PermissionStatus>()); |
+ return; |
+ } |
+ |
+ // This condition is valid if the call is coming from a ChildThread instead of |
+ // a RenderFrame. Some consumers of the service run in Workers and some in |
+ // Frames. In the context of a Worker, it is not possible to show a |
+ // permission prompt because there is no tab. In the context of a Frame, we |
+ // can. Even if the call comes from a context where it is not possible to show |
+ // any UI, we want to still return something relevant so the current |
+ // permission status is returned for each permission. |
+ if (!context_->render_frame_host()) { |
+ mojo::Array<PermissionStatus> result(permissions.size()); |
+ for (size_t i = 0; i < permissions.size(); ++i) { |
+ result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin)); |
+ } |
+ callback.Run(result.Pass()); |
+ return; |
+ } |
+ |
+ BrowserContext* browser_context = context_->GetBrowserContext(); |
+ DCHECK(browser_context); |
+ if (!browser_context->GetPermissionManager()) { |
+ mojo::Array<PermissionStatus> result(permissions.size()); |
+ for (size_t i = 0; i < permissions.size(); ++i) { |
+ result[i] = PERMISSION_STATUS_DENIED; |
+ } |
+ callback.Run(result.Pass()); |
+ return; |
+ } |
+ |
+ std::vector<PermissionType> permission_types; |
+ permission_types.reserve(permissions.size()); |
+ for (size_t i = 0; i < permissions.size(); ++i) { |
+ permission_types.push_back( |
+ PermissionNameToPermissionType(permissions[i])); |
+ } |
+ PermissionPendingMultipleRequest* request = |
+ new PermissionPendingMultipleRequest(callback, permissions.size()); |
+ int request_id = pending_requests_.Add(request); |
+ |
+ browser_context->GetPermissionManager()->RequestPermissions( |
+ permission_types, |
+ context_->render_frame_host(), |
+ request_id, |
+ GURL(origin), |
+ user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) |
+ base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse, |
+ weak_factory_.GetWeakPtr(), |
+ request_id, |
+ request)); |
} |
void PermissionServiceImpl::OnRequestPermissionResponse( |
int request_id, |
+ PermissionPendingSingleRequest* request, |
PermissionStatus status) { |
- PendingRequest* request = pending_requests_.Lookup(request_id); |
PermissionStatusCallback callback(request->callback); |
request->callback.reset(); |
pending_requests_.Remove(request_id); |
+ |
callback.Run(status); |
} |
+void PermissionServiceImpl::OnRequestPermissionsResponse( |
+ int request_id, |
+ PermissionPendingMultipleRequest* request, |
+ const std::vector<PermissionStatus>& status) { |
+ PermissionsStatusCallback callback(request->callback); |
+ request->callback.reset(); |
+ pending_requests_.Remove(request_id); |
+ |
+ mojo::Array<PermissionStatus> status_array(status.size()); |
+ for (size_t i = 0; i < status.size(); i++) { |
+ status_array[i] = status[i]; |
+ } |
+ callback.Run(status_array.Pass()); |
+} |
+ |
void PermissionServiceImpl::CancelPendingOperations() { |
DCHECK(context_->render_frame_host()); |
DCHECK(context_->GetBrowserContext()); |
@@ -143,13 +210,11 @@ void PermissionServiceImpl::CancelPendingOperations() { |
return; |
// Cancel pending requests. |
- for (RequestsMap::Iterator<PendingRequest> it(&pending_requests_); |
+ for (RequestsMap::Iterator<PermissionPendingRequest> it(&pending_requests_); |
!it.IsAtEnd(); it.Advance()) { |
- permission_manager->CancelPermissionRequest( |
- it.GetCurrentValue()->permission, |
- context_->render_frame_host(), |
- it.GetCurrentKey(), |
- it.GetCurrentValue()->origin); |
+ it.GetCurrentValue()->Cancel(permission_manager, |
+ context_->render_frame_host(), |
+ it.GetCurrentKey()); |
} |
pending_requests_.Clear(); |