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

Unified Diff: chrome/browser/permissions/permission_manager.cc

Issue 1316863010: browser: implement multiple permission requesting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@request-multiple-content
Patch Set: Cut down on CL size Created 5 years, 3 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: chrome/browser/permissions/permission_manager.cc
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc
index 2422d1b170b59ff58ed59115b00421499874be8f..cc3e01d883b7c0a9dc3fe3a199c7d06783c0c38c 100644
--- a/chrome/browser/permissions/permission_manager.cc
+++ b/chrome/browser/permissions/permission_manager.cc
@@ -78,6 +78,13 @@ ContentSettingsType PermissionTypeToContentSetting(PermissionType permission) {
return CONTENT_SETTINGS_TYPE_DEFAULT;
}
+void PermissionRequestResponseCallbackWrapper(
+ const base::Callback<void(PermissionStatus)>& callback,
+ const std::vector<PermissionStatus>& vector) {
+ DCHECK(vector.size() == 1);
+ callback.Run(vector[0]);
+}
+
// Returns whether the permission has a constant PermissionStatus value (i.e.
// always approved or always denied)
// The PermissionTypes for which true is returned should be exactly those which
@@ -114,7 +121,38 @@ PermissionStatus GetPermissionStatusForConstantPermission(PermissionType type) {
} // anonymous namespace
struct PermissionManager::PendingRequest {
- PermissionType permission;
+ const GURL requesting_origin;
+ const size_t count;
+ size_t pending;
+ const base::Callback<void(
+ const std::vector<PermissionStatus>&)> callback;
+
+ const std::vector<PermissionType> permissions;
+ std::vector<PermissionStatus> result;
+
+ PendingRequest(const GURL& requesting_origin,
+ const std::vector<PermissionType> permissions,
+ const base::Callback<void(
+ const std::vector<PermissionStatus>&)>& callback)
+ : requesting_origin(requesting_origin),
+ count(permissions.size()),
+ pending(permissions.size()),
+ callback(callback),
+ permissions(permissions),
+ result(permissions.size(), content::PERMISSION_STATUS_DENIED) {
+ }
+
+ // Returns if there are no pending permission requests.
+ bool SetPermission(int index, PermissionStatus status) {
+ PermissionType current_type = permissions[index];
+ for (size_t i = index; i < count; ++i) {
+ if (permissions[i] != current_type)
+ continue;
+ result[i] = status;
+ pending -= 1;
+ }
+ return pending == 0;
+ }
};
struct PermissionManager::Subscription {
@@ -141,29 +179,41 @@ int PermissionManager::RequestPermission(
const GURL& requesting_origin,
bool user_gesture,
const base::Callback<void(PermissionStatus)>& callback) {
- if (IsConstantPermission(permission)) {
- callback.Run(GetPermissionStatusForConstantPermission(permission));
- return -1;
- }
+ return RequestPermissionsInternal(
+ std::vector<PermissionType>(1, permission),
+ render_frame_host,
+ requesting_origin,
+ user_gesture,
+ base::Bind(&PermissionRequestResponseCallbackWrapper, callback));
+}
- PermissionContextBase* context = PermissionContext::Get(profile_, permission);
- if (!context) {
- callback.Run(content::PERMISSION_STATUS_DENIED);
- return -1;
- }
+int PermissionManager::RequestPermissions(
+ const std::vector<PermissionType>& permissions,
+ content::RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<void(
+ const std::vector<PermissionStatus>&)>& callback) {
+ return RequestPermissionsInternal(
+ permissions,
+ render_frame_host,
+ requesting_origin,
+ user_gesture,
+ callback);
+}
+int PermissionManager::RequestPermissionsInternal(
+ const std::vector<PermissionType>& permissions,
+ content::RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<void(
+ const std::vector<PermissionStatus>&)>& callback) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
- if (IsPermissionBubbleManagerMissing(web_contents)) {
- callback.Run(
- GetPermissionStatus(permission, requesting_origin,
- web_contents->GetLastCommittedURL().GetOrigin()));
- return -1;
- }
- PendingRequest* pending_request = new PendingRequest();
- pending_request->permission = permission;
- int request_id = pending_requests_.Add(pending_request);
+ int request_id = pending_requests_.Add(new PendingRequest(
+ requesting_origin, permissions, callback));
int render_process_id = render_frame_host->GetProcess()->GetID();
int render_frame_id = render_frame_host->GetRoutingID();
@@ -171,21 +221,56 @@ int PermissionManager::RequestPermission(
render_frame_id,
request_id);
- context->RequestPermission(
- web_contents, request, requesting_origin, user_gesture,
- base::Bind(&PermissionManager::OnPermissionRequestResponse,
- weak_ptr_factory_.GetWeakPtr(),
- request_id,
- callback));
+ bool seen_types[static_cast<int>(PermissionType::NUM)] = { false };
+ for (size_t i = 0; i < permissions.size(); ++i) {
+ const PermissionType current_type = permissions[i];
+ if (seen_types[static_cast<int>(current_type)])
+ continue;
+ seen_types[static_cast<int>(current_type)] = true;
+
+ if (IsConstantPermission(current_type) ||
+ IsPermissionBubbleManagerMissing(web_contents)) {
+ OnPermissionRequestResponseInternal(
+ request_id, i, GetPermissionStatus(current_type, requesting_origin,
+ web_contents->GetLastCommittedURL().GetOrigin()));
+ continue;
+ }
+
+ PermissionContextBase* context =
+ PermissionContext::Get(profile_, current_type);
+ if (!context) {
+ OnPermissionRequestResponseInternal(
+ request_id, i, content::PERMISSION_STATUS_DENIED);
+ continue;
+ }
+
+ context->RequestPermission(
+ content::WebContents::FromRenderFrameHost(render_frame_host),
+ request, requesting_origin, user_gesture,
+ base::Bind(&PermissionManager::OnPermissionRequestResponse,
+ weak_ptr_factory_.GetWeakPtr(), request_id, i));
+ }
return request_id;
}
void PermissionManager::OnPermissionRequestResponse(
int request_id,
- const base::Callback<void(PermissionStatus)>& callback,
+ int request_index,
ContentSetting content_setting) {
- pending_requests_.Remove(request_id);
- callback.Run(ContentSettingToPermissionStatus(content_setting));
+ OnPermissionRequestResponseInternal(request_id, request_index,
+ ContentSettingToPermissionStatus(content_setting));
+}
+
+void PermissionManager::OnPermissionRequestResponseInternal(
+ int request_id,
+ int request_index,
+ PermissionStatus status) {
+ PendingRequest* pending_request = pending_requests_.Lookup(request_id);
+ bool finished = pending_request->SetPermission(request_index, status);
+ if (finished) {
+ pending_request->callback.Run(pending_request->result);
+ pending_requests_.Remove(request_id);
+ }
}
void PermissionManager::CancelPermissionRequest(
@@ -195,12 +280,6 @@ void PermissionManager::CancelPermissionRequest(
if (!pending_request)
return;
- PermissionContextBase* context = PermissionContext::Get(
- profile_, pending_request->permission);
- pending_requests_.Remove(request_id);
- if (!context)
- return;
-
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
if (IsPermissionBubbleManagerMissing(web_contents))
@@ -211,8 +290,14 @@ void PermissionManager::CancelPermissionRequest(
const PermissionRequestID request(render_process_id,
render_frame_id,
request_id);
-
- context->CancelPermissionRequest(web_contents, request);
+ for (size_t i = 0; i < pending_request->count; ++i) {
+ PermissionContextBase* context = PermissionContext::Get(
+ profile_, pending_request->permissions[i]);
+ if (!context)
+ continue;
+ context->CancelPermissionRequest(web_contents, request);
+ }
+ pending_requests_.Remove(request_id);
}
void PermissionManager::ResetPermission(PermissionType permission,

Powered by Google App Engine
This is Rietveld 408576698