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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/permissions/permission_manager.h" 5 #include "chrome/browser/permissions/permission_manager.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "chrome/browser/permissions/permission_context.h" 8 #include "chrome/browser/permissions/permission_context.h"
9 #include "chrome/browser/permissions/permission_context_base.h" 9 #include "chrome/browser/permissions/permission_context_base.h"
10 #include "chrome/browser/permissions/permission_request_id.h" 10 #include "chrome/browser/permissions/permission_request_id.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 } 104 }
105 105
106 PermissionStatus GetPermissionStatusForConstantPermission( 106 PermissionStatus GetPermissionStatusForConstantPermission(
107 PermissionType type) { 107 PermissionType type) {
108 return ContentSettingToPermissionStatus( 108 return ContentSettingToPermissionStatus(
109 GetContentSettingForConstantPermission(type)); 109 GetContentSettingForConstantPermission(type));
110 } 110 }
111 111
112 } // anonymous namespace 112 } // anonymous namespace
113 113
114 struct PermissionManager::PendingResponse {
115 PermissionType type;
116 PermissionStatus status;
117
118 PendingResponse(PermissionType type, PermissionStatus status)
119 : type(type), status(status) {
120 }
121 };
122
123 struct PermissionManager::PendingResponses {
124 GURL requesting_origin;
125 size_t count;
126 size_t pending;
127 std::vector<PendingResponse> responses;
128 };
129
114 struct PermissionManager::Subscription { 130 struct PermissionManager::Subscription {
115 PermissionType permission; 131 PermissionType permission;
116 GURL requesting_origin; 132 GURL requesting_origin;
117 GURL embedding_origin; 133 GURL embedding_origin;
118 base::Callback<void(PermissionStatus)> callback; 134 base::Callback<void(PermissionStatus)> callback;
119 ContentSetting current_value; 135 ContentSetting current_value;
120 }; 136 };
121 137
122 PermissionManager::PermissionManager(Profile* profile) 138 PermissionManager::PermissionManager(Profile* profile)
123 : profile_(profile) { 139 : profile_(profile),
140 weak_ptr_factory_(this) {
124 } 141 }
125 142
126 PermissionManager::~PermissionManager() { 143 PermissionManager::~PermissionManager() {
127 if (!subscriptions_.IsEmpty()) 144 if (!subscriptions_.IsEmpty())
128 profile_->GetHostContentSettingsMap()->RemoveObserver(this); 145 profile_->GetHostContentSettingsMap()->RemoveObserver(this);
129 } 146 }
130 147
131 void PermissionManager::RequestPermission( 148 void PermissionManager::RequestPermission(
132 PermissionType permission, 149 PermissionType permission,
133 content::RenderFrameHost* render_frame_host, 150 content::RenderFrameHost* render_frame_host,
(...skipping 19 matching lines...) Expand all
153 request_id, 170 request_id,
154 requesting_origin); 171 requesting_origin);
155 172
156 context->RequestPermission( 173 context->RequestPermission(
157 content::WebContents::FromRenderFrameHost(render_frame_host), 174 content::WebContents::FromRenderFrameHost(render_frame_host),
158 request, requesting_origin, user_gesture, 175 request, requesting_origin, user_gesture,
159 base::Bind(&PermissionStatusCallbackWrapper, 176 base::Bind(&PermissionStatusCallbackWrapper,
160 callback)); 177 callback));
161 } 178 }
162 179
180 void PermissionManager::RequestPermissions(
181 const std::vector<PermissionType>& permissions,
182 content::RenderFrameHost* render_frame_host,
183 int request_id,
184 const GURL& requesting_origin,
185 bool user_gesture,
186 const base::Callback<void(const StatusVector&)>& callback) {
187 int render_process_id = render_frame_host->GetProcess()->GetID();
188 int render_frame_id = render_frame_host->GetRoutingID();
189 const PermissionRequestID request(render_process_id,
190 render_frame_id,
191 request_id,
192 requesting_origin);
193
194 // Pass complete control of the scoped pointer to the map.
195 // Locally we will use the raw pointer and the response will be removed from
196 // the map once all the responses return.
197 scoped_ptr<PendingResponses> scoped_response(new PendingResponses());
198 PendingResponses* pending_responses = scoped_response.get();
199 pending_batch_responses_.add(request_id, scoped_response.Pass());
200
201 pending_responses->requesting_origin = requesting_origin;
202 pending_responses->count = permissions.size();
203 pending_responses->pending = permissions.size();
204
205 for (size_t i = 0; i < permissions.size(); ++i) {
206 pending_responses->responses.emplace_back(
207 permissions[i],
208 content::PERMISSION_STATUS_DENIED);
209 }
210
211 // The pending responses should all be added to the vector before running
212 // this loop so duplicate permissions are handled properly.
213 bool seen_types[static_cast<int>(PermissionType::NUM)] = { false };
214 for (size_t i = 0; i < permissions.size(); ++i) {
215 const PermissionType current_type = permissions[i];
216 const int current_type_index = static_cast<int>(current_type);
217 if (seen_types[current_type_index])
218 continue;
219 seen_types[current_type_index] = true;
220
221 if (IsConstantPermission(current_type)) {
222 OnRequestsResponse(callback, request, pending_responses, i,
223 GetContentSettingForConstantPermission(current_type));
224 continue;
225 }
226
227 PermissionContextBase* context =
228 PermissionContext::Get(profile_, current_type);
229 if (!context) {
230 OnRequestsResponse(callback, request, pending_responses, i,
231 CONTENT_SETTING_BLOCK);
232 continue;
233 }
234 context->RequestPermission(
235 content::WebContents::FromRenderFrameHost(render_frame_host),
236 request, requesting_origin, user_gesture,
237 base::Bind(&PermissionManager::OnRequestsResponse,
238 weak_ptr_factory_.GetWeakPtr(),
239 callback,
240 request,
241 pending_responses,
242 i));
243 }
244 }
245
246 void PermissionManager::OnRequestsResponse(
247 const base::Callback<void(const StatusVector&)>& callback,
248 const PermissionRequestID request,
249 PendingResponses* pending_responses,
250 int index,
251 ContentSetting content_setting) {
252 PendingResponse& response = pending_responses->responses[index];
253 response.status = ContentSettingToPermissionStatus(content_setting);
254
255 for (size_t i = index + 1; i < pending_responses->responses.size(); ++i) {
256 if (pending_responses->responses[i].type == response.type) {
257 pending_responses->responses[i].status = response.status;
258 --pending_responses->pending;
259 }
260 }
261
262 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
263 std::vector<PermissionStatus> status;
264 for (auto response : pending_responses->responses) {
265 status.push_back(response.status);
266 }
267 pending_batch_responses_.erase(request.request_id());
268 callback.Run(status);
269 }
270 }
271
163 void PermissionManager::CancelPermissionRequest( 272 void PermissionManager::CancelPermissionRequest(
164 PermissionType permission, 273 PermissionType permission,
165 content::RenderFrameHost* render_frame_host, 274 content::RenderFrameHost* render_frame_host,
166 int request_id, 275 int request_id,
167 const GURL& requesting_origin) { 276 const GURL& requesting_origin) {
168 PermissionContextBase* context = PermissionContext::Get(profile_, permission); 277 PermissionContextBase* context = PermissionContext::Get(profile_, permission);
169 if (!context) 278 if (!context)
170 return; 279 return;
171 280
172 int render_process_id = render_frame_host->GetProcess()->GetID(); 281 int render_process_id = render_frame_host->GetProcess()->GetID();
173 int render_frame_id = render_frame_host->GetRoutingID(); 282 int render_frame_id = render_frame_host->GetRoutingID();
174 const PermissionRequestID request(render_process_id, 283 const PermissionRequestID request(render_process_id,
175 render_frame_id, 284 render_frame_id,
176 request_id, 285 request_id,
177 requesting_origin); 286 requesting_origin);
178 287
179 context->CancelPermissionRequest( 288 context->CancelPermissionRequest(
180 content::WebContents::FromRenderFrameHost(render_frame_host), request); 289 content::WebContents::FromRenderFrameHost(render_frame_host), request);
181 } 290 }
182 291
292 void PermissionManager::CancelPermissionsRequest(
293 content::RenderFrameHost* render_frame_host,
294 int request_id) {
295 PendingResponses* pending_responses =
296 pending_batch_responses_.get(request_id);
297
298 int render_process_id = render_frame_host->GetProcess()->GetID();
299 int render_frame_id = render_frame_host->GetRoutingID();
300 const PermissionRequestID request(render_process_id,
301 render_frame_id,
302 request_id,
303 pending_responses->requesting_origin);
304
305 for (size_t i = 0; i < pending_responses->count; ++i) {
306 PermissionType type = pending_responses->responses[i].type;
307 PermissionContextBase* context = PermissionContext::Get(profile_, type);
308 if (!context) continue;
309
310 context->CancelPermissionRequest(
311 content::WebContents::FromRenderFrameHost(render_frame_host), request);
312 }
313 pending_batch_responses_.clear();
314 }
315
183 void PermissionManager::ResetPermission(PermissionType permission, 316 void PermissionManager::ResetPermission(PermissionType permission,
184 const GURL& requesting_origin, 317 const GURL& requesting_origin,
185 const GURL& embedding_origin) { 318 const GURL& embedding_origin) {
186 PermissionContextBase* context = PermissionContext::Get(profile_, permission); 319 PermissionContextBase* context = PermissionContext::Get(profile_, permission);
187 if (!context) 320 if (!context)
188 return; 321 return;
189 322
190 context->ResetPermission(requesting_origin.GetOrigin(), 323 context->ResetPermission(requesting_origin.GetOrigin(),
191 embedding_origin.GetOrigin()); 324 embedding_origin.GetOrigin());
192 } 325 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 // Add the callback to |callbacks| which will be run after the loop to 421 // Add the callback to |callbacks| which will be run after the loop to
289 // prevent re-entrance issues. 422 // prevent re-entrance issues.
290 callbacks.push_back( 423 callbacks.push_back(
291 base::Bind(subscription->callback, 424 base::Bind(subscription->callback,
292 ContentSettingToPermissionStatus(new_value))); 425 ContentSettingToPermissionStatus(new_value)));
293 } 426 }
294 427
295 for (const auto& callback : callbacks) 428 for (const auto& callback : callbacks)
296 callback.Run(); 429 callback.Run();
297 } 430 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698