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

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: 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: chrome/browser/permissions/permission_manager.cc
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc
index 7ef2d83786bde92216bda897453ea1f5473b5d0c..db131e0f5fcaf0fca1c2bd1a963bdee60e33f5ea 100644
--- a/chrome/browser/permissions/permission_manager.cc
+++ b/chrome/browser/permissions/permission_manager.cc
@@ -78,6 +78,23 @@ void PermissionStatusCallbackWrapper(
} // anonymous namespace
+struct PermissionManager::PendingResponse {
Lalit Maganti (personal) 2015/08/03 23:10:26 Move to header and keep implementation here.
+ bool responded;
+ PermissionType type;
+ PermissionStatus status;
+
+ PendingResponse(bool responded, PermissionType type, PermissionStatus status)
+ : responded(responded), type(type), status(status) {
+ }
+};
+
+struct PermissionManager::PendingResponses {
Lalit Maganti (personal) 2015/08/03 23:10:26 Ditto.
+ GURL requesting_origin;
+ size_t count;
Lalit Maganti (personal) 2015/08/03 23:10:26 Make this immutable and another field.
+ std::vector<PendingResponse> responses;
+ base::Callback<void(const StatusVector&)> callback;
+};
+
struct PermissionManager::Subscription {
PermissionType permission;
GURL requesting_origin;
@@ -87,7 +104,8 @@ struct PermissionManager::Subscription {
};
PermissionManager::PermissionManager(Profile* profile)
- : profile_(profile) {
+ : profile_(profile),
+ weak_ptr_factory_(this) {
}
PermissionManager::~PermissionManager() {
@@ -122,6 +140,76 @@ 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();
Lalit Maganti (personal) 2015/08/03 23:10:26 Move *
+ pending_batch_responses_.add(request_id, scoped_response.Pass());
+
+ pending_responses->requesting_origin = requesting_origin;
+ pending_responses->count = permissions.size();
+ pending_responses->callback = callback;
+
+ for (size_t i = 0; i < permissions.size(); ++i) {
+ pending_responses->responses.emplace_back(
+ false,
+ permissions[i],
+ content::PERMISSION_STATUS_DENIED);
+
+ PermissionContextBase* context =
+ PermissionContext::Get(profile_, permissions[i]);
+ 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);
+
+ if (--pending_responses->count == 0) {
+ std::vector<PermissionStatus> status;
+ for (auto response : pending_responses->responses) {
+ status.push_back(response.status);
+ }
+ callback.Run(status);
Lalit Maganti (personal) 2015/08/03 23:10:26 Move this after next line
+
+ pending_batch_responses_.erase(request.request_id());
+ }
+}
+
void PermissionManager::CancelPermissionRequest(
PermissionType permission,
content::RenderFrameHost* render_frame_host,
@@ -142,6 +230,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) {
Lalit Maganti (personal) 2015/08/03 23:10:26 This is totally wrong - we need to store actual an
+ PermissionContextBase* context =
+ PermissionContext::Get(profile_, pending_responses->responses[i].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