aw_permission_manager.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  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
  3. // found in the LICENSE file.
  4. #include "android_webview/browser/aw_permission_manager.h"
  5. #include <memory>
  6. #include <string>
  7. #include <unordered_map>
  8. #include <utility>
  9. #include "android_webview/browser/aw_browser_permission_request_delegate.h"
  10. #include "base/bind.h"
  11. #include "base/callback.h"
  12. #include "base/logging.h"
  13. #include "components/permissions/permission_util.h"
  14. #include "content/public/browser/child_process_security_policy.h"
  15. #include "content/public/browser/permission_controller.h"
  16. #include "content/public/browser/permission_result.h"
  17. #include "content/public/browser/render_frame_host.h"
  18. #include "content/public/browser/render_process_host.h"
  19. #include "content/public/browser/web_contents.h"
  20. #include "third_party/blink/public/common/permissions/permission_utils.h"
  21. using blink::PermissionType;
  22. using blink::mojom::PermissionStatus;
  23. using RequestPermissionsCallback =
  24. base::OnceCallback<void(const std::vector<PermissionStatus>&)>;
  25. namespace android_webview {
  26. namespace {
  27. void PermissionRequestResponseCallbackWrapper(
  28. base::OnceCallback<void(PermissionStatus)> callback,
  29. const std::vector<PermissionStatus>& vector) {
  30. DCHECK_EQ(vector.size(), 1ul);
  31. std::move(callback).Run(vector.at(0));
  32. }
  33. } // namespace
  34. class LastRequestResultCache {
  35. public:
  36. LastRequestResultCache() = default;
  37. LastRequestResultCache(const LastRequestResultCache&) = delete;
  38. LastRequestResultCache& operator=(const LastRequestResultCache&) = delete;
  39. void SetResult(PermissionType permission,
  40. const GURL& requesting_origin,
  41. const GURL& embedding_origin,
  42. PermissionStatus status) {
  43. DCHECK(status == PermissionStatus::GRANTED ||
  44. status == PermissionStatus::DENIED);
  45. // TODO(ddorwin): We should be denying empty origins at a higher level.
  46. if (requesting_origin.is_empty() || embedding_origin.is_empty()) {
  47. DLOG(WARNING) << "Not caching result because of empty origin.";
  48. return;
  49. }
  50. if (!requesting_origin.is_valid()) {
  51. NOTREACHED() << requesting_origin.possibly_invalid_spec();
  52. return;
  53. }
  54. if (!embedding_origin.is_valid()) {
  55. NOTREACHED() << embedding_origin.possibly_invalid_spec();
  56. return;
  57. }
  58. if (permission != PermissionType::PROTECTED_MEDIA_IDENTIFIER) {
  59. // Other permissions are not cached.
  60. return;
  61. }
  62. std::string key = GetCacheKey(requesting_origin, embedding_origin);
  63. if (key.empty()) {
  64. NOTREACHED();
  65. // Never store an empty key because it could inadvertently be used for
  66. // another combination.
  67. return;
  68. }
  69. pmi_result_cache_[key] = status;
  70. }
  71. PermissionStatus GetResult(PermissionType permission,
  72. const GURL& requesting_origin,
  73. const GURL& embedding_origin) const {
  74. // TODO(ddorwin): We should be denying empty origins at a higher level.
  75. if (requesting_origin.is_empty() || embedding_origin.is_empty()) {
  76. return PermissionStatus::ASK;
  77. }
  78. DCHECK(requesting_origin.is_valid())
  79. << requesting_origin.possibly_invalid_spec();
  80. DCHECK(embedding_origin.is_valid())
  81. << embedding_origin.possibly_invalid_spec();
  82. if (permission != PermissionType::PROTECTED_MEDIA_IDENTIFIER) {
  83. NOTREACHED() << "Results are only cached for PROTECTED_MEDIA_IDENTIFIER";
  84. return PermissionStatus::ASK;
  85. }
  86. std::string key = GetCacheKey(requesting_origin, embedding_origin);
  87. StatusMap::const_iterator it = pmi_result_cache_.find(key);
  88. if (it == pmi_result_cache_.end()) {
  89. DLOG(WARNING) << "GetResult() called for uncached origins: " << key;
  90. return PermissionStatus::ASK;
  91. }
  92. DCHECK(!key.empty());
  93. return it->second;
  94. }
  95. void ClearResult(PermissionType permission,
  96. const GURL& requesting_origin,
  97. const GURL& embedding_origin) {
  98. // TODO(ddorwin): We should be denying empty origins at a higher level.
  99. if (requesting_origin.is_empty() || embedding_origin.is_empty()) {
  100. return;
  101. }
  102. DCHECK(requesting_origin.is_valid())
  103. << requesting_origin.possibly_invalid_spec();
  104. DCHECK(embedding_origin.is_valid())
  105. << embedding_origin.possibly_invalid_spec();
  106. if (permission != PermissionType::PROTECTED_MEDIA_IDENTIFIER) {
  107. // Other permissions are not cached, so nothing to clear.
  108. return;
  109. }
  110. std::string key = GetCacheKey(requesting_origin, embedding_origin);
  111. pmi_result_cache_.erase(key);
  112. }
  113. private:
  114. // Returns a concatenation of the origins to be used as the index.
  115. // Returns the empty string if either origin is invalid or empty.
  116. static std::string GetCacheKey(const GURL& requesting_origin,
  117. const GURL& embedding_origin) {
  118. const std::string& requesting = requesting_origin.spec();
  119. const std::string& embedding = embedding_origin.spec();
  120. if (requesting.empty() || embedding.empty())
  121. return std::string();
  122. return requesting + "," + embedding;
  123. }
  124. using StatusMap = std::unordered_map<std::string, PermissionStatus>;
  125. StatusMap pmi_result_cache_;
  126. };
  127. class AwPermissionManager::PendingRequest {
  128. public:
  129. PendingRequest(const std::vector<PermissionType> permissions,
  130. GURL requesting_origin,
  131. GURL embedding_origin,
  132. int render_process_id,
  133. int render_frame_id,
  134. RequestPermissionsCallback callback)
  135. : permissions(permissions),
  136. requesting_origin(requesting_origin),
  137. embedding_origin(embedding_origin),
  138. render_process_id(render_process_id),
  139. render_frame_id(render_frame_id),
  140. callback(std::move(callback)),
  141. results(permissions.size(), PermissionStatus::DENIED),
  142. cancelled_(false) {
  143. for (size_t i = 0; i < permissions.size(); ++i)
  144. permission_index_map_.insert(std::make_pair(permissions[i], i));
  145. }
  146. ~PendingRequest() = default;
  147. void SetPermissionStatus(PermissionType type, PermissionStatus status) {
  148. auto result = permission_index_map_.find(type);
  149. if (result == permission_index_map_.end()) {
  150. NOTREACHED();
  151. return;
  152. }
  153. DCHECK(!IsCompleted());
  154. results[result->second] = status;
  155. if (type == PermissionType::MIDI_SYSEX &&
  156. status == PermissionStatus::GRANTED) {
  157. content::ChildProcessSecurityPolicy::GetInstance()
  158. ->GrantSendMidiSysExMessage(render_process_id);
  159. }
  160. resolved_permissions_.insert(type);
  161. }
  162. PermissionStatus GetPermissionStatus(PermissionType type) {
  163. auto result = permission_index_map_.find(type);
  164. if (result == permission_index_map_.end()) {
  165. NOTREACHED();
  166. return PermissionStatus::DENIED;
  167. }
  168. return results[result->second];
  169. }
  170. bool HasPermissionType(PermissionType type) {
  171. return permission_index_map_.find(type) != permission_index_map_.end();
  172. }
  173. bool IsCompleted() const {
  174. return results.size() == resolved_permissions_.size();
  175. }
  176. bool IsCompleted(PermissionType type) const {
  177. return resolved_permissions_.count(type) != 0;
  178. }
  179. void Cancel() { cancelled_ = true; }
  180. bool IsCancelled() const { return cancelled_; }
  181. std::vector<PermissionType> permissions;
  182. GURL requesting_origin;
  183. GURL embedding_origin;
  184. int render_process_id;
  185. int render_frame_id;
  186. RequestPermissionsCallback callback;
  187. std::vector<PermissionStatus> results;
  188. private:
  189. std::map<PermissionType, size_t> permission_index_map_;
  190. std::set<PermissionType> resolved_permissions_;
  191. bool cancelled_;
  192. };
  193. AwPermissionManager::AwPermissionManager()
  194. : result_cache_(new LastRequestResultCache) {}
  195. AwPermissionManager::~AwPermissionManager() {
  196. CancelPermissionRequests();
  197. }
  198. void AwPermissionManager::RequestPermission(
  199. PermissionType permission,
  200. content::RenderFrameHost* render_frame_host,
  201. const GURL& requesting_origin,
  202. bool user_gesture,
  203. base::OnceCallback<void(PermissionStatus)> callback) {
  204. RequestPermissions(std::vector<PermissionType>(1, permission),
  205. render_frame_host, requesting_origin, user_gesture,
  206. base::BindOnce(&PermissionRequestResponseCallbackWrapper,
  207. std::move(callback)));
  208. }
  209. void AwPermissionManager::RequestPermissions(
  210. const std::vector<PermissionType>& permissions,
  211. content::RenderFrameHost* render_frame_host,
  212. const GURL& requesting_origin,
  213. bool user_gesture,
  214. base::OnceCallback<void(const std::vector<PermissionStatus>&)> callback) {
  215. if (permissions.empty()) {
  216. std::move(callback).Run(std::vector<PermissionStatus>());
  217. return;
  218. }
  219. const GURL& embedding_origin = LastCommittedOrigin(render_frame_host);
  220. auto pending_request = std::make_unique<PendingRequest>(
  221. permissions, requesting_origin, embedding_origin,
  222. GetRenderProcessID(render_frame_host),
  223. GetRenderFrameID(render_frame_host), std::move(callback));
  224. std::vector<bool> should_delegate_requests =
  225. std::vector<bool>(permissions.size(), true);
  226. for (size_t i = 0; i < permissions.size(); ++i) {
  227. for (PendingRequestsMap::Iterator<PendingRequest> it(&pending_requests_);
  228. !it.IsAtEnd(); it.Advance()) {
  229. if (it.GetCurrentValue()->HasPermissionType(permissions[i]) &&
  230. it.GetCurrentValue()->requesting_origin == requesting_origin) {
  231. if (it.GetCurrentValue()->IsCompleted(permissions[i])) {
  232. pending_request->SetPermissionStatus(
  233. permissions[i],
  234. it.GetCurrentValue()->GetPermissionStatus(permissions[i]));
  235. }
  236. should_delegate_requests[i] = false;
  237. break;
  238. }
  239. }
  240. }
  241. // Keep copy of pointer for performing further operations after ownership is
  242. // transferred to pending_requests_
  243. PendingRequest* pending_request_raw = pending_request.get();
  244. const int request_id = pending_requests_.Add(std::move(pending_request));
  245. AwBrowserPermissionRequestDelegate* delegate =
  246. GetDelegate(pending_request_raw->render_process_id,
  247. pending_request_raw->render_frame_id);
  248. for (size_t i = 0; i < permissions.size(); ++i) {
  249. if (!should_delegate_requests[i])
  250. continue;
  251. if (!delegate) {
  252. DVLOG(0) << "Dropping permissions request for "
  253. << static_cast<int>(permissions[i]);
  254. pending_request_raw->SetPermissionStatus(permissions[i],
  255. PermissionStatus::DENIED);
  256. continue;
  257. }
  258. switch (permissions[i]) {
  259. case PermissionType::GEOLOCATION:
  260. delegate->RequestGeolocationPermission(
  261. pending_request_raw->requesting_origin,
  262. base::BindOnce(&OnRequestResponse, weak_ptr_factory_.GetWeakPtr(),
  263. request_id, permissions[i]));
  264. break;
  265. case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
  266. delegate->RequestProtectedMediaIdentifierPermission(
  267. pending_request_raw->requesting_origin,
  268. base::BindOnce(&OnRequestResponse, weak_ptr_factory_.GetWeakPtr(),
  269. request_id, permissions[i]));
  270. break;
  271. case PermissionType::MIDI_SYSEX:
  272. delegate->RequestMIDISysexPermission(
  273. pending_request_raw->requesting_origin,
  274. base::BindOnce(&OnRequestResponse, weak_ptr_factory_.GetWeakPtr(),
  275. request_id, permissions[i]));
  276. break;
  277. case PermissionType::AUDIO_CAPTURE:
  278. case PermissionType::VIDEO_CAPTURE:
  279. case PermissionType::NOTIFICATIONS:
  280. case PermissionType::DURABLE_STORAGE:
  281. case PermissionType::BACKGROUND_SYNC:
  282. case PermissionType::ACCESSIBILITY_EVENTS:
  283. case PermissionType::CLIPBOARD_READ_WRITE:
  284. case PermissionType::CLIPBOARD_SANITIZED_WRITE:
  285. case PermissionType::PAYMENT_HANDLER:
  286. case PermissionType::BACKGROUND_FETCH:
  287. case PermissionType::IDLE_DETECTION:
  288. case PermissionType::PERIODIC_BACKGROUND_SYNC:
  289. case PermissionType::NFC:
  290. case PermissionType::VR:
  291. case PermissionType::AR:
  292. case PermissionType::STORAGE_ACCESS_GRANT:
  293. case PermissionType::CAMERA_PAN_TILT_ZOOM:
  294. case PermissionType::WINDOW_PLACEMENT:
  295. case PermissionType::LOCAL_FONTS:
  296. case PermissionType::DISPLAY_CAPTURE:
  297. NOTIMPLEMENTED() << "RequestPermissions is not implemented for "
  298. << static_cast<int>(permissions[i]);
  299. pending_request_raw->SetPermissionStatus(permissions[i],
  300. PermissionStatus::DENIED);
  301. break;
  302. case PermissionType::MIDI:
  303. case PermissionType::SENSORS:
  304. case PermissionType::WAKE_LOCK_SCREEN:
  305. // PermissionType::SENSORS requests are always granted so that access
  306. // to device motion and device orientation data (and underlying
  307. // sensors) works in the WebView. SensorProviderImpl::GetSensor()
  308. // filters requests for other types of sensors.
  309. pending_request_raw->SetPermissionStatus(permissions[i],
  310. PermissionStatus::GRANTED);
  311. break;
  312. case PermissionType::WAKE_LOCK_SYSTEM:
  313. pending_request_raw->SetPermissionStatus(permissions[i],
  314. PermissionStatus::DENIED);
  315. break;
  316. case PermissionType::NUM:
  317. NOTREACHED() << "PermissionType::NUM was not expected here.";
  318. pending_request_raw->SetPermissionStatus(permissions[i],
  319. PermissionStatus::DENIED);
  320. break;
  321. }
  322. }
  323. // If delegate resolve the permission synchronously, all requests could be
  324. // already resolved here.
  325. if (!pending_requests_.Lookup(request_id))
  326. return;
  327. // If requests are resolved without calling delegate functions, e.g.
  328. // PermissionType::MIDI is permitted within the previous for-loop, all
  329. // requests could be already resolved, but still in the |pending_requests_|
  330. // without invoking the callback.
  331. if (pending_request_raw->IsCompleted()) {
  332. std::vector<PermissionStatus> results = pending_request_raw->results;
  333. RequestPermissionsCallback completed_callback =
  334. std::move(pending_request_raw->callback);
  335. pending_requests_.Remove(request_id);
  336. std::move(completed_callback).Run(results);
  337. }
  338. }
  339. // static
  340. void AwPermissionManager::OnRequestResponse(
  341. const base::WeakPtr<AwPermissionManager>& manager,
  342. int request_id,
  343. PermissionType permission,
  344. bool allowed) {
  345. // All delegate functions should be cancelled when the manager runs
  346. // destructor. Therefore |manager| should be always valid here.
  347. DCHECK(manager);
  348. PermissionStatus status =
  349. allowed ? PermissionStatus::GRANTED : PermissionStatus::DENIED;
  350. PendingRequest* pending_request =
  351. manager->pending_requests_.Lookup(request_id);
  352. manager->result_cache_->SetResult(permission,
  353. pending_request->requesting_origin,
  354. pending_request->embedding_origin, status);
  355. std::vector<int> complete_request_ids;
  356. std::vector<
  357. std::pair<RequestPermissionsCallback, std::vector<PermissionStatus>>>
  358. complete_request_pairs;
  359. for (PendingRequestsMap::Iterator<PendingRequest> it(
  360. &manager->pending_requests_);
  361. !it.IsAtEnd(); it.Advance()) {
  362. if (!it.GetCurrentValue()->HasPermissionType(permission) ||
  363. it.GetCurrentValue()->requesting_origin !=
  364. pending_request->requesting_origin) {
  365. continue;
  366. }
  367. it.GetCurrentValue()->SetPermissionStatus(permission, status);
  368. if (it.GetCurrentValue()->IsCompleted()) {
  369. complete_request_ids.push_back(it.GetCurrentKey());
  370. if (!it.GetCurrentValue()->IsCancelled()) {
  371. complete_request_pairs.emplace_back(
  372. std::move(it.GetCurrentValue()->callback),
  373. std::move(it.GetCurrentValue()->results));
  374. }
  375. }
  376. }
  377. for (auto id : complete_request_ids)
  378. manager->pending_requests_.Remove(id);
  379. for (auto& pair : complete_request_pairs)
  380. std::move(pair.first).Run(pair.second);
  381. }
  382. void AwPermissionManager::ResetPermission(PermissionType permission,
  383. const GURL& requesting_origin,
  384. const GURL& embedding_origin) {
  385. result_cache_->ClearResult(permission, requesting_origin, embedding_origin);
  386. }
  387. void AwPermissionManager::RequestPermissionsFromCurrentDocument(
  388. const std::vector<PermissionType>& permissions,
  389. content::RenderFrameHost* render_frame_host,
  390. bool user_gesture,
  391. base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)>
  392. callback) {
  393. RequestPermissions(permissions, render_frame_host,
  394. LastCommittedOrigin(render_frame_host), user_gesture,
  395. std::move(callback));
  396. }
  397. PermissionStatus AwPermissionManager::GetPermissionStatus(
  398. PermissionType permission,
  399. const GURL& requesting_origin,
  400. const GURL& embedding_origin) {
  401. // Method is called outside the Permissions API only for this permission.
  402. if (permission == PermissionType::PROTECTED_MEDIA_IDENTIFIER) {
  403. return result_cache_->GetResult(permission, requesting_origin,
  404. embedding_origin);
  405. } else if (permission == PermissionType::MIDI ||
  406. permission == PermissionType::SENSORS) {
  407. return PermissionStatus::GRANTED;
  408. }
  409. return PermissionStatus::DENIED;
  410. }
  411. content::PermissionResult
  412. AwPermissionManager::GetPermissionResultForOriginWithoutContext(
  413. blink::PermissionType permission,
  414. const url::Origin& origin) {
  415. blink::mojom::PermissionStatus status =
  416. GetPermissionStatus(permission, origin.GetURL(), origin.GetURL());
  417. return content::PermissionResult(
  418. status, content::PermissionStatusSource::UNSPECIFIED);
  419. }
  420. PermissionStatus AwPermissionManager::GetPermissionStatusForCurrentDocument(
  421. PermissionType permission,
  422. content::RenderFrameHost* render_frame_host) {
  423. return GetPermissionStatus(
  424. permission,
  425. permissions::PermissionUtil::GetLastCommittedOriginAsURL(
  426. render_frame_host),
  427. permissions::PermissionUtil::GetLastCommittedOriginAsURL(
  428. render_frame_host->GetMainFrame()));
  429. }
  430. PermissionStatus AwPermissionManager::GetPermissionStatusForWorker(
  431. PermissionType permission,
  432. content::RenderProcessHost* render_process_host,
  433. const GURL& worker_origin) {
  434. return GetPermissionStatus(permission, worker_origin, worker_origin);
  435. }
  436. AwPermissionManager::SubscriptionId
  437. AwPermissionManager::SubscribePermissionStatusChange(
  438. PermissionType permission,
  439. content::RenderProcessHost* render_process_host,
  440. content::RenderFrameHost* render_frame_host,
  441. const GURL& requesting_origin,
  442. base::RepeatingCallback<void(PermissionStatus)> callback) {
  443. return SubscriptionId();
  444. }
  445. void AwPermissionManager::UnsubscribePermissionStatusChange(
  446. SubscriptionId subscription_id) {}
  447. void AwPermissionManager::CancelPermissionRequest(int request_id) {
  448. PendingRequest* pending_request = pending_requests_.Lookup(request_id);
  449. if (!pending_request || pending_request->IsCancelled())
  450. return;
  451. pending_request->Cancel();
  452. const GURL& embedding_origin = pending_request->embedding_origin;
  453. const GURL& requesting_origin = pending_request->requesting_origin;
  454. for (auto permission : pending_request->permissions)
  455. result_cache_->ClearResult(permission, requesting_origin, embedding_origin);
  456. AwBrowserPermissionRequestDelegate* delegate = GetDelegate(
  457. pending_request->render_process_id, pending_request->render_frame_id);
  458. for (auto permission : pending_request->permissions) {
  459. // If the permission was already resolved, we do not need to cancel it.
  460. if (pending_request->IsCompleted(permission))
  461. continue;
  462. // If another pending_request waits for the same permission being resolved,
  463. // we should not cancel the delegate's request.
  464. bool should_not_cancel_ = false;
  465. for (PendingRequestsMap::Iterator<PendingRequest> it(&pending_requests_);
  466. !it.IsAtEnd(); it.Advance()) {
  467. if (it.GetCurrentValue() != pending_request &&
  468. it.GetCurrentValue()->HasPermissionType(permission) &&
  469. it.GetCurrentValue()->requesting_origin == requesting_origin &&
  470. !it.GetCurrentValue()->IsCompleted(permission)) {
  471. should_not_cancel_ = true;
  472. break;
  473. }
  474. }
  475. if (should_not_cancel_)
  476. continue;
  477. switch (permission) {
  478. case PermissionType::GEOLOCATION:
  479. if (delegate)
  480. delegate->CancelGeolocationPermissionRequests(requesting_origin);
  481. break;
  482. case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
  483. if (delegate)
  484. delegate->CancelProtectedMediaIdentifierPermissionRequests(
  485. requesting_origin);
  486. break;
  487. case PermissionType::MIDI_SYSEX:
  488. if (delegate)
  489. delegate->CancelMIDISysexPermissionRequests(requesting_origin);
  490. break;
  491. case PermissionType::NOTIFICATIONS:
  492. case PermissionType::DURABLE_STORAGE:
  493. case PermissionType::AUDIO_CAPTURE:
  494. case PermissionType::VIDEO_CAPTURE:
  495. case PermissionType::BACKGROUND_SYNC:
  496. case PermissionType::ACCESSIBILITY_EVENTS:
  497. case PermissionType::CLIPBOARD_READ_WRITE:
  498. case PermissionType::CLIPBOARD_SANITIZED_WRITE:
  499. case PermissionType::PAYMENT_HANDLER:
  500. case PermissionType::BACKGROUND_FETCH:
  501. case PermissionType::IDLE_DETECTION:
  502. case PermissionType::PERIODIC_BACKGROUND_SYNC:
  503. case PermissionType::NFC:
  504. case PermissionType::VR:
  505. case PermissionType::AR:
  506. case PermissionType::STORAGE_ACCESS_GRANT:
  507. case PermissionType::CAMERA_PAN_TILT_ZOOM:
  508. case PermissionType::WINDOW_PLACEMENT:
  509. case PermissionType::LOCAL_FONTS:
  510. case PermissionType::DISPLAY_CAPTURE:
  511. NOTIMPLEMENTED() << "CancelPermission not implemented for "
  512. << static_cast<int>(permission);
  513. break;
  514. case PermissionType::MIDI:
  515. case PermissionType::SENSORS:
  516. case PermissionType::WAKE_LOCK_SCREEN:
  517. case PermissionType::WAKE_LOCK_SYSTEM:
  518. // There is nothing to cancel so this is simply ignored.
  519. break;
  520. case PermissionType::NUM:
  521. NOTREACHED() << "PermissionType::NUM was not expected here.";
  522. break;
  523. }
  524. pending_request->SetPermissionStatus(permission, PermissionStatus::DENIED);
  525. }
  526. // If there are still active requests, we should not remove request_id here,
  527. // but just do not invoke a relevant callback when the request is resolved in
  528. // OnRequestResponse().
  529. if (pending_request->IsCompleted())
  530. pending_requests_.Remove(request_id);
  531. }
  532. void AwPermissionManager::CancelPermissionRequests() {
  533. std::vector<int> request_ids;
  534. for (PendingRequestsMap::Iterator<PendingRequest> it(&pending_requests_);
  535. !it.IsAtEnd(); it.Advance()) {
  536. request_ids.push_back(it.GetCurrentKey());
  537. }
  538. for (auto request_id : request_ids)
  539. CancelPermissionRequest(request_id);
  540. DCHECK(pending_requests_.IsEmpty());
  541. }
  542. int AwPermissionManager::GetRenderProcessID(
  543. content::RenderFrameHost* render_frame_host) {
  544. return render_frame_host->GetProcess()->GetID();
  545. }
  546. int AwPermissionManager::GetRenderFrameID(
  547. content::RenderFrameHost* render_frame_host) {
  548. return render_frame_host->GetRoutingID();
  549. }
  550. GURL AwPermissionManager::LastCommittedOrigin(
  551. content::RenderFrameHost* render_frame_host) {
  552. return permissions::PermissionUtil::GetLastCommittedOriginAsURL(
  553. render_frame_host);
  554. }
  555. AwBrowserPermissionRequestDelegate* AwPermissionManager::GetDelegate(
  556. int render_process_id,
  557. int render_frame_id) {
  558. return AwBrowserPermissionRequestDelegate::FromID(render_process_id,
  559. render_frame_id);
  560. }
  561. } // namespace android_webview