OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |