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

Side by Side Diff: android_webview/browser/aw_permission_manager.cc

Issue 2143573002: Implement AwPermissionManager::RequestPermissions (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: reviw #20 Created 4 years, 5 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 "android_webview/browser/aw_permission_manager.h" 5 #include "android_webview/browser/aw_permission_manager.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "android_webview/browser/aw_browser_permission_request_delegate.h" 9 #include "android_webview/browser/aw_browser_permission_request_delegate.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/containers/hash_tables.h" 11 #include "base/containers/hash_tables.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "content/public/browser/permission_type.h" 13 #include "content/public/browser/permission_type.h"
14 #include "content/public/browser/render_frame_host.h" 14 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/browser/render_process_host.h" 15 #include "content/public/browser/render_process_host.h"
16 #include "content/public/browser/web_contents.h" 16 #include "content/public/browser/web_contents.h"
17 17
18 using blink::mojom::PermissionStatus; 18 using blink::mojom::PermissionStatus;
19 using content::PermissionType; 19 using content::PermissionType;
20 20
21 using RequestPermissionsCallback =
22 base::Callback<void(const std::vector<PermissionStatus>&)>;
23
21 namespace android_webview { 24 namespace android_webview {
22 25
26 namespace {
27
28 void PermissionRequestResponseCallbackWrapper(
29 const base::Callback<void(PermissionStatus)>& callback,
30 const std::vector<PermissionStatus>& vector) {
31 DCHECK_EQ(vector.size(), 1ul);
32 callback.Run(vector[0]);
33 }
34
35 } // namespace
36
23 class LastRequestResultCache { 37 class LastRequestResultCache {
24 public: 38 public:
25 LastRequestResultCache() = default; 39 LastRequestResultCache() = default;
26 40
27 void SetResult(PermissionType permission, 41 void SetResult(PermissionType permission,
28 const GURL& requesting_origin, 42 const GURL& requesting_origin,
29 const GURL& embedding_origin, 43 const GURL& embedding_origin,
30 PermissionStatus status) { 44 PermissionStatus status) {
31 DCHECK(status == PermissionStatus::GRANTED || 45 DCHECK(status == PermissionStatus::GRANTED ||
32 status == PermissionStatus::DENIED); 46 status == PermissionStatus::DENIED);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 return std::string(); 138 return std::string();
125 return requesting + "," + embedding; 139 return requesting + "," + embedding;
126 } 140 }
127 141
128 using StatusMap = base::hash_map<std::string, PermissionStatus>; 142 using StatusMap = base::hash_map<std::string, PermissionStatus>;
129 StatusMap pmi_result_cache_; 143 StatusMap pmi_result_cache_;
130 144
131 DISALLOW_COPY_AND_ASSIGN(LastRequestResultCache); 145 DISALLOW_COPY_AND_ASSIGN(LastRequestResultCache);
132 }; 146 };
133 147
134 struct AwPermissionManager::PendingRequest { 148 class AwPermissionManager::PendingRequest {
135 public: 149 public:
136 PendingRequest(PermissionType permission, 150 PendingRequest(const std::vector<PermissionType> permissions,
137 GURL requesting_origin, 151 GURL requesting_origin,
138 GURL embedding_origin, 152 GURL embedding_origin,
139 content::RenderFrameHost* render_frame_host, 153 int render_process_id,
140 const base::Callback<void(PermissionStatus)>& callback) 154 int render_frame_id,
141 : permission(permission), 155 const RequestPermissionsCallback callback)
142 requesting_origin(requesting_origin), 156 : permissions(permissions),
143 embedding_origin(embedding_origin), 157 requesting_origin(requesting_origin),
144 render_process_id(render_frame_host->GetProcess()->GetID()), 158 embedding_origin(embedding_origin),
145 render_frame_id(render_frame_host->GetRoutingID()), 159 render_process_id(render_process_id),
146 callback(callback) { 160 render_frame_id(render_frame_id),
161 callback(callback),
162 results(permissions.size(), PermissionStatus::DENIED),
163 cancelled_(false) {
164 for (size_t i = 0; i < permissions.size(); ++i)
165 permission_index_map_.insert(std::make_pair(permissions[i], i));
147 } 166 }
148 167
149 ~PendingRequest() = default; 168 ~PendingRequest() = default;
150 169
151 PermissionType permission; 170 void SetPermissionStatus(PermissionType type, PermissionStatus status) {
171 auto result = permission_index_map_.find(type);
172 if (result == permission_index_map_.end()) {
173 NOTREACHED();
174 return;
175 }
176 DCHECK(!IsComplete());
177 results[result->second] = status;
178 resolved_permissions_.insert(type);
179 }
180
181 PermissionStatus GetPermissionStatus(PermissionType type) {
182 auto result = permission_index_map_.find(type);
183 if (result == permission_index_map_.end()) {
184 NOTREACHED();
185 return PermissionStatus::DENIED;
186 }
187 return results[result->second];
188 }
189
190 bool HasPermissionType(PermissionType type) {
191 return permission_index_map_.find(type) != permission_index_map_.end();
192 }
193
194 bool IsComplete() const {
195 return results.size() == resolved_permissions_.size();
196 }
197
198 bool IsComplete(PermissionType type) const {
199 return resolved_permissions_.count(type) != 0;
200 }
201
202 void Cancel() { cancelled_ = true; }
203
204 bool IsCancelled() const { return cancelled_; }
205
206 std::vector<PermissionType> permissions;
152 GURL requesting_origin; 207 GURL requesting_origin;
153 GURL embedding_origin; 208 GURL embedding_origin;
154 int render_process_id; 209 int render_process_id;
155 int render_frame_id; 210 int render_frame_id;
156 base::Callback<void(PermissionStatus)> callback; 211 RequestPermissionsCallback callback;
212 std::vector<PermissionStatus> results;
213
214 private:
215 std::map<PermissionType, size_t> permission_index_map_;
216 std::set<PermissionType> resolved_permissions_;
217 bool cancelled_;
157 }; 218 };
158 219
159 AwPermissionManager::AwPermissionManager() 220 AwPermissionManager::AwPermissionManager()
160 : content::PermissionManager(), 221 : content::PermissionManager(),
161 result_cache_(new LastRequestResultCache), 222 result_cache_(new LastRequestResultCache),
162 weak_ptr_factory_(this) { 223 weak_ptr_factory_(this) {
163 } 224 }
164 225
165 AwPermissionManager::~AwPermissionManager() { 226 AwPermissionManager::~AwPermissionManager() {
227 CancelPermissionRequests();
166 } 228 }
167 229
168 int AwPermissionManager::RequestPermission( 230 int AwPermissionManager::RequestPermission(
169 PermissionType permission, 231 PermissionType permission,
170 content::RenderFrameHost* render_frame_host, 232 content::RenderFrameHost* render_frame_host,
171 const GURL& requesting_origin, 233 const GURL& requesting_origin,
172 bool user_gesture, 234 bool user_gesture,
173 const base::Callback<void(PermissionStatus)>& callback) { 235 const base::Callback<void(PermissionStatus)>& callback) {
174 int render_process_id = render_frame_host->GetProcess()->GetID(); 236 return RequestPermissions(
175 int render_frame_id = render_frame_host->GetRoutingID(); 237 std::vector<PermissionType>(1, permission), render_frame_host,
176 AwBrowserPermissionRequestDelegate* delegate = 238 requesting_origin, user_gesture,
177 AwBrowserPermissionRequestDelegate::FromID(render_process_id, 239 base::Bind(&PermissionRequestResponseCallbackWrapper, callback));
178 render_frame_id);
179 if (!delegate) {
180 DVLOG(0) << "Dropping permission request for "
181 << static_cast<int>(permission);
182 callback.Run(PermissionStatus::DENIED);
183 return kNoPendingOperation;
184 }
185
186 // Do not delegate any requests which are already pending.
187 bool should_delegate_request = true;
188 for (PendingRequestsMap::Iterator<PendingRequest> it(&pending_requests_);
189 !it.IsAtEnd(); it.Advance()) {
190 if (permission == it.GetCurrentValue()->permission) {
191 should_delegate_request = false;
192 break;
193 }
194 }
195
196 const GURL& embedding_origin =
197 content::WebContents::FromRenderFrameHost(render_frame_host)
198 ->GetLastCommittedURL().GetOrigin();
199
200 int request_id = kNoPendingOperation;
201 switch (permission) {
202 case PermissionType::GEOLOCATION:
203 request_id = pending_requests_.Add(new PendingRequest(
204 permission, requesting_origin,
205 embedding_origin, render_frame_host,
206 callback));
207 if (should_delegate_request) {
208 delegate->RequestGeolocationPermission(
209 requesting_origin,
210 base::Bind(&OnRequestResponse,
211 weak_ptr_factory_.GetWeakPtr(), request_id,
212 callback));
213 }
214 break;
215 case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
216 request_id = pending_requests_.Add(new PendingRequest(
217 permission, requesting_origin,
218 embedding_origin, render_frame_host,
219 callback));
220 if (should_delegate_request) {
221 delegate->RequestProtectedMediaIdentifierPermission(
222 requesting_origin,
223 base::Bind(&OnRequestResponse,
224 weak_ptr_factory_.GetWeakPtr(), request_id,
225 callback));
226 }
227 break;
228 case PermissionType::MIDI_SYSEX:
229 request_id = pending_requests_.Add(new PendingRequest(
230 permission, requesting_origin,
231 embedding_origin, render_frame_host,
232 callback));
233 if (should_delegate_request) {
234 delegate->RequestMIDISysexPermission(
235 requesting_origin,
236 base::Bind(&OnRequestResponse,
237 weak_ptr_factory_.GetWeakPtr(), request_id,
238 callback));
239 }
240 break;
241 case PermissionType::AUDIO_CAPTURE:
242 case PermissionType::VIDEO_CAPTURE:
243 case PermissionType::NOTIFICATIONS:
244 case PermissionType::PUSH_MESSAGING:
245 case PermissionType::DURABLE_STORAGE:
246 case PermissionType::BACKGROUND_SYNC:
247 NOTIMPLEMENTED() << "RequestPermission is not implemented for "
248 << static_cast<int>(permission);
249 callback.Run(PermissionStatus::DENIED);
250 break;
251 case PermissionType::MIDI:
252 callback.Run(PermissionStatus::GRANTED);
253 break;
254 case PermissionType::NUM:
255 NOTREACHED() << "PermissionType::NUM was not expected here.";
256 callback.Run(PermissionStatus::DENIED);
257 break;
258 }
259 return request_id;
260 } 240 }
261 241
262 int AwPermissionManager::RequestPermissions( 242 int AwPermissionManager::RequestPermissions(
263 const std::vector<PermissionType>& permissions, 243 const std::vector<PermissionType>& permissions,
264 content::RenderFrameHost* render_frame_host, 244 content::RenderFrameHost* render_frame_host,
265 const GURL& requesting_origin, 245 const GURL& requesting_origin,
266 bool user_gesture, 246 bool user_gesture,
267 const base::Callback<void( 247 const base::Callback<void(const std::vector<PermissionStatus>&)>&
268 const std::vector<PermissionStatus>&)>& callback) { 248 callback) {
269 NOTIMPLEMENTED() << "RequestPermissions has not been implemented in WebView"; 249 if (permissions.empty()) {
270 250 callback.Run(std::vector<PermissionStatus>());
271 std::vector<PermissionStatus> result(permissions.size()); 251 return kNoPendingOperation;
272 const GURL& embedding_origin = 252 }
273 content::WebContents::FromRenderFrameHost(render_frame_host) 253
274 ->GetLastCommittedURL().GetOrigin(); 254 const GURL& embedding_origin = LastCommittedOrigin(render_frame_host);
275 255
276 for (PermissionType type : permissions) { 256 PendingRequest* pending_request =
277 result.push_back(GetPermissionStatus( 257 new PendingRequest(permissions, requesting_origin, embedding_origin,
278 type, requesting_origin, embedding_origin)); 258 GetRenderProcessID(render_frame_host),
279 } 259 GetRenderFrameID(render_frame_host), callback);
280 260 std::vector<bool> should_delegate_requests =
281 callback.Run(result); 261 std::vector<bool>(permissions.size());
282 return kNoPendingOperation; 262 for (size_t i = 0; i < permissions.size(); ++i) {
263 bool should_delegate_request = true;
264 for (PendingRequestsMap::Iterator<PendingRequest> it(&pending_requests_);
265 !it.IsAtEnd(); it.Advance()) {
266 if (it.GetCurrentValue()->HasPermissionType(permissions[i])) {
267 if (!it.GetCurrentValue()->IsComplete(permissions[i])) {
268 should_delegate_request = false;
Tobias Sargeant 2016/07/25 13:29:53 Should this also be dependent on a requesting_orig
Takashi Toyoshima 2016/07/26 04:58:30 No. If there is a running request for the same pe
269 } else {
270 if (it.GetCurrentValue()->requesting_origin == requesting_origin) {
271 should_delegate_request = false;
272 pending_request->SetPermissionStatus(
273 permissions[i],
274 it.GetCurrentValue()->GetPermissionStatus(permissions[i]));
275 }
276 }
277 }
278 }
279 should_delegate_requests[i] = should_delegate_request;
280 }
281
282 int request_id = pending_requests_.Add(pending_request);
283
284 for (size_t i = 0; i < permissions.size(); ++i) {
285 if (!should_delegate_requests[i])
286 continue;
287 RequestPermissionInternal(permissions[i], request_id);
288 }
289
290 // If delegate resolve the permission synchronously, all requests could be
291 // already resolved here.
292 if (!pending_requests_.Lookup(request_id))
293 return kNoPendingOperation;
294
295 // If requests are resolved without calling delegate functions, e.g.
296 // PermissionType::MIDI is permitted within the previous for-loop, all
297 // requests could be already resolved, but still in the |pending_requests_|
298 // without invoking the callback.
299 if (pending_request->IsComplete()) {
300 std::vector<PermissionStatus> results = pending_request->results;
301 pending_requests_.Remove(request_id);
302 callback.Run(results);
303 return kNoPendingOperation;
304 }
305
306 return request_id;
283 } 307 }
284 308
285 // static 309 // static
286 void AwPermissionManager::OnRequestResponse( 310 void AwPermissionManager::OnRequestResponse(
287 const base::WeakPtr<AwPermissionManager>& manager, 311 const base::WeakPtr<AwPermissionManager>& manager,
288 int request_id, 312 int request_id,
289 const base::Callback<void(PermissionStatus)>& callback, 313 PermissionType permission,
290 bool allowed) { 314 bool allowed) {
315 // All delegate functions should be cancelled when the manager runs
316 // destructor. Therefore |manager| should be always valid here.
317 DCHECK(manager);
318
291 PermissionStatus status = 319 PermissionStatus status =
292 allowed ? PermissionStatus::GRANTED : PermissionStatus::DENIED; 320 allowed ? PermissionStatus::GRANTED : PermissionStatus::DENIED;
293 if (manager.get()) { 321 PendingRequest* pending_request =
294 PendingRequest* pending_request = 322 manager->pending_requests_.Lookup(request_id);
295 manager->pending_requests_.Lookup(request_id); 323
296 324 manager->result_cache_->SetResult(permission,
297 for (PendingRequestsMap::Iterator<PendingRequest> it( 325 pending_request->requesting_origin,
298 &manager->pending_requests_); 326 pending_request->embedding_origin, status);
299 !it.IsAtEnd(); it.Advance()) { 327
300 if (pending_request->permission == it.GetCurrentValue()->permission && 328 std::vector<int> complete_request_ids;
301 it.GetCurrentKey() != request_id) { 329 std::vector<std::pair<const RequestPermissionsCallback,
302 it.GetCurrentValue()->callback.Run(status); 330 std::vector<PermissionStatus>>>
303 manager->pending_requests_.Remove(it.GetCurrentKey()); 331 complete_request_pairs;
304 } 332 for (PendingRequestsMap::Iterator<PendingRequest> it(
305 } 333 &manager->pending_requests_);
306 334 !it.IsAtEnd(); it.Advance()) {
307 manager->result_cache_->SetResult( 335 if (!it.GetCurrentValue()->HasPermissionType(permission) ||
308 pending_request->permission, 336 it.GetCurrentValue()->requesting_origin !=
309 pending_request->requesting_origin, 337 pending_request->requesting_origin) {
310 pending_request->embedding_origin, 338 continue;
311 status); 339 }
312 manager->pending_requests_.Remove(request_id); 340 it.GetCurrentValue()->SetPermissionStatus(permission, status);
313 } 341 if (it.GetCurrentValue()->IsComplete()) {
314 callback.Run(status); 342 complete_request_ids.push_back(it.GetCurrentKey());
343 if (!it.GetCurrentValue()->IsCancelled()) {
344 complete_request_pairs.push_back(std::make_pair(
345 it.GetCurrentValue()->callback, it.GetCurrentValue()->results));
346 }
347 }
348 }
349 for (auto id : complete_request_ids)
350 manager->pending_requests_.Remove(id);
351 for (auto pair : complete_request_pairs)
352 pair.first.Run(pair.second);
353
354 manager->MayRequestNextPermission(permission);
315 } 355 }
316 356
317 void AwPermissionManager::CancelPermissionRequest(int request_id) { 357 void AwPermissionManager::CancelPermissionRequest(int request_id) {
318 PendingRequest* pending_request = pending_requests_.Lookup(request_id); 358 PendingRequest* pending_request = pending_requests_.Lookup(request_id);
319 if (!pending_request) 359 if (!pending_request || pending_request->IsCancelled())
320 return; 360 return;
321 361 pending_request->Cancel();
322 content::RenderFrameHost* render_frame_host = 362
323 content::RenderFrameHost::FromID(pending_request->render_process_id, 363 const GURL& embedding_origin = pending_request->embedding_origin;
324 pending_request->render_frame_id); 364 const GURL& requesting_origin = pending_request->requesting_origin;
325 content::WebContents* web_contents = 365 for (auto permission : pending_request->permissions)
326 content::WebContents::FromRenderFrameHost(render_frame_host); 366 result_cache_->ClearResult(permission, requesting_origin, embedding_origin);
327 DCHECK(web_contents); 367
328 368 AwBrowserPermissionRequestDelegate* delegate = GetDelegate(
329 // The caller is canceling (presumably) the most recent request. Assuming the 369 pending_request->render_process_id, pending_request->render_frame_id);
330 // request did not complete, the user did not respond to the requset.
331 // Thus, assume we do not know the result.
332 const GURL& embedding_origin = web_contents
333 ->GetLastCommittedURL().GetOrigin();
334 result_cache_->ClearResult(
335 pending_request->permission,
336 pending_request->requesting_origin,
337 embedding_origin);
338
339 AwBrowserPermissionRequestDelegate* delegate =
340 AwBrowserPermissionRequestDelegate::FromID(
341 pending_request->render_process_id,
342 pending_request->render_frame_id);
343 if (!delegate) { 370 if (!delegate) {
344 pending_requests_.Remove(request_id); 371 pending_requests_.Remove(request_id);
345 return; 372 return;
346 } 373 }
347 374
348 switch (pending_request->permission) { 375 for (auto permission : pending_request->permissions) {
349 case PermissionType::GEOLOCATION: 376 // If the permission was already resolved, we do not need to cancel it.
350 delegate->CancelGeolocationPermissionRequests( 377 if (pending_request->IsComplete(permission))
351 pending_request->requesting_origin); 378 continue;
352 break; 379
353 case PermissionType::PROTECTED_MEDIA_IDENTIFIER: 380 // If another pending_request waits for the same permission being resolved,
354 delegate->CancelProtectedMediaIdentifierPermissionRequests( 381 // we should not cancel the request.
355 pending_request->requesting_origin); 382 bool should_not_cancel_ = false;
356 break; 383 for (PendingRequestsMap::Iterator<PendingRequest> it(&pending_requests_);
357 case PermissionType::MIDI_SYSEX: 384 !it.IsAtEnd(); it.Advance()) {
358 delegate->CancelMIDISysexPermissionRequests( 385 if (it.GetCurrentValue() == pending_request ||
359 pending_request->requesting_origin); 386 it.GetCurrentValue()->requesting_origin != requesting_origin) {
360 break; 387 continue;
361 case PermissionType::NOTIFICATIONS: 388 }
362 case PermissionType::PUSH_MESSAGING: 389 // We need to check if |permission| was resolved for the current request
363 case PermissionType::DURABLE_STORAGE: 390 // in addition to the |pending_request|. This is because |permission|
364 case PermissionType::AUDIO_CAPTURE: 391 // might be resolved for the current request before |pending_request| was
365 case PermissionType::VIDEO_CAPTURE: 392 // issued.
366 case PermissionType::BACKGROUND_SYNC: 393 if (it.GetCurrentValue()->HasPermissionType(permission) &&
367 NOTIMPLEMENTED() << "CancelPermission not implemented for " 394 !it.GetCurrentValue()->IsComplete(permission)) {
368 << static_cast<int>(pending_request->permission); 395 should_not_cancel_ = true;
369 break; 396 break;
370 case PermissionType::MIDI: 397 }
371 // There is nothing to cancel so this is simply ignored. 398 }
372 break; 399 if (should_not_cancel_)
373 case PermissionType::NUM: 400 continue;
374 NOTREACHED() << "PermissionType::NUM was not expected here."; 401
375 break; 402 switch (permission) {
376 } 403 case PermissionType::GEOLOCATION:
377 404 delegate->CancelGeolocationPermissionRequests(requesting_origin);
378 pending_requests_.Remove(request_id); 405 break;
406 case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
407 delegate->CancelProtectedMediaIdentifierPermissionRequests(
408 requesting_origin);
409 break;
410 case PermissionType::MIDI_SYSEX:
411 delegate->CancelMIDISysexPermissionRequests(requesting_origin);
412 break;
413 case PermissionType::NOTIFICATIONS:
414 case PermissionType::PUSH_MESSAGING:
415 case PermissionType::DURABLE_STORAGE:
416 case PermissionType::AUDIO_CAPTURE:
417 case PermissionType::VIDEO_CAPTURE:
418 case PermissionType::BACKGROUND_SYNC:
419 NOTIMPLEMENTED() << "CancelPermission not implemented for "
420 << static_cast<int>(permission);
421 break;
422 case PermissionType::MIDI:
423 // There is nothing to cancel so this is simply ignored.
424 break;
425 case PermissionType::NUM:
426 NOTREACHED() << "PermissionType::NUM was not expected here.";
427 break;
428 }
429 pending_request->SetPermissionStatus(permission, PermissionStatus::DENIED);
430 MayRequestNextPermission(permission);
431 }
432
433 // If there are still active requests, we should not remove request_id here,
434 // but just do not invoke a relevant callback when the request is resolved in
435 // OnRequestResponse().
436 if (pending_request->IsComplete())
437 pending_requests_.Remove(request_id);
379 } 438 }
380 439
381 void AwPermissionManager::ResetPermission(PermissionType permission, 440 void AwPermissionManager::ResetPermission(PermissionType permission,
382 const GURL& requesting_origin, 441 const GURL& requesting_origin,
383 const GURL& embedding_origin) { 442 const GURL& embedding_origin) {
384 result_cache_->ClearResult(permission, requesting_origin, embedding_origin); 443 result_cache_->ClearResult(permission, requesting_origin, embedding_origin);
385 } 444 }
386 445
387 PermissionStatus AwPermissionManager::GetPermissionStatus( 446 PermissionStatus AwPermissionManager::GetPermissionStatus(
388 PermissionType permission, 447 PermissionType permission,
(...skipping 21 matching lines...) Expand all
410 const GURL& requesting_origin, 469 const GURL& requesting_origin,
411 const GURL& embedding_origin, 470 const GURL& embedding_origin,
412 const base::Callback<void(PermissionStatus)>& callback) { 471 const base::Callback<void(PermissionStatus)>& callback) {
413 return kNoPendingOperation; 472 return kNoPendingOperation;
414 } 473 }
415 474
416 void AwPermissionManager::UnsubscribePermissionStatusChange( 475 void AwPermissionManager::UnsubscribePermissionStatusChange(
417 int subscription_id) { 476 int subscription_id) {
418 } 477 }
419 478
479 void AwPermissionManager::CancelPermissionRequests() {
480 std::vector<int> request_ids;
481 for (PendingRequestsMap::Iterator<PendingRequest> it(&pending_requests_);
482 !it.IsAtEnd(); it.Advance()) {
483 request_ids.push_back(it.GetCurrentKey());
484 }
485 for (auto request_id : request_ids)
486 CancelPermissionRequest(request_id);
487 DCHECK(pending_requests_.IsEmpty());
488 }
489
490 bool AwPermissionManager::RequestPermissionInternal(
Tobias Sargeant 2016/07/25 13:29:53 Couldn't this method just take request and delegat
Takashi Toyoshima 2016/07/26 04:58:30 Done.
491 PermissionType permission,
492 int request_id) {
493 PendingRequest* request = pending_requests_.Lookup(request_id);
494 DCHECK(request);
495 DCHECK(!request->IsComplete(permission));
496
497 AwBrowserPermissionRequestDelegate* delegate =
498 GetDelegate(request->render_process_id, request->render_frame_id);
499 if (!delegate) {
500 DVLOG(0) << "Dropping permissions request for "
501 << static_cast<int>(permission);
502 request->SetPermissionStatus(permission, PermissionStatus::DENIED);
503 return false;
504 }
505
506 switch (permission) {
507 case PermissionType::GEOLOCATION:
508 delegate->RequestGeolocationPermission(
509 request->requesting_origin,
510 base::Bind(&OnRequestResponse, weak_ptr_factory_.GetWeakPtr(),
511 request_id, permission));
512 break;
513 case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
514 delegate->RequestProtectedMediaIdentifierPermission(
515 request->requesting_origin,
516 base::Bind(&OnRequestResponse, weak_ptr_factory_.GetWeakPtr(),
517 request_id, permission));
518 break;
519 case PermissionType::MIDI_SYSEX:
520 delegate->RequestMIDISysexPermission(
521 request->requesting_origin,
522 base::Bind(&OnRequestResponse, weak_ptr_factory_.GetWeakPtr(),
523 request_id, permission));
524 break;
525 case PermissionType::AUDIO_CAPTURE:
526 case PermissionType::VIDEO_CAPTURE:
527 case PermissionType::NOTIFICATIONS:
528 case PermissionType::PUSH_MESSAGING:
529 case PermissionType::DURABLE_STORAGE:
530 case PermissionType::BACKGROUND_SYNC:
531 NOTIMPLEMENTED() << "RequestPermissions is not implemented for "
532 << static_cast<int>(permission);
533 request->SetPermissionStatus(permission, PermissionStatus::DENIED);
534 return false;
535 case PermissionType::MIDI:
536 request->SetPermissionStatus(permission, PermissionStatus::GRANTED);
537 return false;
538 case PermissionType::NUM:
539 NOTREACHED() << "PermissionType::NUM was not expected here.";
540 request->SetPermissionStatus(permission, PermissionStatus::DENIED);
541 return false;
542 }
543 return true;
544 }
545
546 void AwPermissionManager::MayRequestNextPermission(PermissionType permission) {
547 for (PendingRequestsMap::Iterator<PendingRequest> it(&pending_requests_);
548 !it.IsAtEnd(); it.Advance()) {
549 if (it.GetCurrentValue()->IsCancelled() ||
550 !it.GetCurrentValue()->HasPermissionType(permission) ||
551 it.GetCurrentValue()->IsComplete(permission)) {
552 continue;
553 }
554 if (RequestPermissionInternal(permission, it.GetCurrentKey()))
555 break;
556 }
557 }
558
559 int AwPermissionManager::GetRenderProcessID(
560 content::RenderFrameHost* render_frame_host) {
561 return render_frame_host->GetProcess()->GetID();
562 }
563
564 int AwPermissionManager::GetRenderFrameID(
565 content::RenderFrameHost* render_frame_host) {
566 return render_frame_host->GetRoutingID();
567 }
568
569 GURL AwPermissionManager::LastCommittedOrigin(
570 content::RenderFrameHost* render_frame_host) {
571 return content::WebContents::FromRenderFrameHost(render_frame_host)
572 ->GetLastCommittedURL().GetOrigin();
573 }
574
575 AwBrowserPermissionRequestDelegate* AwPermissionManager::GetDelegate(
576 int render_process_id, int render_frame_id) {
577 return AwBrowserPermissionRequestDelegate::FromID(render_process_id,
578 render_frame_id);
579 }
580
420 } // namespace android_webview 581 } // namespace android_webview
OLDNEW
« no previous file with comments | « android_webview/browser/aw_permission_manager.h ('k') | android_webview/browser/aw_permission_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698