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

Unified Diff: content/browser/permissions/permission_service_impl.cc

Issue 1260193009: renderer: implement multiple permission requesting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@permissions-request-multiple
Patch Set: Merge patches Created 5 years, 4 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/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();

Powered by Google App Engine
This is Rietveld 408576698