aw_permission_manager_unittest.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. // Copyright 2016 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 <list>
  6. #include <memory>
  7. #include "android_webview/browser/aw_browser_permission_request_delegate.h"
  8. #include "android_webview/browser/permission/permission_callback.h"
  9. #include "base/bind.h"
  10. #include "base/callback_helpers.h"
  11. #include "base/memory/raw_ptr.h"
  12. #include "content/public/browser/permission_controller.h"
  13. #include "testing/gtest/include/gtest/gtest.h"
  14. #include "third_party/blink/public/common/permissions/permission_utils.h"
  15. #include "url/gurl.h"
  16. using blink::PermissionType;
  17. using blink::mojom::PermissionStatus;
  18. namespace android_webview {
  19. namespace {
  20. int kRenderProcessIDForTesting = 8;
  21. int kRenderFrameIDForTesting = 19;
  22. const char kEmbeddingOrigin[] = "https://www.google.com/";
  23. const char kRequestingOrigin1[] = "https://www.google.com/";
  24. const char kRequestingOrigin2[] = "https://www.chromium.org/";
  25. class AwBrowserPermissionRequestDelegateForTesting final
  26. : public AwBrowserPermissionRequestDelegate {
  27. public:
  28. void EnqueueResponse(const std::string& origin,
  29. PermissionType type,
  30. bool grant) {
  31. for (auto it = request_.begin(); it != request_.end(); ++it) {
  32. if ((*it)->type != type || (*it)->origin != origin)
  33. continue;
  34. PermissionCallback callback = std::move((*it)->callback);
  35. request_.erase(it);
  36. std::move(callback).Run(grant);
  37. return;
  38. }
  39. response_.push_back(std::make_unique<Response>(origin, type, grant));
  40. }
  41. // AwBrowserPermissionRequestDelegate:
  42. void RequestProtectedMediaIdentifierPermission(
  43. const GURL& origin,
  44. PermissionCallback callback) override {}
  45. void CancelProtectedMediaIdentifierPermissionRequests(
  46. const GURL& origin) override {}
  47. void RequestGeolocationPermission(const GURL& origin,
  48. PermissionCallback callback) override {
  49. RequestPermission(origin, PermissionType::GEOLOCATION, std::move(callback));
  50. }
  51. void CancelGeolocationPermissionRequests(const GURL& origin) override {
  52. CancelPermission(origin, PermissionType::GEOLOCATION);
  53. }
  54. void RequestMIDISysexPermission(const GURL& origin,
  55. PermissionCallback callback) override {
  56. RequestPermission(origin, PermissionType::MIDI_SYSEX, std::move(callback));
  57. }
  58. void CancelMIDISysexPermissionRequests(const GURL& origin) override {
  59. CancelPermission(origin, PermissionType::MIDI_SYSEX);
  60. }
  61. private:
  62. void RequestPermission(const GURL& origin,
  63. PermissionType type,
  64. PermissionCallback callback) {
  65. for (auto it = response_.begin(); it != response_.end(); ++it) {
  66. if ((*it)->type != type || (*it)->origin != origin)
  67. continue;
  68. bool grant = (*it)->grant;
  69. response_.erase(it);
  70. std::move(callback).Run(grant);
  71. return;
  72. }
  73. request_.push_back(
  74. std::make_unique<Request>(origin, type, std::move(callback)));
  75. }
  76. void CancelPermission(const GURL& origin, PermissionType type) {
  77. for (auto it = request_.begin(); it != request_.end(); ++it) {
  78. if ((*it)->type != type || (*it)->origin != origin)
  79. continue;
  80. request_.erase(it);
  81. return;
  82. }
  83. NOTREACHED();
  84. }
  85. private:
  86. struct Request {
  87. GURL origin;
  88. PermissionType type;
  89. PermissionCallback callback;
  90. Request(const GURL& origin,
  91. PermissionType type,
  92. PermissionCallback callback)
  93. : origin(origin), type(type), callback(std::move(callback)) {}
  94. };
  95. struct Response {
  96. GURL origin;
  97. PermissionType type;
  98. bool grant;
  99. Response(const std::string& origin, PermissionType type, bool grant)
  100. : origin(GURL(origin)), type(type), grant(grant) {}
  101. };
  102. std::list<std::unique_ptr<Response>> response_;
  103. std::list<std::unique_ptr<Request>> request_;
  104. };
  105. class AwPermissionManagerForTesting : public AwPermissionManager {
  106. public:
  107. ~AwPermissionManagerForTesting() override {
  108. // Call CancelPermissionRequests() from here so that it calls virtual
  109. // methods correctly.
  110. CancelPermissionRequests();
  111. }
  112. void EnqueuePermissionResponse(const std::string& origin,
  113. PermissionType type,
  114. bool grant) {
  115. delegate()->EnqueueResponse(origin, type, grant);
  116. }
  117. private:
  118. AwBrowserPermissionRequestDelegateForTesting* delegate() {
  119. if (!delegate_) {
  120. delegate_ =
  121. std::make_unique<AwBrowserPermissionRequestDelegateForTesting>();
  122. }
  123. return delegate_.get();
  124. }
  125. // AwPermissionManager:
  126. int GetRenderProcessID(content::RenderFrameHost* render_frame_host) override {
  127. return kRenderProcessIDForTesting;
  128. }
  129. int GetRenderFrameID(content::RenderFrameHost* render_frame_host) override {
  130. return kRenderFrameIDForTesting;
  131. }
  132. GURL LastCommittedOrigin(
  133. content::RenderFrameHost* render_frame_host) override {
  134. return GURL(kEmbeddingOrigin);
  135. }
  136. AwBrowserPermissionRequestDelegate* GetDelegate(
  137. int render_process_id,
  138. int render_frame_id) override {
  139. CHECK_EQ(kRenderProcessIDForTesting, render_process_id);
  140. CHECK_EQ(kRenderFrameIDForTesting, render_frame_id);
  141. return delegate();
  142. }
  143. std::unique_ptr<AwBrowserPermissionRequestDelegateForTesting> delegate_;
  144. };
  145. class AwPermissionManagerTest : public testing::Test {
  146. public:
  147. AwPermissionManagerTest()
  148. : render_frame_host(nullptr) {}
  149. void PermissionRequestResponse(int id, const PermissionStatus status) {
  150. resolved_permission_status.push_back(status);
  151. resolved_permission_request_id.push_back(id);
  152. }
  153. void PermissionsRequestResponse(int id,
  154. const std::vector<PermissionStatus>& status) {
  155. resolved_permission_status.insert(resolved_permission_status.end(),
  156. status.begin(), status.end());
  157. for (size_t i = 0; i < status.size(); ++i)
  158. resolved_permission_request_id.push_back(id);
  159. }
  160. protected:
  161. void SetUp() override {
  162. manager = std::make_unique<AwPermissionManagerForTesting>();
  163. }
  164. void TearDown() override { manager.reset(); }
  165. void EnqueuePermissionResponse(const std::string& origin,
  166. PermissionType type,
  167. bool grant) {
  168. CHECK(manager);
  169. manager->EnqueuePermissionResponse(origin, type, grant);
  170. }
  171. std::unique_ptr<AwPermissionManagerForTesting> manager;
  172. // Use nullptr for testing. AwPermissionManagerForTesting override all methods
  173. // that touch RenderFrameHost to work with nullptr.
  174. raw_ptr<content::RenderFrameHost> render_frame_host;
  175. std::vector<PermissionStatus> resolved_permission_status;
  176. std::vector<int> resolved_permission_request_id;
  177. };
  178. // The most simple test, PermissionType::MIDI is hard-coded to be granted.
  179. TEST_F(AwPermissionManagerTest, MIDIPermissionIsGrantedSynchronously) {
  180. manager->RequestPermission(
  181. PermissionType::MIDI, render_frame_host, GURL(kRequestingOrigin1), true,
  182. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  183. base::Unretained(this), 0));
  184. ASSERT_EQ(1u, resolved_permission_status.size());
  185. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  186. }
  187. // Test the case a delegate is called, and it resolves the permission
  188. // synchronously.
  189. TEST_F(AwPermissionManagerTest, SinglePermissionRequestIsGrantedSynchronously) {
  190. // Permission should be granted in this scenario.
  191. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  192. PermissionType::GEOLOCATION, true);
  193. manager->RequestPermission(
  194. PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
  195. true,
  196. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  197. base::Unretained(this), 0));
  198. ASSERT_EQ(1u, resolved_permission_status.size());
  199. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  200. // Permission should not be granted in this scenario.
  201. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  202. PermissionType::GEOLOCATION, false);
  203. manager->RequestPermission(
  204. PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
  205. true,
  206. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  207. base::Unretained(this), 0));
  208. ASSERT_EQ(2u, resolved_permission_status.size());
  209. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[1]);
  210. }
  211. // Test the case a delegate is called, and it resolves the permission
  212. // asynchronously.
  213. TEST_F(AwPermissionManagerTest,
  214. SinglePermissionRequestIsGrantedAsynchronously) {
  215. manager->RequestPermission(
  216. PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
  217. true,
  218. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  219. base::Unretained(this), 0));
  220. EXPECT_EQ(0u, resolved_permission_status.size());
  221. // This will resolve the permission.
  222. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  223. PermissionType::GEOLOCATION, true);
  224. ASSERT_EQ(1u, resolved_permission_status.size());
  225. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  226. }
  227. // Test the case a delegate is called, and the manager is deleted before the
  228. // delegate callback is invoked.
  229. TEST_F(AwPermissionManagerTest, ManagerIsDeletedWhileDelegateProcesses) {
  230. manager->RequestPermission(
  231. PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
  232. true,
  233. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  234. base::Unretained(this), 0));
  235. EXPECT_EQ(0u, resolved_permission_status.size());
  236. // Delete the manager.
  237. manager.reset();
  238. // All requests are cancelled internally.
  239. EXPECT_EQ(0u, resolved_permission_status.size());
  240. }
  241. // Test the case multiple permissions are requested for the same origin, and the
  242. // second permission is also resolved when the first permission is resolved.
  243. TEST_F(AwPermissionManagerTest,
  244. MultiplePermissionRequestsAreGrantedTogether) {
  245. manager->RequestPermission(
  246. PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
  247. true,
  248. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  249. base::Unretained(this), 1));
  250. manager->RequestPermission(
  251. PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
  252. true,
  253. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  254. base::Unretained(this), 2));
  255. EXPECT_EQ(0u, resolved_permission_status.size());
  256. // This will resolve the permission.
  257. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  258. PermissionType::GEOLOCATION, true);
  259. ASSERT_EQ(2u, resolved_permission_status.size());
  260. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  261. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
  262. }
  263. // Test the case multiple permissions are requested for different origins, and
  264. // each permission is resolved respectively in the requested order.
  265. TEST_F(AwPermissionManagerTest,
  266. MultiplePermissionRequestsAreGrantedRespectively) {
  267. manager->RequestPermission(
  268. PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
  269. true,
  270. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  271. base::Unretained(this), 1));
  272. manager->RequestPermission(
  273. PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin2),
  274. true,
  275. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  276. base::Unretained(this), 2));
  277. EXPECT_EQ(0u, resolved_permission_status.size());
  278. // This will resolve the first request.
  279. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  280. PermissionType::GEOLOCATION, true);
  281. ASSERT_EQ(1u, resolved_permission_status.size());
  282. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  283. EXPECT_EQ(1, resolved_permission_request_id[0]);
  284. // This will resolve the second request.
  285. manager->EnqueuePermissionResponse(kRequestingOrigin2,
  286. PermissionType::GEOLOCATION, false);
  287. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[1]);
  288. EXPECT_EQ(2, resolved_permission_request_id[1]);
  289. }
  290. // Test the case multiple permissions are requested through single
  291. // RequestPermissions call, then resolved synchronously.
  292. TEST_F(AwPermissionManagerTest,
  293. SinglePermissionsRequestIsGrantedSynchronously) {
  294. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  295. PermissionType::MIDI_SYSEX, false);
  296. std::vector<PermissionType> permissions = {PermissionType::MIDI,
  297. PermissionType::MIDI_SYSEX};
  298. manager->RequestPermissions(
  299. permissions, render_frame_host, GURL(kRequestingOrigin1), true,
  300. base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
  301. base::Unretained(this), 0));
  302. ASSERT_EQ(2u, resolved_permission_status.size());
  303. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  304. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[1]);
  305. }
  306. // Test the case multiple permissions are requested through single
  307. // RequestPermissions call, then one is resolved synchronously, the other is
  308. // resolved asynchronously.
  309. TEST_F(AwPermissionManagerTest,
  310. SinglePermissionsRequestIsGrantedAsynchronously) {
  311. std::vector<PermissionType> permissions = {PermissionType::MIDI,
  312. PermissionType::MIDI_SYSEX};
  313. manager->RequestPermissions(
  314. permissions, render_frame_host, GURL(kRequestingOrigin1), true,
  315. base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
  316. base::Unretained(this), 0));
  317. // PermissionType::MIDI is resolved synchronously, but all permissions result
  318. // are notified together when all permissions are resolved.
  319. EXPECT_EQ(0u, resolved_permission_status.size());
  320. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  321. PermissionType::MIDI_SYSEX, false);
  322. ASSERT_EQ(2u, resolved_permission_status.size());
  323. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  324. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[1]);
  325. }
  326. // Test the case multiple permissions are requested multiple times as follow.
  327. // 1. Permission A and B are requested.
  328. // 2. Permission A is resolved.
  329. // 3. Permission A is requested for the same origin before the B is resolved.
  330. TEST_F(AwPermissionManagerTest, ComplicatedRequestScenario1) {
  331. // In the first case, the permission A is a type that does not call an
  332. // internal delegate method.
  333. std::vector<PermissionType> permissions_1 = {PermissionType::MIDI,
  334. PermissionType::MIDI_SYSEX};
  335. manager->RequestPermissions(
  336. permissions_1, render_frame_host, GURL(kRequestingOrigin1), true,
  337. base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
  338. base::Unretained(this), 1));
  339. EXPECT_EQ(0u, resolved_permission_status.size());
  340. manager->RequestPermission(
  341. PermissionType::MIDI, render_frame_host, GURL(kRequestingOrigin1), true,
  342. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  343. base::Unretained(this), 2));
  344. ASSERT_EQ(1u, resolved_permission_status.size());
  345. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  346. EXPECT_EQ(2, resolved_permission_request_id[0]);
  347. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  348. PermissionType::MIDI_SYSEX, true);
  349. ASSERT_EQ(3u, resolved_permission_status.size());
  350. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
  351. EXPECT_EQ(1, resolved_permission_request_id[1]);
  352. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[2]);
  353. EXPECT_EQ(1, resolved_permission_request_id[2]);
  354. // In the second case, the permission A is a type that calls an internal
  355. // delegate method.
  356. std::vector<PermissionType> permissions_2 = {PermissionType::GEOLOCATION,
  357. PermissionType::MIDI_SYSEX};
  358. manager->RequestPermissions(
  359. permissions_2, render_frame_host, GURL(kRequestingOrigin1), true,
  360. base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
  361. base::Unretained(this), 3));
  362. ASSERT_EQ(3u, resolved_permission_status.size());
  363. // The permission A is resolved, but the first request isn't finished.
  364. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  365. PermissionType::GEOLOCATION, false);
  366. ASSERT_EQ(3u, resolved_permission_status.size());
  367. manager->RequestPermission(
  368. PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
  369. true,
  370. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  371. base::Unretained(this), 4));
  372. // The second request is finished first by using the resolved result for the
  373. // first request.
  374. ASSERT_EQ(4u, resolved_permission_status.size());
  375. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[3]);
  376. EXPECT_EQ(4, resolved_permission_request_id[3]);
  377. // Then the first request is finished.
  378. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  379. PermissionType::MIDI_SYSEX, true);
  380. ASSERT_EQ(6u, resolved_permission_status.size());
  381. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[4]);
  382. EXPECT_EQ(3, resolved_permission_request_id[4]);
  383. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[5]);
  384. EXPECT_EQ(3, resolved_permission_request_id[5]);
  385. }
  386. // Test the case multiple permissions are requested multiple times as follow.
  387. // 1. Permission A and B are requested.
  388. // 2. Permission A is resolved.
  389. // 3. Permission A is requested for a different origin before the B is
  390. // resolved.
  391. TEST_F(AwPermissionManagerTest, ComplicatedRequestScenario2) {
  392. // In the first case, the permission A is a type that does not call an
  393. // internal delegate method.
  394. std::vector<PermissionType> permissions_1 = {PermissionType::MIDI,
  395. PermissionType::MIDI_SYSEX};
  396. manager->RequestPermissions(
  397. permissions_1, render_frame_host, GURL(kRequestingOrigin1), true,
  398. base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
  399. base::Unretained(this), 1));
  400. EXPECT_EQ(0u, resolved_permission_status.size());
  401. manager->RequestPermission(
  402. PermissionType::MIDI, render_frame_host, GURL(kRequestingOrigin2), true,
  403. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  404. base::Unretained(this), 2));
  405. ASSERT_EQ(1u, resolved_permission_status.size());
  406. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  407. EXPECT_EQ(2, resolved_permission_request_id[0]);
  408. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  409. PermissionType::MIDI_SYSEX, true);
  410. ASSERT_EQ(3u, resolved_permission_status.size());
  411. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
  412. EXPECT_EQ(1, resolved_permission_request_id[1]);
  413. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[2]);
  414. EXPECT_EQ(1, resolved_permission_request_id[2]);
  415. // In the second case, the permission A is a type that calls an internal
  416. // delegate method.
  417. std::vector<PermissionType> permissions_2 = {PermissionType::GEOLOCATION,
  418. PermissionType::MIDI_SYSEX};
  419. manager->RequestPermissions(
  420. permissions_2, render_frame_host, GURL(kRequestingOrigin1), true,
  421. base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
  422. base::Unretained(this), 3));
  423. ASSERT_EQ(3u, resolved_permission_status.size());
  424. // The permission A is resolved, but the first request isn't finished.
  425. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  426. PermissionType::GEOLOCATION, false);
  427. ASSERT_EQ(3u, resolved_permission_status.size());
  428. // The second request could be resolved synchronously even if the first
  429. // request isn't finished.
  430. manager->EnqueuePermissionResponse(kRequestingOrigin2,
  431. PermissionType::GEOLOCATION, true);
  432. manager->RequestPermission(
  433. PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin2),
  434. true,
  435. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  436. base::Unretained(this), 4));
  437. ASSERT_EQ(4u, resolved_permission_status.size());
  438. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[3]);
  439. EXPECT_EQ(4, resolved_permission_request_id[3]);
  440. // The first request is finished.
  441. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  442. PermissionType::MIDI_SYSEX, true);
  443. ASSERT_EQ(6u, resolved_permission_status.size());
  444. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[4]);
  445. EXPECT_EQ(3, resolved_permission_request_id[4]);
  446. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[5]);
  447. EXPECT_EQ(3, resolved_permission_request_id[5]);
  448. }
  449. // Test the case multiple permissions are requested multiple times as follow.
  450. // 1. Permission A and B are requested.
  451. // 2. Permission B is resolved.
  452. // 3. Permission A is requested for the same origin before the A is resolved.
  453. TEST_F(AwPermissionManagerTest, ComplicatedRequestScenario3) {
  454. // In the first case, the permission A is a type that does not call an
  455. // internal delegate method.
  456. std::vector<PermissionType> permissions_1 = {PermissionType::MIDI,
  457. PermissionType::MIDI_SYSEX};
  458. manager->RequestPermissions(
  459. permissions_1, render_frame_host, GURL(kRequestingOrigin1), true,
  460. base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
  461. base::Unretained(this), 1));
  462. EXPECT_EQ(0u, resolved_permission_status.size());
  463. manager->RequestPermission(
  464. PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin1),
  465. true,
  466. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  467. base::Unretained(this), 2));
  468. EXPECT_EQ(0u, resolved_permission_status.size());
  469. // Resolving the first request results in both requests finished.
  470. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  471. PermissionType::MIDI_SYSEX, false);
  472. ASSERT_EQ(3u, resolved_permission_status.size());
  473. // Note: The result order in the same requiest is ensured, but each results
  474. // for a request can be swapped because the manager use IDMap to resolve
  475. // matched requests.
  476. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
  477. EXPECT_EQ(1, resolved_permission_request_id[1]);
  478. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[2]);
  479. EXPECT_EQ(1, resolved_permission_request_id[2]);
  480. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[0]);
  481. EXPECT_EQ(2, resolved_permission_request_id[0]);
  482. // In the second case, the permission A is a type that calls an internal
  483. // delegate method.
  484. std::vector<PermissionType> permissions_2 = {PermissionType::GEOLOCATION,
  485. PermissionType::MIDI_SYSEX};
  486. manager->RequestPermissions(
  487. permissions_2, render_frame_host, GURL(kRequestingOrigin1), true,
  488. base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
  489. base::Unretained(this), 3));
  490. ASSERT_EQ(3u, resolved_permission_status.size());
  491. // The permission B is resolved, but the first request isn't finished.
  492. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  493. PermissionType::GEOLOCATION, false);
  494. ASSERT_EQ(3u, resolved_permission_status.size());
  495. manager->RequestPermission(
  496. PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin1),
  497. true,
  498. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  499. base::Unretained(this), 4));
  500. ASSERT_EQ(3u, resolved_permission_status.size());
  501. // Resolving the first request results in both requests finished.
  502. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  503. PermissionType::MIDI_SYSEX, true);
  504. ASSERT_EQ(6u, resolved_permission_status.size());
  505. // Order can be swapped. See Note in ComplicatedRequestScenario1.
  506. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[4]);
  507. EXPECT_EQ(3, resolved_permission_request_id[4]);
  508. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[5]);
  509. EXPECT_EQ(3, resolved_permission_request_id[5]);
  510. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[3]);
  511. EXPECT_EQ(4, resolved_permission_request_id[3]);
  512. }
  513. // Test the case multiple permissions are requested multiple times as follow.
  514. // 1. Permission A and B are requested.
  515. // 2. Permission B is resolved.
  516. // 3. Permission A is requested for a different origin before the A is
  517. // resolved.
  518. TEST_F(AwPermissionManagerTest, ComplicatedRequestScenario4) {
  519. // In the first case, the permission A is a type that does not call an
  520. // internal delegate method.
  521. std::vector<PermissionType> permissions_1 = {PermissionType::MIDI,
  522. PermissionType::MIDI_SYSEX};
  523. manager->RequestPermissions(
  524. permissions_1, render_frame_host, GURL(kRequestingOrigin1), true,
  525. base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
  526. base::Unretained(this), 1));
  527. EXPECT_EQ(0u, resolved_permission_status.size());
  528. manager->RequestPermission(
  529. PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin2),
  530. true,
  531. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  532. base::Unretained(this), 2));
  533. EXPECT_EQ(0u, resolved_permission_status.size());
  534. // The second request could be resolved synchronously even if the first
  535. // request isn't finished.
  536. manager->EnqueuePermissionResponse(kRequestingOrigin2,
  537. PermissionType::MIDI_SYSEX, true);
  538. ASSERT_EQ(1u, resolved_permission_status.size());
  539. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  540. EXPECT_EQ(2, resolved_permission_request_id[0]);
  541. // The first request is finished.
  542. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  543. PermissionType::MIDI_SYSEX, false);
  544. ASSERT_EQ(3u, resolved_permission_status.size());
  545. EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
  546. EXPECT_EQ(1, resolved_permission_request_id[1]);
  547. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[2]);
  548. EXPECT_EQ(1, resolved_permission_request_id[2]);
  549. // In the second case, the permission A is a type that calls an internal
  550. // delegate method.
  551. std::vector<PermissionType> permissions_2 = {PermissionType::GEOLOCATION,
  552. PermissionType::MIDI_SYSEX};
  553. manager->RequestPermissions(
  554. permissions_2, render_frame_host, GURL(kRequestingOrigin1), true,
  555. base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
  556. base::Unretained(this), 3));
  557. ASSERT_EQ(3u, resolved_permission_status.size());
  558. // The permission B is resolved, but the first request isn't finished.
  559. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  560. PermissionType::GEOLOCATION, false);
  561. ASSERT_EQ(3u, resolved_permission_status.size());
  562. manager->RequestPermission(
  563. PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin2),
  564. true,
  565. base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
  566. base::Unretained(this), 4));
  567. ASSERT_EQ(3u, resolved_permission_status.size());
  568. // The second request could be resolved synchronously even if the first
  569. // request isn't finished.
  570. manager->EnqueuePermissionResponse(kRequestingOrigin2,
  571. PermissionType::MIDI_SYSEX, false);
  572. ASSERT_EQ(4u, resolved_permission_status.size());
  573. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[3]);
  574. EXPECT_EQ(4, resolved_permission_request_id[3]);
  575. // Resolving the first request results in resuming the second request.
  576. manager->EnqueuePermissionResponse(kRequestingOrigin1,
  577. PermissionType::MIDI_SYSEX, false);
  578. ASSERT_EQ(6u, resolved_permission_status.size());
  579. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[4]);
  580. EXPECT_EQ(3, resolved_permission_request_id[4]);
  581. EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[5]);
  582. EXPECT_EQ(3, resolved_permission_request_id[5]);
  583. }
  584. } // namespace
  585. } // namespace android_webview