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

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

Issue 1260193009: renderer: implement multiple permission requesting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@permissions-request-multiple
Patch Set: 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: chrome/browser/permissions/permission_manager.cc
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc
index 690730477b049c7be22a8fc46577aab3ed63993a..ea8d2a55cd73224089920773681091c701cf4891 100644
--- a/chrome/browser/permissions/permission_manager.cc
+++ b/chrome/browser/permissions/permission_manager.cc
@@ -111,6 +111,22 @@ PermissionStatus GetPermissionStatusForConstantPermission(
} // anonymous namespace
+struct PermissionManager::PendingResponse {
+ PermissionType type;
+ PermissionStatus status;
+
+ PendingResponse(PermissionType type, PermissionStatus status)
+ : type(type), status(status) {
+ }
+};
+
+struct PermissionManager::PendingResponses {
+ GURL requesting_origin;
+ size_t count;
+ size_t pending;
+ std::vector<PendingResponse> responses;
+};
+
struct PermissionManager::Subscription {
PermissionType permission;
GURL requesting_origin;
@@ -120,7 +136,8 @@ struct PermissionManager::Subscription {
};
PermissionManager::PermissionManager(Profile* profile)
- : profile_(profile) {
+ : profile_(profile),
+ weak_ptr_factory_(this) {
}
PermissionManager::~PermissionManager() {
@@ -160,6 +177,98 @@ void PermissionManager::RequestPermission(
callback));
}
+void PermissionManager::RequestPermissions(
+ const std::vector<PermissionType>& permissions,
+ content::RenderFrameHost* render_frame_host,
+ int request_id,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<void(const StatusVector&)>& callback) {
+ int render_process_id = render_frame_host->GetProcess()->GetID();
+ int render_frame_id = render_frame_host->GetRoutingID();
+ const PermissionRequestID request(render_process_id,
+ render_frame_id,
+ request_id,
+ requesting_origin);
+
+ // Pass complete control of the scoped pointer to the map.
+ // Locally we will use the raw pointer and the response will be removed from
+ // the map once all the responses return.
+ scoped_ptr<PendingResponses> scoped_response(new PendingResponses());
+ PendingResponses* pending_responses = scoped_response.get();
+ pending_batch_responses_.add(request_id, scoped_response.Pass());
+
+ pending_responses->requesting_origin = requesting_origin;
+ pending_responses->count = permissions.size();
+ pending_responses->pending = permissions.size();
+
+ for (size_t i = 0; i < permissions.size(); ++i) {
+ pending_responses->responses.emplace_back(
+ permissions[i],
+ content::PERMISSION_STATUS_DENIED);
+ }
+
+ // The pending responses should all be added to the vector before running
+ // this loop so duplicate permissions are handled properly.
+ bool seen_types[static_cast<int>(PermissionType::NUM)] = { false };
+ for (size_t i = 0; i < permissions.size(); ++i) {
+ const PermissionType current_type = permissions[i];
+ const int current_type_index = static_cast<int>(current_type);
+ if (seen_types[current_type_index])
+ continue;
+ seen_types[current_type_index] = true;
+
+ if (IsConstantPermission(current_type)) {
+ OnRequestsResponse(callback, request, pending_responses, i,
+ GetContentSettingForConstantPermission(current_type));
+ continue;
+ }
+
+ PermissionContextBase* context =
+ PermissionContext::Get(profile_, current_type);
+ if (!context) {
+ OnRequestsResponse(callback, request, pending_responses, i,
+ CONTENT_SETTING_BLOCK);
+ continue;
+ }
+ context->RequestPermission(
+ content::WebContents::FromRenderFrameHost(render_frame_host),
+ request, requesting_origin, user_gesture,
+ base::Bind(&PermissionManager::OnRequestsResponse,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback,
+ request,
+ pending_responses,
+ i));
+ }
+}
+
+void PermissionManager::OnRequestsResponse(
+ const base::Callback<void(const StatusVector&)>& callback,
+ const PermissionRequestID request,
+ PendingResponses* pending_responses,
+ int index,
+ ContentSetting content_setting) {
+ PendingResponse& response = pending_responses->responses[index];
+ response.status = ContentSettingToPermissionStatus(content_setting);
+
+ for (size_t i = index + 1; i < pending_responses->responses.size(); ++i) {
+ if (pending_responses->responses[i].type == response.type) {
+ pending_responses->responses[i].status = response.status;
+ --pending_responses->pending;
+ }
+ }
+
+ if (--pending_responses->pending == 0) {
mlamouri (slow - plz ping) 2015/08/18 13:37:15 shrug... please don't do that :)
Lalit Maganti 2015/08/20 14:23:30 Haha I thought this might be a bit amusing :) Cha
+ std::vector<PermissionStatus> status;
+ for (auto response : pending_responses->responses) {
+ status.push_back(response.status);
+ }
+ pending_batch_responses_.erase(request.request_id());
+ callback.Run(status);
+ }
+}
+
void PermissionManager::CancelPermissionRequest(
PermissionType permission,
content::RenderFrameHost* render_frame_host,
@@ -180,6 +289,30 @@ void PermissionManager::CancelPermissionRequest(
content::WebContents::FromRenderFrameHost(render_frame_host), request);
}
+void PermissionManager::CancelPermissionsRequest(
+ content::RenderFrameHost* render_frame_host,
+ int request_id) {
+ PendingResponses* pending_responses =
+ pending_batch_responses_.get(request_id);
+
+ int render_process_id = render_frame_host->GetProcess()->GetID();
+ int render_frame_id = render_frame_host->GetRoutingID();
+ const PermissionRequestID request(render_process_id,
+ render_frame_id,
+ request_id,
+ pending_responses->requesting_origin);
+
+ for (size_t i = 0; i < pending_responses->count; ++i) {
+ PermissionType type = pending_responses->responses[i].type;
+ PermissionContextBase* context = PermissionContext::Get(profile_, type);
+ if (!context) continue;
+
+ context->CancelPermissionRequest(
+ content::WebContents::FromRenderFrameHost(render_frame_host), request);
+ }
+ pending_batch_responses_.clear();
+}
+
void PermissionManager::ResetPermission(PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) {

Powered by Google App Engine
This is Rietveld 408576698