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) { |