123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696 |
- // Copyright 2016 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "android_webview/browser/aw_permission_manager.h"
- #include <list>
- #include <memory>
- #include "android_webview/browser/aw_browser_permission_request_delegate.h"
- #include "android_webview/browser/permission/permission_callback.h"
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/memory/raw_ptr.h"
- #include "content/public/browser/permission_controller.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/blink/public/common/permissions/permission_utils.h"
- #include "url/gurl.h"
- using blink::PermissionType;
- using blink::mojom::PermissionStatus;
- namespace android_webview {
- namespace {
- int kRenderProcessIDForTesting = 8;
- int kRenderFrameIDForTesting = 19;
- const char kEmbeddingOrigin[] = "https://www.google.com/";
- const char kRequestingOrigin1[] = "https://www.google.com/";
- const char kRequestingOrigin2[] = "https://www.chromium.org/";
- class AwBrowserPermissionRequestDelegateForTesting final
- : public AwBrowserPermissionRequestDelegate {
- public:
- void EnqueueResponse(const std::string& origin,
- PermissionType type,
- bool grant) {
- for (auto it = request_.begin(); it != request_.end(); ++it) {
- if ((*it)->type != type || (*it)->origin != origin)
- continue;
- PermissionCallback callback = std::move((*it)->callback);
- request_.erase(it);
- std::move(callback).Run(grant);
- return;
- }
- response_.push_back(std::make_unique<Response>(origin, type, grant));
- }
- // AwBrowserPermissionRequestDelegate:
- void RequestProtectedMediaIdentifierPermission(
- const GURL& origin,
- PermissionCallback callback) override {}
- void CancelProtectedMediaIdentifierPermissionRequests(
- const GURL& origin) override {}
- void RequestGeolocationPermission(const GURL& origin,
- PermissionCallback callback) override {
- RequestPermission(origin, PermissionType::GEOLOCATION, std::move(callback));
- }
- void CancelGeolocationPermissionRequests(const GURL& origin) override {
- CancelPermission(origin, PermissionType::GEOLOCATION);
- }
- void RequestMIDISysexPermission(const GURL& origin,
- PermissionCallback callback) override {
- RequestPermission(origin, PermissionType::MIDI_SYSEX, std::move(callback));
- }
- void CancelMIDISysexPermissionRequests(const GURL& origin) override {
- CancelPermission(origin, PermissionType::MIDI_SYSEX);
- }
- private:
- void RequestPermission(const GURL& origin,
- PermissionType type,
- PermissionCallback callback) {
- for (auto it = response_.begin(); it != response_.end(); ++it) {
- if ((*it)->type != type || (*it)->origin != origin)
- continue;
- bool grant = (*it)->grant;
- response_.erase(it);
- std::move(callback).Run(grant);
- return;
- }
- request_.push_back(
- std::make_unique<Request>(origin, type, std::move(callback)));
- }
- void CancelPermission(const GURL& origin, PermissionType type) {
- for (auto it = request_.begin(); it != request_.end(); ++it) {
- if ((*it)->type != type || (*it)->origin != origin)
- continue;
- request_.erase(it);
- return;
- }
- NOTREACHED();
- }
- private:
- struct Request {
- GURL origin;
- PermissionType type;
- PermissionCallback callback;
- Request(const GURL& origin,
- PermissionType type,
- PermissionCallback callback)
- : origin(origin), type(type), callback(std::move(callback)) {}
- };
- struct Response {
- GURL origin;
- PermissionType type;
- bool grant;
- Response(const std::string& origin, PermissionType type, bool grant)
- : origin(GURL(origin)), type(type), grant(grant) {}
- };
- std::list<std::unique_ptr<Response>> response_;
- std::list<std::unique_ptr<Request>> request_;
- };
- class AwPermissionManagerForTesting : public AwPermissionManager {
- public:
- ~AwPermissionManagerForTesting() override {
- // Call CancelPermissionRequests() from here so that it calls virtual
- // methods correctly.
- CancelPermissionRequests();
- }
- void EnqueuePermissionResponse(const std::string& origin,
- PermissionType type,
- bool grant) {
- delegate()->EnqueueResponse(origin, type, grant);
- }
- private:
- AwBrowserPermissionRequestDelegateForTesting* delegate() {
- if (!delegate_) {
- delegate_ =
- std::make_unique<AwBrowserPermissionRequestDelegateForTesting>();
- }
- return delegate_.get();
- }
- // AwPermissionManager:
- int GetRenderProcessID(content::RenderFrameHost* render_frame_host) override {
- return kRenderProcessIDForTesting;
- }
- int GetRenderFrameID(content::RenderFrameHost* render_frame_host) override {
- return kRenderFrameIDForTesting;
- }
- GURL LastCommittedOrigin(
- content::RenderFrameHost* render_frame_host) override {
- return GURL(kEmbeddingOrigin);
- }
- AwBrowserPermissionRequestDelegate* GetDelegate(
- int render_process_id,
- int render_frame_id) override {
- CHECK_EQ(kRenderProcessIDForTesting, render_process_id);
- CHECK_EQ(kRenderFrameIDForTesting, render_frame_id);
- return delegate();
- }
- std::unique_ptr<AwBrowserPermissionRequestDelegateForTesting> delegate_;
- };
- class AwPermissionManagerTest : public testing::Test {
- public:
- AwPermissionManagerTest()
- : render_frame_host(nullptr) {}
- void PermissionRequestResponse(int id, const PermissionStatus status) {
- resolved_permission_status.push_back(status);
- resolved_permission_request_id.push_back(id);
- }
- void PermissionsRequestResponse(int id,
- const std::vector<PermissionStatus>& status) {
- resolved_permission_status.insert(resolved_permission_status.end(),
- status.begin(), status.end());
- for (size_t i = 0; i < status.size(); ++i)
- resolved_permission_request_id.push_back(id);
- }
- protected:
- void SetUp() override {
- manager = std::make_unique<AwPermissionManagerForTesting>();
- }
- void TearDown() override { manager.reset(); }
- void EnqueuePermissionResponse(const std::string& origin,
- PermissionType type,
- bool grant) {
- CHECK(manager);
- manager->EnqueuePermissionResponse(origin, type, grant);
- }
- std::unique_ptr<AwPermissionManagerForTesting> manager;
- // Use nullptr for testing. AwPermissionManagerForTesting override all methods
- // that touch RenderFrameHost to work with nullptr.
- raw_ptr<content::RenderFrameHost> render_frame_host;
- std::vector<PermissionStatus> resolved_permission_status;
- std::vector<int> resolved_permission_request_id;
- };
- // The most simple test, PermissionType::MIDI is hard-coded to be granted.
- TEST_F(AwPermissionManagerTest, MIDIPermissionIsGrantedSynchronously) {
- manager->RequestPermission(
- PermissionType::MIDI, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 0));
- ASSERT_EQ(1u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
- }
- // Test the case a delegate is called, and it resolves the permission
- // synchronously.
- TEST_F(AwPermissionManagerTest, SinglePermissionRequestIsGrantedSynchronously) {
- // Permission should be granted in this scenario.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::GEOLOCATION, true);
- manager->RequestPermission(
- PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 0));
- ASSERT_EQ(1u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
- // Permission should not be granted in this scenario.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::GEOLOCATION, false);
- manager->RequestPermission(
- PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 0));
- ASSERT_EQ(2u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[1]);
- }
- // Test the case a delegate is called, and it resolves the permission
- // asynchronously.
- TEST_F(AwPermissionManagerTest,
- SinglePermissionRequestIsGrantedAsynchronously) {
- manager->RequestPermission(
- PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 0));
- EXPECT_EQ(0u, resolved_permission_status.size());
- // This will resolve the permission.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::GEOLOCATION, true);
- ASSERT_EQ(1u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
- }
- // Test the case a delegate is called, and the manager is deleted before the
- // delegate callback is invoked.
- TEST_F(AwPermissionManagerTest, ManagerIsDeletedWhileDelegateProcesses) {
- manager->RequestPermission(
- PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 0));
- EXPECT_EQ(0u, resolved_permission_status.size());
- // Delete the manager.
- manager.reset();
- // All requests are cancelled internally.
- EXPECT_EQ(0u, resolved_permission_status.size());
- }
- // Test the case multiple permissions are requested for the same origin, and the
- // second permission is also resolved when the first permission is resolved.
- TEST_F(AwPermissionManagerTest,
- MultiplePermissionRequestsAreGrantedTogether) {
- manager->RequestPermission(
- PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 1));
- manager->RequestPermission(
- PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 2));
- EXPECT_EQ(0u, resolved_permission_status.size());
- // This will resolve the permission.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::GEOLOCATION, true);
- ASSERT_EQ(2u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
- }
- // Test the case multiple permissions are requested for different origins, and
- // each permission is resolved respectively in the requested order.
- TEST_F(AwPermissionManagerTest,
- MultiplePermissionRequestsAreGrantedRespectively) {
- manager->RequestPermission(
- PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 1));
- manager->RequestPermission(
- PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin2),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 2));
- EXPECT_EQ(0u, resolved_permission_status.size());
- // This will resolve the first request.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::GEOLOCATION, true);
- ASSERT_EQ(1u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
- EXPECT_EQ(1, resolved_permission_request_id[0]);
- // This will resolve the second request.
- manager->EnqueuePermissionResponse(kRequestingOrigin2,
- PermissionType::GEOLOCATION, false);
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[1]);
- EXPECT_EQ(2, resolved_permission_request_id[1]);
- }
- // Test the case multiple permissions are requested through single
- // RequestPermissions call, then resolved synchronously.
- TEST_F(AwPermissionManagerTest,
- SinglePermissionsRequestIsGrantedSynchronously) {
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::MIDI_SYSEX, false);
- std::vector<PermissionType> permissions = {PermissionType::MIDI,
- PermissionType::MIDI_SYSEX};
- manager->RequestPermissions(
- permissions, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
- base::Unretained(this), 0));
- ASSERT_EQ(2u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[1]);
- }
- // Test the case multiple permissions are requested through single
- // RequestPermissions call, then one is resolved synchronously, the other is
- // resolved asynchronously.
- TEST_F(AwPermissionManagerTest,
- SinglePermissionsRequestIsGrantedAsynchronously) {
- std::vector<PermissionType> permissions = {PermissionType::MIDI,
- PermissionType::MIDI_SYSEX};
- manager->RequestPermissions(
- permissions, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
- base::Unretained(this), 0));
- // PermissionType::MIDI is resolved synchronously, but all permissions result
- // are notified together when all permissions are resolved.
- EXPECT_EQ(0u, resolved_permission_status.size());
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::MIDI_SYSEX, false);
- ASSERT_EQ(2u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[1]);
- }
- // Test the case multiple permissions are requested multiple times as follow.
- // 1. Permission A and B are requested.
- // 2. Permission A is resolved.
- // 3. Permission A is requested for the same origin before the B is resolved.
- TEST_F(AwPermissionManagerTest, ComplicatedRequestScenario1) {
- // In the first case, the permission A is a type that does not call an
- // internal delegate method.
- std::vector<PermissionType> permissions_1 = {PermissionType::MIDI,
- PermissionType::MIDI_SYSEX};
- manager->RequestPermissions(
- permissions_1, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
- base::Unretained(this), 1));
- EXPECT_EQ(0u, resolved_permission_status.size());
- manager->RequestPermission(
- PermissionType::MIDI, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 2));
- ASSERT_EQ(1u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
- EXPECT_EQ(2, resolved_permission_request_id[0]);
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::MIDI_SYSEX, true);
- ASSERT_EQ(3u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
- EXPECT_EQ(1, resolved_permission_request_id[1]);
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[2]);
- EXPECT_EQ(1, resolved_permission_request_id[2]);
- // In the second case, the permission A is a type that calls an internal
- // delegate method.
- std::vector<PermissionType> permissions_2 = {PermissionType::GEOLOCATION,
- PermissionType::MIDI_SYSEX};
- manager->RequestPermissions(
- permissions_2, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
- base::Unretained(this), 3));
- ASSERT_EQ(3u, resolved_permission_status.size());
- // The permission A is resolved, but the first request isn't finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::GEOLOCATION, false);
- ASSERT_EQ(3u, resolved_permission_status.size());
- manager->RequestPermission(
- PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 4));
- // The second request is finished first by using the resolved result for the
- // first request.
- ASSERT_EQ(4u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[3]);
- EXPECT_EQ(4, resolved_permission_request_id[3]);
- // Then the first request is finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::MIDI_SYSEX, true);
- ASSERT_EQ(6u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[4]);
- EXPECT_EQ(3, resolved_permission_request_id[4]);
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[5]);
- EXPECT_EQ(3, resolved_permission_request_id[5]);
- }
- // Test the case multiple permissions are requested multiple times as follow.
- // 1. Permission A and B are requested.
- // 2. Permission A is resolved.
- // 3. Permission A is requested for a different origin before the B is
- // resolved.
- TEST_F(AwPermissionManagerTest, ComplicatedRequestScenario2) {
- // In the first case, the permission A is a type that does not call an
- // internal delegate method.
- std::vector<PermissionType> permissions_1 = {PermissionType::MIDI,
- PermissionType::MIDI_SYSEX};
- manager->RequestPermissions(
- permissions_1, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
- base::Unretained(this), 1));
- EXPECT_EQ(0u, resolved_permission_status.size());
- manager->RequestPermission(
- PermissionType::MIDI, render_frame_host, GURL(kRequestingOrigin2), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 2));
- ASSERT_EQ(1u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
- EXPECT_EQ(2, resolved_permission_request_id[0]);
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::MIDI_SYSEX, true);
- ASSERT_EQ(3u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
- EXPECT_EQ(1, resolved_permission_request_id[1]);
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[2]);
- EXPECT_EQ(1, resolved_permission_request_id[2]);
- // In the second case, the permission A is a type that calls an internal
- // delegate method.
- std::vector<PermissionType> permissions_2 = {PermissionType::GEOLOCATION,
- PermissionType::MIDI_SYSEX};
- manager->RequestPermissions(
- permissions_2, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
- base::Unretained(this), 3));
- ASSERT_EQ(3u, resolved_permission_status.size());
- // The permission A is resolved, but the first request isn't finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::GEOLOCATION, false);
- ASSERT_EQ(3u, resolved_permission_status.size());
- // The second request could be resolved synchronously even if the first
- // request isn't finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin2,
- PermissionType::GEOLOCATION, true);
- manager->RequestPermission(
- PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin2),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 4));
- ASSERT_EQ(4u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[3]);
- EXPECT_EQ(4, resolved_permission_request_id[3]);
- // The first request is finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::MIDI_SYSEX, true);
- ASSERT_EQ(6u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[4]);
- EXPECT_EQ(3, resolved_permission_request_id[4]);
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[5]);
- EXPECT_EQ(3, resolved_permission_request_id[5]);
- }
- // Test the case multiple permissions are requested multiple times as follow.
- // 1. Permission A and B are requested.
- // 2. Permission B is resolved.
- // 3. Permission A is requested for the same origin before the A is resolved.
- TEST_F(AwPermissionManagerTest, ComplicatedRequestScenario3) {
- // In the first case, the permission A is a type that does not call an
- // internal delegate method.
- std::vector<PermissionType> permissions_1 = {PermissionType::MIDI,
- PermissionType::MIDI_SYSEX};
- manager->RequestPermissions(
- permissions_1, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
- base::Unretained(this), 1));
- EXPECT_EQ(0u, resolved_permission_status.size());
- manager->RequestPermission(
- PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin1),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 2));
- EXPECT_EQ(0u, resolved_permission_status.size());
- // Resolving the first request results in both requests finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::MIDI_SYSEX, false);
- ASSERT_EQ(3u, resolved_permission_status.size());
- // Note: The result order in the same requiest is ensured, but each results
- // for a request can be swapped because the manager use IDMap to resolve
- // matched requests.
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
- EXPECT_EQ(1, resolved_permission_request_id[1]);
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[2]);
- EXPECT_EQ(1, resolved_permission_request_id[2]);
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[0]);
- EXPECT_EQ(2, resolved_permission_request_id[0]);
- // In the second case, the permission A is a type that calls an internal
- // delegate method.
- std::vector<PermissionType> permissions_2 = {PermissionType::GEOLOCATION,
- PermissionType::MIDI_SYSEX};
- manager->RequestPermissions(
- permissions_2, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
- base::Unretained(this), 3));
- ASSERT_EQ(3u, resolved_permission_status.size());
- // The permission B is resolved, but the first request isn't finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::GEOLOCATION, false);
- ASSERT_EQ(3u, resolved_permission_status.size());
- manager->RequestPermission(
- PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin1),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 4));
- ASSERT_EQ(3u, resolved_permission_status.size());
- // Resolving the first request results in both requests finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::MIDI_SYSEX, true);
- ASSERT_EQ(6u, resolved_permission_status.size());
- // Order can be swapped. See Note in ComplicatedRequestScenario1.
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[4]);
- EXPECT_EQ(3, resolved_permission_request_id[4]);
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[5]);
- EXPECT_EQ(3, resolved_permission_request_id[5]);
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[3]);
- EXPECT_EQ(4, resolved_permission_request_id[3]);
- }
- // Test the case multiple permissions are requested multiple times as follow.
- // 1. Permission A and B are requested.
- // 2. Permission B is resolved.
- // 3. Permission A is requested for a different origin before the A is
- // resolved.
- TEST_F(AwPermissionManagerTest, ComplicatedRequestScenario4) {
- // In the first case, the permission A is a type that does not call an
- // internal delegate method.
- std::vector<PermissionType> permissions_1 = {PermissionType::MIDI,
- PermissionType::MIDI_SYSEX};
- manager->RequestPermissions(
- permissions_1, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
- base::Unretained(this), 1));
- EXPECT_EQ(0u, resolved_permission_status.size());
- manager->RequestPermission(
- PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin2),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 2));
- EXPECT_EQ(0u, resolved_permission_status.size());
- // The second request could be resolved synchronously even if the first
- // request isn't finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin2,
- PermissionType::MIDI_SYSEX, true);
- ASSERT_EQ(1u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
- EXPECT_EQ(2, resolved_permission_request_id[0]);
- // The first request is finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::MIDI_SYSEX, false);
- ASSERT_EQ(3u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
- EXPECT_EQ(1, resolved_permission_request_id[1]);
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[2]);
- EXPECT_EQ(1, resolved_permission_request_id[2]);
- // In the second case, the permission A is a type that calls an internal
- // delegate method.
- std::vector<PermissionType> permissions_2 = {PermissionType::GEOLOCATION,
- PermissionType::MIDI_SYSEX};
- manager->RequestPermissions(
- permissions_2, render_frame_host, GURL(kRequestingOrigin1), true,
- base::BindOnce(&AwPermissionManagerTest::PermissionsRequestResponse,
- base::Unretained(this), 3));
- ASSERT_EQ(3u, resolved_permission_status.size());
- // The permission B is resolved, but the first request isn't finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::GEOLOCATION, false);
- ASSERT_EQ(3u, resolved_permission_status.size());
- manager->RequestPermission(
- PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin2),
- true,
- base::BindOnce(&AwPermissionManagerTest::PermissionRequestResponse,
- base::Unretained(this), 4));
- ASSERT_EQ(3u, resolved_permission_status.size());
- // The second request could be resolved synchronously even if the first
- // request isn't finished.
- manager->EnqueuePermissionResponse(kRequestingOrigin2,
- PermissionType::MIDI_SYSEX, false);
- ASSERT_EQ(4u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[3]);
- EXPECT_EQ(4, resolved_permission_request_id[3]);
- // Resolving the first request results in resuming the second request.
- manager->EnqueuePermissionResponse(kRequestingOrigin1,
- PermissionType::MIDI_SYSEX, false);
- ASSERT_EQ(6u, resolved_permission_status.size());
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[4]);
- EXPECT_EQ(3, resolved_permission_request_id[4]);
- EXPECT_EQ(PermissionStatus::DENIED, resolved_permission_status[5]);
- EXPECT_EQ(3, resolved_permission_request_id[5]);
- }
- } // namespace
- } // namespace android_webview
|