// Copyright 2020 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 "content/browser/mojo_binder_policy_applier.h"

#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "content/browser/mojo_binder_policy_map_impl.h"
#include "content/test/test_mojo_binder_policy_applier_unittest.mojom.h"
#include "mojo/public/cpp/bindings/generic_pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

// A test class that implements test interfaces and provides verification
// methods.
class TestReceiverCollector : public mojom::TestInterfaceForDefer,
                              public mojom::TestInterfaceForGrant,
                              public mojom::TestInterfaceForCancel,
                              public mojom::TestInterfaceForUnexpected {
 public:
  TestReceiverCollector() = default;

  ~TestReceiverCollector() override = default;

  // Deletes copy and move operations.
  TestReceiverCollector(const TestReceiverCollector& other) = delete;
  TestReceiverCollector& operator=(const TestReceiverCollector& other) = delete;
  TestReceiverCollector(TestReceiverCollector&&) = delete;
  TestReceiverCollector& operator=(TestReceiverCollector&&) = delete;

  void BindDeferInterface(
      mojo::PendingReceiver<mojom::TestInterfaceForDefer> receiver) {
    ASSERT_FALSE(defer_receiver_.is_bound());
    defer_receiver_.Bind(std::move(receiver));
  }

  void BindGrantInterface(
      mojo::PendingReceiver<mojom::TestInterfaceForGrant> receiver) {
    ASSERT_FALSE(grant_receiver_.is_bound());
    grant_receiver_.Bind(std::move(receiver));
  }

  void BindCancelInterface(
      mojo::PendingReceiver<mojom::TestInterfaceForCancel> receiver) {
    ASSERT_FALSE(cancel_receiver_.is_bound());
    cancel_receiver_.Bind(std::move(receiver));
  }

  void BindUnexpectedInterface(
      mojo::PendingReceiver<mojom::TestInterfaceForUnexpected> receiver) {
    ASSERT_FALSE(unexpected_receiver_.is_bound());
    unexpected_receiver_.Bind(std::move(receiver));
  }

  // mojom::TestInterfaceForDefer implementation.
  void Ping(PingCallback callback) override { NOTREACHED(); }

  // Will be called when MojoBinderPolicyApplier::ApplyPolicyToBinder()
  // handles a kCancel binding request.
  void Cancel(const std::string& interface_name) {
    is_cancelled_ = true;
    cancelled_interface_ = interface_name;
  }

  // Used to check if the cancel_closure of MojoBinderPolicyApplier was
  // executed.
  bool IsCancelled() { return is_cancelled_; }

  const std::string& cancelled_interface() const {
    return cancelled_interface_;
  }

  bool IsDeferReceiverBound() const { return defer_receiver_.is_bound(); }

  bool IsGrantReceiverBound() const { return grant_receiver_.is_bound(); }

  bool IsCancelReceiverBound() const { return cancel_receiver_.is_bound(); }

  bool IsUnexpectedReceiverBound() const {
    return unexpected_receiver_.is_bound();
  }

 private:
  mojo::Receiver<mojom::TestInterfaceForDefer> defer_receiver_{this};
  mojo::Receiver<mojom::TestInterfaceForGrant> grant_receiver_{this};
  mojo::Receiver<mojom::TestInterfaceForCancel> cancel_receiver_{this};
  mojo::Receiver<mojom::TestInterfaceForUnexpected> unexpected_receiver_{this};
  bool is_cancelled_ = false;
  std::string cancelled_interface_;
};

class MojoBinderPolicyApplierTest : public testing::Test,
                                    mojom::MojoContextProvider {
 public:
  MojoBinderPolicyApplierTest() = default;

  // mojom::MojoContextProvider
  void GrantAll() override { policy_applier_.GrantAll(); }

 protected:
  std::vector<base::OnceClosure>& deferred_binders() {
    return policy_applier_.deferred_binders_;
  }

  // Calls MojoBinderPolicyApplier::GrantAll() inside a Mojo message dispatch
  // stack.
  void RunGrantAll() {
    DCHECK(!receiver_.is_bound());
    receiver_.Bind(remote_.BindNewPipeAndPassReceiver());
    remote_->GrantAll();
    remote_.FlushForTesting();
  }

  const MojoBinderPolicyMapImpl policy_map_{
      {{"content.mojom.TestInterfaceForDefer",
        MojoBinderNonAssociatedPolicy::kDefer},
       {"content.mojom.TestInterfaceForGrant",
        MojoBinderNonAssociatedPolicy::kGrant},
       {"content.mojom.TestInterfaceForCancel",
        MojoBinderNonAssociatedPolicy::kCancel},
       {"content.mojom.TestInterfaceForUnexpected",
        MojoBinderNonAssociatedPolicy::kUnexpected}}};
  TestReceiverCollector collector_{};
  MojoBinderPolicyApplier policy_applier_{
      &policy_map_, base::BindOnce(&TestReceiverCollector::Cancel,
                                   base::Unretained(&collector_))};

 private:
  base::test::TaskEnvironment task_environment_;
  mojo::Remote<mojom::MojoContextProvider> remote_;
  mojo::Receiver<mojom::MojoContextProvider> receiver_{this};
};

// Verifies that interfaces whose policies are kGrant can be bound immediately.
TEST_F(MojoBinderPolicyApplierTest, GrantInEnforce) {
  // Initialize Mojo interfaces.
  mojo::Remote<mojom::TestInterfaceForGrant> grant_remote;
  mojo::GenericPendingReceiver grant_receiver(
      grant_remote.BindNewPipeAndPassReceiver());

  // Bind the interface immediately if the policy is kGrant.
  const std::string interface_name = grant_receiver.interface_name().value();
  EXPECT_FALSE(collector_.IsCancelled());
  EXPECT_FALSE(collector_.IsGrantReceiverBound());
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      interface_name,
      base::BindOnce(&TestReceiverCollector::BindGrantInterface,
                     base::Unretained(&collector_),
                     grant_receiver.As<mojom::TestInterfaceForGrant>()));
  EXPECT_TRUE(collector_.IsGrantReceiverBound());
  EXPECT_FALSE(collector_.IsCancelled());
}

// Verifies that interfaces whose policies are kDefer cannot be bound until
// GrantAll() is called.
TEST_F(MojoBinderPolicyApplierTest, DeferInEnforce) {
  // Initialize Mojo interfaces.
  mojo::Remote<mojom::TestInterfaceForDefer> defer_remote;
  mojo::GenericPendingReceiver defer_receiver(
      defer_remote.BindNewPipeAndPassReceiver());

  // Delay binding the interface until GrantAll() is called.
  const std::string interface_name = defer_receiver.interface_name().value();
  EXPECT_FALSE(collector_.IsCancelled());
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      interface_name,
      base::BindOnce(&TestReceiverCollector::BindDeferInterface,
                     base::Unretained(&collector_),
                     defer_receiver.As<mojom::TestInterfaceForDefer>()));
  EXPECT_FALSE(collector_.IsDeferReceiverBound());
  EXPECT_EQ(1U, deferred_binders().size());

  RunGrantAll();
  EXPECT_EQ(0U, deferred_binders().size());
  EXPECT_TRUE(collector_.IsDeferReceiverBound());
  EXPECT_FALSE(collector_.IsCancelled());
}

// Verifies that MojoBinderPolicyApplier will run `cancel_closure` when running
// in the kEnforce mode and receiving an interface whose policy is kCancel,
TEST_F(MojoBinderPolicyApplierTest, CancelInEnforce) {
  // Initialize Mojo interfaces.
  mojo::Remote<mojom::TestInterfaceForCancel> cancel_remote;
  mojo::GenericPendingReceiver cancel_receiver(
      cancel_remote.BindNewPipeAndPassReceiver());

  const std::string interface_name = cancel_receiver.interface_name().value();
  EXPECT_FALSE(collector_.IsCancelled());
  EXPECT_FALSE(collector_.IsCancelReceiverBound());
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      interface_name,
      base::BindOnce(&TestReceiverCollector::BindCancelInterface,
                     base::Unretained(&collector_),
                     cancel_receiver.As<mojom::TestInterfaceForCancel>()));
  EXPECT_TRUE(collector_.IsCancelled());
  EXPECT_EQ(collector_.cancelled_interface(),
            "content.mojom.TestInterfaceForCancel");
  EXPECT_FALSE(collector_.IsCancelReceiverBound());
}

// When MojoBinderPolicyApplier runs in the kPrepareToGrantAll mode, verifies it
// applies kGrant for kGrant interfaces.
TEST_F(MojoBinderPolicyApplierTest, GrantInPrepareToGrantAll) {
  // Initialize Mojo interfaces.
  mojo::Remote<mojom::TestInterfaceForGrant> grant_remote;
  mojo::GenericPendingReceiver grant_receiver(
      grant_remote.BindNewPipeAndPassReceiver());

  policy_applier_.PrepareToGrantAll();
  const std::string grant_interface_name =
      grant_receiver.interface_name().value();
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      grant_interface_name,
      base::BindOnce(&TestReceiverCollector::BindGrantInterface,
                     base::Unretained(&collector_),
                     grant_receiver.As<mojom::TestInterfaceForGrant>()));
  EXPECT_TRUE(collector_.IsGrantReceiverBound());
}

// When MojoBinderPolicyApplier runs in the kPrepareToGrantAll mode, verifies it
// applies kDefer for kDefer interfaces.
TEST_F(MojoBinderPolicyApplierTest, DeferInPrepareToGrantAll) {
  // Initialize Mojo interfaces.
  mojo::Remote<mojom::TestInterfaceForDefer> defer_remote;
  mojo::GenericPendingReceiver defer_receiver(
      defer_remote.BindNewPipeAndPassReceiver());

  policy_applier_.PrepareToGrantAll();
  const std::string defer_interface_name =
      defer_receiver.interface_name().value();
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      defer_interface_name,
      base::BindOnce(&TestReceiverCollector::BindDeferInterface,
                     base::Unretained(&collector_),
                     defer_receiver.As<mojom::TestInterfaceForDefer>()));
  EXPECT_FALSE(collector_.IsDeferReceiverBound());
  EXPECT_EQ(1U, deferred_binders().size());

  RunGrantAll();
  EXPECT_TRUE(collector_.IsDeferReceiverBound());
  EXPECT_EQ(0U, deferred_binders().size());
}

// When MojoBinderPolicyApplier runs in the kPrepareToGrantAll mode, verifies it
// applies kGrant rather than kCancel policy when receiving a kCancel interface
// binding request.
TEST_F(MojoBinderPolicyApplierTest, CancelInPrepareToGrantAll) {
  // Initialize Mojo interfaces.
  mojo::Remote<mojom::TestInterfaceForCancel> cancel_remote;
  mojo::GenericPendingReceiver cancel_receiver(
      cancel_remote.BindNewPipeAndPassReceiver());

  policy_applier_.PrepareToGrantAll();
  const std::string cancel_interface_name =
      cancel_receiver.interface_name().value();
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      cancel_interface_name,
      base::BindOnce(&TestReceiverCollector::BindCancelInterface,
                     base::Unretained(&collector_),
                     cancel_receiver.As<mojom::TestInterfaceForCancel>()));
  EXPECT_FALSE(collector_.IsCancelled());
  EXPECT_TRUE(collector_.IsCancelReceiverBound());
}

TEST_F(MojoBinderPolicyApplierTest, UnexpectedInPrepareToGrantAll) {
  // Initialize Mojo interfaces.
  mojo::Remote<mojom::TestInterfaceForUnexpected> unexpected_remote;
  mojo::GenericPendingReceiver unexpected_receiver(
      unexpected_remote.BindNewPipeAndPassReceiver());

  policy_applier_.PrepareToGrantAll();
  const std::string interface_name =
      unexpected_receiver.interface_name().value();
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      interface_name,
      base::BindOnce(
          &TestReceiverCollector::BindUnexpectedInterface,
          base::Unretained(&collector_),
          unexpected_receiver.As<mojom::TestInterfaceForUnexpected>()));
  EXPECT_FALSE(collector_.IsCancelled());
  EXPECT_TRUE(collector_.IsUnexpectedReceiverBound());
}

// Verifies that all interfaces are bound immediately if GrantAll() is called,
// regardless of policies.
TEST_F(MojoBinderPolicyApplierTest, BindInterfacesAfterResolving) {
  // Initialize Mojo interfaces.
  mojo::Remote<mojom::TestInterfaceForDefer> defer_remote;
  mojo::GenericPendingReceiver defer_receiver(
      defer_remote.BindNewPipeAndPassReceiver());
  mojo::Remote<mojom::TestInterfaceForGrant> grant_remote;
  mojo::GenericPendingReceiver grant_receiver(
      grant_remote.BindNewPipeAndPassReceiver());
  mojo::Remote<mojom::TestInterfaceForCancel> cancel_remote;
  mojo::GenericPendingReceiver cancel_receiver(
      cancel_remote.BindNewPipeAndPassReceiver());
  mojo::Remote<mojom::TestInterfaceForUnexpected> unexpected_remote;
  mojo::GenericPendingReceiver unexpected_receiver(
      unexpected_remote.BindNewPipeAndPassReceiver());

  RunGrantAll();

  // All interfaces should be bound immediately.
  const std::string defer_interface_name =
      defer_receiver.interface_name().value();
  const std::string grant_interface_name =
      grant_receiver.interface_name().value();
  const std::string cancel_interface_name =
      cancel_receiver.interface_name().value();
  const std::string unexpected_interface_name =
      unexpected_receiver.interface_name().value();
  EXPECT_FALSE(collector_.IsCancelled());
  EXPECT_FALSE(collector_.IsGrantReceiverBound());
  EXPECT_FALSE(collector_.IsDeferReceiverBound());
  EXPECT_FALSE(collector_.IsCancelReceiverBound());
  EXPECT_FALSE(collector_.IsUnexpectedReceiverBound());
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      defer_interface_name,
      base::BindOnce(&TestReceiverCollector::BindDeferInterface,
                     base::Unretained(&collector_),
                     defer_receiver.As<mojom::TestInterfaceForDefer>()));
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      grant_interface_name,
      base::BindOnce(&TestReceiverCollector::BindGrantInterface,
                     base::Unretained(&collector_),
                     grant_receiver.As<mojom::TestInterfaceForGrant>()));
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      cancel_interface_name,
      base::BindOnce(&TestReceiverCollector::BindCancelInterface,
                     base::Unretained(&collector_),
                     cancel_receiver.As<mojom::TestInterfaceForCancel>()));
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      unexpected_interface_name,
      base::BindOnce(
          &TestReceiverCollector::BindUnexpectedInterface,
          base::Unretained(&collector_),
          unexpected_receiver.As<mojom::TestInterfaceForUnexpected>()));
  EXPECT_TRUE(collector_.IsGrantReceiverBound());
  EXPECT_TRUE(collector_.IsDeferReceiverBound());
  EXPECT_TRUE(collector_.IsCancelReceiverBound());
  EXPECT_TRUE(collector_.IsUnexpectedReceiverBound());
  EXPECT_FALSE(collector_.IsCancelled());
  EXPECT_EQ(0U, deferred_binders().size());
}

// Verifies that DropDeferredBinders() deletes all deferred binders.
TEST_F(MojoBinderPolicyApplierTest, DropDeferredBinders) {
  // Initialize Mojo interfaces.
  mojo::Remote<mojom::TestInterfaceForDefer> defer_remote;
  mojo::GenericPendingReceiver defer_receiver(
      defer_remote.BindNewPipeAndPassReceiver());

  const std::string interface_name = defer_receiver.interface_name().value();
  EXPECT_FALSE(collector_.IsCancelled());
  policy_applier_.ApplyPolicyToNonAssociatedBinder(
      interface_name,
      base::BindOnce(&TestReceiverCollector::BindDeferInterface,
                     base::Unretained(&collector_),
                     defer_receiver.As<mojom::TestInterfaceForDefer>()));
  EXPECT_FALSE(collector_.IsDeferReceiverBound());
  EXPECT_EQ(1U, deferred_binders().size());
  policy_applier_.DropDeferredBinders();
  EXPECT_EQ(0U, deferred_binders().size());
  RunGrantAll();
  EXPECT_FALSE(collector_.IsDeferReceiverBound());
}

}  // namespace content
