// 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 "base/bind.h"
#include "base/bind_helpers.h"
#include "content/public/browser/permission_manager.h"
#include "content/public/browser/permission_type.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using blink::mojom::PermissionStatus;
using content::PermissionType;

namespace android_webview {

namespace {

int kNoPendingOperation = -1;

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;
      const base::Callback<void(bool)> callback = (*it)->callback;
      request_.erase(it);
      callback.Run(grant);
      return;
    }
    response_.push_back(std::make_unique<Response>(origin, type, grant));
  }

  // AwBrowserPermissionRequestDelegate:
  void RequestProtectedMediaIdentifierPermission(
      const GURL& origin,
      const base::Callback<void(bool)>& callback) override {}

  void CancelProtectedMediaIdentifierPermissionRequests(
      const GURL& origin) override {}

  void RequestGeolocationPermission(
      const GURL& origin,
      const base::Callback<void(bool)>& callback) override {
    RequestPermission(origin, PermissionType::GEOLOCATION, callback);
  }

  void CancelGeolocationPermissionRequests(const GURL& origin) override {
    CancelPermission(origin, PermissionType::GEOLOCATION);
  }

  void RequestMIDISysexPermission(
      const GURL& origin,
      const base::Callback<void(bool)>& callback) override {
    RequestPermission(origin, PermissionType::MIDI_SYSEX, callback);
  }

  void CancelMIDISysexPermissionRequests(const GURL& origin) override {
    CancelPermission(origin, PermissionType::MIDI_SYSEX);
  }

 private:
  void RequestPermission(const GURL& origin,
                         PermissionType type,
                         const base::Callback<void(bool)>& 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);
      callback.Run(grant);
      return;
    }
    request_.push_back(std::make_unique<Request>(origin, type, 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;
    base::Callback<void(bool)> callback;

    Request(const GURL& origin,
            PermissionType type,
            const base::Callback<void(bool)>& callback)
        : origin(origin), type(type), callback(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_.reset(new 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.reset(new 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.
  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) {
  int request_id = manager->RequestPermission(
      PermissionType::MIDI, render_frame_host, GURL(kRequestingOrigin1), true,
      base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                 base::Unretained(this), 0));
  EXPECT_EQ(kNoPendingOperation, request_id);
  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);
  int request_id = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 0));
  EXPECT_EQ(kNoPendingOperation, request_id);
  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);
  request_id = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 0));
  EXPECT_EQ(kNoPendingOperation, request_id);
  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) {
  int request_id = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 0));
  EXPECT_NE(kNoPendingOperation, request_id);
  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) {
  int request_id = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 0));

  EXPECT_NE(kNoPendingOperation, request_id);
  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) {
  int request_1 = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 1));
  EXPECT_NE(kNoPendingOperation, request_1);

  int request_2 = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 2));
  EXPECT_NE(kNoPendingOperation, request_2);

  EXPECT_NE(request_1, request_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) {
  int request_1 = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 1));
  EXPECT_NE(kNoPendingOperation, request_1);

  int request_2 = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin2),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 2));
  EXPECT_NE(kNoPendingOperation, request_2);

  EXPECT_NE(request_1, request_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};

  int request_id = manager->RequestPermissions(
      permissions,
      render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                       base::Unretained(this), 0));
  EXPECT_EQ(kNoPendingOperation, request_id);

  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};

  int request_id = manager->RequestPermissions(
      permissions,
      render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                       base::Unretained(this), 0));
  EXPECT_NE(kNoPendingOperation, request_id);

  // 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};

  int request_1 = manager->RequestPermissions(
      permissions_1,
      render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                       base::Unretained(this), 1));
  EXPECT_NE(kNoPendingOperation, request_1);
  EXPECT_EQ(0u, resolved_permission_status.size());

  int request_2 = manager->RequestPermission(
      PermissionType::MIDI, render_frame_host, GURL(kRequestingOrigin1), true,
      base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                 base::Unretained(this), 2));
  EXPECT_EQ(kNoPendingOperation, request_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};

  int request_3 = manager->RequestPermissions(
      permissions_2,
      render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                       base::Unretained(this), 3));
  EXPECT_NE(kNoPendingOperation, request_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());

  int request_4 = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 4));
  // The second request is finished first by using the resolved result for the
  // first request.
  EXPECT_EQ(kNoPendingOperation, request_4);
  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};

  int request_1 = manager->RequestPermissions(
      permissions_1,
      render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                       base::Unretained(this), 1));
  EXPECT_NE(kNoPendingOperation, request_1);
  EXPECT_EQ(0u, resolved_permission_status.size());

  int request_2 = manager->RequestPermission(
      PermissionType::MIDI, render_frame_host, GURL(kRequestingOrigin2), true,
      base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                 base::Unretained(this), 2));
  EXPECT_EQ(kNoPendingOperation, request_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};

  int request_3 = manager->RequestPermissions(
      permissions_2,
      render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                       base::Unretained(this), 3));
  EXPECT_NE(kNoPendingOperation, request_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);
  int request_4 = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin2),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 4));
  EXPECT_EQ(kNoPendingOperation, request_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};

  int request_1 = manager->RequestPermissions(
      permissions_1,
      render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                       base::Unretained(this), 1));
  EXPECT_NE(kNoPendingOperation, request_1);
  EXPECT_EQ(0u, resolved_permission_status.size());

  int request_2 = manager->RequestPermission(
      PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 2));
  EXPECT_NE(kNoPendingOperation, request_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};

  int request_3 = manager->RequestPermissions(
      permissions_2,
      render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                       base::Unretained(this), 3));
  EXPECT_NE(kNoPendingOperation, request_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());

  int request_4 = manager->RequestPermission(
      PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 4));
  EXPECT_NE(kNoPendingOperation, request_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};

  int request_1 = manager->RequestPermissions(
      permissions_1,
      render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                       base::Unretained(this), 1));
  EXPECT_NE(kNoPendingOperation, request_1);
  EXPECT_EQ(0u, resolved_permission_status.size());

  int request_2 = manager->RequestPermission(
      PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin2),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 2));
  EXPECT_NE(kNoPendingOperation, request_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};

  int request_3 = manager->RequestPermissions(
      permissions_2,
      render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                       base::Unretained(this), 3));
  EXPECT_NE(kNoPendingOperation, request_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());

  int request_4 = manager->RequestPermission(
      PermissionType::MIDI_SYSEX, render_frame_host, GURL(kRequestingOrigin2),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 4));
  EXPECT_NE(kNoPendingOperation, request_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]);
}

// Test the case CancelPermissionRequest is called for an invalid request.
TEST_F(AwPermissionManagerTest, InvalidRequestIsCancelled) {
  manager->CancelPermissionRequest(0);
}

// Test the case a delegate is called, and cancelled.
TEST_F(AwPermissionManagerTest, SinglePermissionRequestIsCancelled) {
  int request_id = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 0));
  EXPECT_NE(kNoPendingOperation, request_id);
  EXPECT_EQ(0u, resolved_permission_status.size());

  manager->CancelPermissionRequest(request_id);
  EXPECT_EQ(0u, resolved_permission_status.size());

  // This should not resolve the permission.
  manager->EnqueuePermissionResponse(kRequestingOrigin1,
                                     PermissionType::GEOLOCATION, true);
  EXPECT_EQ(0u, resolved_permission_status.size());
}

// Test the case multiple permissions are requested through single call, and
// cancelled.
TEST_F(AwPermissionManagerTest, SinglePermissionsRequestIsCancelled) {
  std::vector<PermissionType> permissions_1 = {PermissionType::MIDI,
                                               PermissionType::MIDI_SYSEX};

  int request_id = manager->RequestPermissions(
      permissions_1, render_frame_host, GURL(kRequestingOrigin1), true,
      base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                 base::Unretained(this), 0));
  EXPECT_NE(kNoPendingOperation, request_id);
  EXPECT_EQ(0u, resolved_permission_status.size());

  manager->CancelPermissionRequest(request_id);
  EXPECT_EQ(0u, resolved_permission_status.size());

  std::vector<PermissionType> permissions_2 = {PermissionType::GEOLOCATION,
                                               PermissionType::MIDI_SYSEX};

  request_id = manager->RequestPermissions(
      permissions_2, render_frame_host, GURL(kRequestingOrigin1), true,
      base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                 base::Unretained(this), 0));
  EXPECT_NE(kNoPendingOperation, request_id);
  EXPECT_EQ(0u, resolved_permission_status.size());

  manager->CancelPermissionRequest(request_id);
  EXPECT_EQ(0u, resolved_permission_status.size());

  // This should not resolve the permission.
  manager->EnqueuePermissionResponse(kRequestingOrigin1,
                                     PermissionType::GEOLOCATION, true);
  manager->EnqueuePermissionResponse(kRequestingOrigin1,
                                     PermissionType::MIDI_SYSEX, true);
  EXPECT_EQ(0u, resolved_permission_status.size());
}

// Test the case multiple permissions are requested, and cancelled as follow.
//  1. Permission A is requested.
//  2. Permission A is requested for the same origin again.
//  3. The first request is cancelled.
TEST_F(AwPermissionManagerTest, ComplicatedCancelScenario1) {
  int request_1 = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 1));
  EXPECT_NE(kNoPendingOperation, request_1);
  EXPECT_EQ(0u, resolved_permission_status.size());

  int request_2 = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 2));
  EXPECT_NE(kNoPendingOperation, request_2);
  EXPECT_EQ(0u, resolved_permission_status.size());

  EXPECT_NE(request_1, request_2);

  manager->CancelPermissionRequest(request_1);
  EXPECT_EQ(0u, resolved_permission_status.size());

  // This should resolve the second request.
  manager->EnqueuePermissionResponse(kRequestingOrigin1,
                                     PermissionType::GEOLOCATION, true);
  EXPECT_EQ(1u, resolved_permission_status.size());
  EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  EXPECT_EQ(2, resolved_permission_request_id[0]);
}

// Test the case multiple permissions are requested, and cancelled as follow.
//  1. Permission A is requested.
//  2. Permission A is requested for a different origin.
//  3. The first request is cancelled.
TEST_F(AwPermissionManagerTest, ComplicatedCancelScenario2) {
  int request_1 = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin1),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 1));
  EXPECT_NE(kNoPendingOperation, request_1);
  EXPECT_EQ(0u, resolved_permission_status.size());

  int request_2 = manager->RequestPermission(
      PermissionType::GEOLOCATION, render_frame_host, GURL(kRequestingOrigin2),
      true, base::Bind(&AwPermissionManagerTest::PermissionRequestResponse,
                       base::Unretained(this), 2));
  EXPECT_NE(kNoPendingOperation, request_2);
  EXPECT_EQ(0u, resolved_permission_status.size());

  EXPECT_NE(request_1, request_2);

  manager->CancelPermissionRequest(request_1);
  EXPECT_EQ(0u, resolved_permission_status.size());

  // This should not resolve the first request.
  manager->EnqueuePermissionResponse(kRequestingOrigin1,
                                     PermissionType::GEOLOCATION, true);
  EXPECT_EQ(0u, resolved_permission_status.size());

  // This should resolve the second request.
  manager->EnqueuePermissionResponse(kRequestingOrigin2,
                                     PermissionType::GEOLOCATION, true);
  EXPECT_EQ(1u, resolved_permission_status.size());
  EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  EXPECT_EQ(2, resolved_permission_request_id[0]);
}

// Test the case multiple permissions are requested, and cancelled as follow.
//  1. Permission A and B are requested.
//  2. Permission A and B are requested for a different origin.
//  3. Permission A for the second request is resolved.
//  4. The second request is cancelled.
TEST_F(AwPermissionManagerTest, ComplicatedCancelScenario3) {
  std::vector<PermissionType> permissions = {PermissionType::GEOLOCATION,
                                             PermissionType::MIDI_SYSEX};

  int request_1 = manager->RequestPermissions(
      permissions, render_frame_host, GURL(kRequestingOrigin1), true,
      base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                 base::Unretained(this), 1));
  EXPECT_NE(kNoPendingOperation, request_1);
  EXPECT_EQ(0u, resolved_permission_status.size());

  int request_2 = manager->RequestPermissions(
      permissions, render_frame_host, GURL(kRequestingOrigin2), true,
      base::Bind(&AwPermissionManagerTest::PermissionsRequestResponse,
                 base::Unretained(this), 2));
  EXPECT_NE(kNoPendingOperation, request_2);
  EXPECT_EQ(0u, resolved_permission_status.size());

  EXPECT_NE(request_1, request_2);

  manager->EnqueuePermissionResponse(kRequestingOrigin2,
                                     PermissionType::GEOLOCATION, true);

  manager->CancelPermissionRequest(request_1);
  EXPECT_EQ(0u, resolved_permission_status.size());

  // This should not resolve the first request.
  manager->EnqueuePermissionResponse(kRequestingOrigin1,
                                     PermissionType::GEOLOCATION, true);
  manager->EnqueuePermissionResponse(kRequestingOrigin1,
                                     PermissionType::MIDI_SYSEX, true);
  EXPECT_EQ(0u, resolved_permission_status.size());

  // This should resolve the second request.
  manager->EnqueuePermissionResponse(kRequestingOrigin2,
                                     PermissionType::MIDI_SYSEX, true);
  EXPECT_EQ(2u, resolved_permission_status.size());
  EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[0]);
  EXPECT_EQ(2, resolved_permission_request_id[0]);
  EXPECT_EQ(PermissionStatus::GRANTED, resolved_permission_status[1]);
  EXPECT_EQ(2, resolved_permission_request_id[1]);
}

}  // namespace

}  // namespace android_webview
