// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/serial/serial_chooser_context.h"

#include <string_view>

#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/scoped_observation.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/test/values_test_util.h"
#include "build/build_config.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/serial/serial_blocklist.h"
#include "chrome/browser/serial/serial_chooser_context_factory.h"
#include "chrome/browser/serial/serial_chooser_histograms.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/permissions/test/object_permission_context_base_mock_permission_observer.h"
#include "components/prefs/testing_pref_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/test/browser_task_environment.h"
#include "google_apis/gaia/gaia_id.h"
#include "services/device/public/cpp/test/fake_serial_port_manager.h"
#include "services/device/public/mojom/serial.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "components/account_id/account_id.h"
#include "components/user_manager/scoped_user_manager.h"
#endif

namespace {

using ::base::test::InvokeFuture;
using ::base::test::ParseJson;
using ::base::test::TestFuture;
using ::content_settings::SettingSource;
using ::testing::_;
using ::testing::NiceMock;

constexpr char kTestUserEmail[] = "user@example.com";

class MockPortObserver : public SerialChooserContext::PortObserver {
 public:
  MockPortObserver() = default;
  MockPortObserver(MockPortObserver&) = delete;
  MockPortObserver& operator=(MockPortObserver&) = delete;
  ~MockPortObserver() override = default;

  MOCK_METHOD1(OnPortAdded, void(const device::mojom::SerialPortInfo&));
  MOCK_METHOD1(OnPortRemoved, void(const device::mojom::SerialPortInfo&));
  MOCK_METHOD1(OnPortConnectedStateChanged,
               void(const device::mojom::SerialPortInfo&));
  MOCK_METHOD0(OnPortManagerConnectionError, void());
  MOCK_METHOD1(OnPermissionRevoked, void(const url::Origin&));
};

device::mojom::SerialPortInfoPtr CreatePersistentBluetoothPort(
    std::optional<std::string> name,
    const std::string& bluetooth_address) {
  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();
  port->display_name = std::move(name);
  port->path = base::FilePath().AppendASCII(bluetooth_address);
  port->bluetooth_service_class_id =
      device::BluetoothUUID("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
  port->has_vendor_id = false;
  port->has_product_id = false;
  return port;
}

device::mojom::SerialPortInfoPtr CreatePersistentUsbPort(
    std::optional<std::string> name,
    const std::string& persistent_id) {
  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();
  port->display_name = std::move(name);
#if BUILDFLAG(IS_WIN)
  port->device_instance_id = persistent_id;
#else
  port->has_vendor_id = true;
  port->vendor_id = 0;
  port->has_product_id = true;
  port->product_id = 0;
  port->serial_number = persistent_id;
#if BUILDFLAG(IS_MAC)
  port->usb_driver_name = "AppleUSBCDC";
#endif
#endif  // BUILDFLAG(IS_WIN)
  return port;
}

class SerialChooserContextTestBase {
 public:
  SerialChooserContextTestBase() = default;
  ~SerialChooserContextTestBase() = default;

  // Disallow copy and assignment.
  SerialChooserContextTestBase(SerialChooserContextTestBase&) = delete;
  SerialChooserContextTestBase& operator=(SerialChooserContextTestBase&) =
      delete;

  void DoSetUp(bool is_affiliated) {
#if BUILDFLAG(IS_CHROMEOS)
    auto fake_user_manager = std::make_unique<ash::FakeChromeUserManager>();
    auto* fake_user_manager_ptr = fake_user_manager.get();
    scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>(
        std::move(fake_user_manager));

    const GaiaId kTestUserGaiaId("1111111111");
    auto account_id =
        AccountId::FromUserEmailGaiaId(kTestUserEmail, kTestUserGaiaId);
    fake_user_manager_ptr->AddUserWithAffiliation(account_id, is_affiliated);
    fake_user_manager_ptr->LoginUser(account_id);
#endif  // BUILDFLAG(IS_CHROMEOS)

    testing_profile_manager_ = std::make_unique<TestingProfileManager>(
        TestingBrowserProcess::GetGlobal());
    ASSERT_TRUE(testing_profile_manager_->SetUp());
    profile_ = testing_profile_manager_->CreateTestingProfile(kTestUserEmail);
    ASSERT_TRUE(profile_);

    mojo::PendingRemote<device::mojom::SerialPortManager> port_manager;
    port_manager_.AddReceiver(port_manager.InitWithNewPipeAndPassReceiver());

    context_ = SerialChooserContextFactory::GetForProfile(profile_);
    context_->SetPortManagerForTesting(std::move(port_manager));
    scoped_permission_observation_.Observe(context_.get());
    scoped_port_observation_.Observe(context_.get());

    // Ensure |context_| is ready to receive SerialPortManagerClient messages.
    context_->FlushPortManagerConnectionForTesting();
  }

  void DoTearDown() {
    // Because SerialBlocklist is a singleton it must be cleared after tests run
    // to prevent leakage between tests.
    feature_list_.Reset();
    SerialBlocklist::Get().ResetToDefaultValuesForTesting();
  }

  void SetDynamicBlocklist(std::string_view value) {
    feature_list_.Reset();

    std::map<std::string, std::string> parameters;
    parameters[kWebSerialBlocklistAdditions.name] = std::string(value);
    feature_list_.InitWithFeaturesAndParameters(
        {{kWebSerialBlocklist, parameters}}, {});

    SerialBlocklist::Get().ResetToDefaultValuesForTesting();
  }

  device::FakeSerialPortManager& port_manager() { return port_manager_; }
  TestingProfile* profile() { return profile_; }
  TestingPrefServiceSimple* local_state() {
    return TestingBrowserProcess::GetGlobal()->GetTestingLocalState();
  }
  SerialChooserContext* context() { return context_; }
  permissions::MockPermissionObserver& permission_observer() {
    return permission_observer_;
  }
  NiceMock<MockPortObserver>& port_observer() { return port_observer_; }

 private:
  content::BrowserTaskEnvironment task_environment_;
  base::test::ScopedFeatureList feature_list_;
  device::FakeSerialPortManager port_manager_;
  std::unique_ptr<TestingProfileManager> testing_profile_manager_;
  raw_ptr<TestingProfile> profile_ = nullptr;

#if BUILDFLAG(IS_CHROMEOS)
  std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_;
#endif

  raw_ptr<SerialChooserContext> context_;
  NiceMock<permissions::MockPermissionObserver> permission_observer_;
  base::ScopedObservation<
      permissions::ObjectPermissionContextBase,
      permissions::ObjectPermissionContextBase::PermissionObserver>
      scoped_permission_observation_{&permission_observer_};
  NiceMock<MockPortObserver> port_observer_;
  base::ScopedObservation<SerialChooserContext,
                          SerialChooserContext::PortObserver>
      scoped_port_observation_{&port_observer_};
};

class SerialChooserContextTest : public SerialChooserContextTestBase,
                                 public testing::Test {
 public:
  void SetUp() override { DoSetUp(/*is_affiliated=*/true); }
  void TearDown() override { DoTearDown(); }
};

class SerialChooserContextAffiliatedTest : public SerialChooserContextTestBase,
                                           public testing::TestWithParam<bool> {
 public:
  SerialChooserContextAffiliatedTest() : is_affiliated_(GetParam()) {}

  void SetUp() override { DoSetUp(is_affiliated_); }
  void TearDown() override { DoTearDown(); }

  bool is_affiliated() const { return is_affiliated_; }

 private:
  bool is_affiliated_;
};

}  // namespace

TEST_F(SerialChooserContextTest, GrantAndRevokeEphemeralPermission) {
  base::HistogramTester histogram_tester;

  const auto origin = url::Origin::Create(GURL("https://google.com"));

  auto port_1 = device::mojom::SerialPortInfo::New();
  port_1->token = base::UnguessableToken::Create();

  auto port_2 = CreatePersistentUsbPort("Persistent Port", "ABC123");
  auto port_3 = CreatePersistentBluetoothPort("Persistent Bluetooth Port",
                                              "aa:aa:aa:aa:aa:aa");

  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_3));

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));

  context()->GrantPortPermission(origin, *port_1);
  EXPECT_TRUE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_3));

  std::vector<std::unique_ptr<SerialChooserContext::Object>> origin_objects =
      context()->GetGrantedObjects(origin);
  ASSERT_EQ(1u, origin_objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetAllGrantedObjects();
  ASSERT_EQ(1u, objects.size());
  EXPECT_EQ(origin.GetURL(), objects[0]->origin);
  EXPECT_EQ(origin_objects[0]->value, objects[0]->value);
  EXPECT_EQ(SettingSource::kUser, objects[0]->source);
  EXPECT_FALSE(objects[0]->incognito);

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));
  EXPECT_CALL(permission_observer(), OnPermissionRevoked(origin));

  context()->RevokeObjectPermission(origin, objects[0]->value);
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_3));
  origin_objects = context()->GetGrantedObjects(origin);
  EXPECT_EQ(0u, origin_objects.size());
  objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(0u, objects.size());

  histogram_tester.ExpectUniqueSample("Permissions.Serial.Revoked",
                                      SerialPermissionRevoked::kEphemeralByUser,
                                      1);
}

TEST_F(SerialChooserContextTest, RevokeEphemeralPermissionByWebsite) {
  base::HistogramTester histogram_tester;

  const auto origin = url::Origin::Create(GURL("https://google.com"));

  auto port_1 = device::mojom::SerialPortInfo::New();
  port_1->token = base::UnguessableToken::Create();

  auto port_2 = CreatePersistentUsbPort("Persistent Port", "ABC123");

  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));

  context()->GrantPortPermission(origin, *port_1);
  EXPECT_TRUE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));

  std::vector<std::unique_ptr<SerialChooserContext::Object>> origin_objects =
      context()->GetGrantedObjects(origin);
  ASSERT_EQ(1u, origin_objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetAllGrantedObjects();
  ASSERT_EQ(1u, objects.size());
  EXPECT_EQ(origin.GetURL(), objects[0]->origin);
  EXPECT_EQ(origin_objects[0]->value, objects[0]->value);
  EXPECT_EQ(SettingSource::kUser, objects[0]->source);
  EXPECT_FALSE(objects[0]->incognito);

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));
  EXPECT_CALL(permission_observer(), OnPermissionRevoked(origin));

  context()->RevokePortPermissionWebInitiated(origin, port_1->token);
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));
  origin_objects = context()->GetGrantedObjects(origin);
  EXPECT_EQ(0u, origin_objects.size());
  objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(0u, objects.size());

  histogram_tester.ExpectUniqueSample(
      "Permissions.Serial.Revoked",
      SerialPermissionRevoked::kEphemeralByWebsite, 1);
}

TEST_F(SerialChooserContextTest, GrantAndCheckPersistentUsbPermission) {
  const auto origin = url::Origin::Create(GURL("https://google.com"));

  // Connect a USB serial port and a Bluetooth serial port. Both are eligible
  // for persistent permissions.
  auto port_1 = CreatePersistentUsbPort("Persistent USB Port", "ABC123");
  auto port_2 = CreatePersistentBluetoothPort("Persistent Bluetooth Port",
                                              "aa:aa:aa:aa:aa:aa");

  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));

  // Grant a persistent permission for the USB serial port.
  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));
  context()->GrantPortPermission(origin, *port_1);

  // Check that permission was granted only for the USB serial port.
  EXPECT_TRUE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));
}

TEST_F(SerialChooserContextTest, GrantAndCheckPersistentBluetoothPermission) {
  const auto origin = url::Origin::Create(GURL("https://google.com"));

  // Connect a USB serial port and a Bluetooth serial port. Both are eligible
  // for persistent permissions.
  auto port_1 = CreatePersistentUsbPort("Persistent USB Port", "ABC123");
  auto port_2 = CreatePersistentBluetoothPort("Persistent Bluetooth Port",
                                              "aa:aa:aa:aa:aa:aa");

  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));

  // Grant a persistent permission for the Bluetooth serial port.
  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));
  context()->GrantPortPermission(origin, *port_2);

  // Check that permission was granted only for the Bluetooth serial port.
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_TRUE(context()->HasPortPermission(origin, *port_2));
}

TEST_F(SerialChooserContextTest, GrantAndRevokePersistentUsbPermission) {
  base::HistogramTester histogram_tester;

  const auto origin = url::Origin::Create(GURL("https://google.com"));

  device::mojom::SerialPortInfoPtr port_1 =
      CreatePersistentUsbPort("Persistent Port", "ABC123");

  auto port_2 = device::mojom::SerialPortInfo::New();
  port_2->token = base::UnguessableToken::Create();

  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));

  context()->GrantPortPermission(origin, *port_1);
  EXPECT_TRUE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));

  std::vector<std::unique_ptr<SerialChooserContext::Object>> origin_objects =
      context()->GetGrantedObjects(origin);
  ASSERT_EQ(1u, origin_objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetAllGrantedObjects();
  ASSERT_EQ(1u, objects.size());
  EXPECT_EQ(origin.GetURL(), objects[0]->origin);
  EXPECT_EQ(origin_objects[0]->value, objects[0]->value);
  EXPECT_EQ(SettingSource::kUser, objects[0]->source);
  EXPECT_FALSE(objects[0]->incognito);

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));
  EXPECT_CALL(permission_observer(), OnPermissionRevoked(origin));

  context()->RevokeObjectPermission(origin, objects[0]->value);
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));
  origin_objects = context()->GetGrantedObjects(origin);
  EXPECT_EQ(0u, origin_objects.size());
  objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(0u, objects.size());

  histogram_tester.ExpectUniqueSample(
      "Permissions.Serial.Revoked", SerialPermissionRevoked::kPersistentByUser,
      1);
}

TEST_F(SerialChooserContextTest, GrantAndRevokePersistentBluetoothPermission) {
  base::HistogramTester histogram_tester;

  const auto origin = url::Origin::Create(GURL("https://google.com"));

  auto port_1 = CreatePersistentBluetoothPort("Persistent Bluetooth Port",
                                              "aa:aa:aa:aa:aa:aa");

  auto port_2 = device::mojom::SerialPortInfo::New();
  port_2->token = base::UnguessableToken::Create();

  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));

  context()->GrantPortPermission(origin, *port_1);
  EXPECT_TRUE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));

  std::vector<std::unique_ptr<SerialChooserContext::Object>> origin_objects =
      context()->GetGrantedObjects(origin);
  ASSERT_EQ(1u, origin_objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetAllGrantedObjects();
  ASSERT_EQ(1u, objects.size());
  EXPECT_EQ(origin.GetURL(), objects[0]->origin);
  EXPECT_EQ(origin_objects[0]->value, objects[0]->value);
  EXPECT_EQ(SettingSource::kUser, objects[0]->source);
  EXPECT_FALSE(objects[0]->incognito);

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));
  EXPECT_CALL(permission_observer(), OnPermissionRevoked(origin));

  context()->RevokeObjectPermission(origin, objects[0]->value);
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));
  origin_objects = context()->GetGrantedObjects(origin);
  EXPECT_EQ(0u, origin_objects.size());
  objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(0u, objects.size());

  histogram_tester.ExpectUniqueSample(
      "Permissions.Serial.Revoked", SerialPermissionRevoked::kPersistentByUser,
      1);
}

TEST_F(SerialChooserContextTest, RevokePersistentPermissionByWebsite) {
  base::HistogramTester histogram_tester;

  const auto origin = url::Origin::Create(GURL("https://google.com"));

  device::mojom::SerialPortInfoPtr port_1 =
      CreatePersistentUsbPort("Persistent Port", "ABC123");

  auto port_2 = device::mojom::SerialPortInfo::New();
  port_2->token = base::UnguessableToken::Create();

  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));

  context()->GrantPortPermission(origin, *port_1);
  EXPECT_TRUE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));

  std::vector<std::unique_ptr<SerialChooserContext::Object>> origin_objects =
      context()->GetGrantedObjects(origin);
  ASSERT_EQ(1u, origin_objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetAllGrantedObjects();
  ASSERT_EQ(1u, objects.size());
  EXPECT_EQ(origin.GetURL(), objects[0]->origin);
  EXPECT_EQ(origin_objects[0]->value, objects[0]->value);
  EXPECT_EQ(SettingSource::kUser, objects[0]->source);
  EXPECT_FALSE(objects[0]->incognito);

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA));
  EXPECT_CALL(permission_observer(), OnPermissionRevoked(origin));

  context()->RevokePortPermissionWebInitiated(origin, port_1->token);
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_1));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port_2));
  origin_objects = context()->GetGrantedObjects(origin);
  EXPECT_EQ(0u, origin_objects.size());
  objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(0u, objects.size());

  histogram_tester.ExpectUniqueSample(
      "Permissions.Serial.Revoked",
      SerialPermissionRevoked::kPersistentByWebsite, 1);
}

TEST_F(SerialChooserContextTest, EphemeralPermissionRevokedOnDisconnect) {
  base::HistogramTester histogram_tester;

  const auto origin = url::Origin::Create(GURL("https://google.com"));

  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();
  port_manager().AddPort(port.Clone());

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA))
      .Times(2);
  EXPECT_CALL(permission_observer(), OnPermissionRevoked(origin));

  context()->GrantPortPermission(origin, *port);
  EXPECT_TRUE(context()->HasPortPermission(origin, *port));

  port_manager().RemovePort(port->token);
  {
    base::RunLoop run_loop;
    EXPECT_CALL(port_observer(), OnPortRemoved(testing::_))
        .WillOnce([&](const device::mojom::SerialPortInfo& info) {
          EXPECT_EQ(port->token, info.token);
          EXPECT_TRUE(context()->HasPortPermission(origin, info));
          run_loop.Quit();
        });
    run_loop.Run();
  }
  EXPECT_FALSE(context()->HasPortPermission(origin, *port));
  auto origin_objects = context()->GetGrantedObjects(origin);
  EXPECT_EQ(0u, origin_objects.size());
  auto objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(0u, objects.size());

  histogram_tester.ExpectUniqueSample(
      "Permissions.Serial.Revoked",
      SerialPermissionRevoked::kEphemeralByDisconnect, 1);
}

TEST_F(SerialChooserContextTest, PersistenceRequiresDisplayName) {
  const auto origin = url::Origin::Create(GURL("https://google.com"));

  device::mojom::SerialPortInfoPtr port =
      CreatePersistentUsbPort(/*name=*/std::nullopt, "ABC123");
  port_manager().AddPort(port.Clone());

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA))
      .Times(2);
  EXPECT_CALL(permission_observer(), OnPermissionRevoked(origin));

  context()->GrantPortPermission(origin, *port);
  EXPECT_TRUE(context()->HasPortPermission(origin, *port));

  // Without a display name a persistent permission cannot be recorded and so
  // removing the device will revoke permission.
  port_manager().RemovePort(port->token);
  {
    base::RunLoop run_loop;
    EXPECT_CALL(port_observer(), OnPortRemoved(testing::_))
        .WillOnce([&](const device::mojom::SerialPortInfo& info) {
          EXPECT_EQ(port->token, info.token);
          EXPECT_TRUE(context()->HasPortPermission(origin, info));
          run_loop.Quit();
        });
    run_loop.Run();
  }
  EXPECT_FALSE(context()->HasPortPermission(origin, *port));
  auto origin_objects = context()->GetGrantedObjects(origin);
  EXPECT_EQ(0u, origin_objects.size());
  auto objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(0u, objects.size());
}

TEST_F(SerialChooserContextTest, PersistentPermissionNotRevokedOnDisconnect) {
  const auto origin = url::Origin::Create(GURL("https://google.com"));
  const char persistent_id[] = "ABC123";

  device::mojom::SerialPortInfoPtr port =
      CreatePersistentUsbPort("Persistent Port", persistent_id);
  port_manager().AddPort(port.Clone());

  context()->GrantPortPermission(origin, *port);
  EXPECT_TRUE(context()->HasPortPermission(origin, *port));

  EXPECT_CALL(permission_observer(),
              OnObjectPermissionChanged(
                  std::make_optional(ContentSettingsType::SERIAL_GUARD),
                  ContentSettingsType::SERIAL_CHOOSER_DATA))
      .Times(0);
  EXPECT_CALL(permission_observer(), OnPermissionRevoked(origin)).Times(0);

  port_manager().RemovePort(port->token);
  {
    base::RunLoop run_loop;
    EXPECT_CALL(port_observer(), OnPortRemoved(testing::_))
        .WillOnce([&](const device::mojom::SerialPortInfo& info) {
          EXPECT_EQ(port->token, info.token);
          EXPECT_TRUE(context()->HasPortPermission(origin, info));
          run_loop.Quit();
        });
    run_loop.Run();
  }

  EXPECT_TRUE(context()->HasPortPermission(origin, *port));
  auto origin_objects = context()->GetGrantedObjects(origin);
  EXPECT_EQ(1u, origin_objects.size());
  auto objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(1u, objects.size());

  // Simulate reconnection of the port. It gets a new token but the same
  // persistent ID. This SerialPortInfo should still match the old permission.
  port = CreatePersistentUsbPort("Persistent Port", persistent_id);
  port_manager().AddPort(port.Clone());

  EXPECT_TRUE(context()->HasPortPermission(origin, *port));
}

TEST_F(SerialChooserContextTest, GuardPermission) {
  const auto origin = url::Origin::Create(GURL("https://google.com"));

  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();

  context()->GrantPortPermission(origin, *port);
  EXPECT_TRUE(context()->HasPortPermission(origin, *port));

  auto* map = HostContentSettingsMapFactory::GetForProfile(profile());
  map->SetContentSettingDefaultScope(origin.GetURL(), origin.GetURL(),
                                     ContentSettingsType::SERIAL_GUARD,
                                     CONTENT_SETTING_BLOCK);
  EXPECT_FALSE(context()->HasPortPermission(origin, *port));

  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetGrantedObjects(origin);
  EXPECT_EQ(0u, objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>>
      all_origin_objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(0u, all_origin_objects.size());
}

TEST_F(SerialChooserContextTest, PolicyGuardPermission) {
  const auto origin = url::Origin::Create(GURL("https://google.com"));
  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();

  context()->GrantPortPermission(origin, *port);

  auto* profile_prefs = profile()->GetTestingPrefService();
  profile_prefs->SetManagedPref(
      prefs::kManagedDefaultSerialGuardSetting,
      std::make_unique<base::Value>(CONTENT_SETTING_BLOCK));
  EXPECT_FALSE(context()->CanRequestObjectPermission(origin));
  EXPECT_FALSE(context()->HasPortPermission(origin, *port));

  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetGrantedObjects(origin);
  EXPECT_EQ(0u, objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>>
      all_origin_objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(0u, all_origin_objects.size());
}

TEST_F(SerialChooserContextTest, PolicyAskForUrls) {
  const auto kFooOrigin = url::Origin::Create(GURL("https://foo.origin"));
  const auto kBarOrigin = url::Origin::Create(GURL("https://bar.origin"));

  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();
  context()->GrantPortPermission(kFooOrigin, *port);
  context()->GrantPortPermission(kBarOrigin, *port);

  // Set the default to "block" so that the policy being tested overrides it.
  auto* profile_prefs = profile()->GetTestingPrefService();
  profile_prefs->SetManagedPref(
      prefs::kManagedDefaultSerialGuardSetting,
      std::make_unique<base::Value>(CONTENT_SETTING_BLOCK));
  profile_prefs->SetManagedPref(prefs::kManagedSerialAskForUrls,
                                ParseJson(R"([ "https://foo.origin" ])"));

  EXPECT_TRUE(context()->CanRequestObjectPermission(kFooOrigin));
  EXPECT_TRUE(context()->HasPortPermission(kFooOrigin, *port));
  EXPECT_FALSE(context()->CanRequestObjectPermission(kBarOrigin));
  EXPECT_FALSE(context()->HasPortPermission(kBarOrigin, *port));

  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetGrantedObjects(kFooOrigin);
  EXPECT_EQ(1u, objects.size());
  objects = context()->GetGrantedObjects(kBarOrigin);
  EXPECT_EQ(0u, objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>>
      all_origin_objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(1u, all_origin_objects.size());
}

TEST_F(SerialChooserContextTest, PolicyBlockedForUrls) {
  const auto kFooOrigin = url::Origin::Create(GURL("https://foo.origin"));
  const auto kBarOrigin = url::Origin::Create(GURL("https://bar.origin"));

  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();
  context()->GrantPortPermission(kFooOrigin, *port);
  context()->GrantPortPermission(kBarOrigin, *port);

  auto* profile_prefs = profile()->GetTestingPrefService();
  profile_prefs->SetManagedPref(prefs::kManagedSerialBlockedForUrls,
                                ParseJson(R"([ "https://foo.origin" ])"));

  EXPECT_FALSE(context()->CanRequestObjectPermission(kFooOrigin));
  EXPECT_FALSE(context()->HasPortPermission(kFooOrigin, *port));
  EXPECT_TRUE(context()->CanRequestObjectPermission(kBarOrigin));
  EXPECT_TRUE(context()->HasPortPermission(kBarOrigin, *port));

  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetGrantedObjects(kFooOrigin);
  EXPECT_EQ(0u, objects.size());
  objects = context()->GetGrantedObjects(kBarOrigin);
  EXPECT_EQ(1u, objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>>
      all_origin_objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(1u, all_origin_objects.size());
}

TEST_F(SerialChooserContextTest, ConflictingSerialAskAndSerialBlockedPolicies) {
  const auto kFooOrigin = url::Origin::Create(GURL("https://foo.origin"));

  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();
  context()->GrantPortPermission(kFooOrigin, *port);

  auto* profile_prefs = profile()->GetTestingPrefService();
  profile_prefs->SetManagedPref(prefs::kManagedSerialAskForUrls,
                                ParseJson(R"([ "https://foo.origin" ])"));
  profile_prefs->SetManagedPref(prefs::kManagedSerialBlockedForUrls,
                                ParseJson(R"([ "https://foo.origin" ])"));

  // When both policies conflict, then the blocking policy wins.
  EXPECT_FALSE(context()->CanRequestObjectPermission(kFooOrigin));
  EXPECT_FALSE(context()->HasPortPermission(kFooOrigin, *port));

  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetGrantedObjects(kFooOrigin);
  EXPECT_EQ(0u, objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>>
      all_origin_objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(0u, all_origin_objects.size());
}

TEST_F(SerialChooserContextTest, BluetoothPortConnectedState) {
  const auto origin = url::Origin::Create(GURL("https://google.com"));

  // Create a Bluetooth serial port.
  auto port = CreatePersistentBluetoothPort("Persistent Bluetooth Port",
                                            "aa:aa:aa:aa:aa:aa");

  // Simulate disconnection of the Bluetooth device hosting `port`. The observer
  // is notified that the port is now disconnected.
  TestFuture<const device::mojom::SerialPortInfo&> port_future;
  EXPECT_CALL(port_observer(), OnPortConnectedStateChanged)
      .WillOnce(InvokeFuture(port_future));
  auto disconnected_port = port.Clone();
  disconnected_port->connected = false;
  context()->OnPortConnectedStateChanged(std::move(disconnected_port));
  EXPECT_EQ(port_future.Get().token, port->token);
  EXPECT_FALSE(port_future.Get().connected);
}

TEST_P(SerialChooserContextAffiliatedTest, PolicyAllowForUrls) {
  const auto kFooOrigin = url::Origin::Create(GURL("https://foo.origin"));
  const auto kBarOrigin = url::Origin::Create(GURL("https://bar.origin"));

  local_state()->SetManagedPref(prefs::kManagedSerialAllowAllPortsForUrls,
                                ParseJson(R"([ "https://foo.origin" ])"));
  local_state()->SetManagedPref(prefs::kManagedSerialAllowUsbDevicesForUrls,
                                ParseJson(R"([
               {
                 "devices": [{ "vendor_id": 6353, "product_id": 19985 }],
                 "urls": [ "https://bar.origin" ]
               }
             ])"));

  auto platform_port = device::mojom::SerialPortInfo::New();
  platform_port->token = base::UnguessableToken::Create();

  auto usb_port1 = device::mojom::SerialPortInfo::New();
  usb_port1->token = base::UnguessableToken::Create();
  usb_port1->has_vendor_id = true;
  usb_port1->vendor_id = 0x18D1;
  usb_port1->has_product_id = true;
  usb_port1->product_id = 0x4E11;

  auto usb_port2 = device::mojom::SerialPortInfo::New();
  usb_port2->token = base::UnguessableToken::Create();
  usb_port2->has_vendor_id = true;
  usb_port2->vendor_id = 0x18D1;
  usb_port2->has_product_id = true;
  usb_port2->product_id = 0x4E12;

  EXPECT_TRUE(context()->CanRequestObjectPermission(kFooOrigin));
  EXPECT_TRUE(context()->CanRequestObjectPermission(kBarOrigin));

  if (is_affiliated()) {
    EXPECT_TRUE(context()->HasPortPermission(kFooOrigin, *platform_port));
    EXPECT_TRUE(context()->HasPortPermission(kFooOrigin, *usb_port1));
    EXPECT_TRUE(context()->HasPortPermission(kFooOrigin, *usb_port2));

    EXPECT_FALSE(context()->HasPortPermission(kBarOrigin, *platform_port));
    EXPECT_TRUE(context()->HasPortPermission(kBarOrigin, *usb_port1));
    EXPECT_FALSE(context()->HasPortPermission(kBarOrigin, *usb_port2));

    auto foo_objects = context()->GetGrantedObjects(kFooOrigin);
    ASSERT_EQ(1u, foo_objects.size());
    const auto& foo_object = foo_objects.front();
    EXPECT_EQ(kFooOrigin.GetURL(), foo_object->origin);
    EXPECT_EQ(u"Any serial port",
              context()->GetObjectDisplayName(foo_object->value));
    EXPECT_EQ(SettingSource::kPolicy, foo_object->source);
    EXPECT_FALSE(foo_object->incognito);

    auto bar_objects = context()->GetGrantedObjects(kBarOrigin);
    ASSERT_EQ(1u, bar_objects.size());
    const auto& bar_object = bar_objects.front();
    EXPECT_EQ(kBarOrigin.GetURL(), bar_object->origin);
#if BUILDFLAG(IS_ANDROID)
    // Android doesn't include the USB device list because it takes too much
    // space
    EXPECT_EQ(u"USB device (18D1:4E11)",
              context()->GetObjectDisplayName(bar_object->value));
#else
    EXPECT_EQ(u"Nexus One", context()->GetObjectDisplayName(bar_object->value));
#endif  // BUILDFLAG(IS_ANDROID)
    EXPECT_EQ(SettingSource::kPolicy, bar_object->source);
    EXPECT_FALSE(bar_object->incognito);

    auto all_objects = context()->GetAllGrantedObjects();
    EXPECT_EQ(2u, all_objects.size());
    bool found_foo_object = false, found_bar_object = false;
    for (const auto& object : all_objects) {
      if (object->origin == kFooOrigin.GetURL()) {
        EXPECT_FALSE(found_foo_object);
        found_foo_object = true;
        EXPECT_EQ(u"Any serial port",
                  context()->GetObjectDisplayName(object->value));
      } else if (object->origin == kBarOrigin.GetURL()) {
        EXPECT_FALSE(found_bar_object);
        found_bar_object = true;
#if BUILDFLAG(IS_ANDROID)
        // Android doesn't include the USB device list because it takes too much
        // space
        EXPECT_EQ(u"USB device (18D1:4E11)",
                  context()->GetObjectDisplayName(object->value));
#else
        EXPECT_EQ(u"Nexus One", context()->GetObjectDisplayName(object->value));
#endif  // BUILDFLAG(IS_ANDROID)
      }
      EXPECT_EQ(SettingSource::kPolicy, object->source);
      EXPECT_FALSE(object->incognito);
    }
    EXPECT_TRUE(found_foo_object);
    EXPECT_TRUE(found_bar_object);
  } else {
    // Policy-defined port permissions are not set for unaffiliated users.
    EXPECT_FALSE(context()->HasPortPermission(kFooOrigin, *platform_port));
    EXPECT_FALSE(context()->HasPortPermission(kFooOrigin, *usb_port1));
    EXPECT_FALSE(context()->HasPortPermission(kFooOrigin, *usb_port2));

    EXPECT_FALSE(context()->HasPortPermission(kBarOrigin, *platform_port));
    EXPECT_FALSE(context()->HasPortPermission(kBarOrigin, *usb_port1));
    EXPECT_FALSE(context()->HasPortPermission(kBarOrigin, *usb_port2));

    auto foo_objects = context()->GetGrantedObjects(kFooOrigin);
    EXPECT_EQ(0u, foo_objects.size());

    auto bar_objects = context()->GetGrantedObjects(kBarOrigin);
    EXPECT_EQ(0u, bar_objects.size());

    auto all_objects = context()->GetAllGrantedObjects();
    EXPECT_EQ(0u, all_objects.size());
  }
}

TEST_P(SerialChooserContextAffiliatedTest,
       PolicyAllowForUrlsDescriptionStrings) {
  const auto kFooOrigin = url::Origin::Create(GURL("https://foo.origin"));
  const auto kBarOrigin = url::Origin::Create(GURL("https://bar.origin"));

  local_state()->SetManagedPref(prefs::kManagedSerialAllowUsbDevicesForUrls,
                                ParseJson(R"([
               {
                 "devices": [{ "vendor_id": 6353 }],
                 "urls": [ "https://google.com" ]
               },
               {
                 "devices": [{ "vendor_id": 6354 }],
                 "urls": [ "https://unknown-vendor.com" ]
               },
               {
                 "devices": [{ "vendor_id": 6353, "product_id": 5678 }],
                 "urls": [ "https://unknown-product.google.com" ]
               },
               {
                 "devices": [{ "vendor_id": 6354, "product_id": 5678 }],
                 "urls": [ "https://unknown-product.unknown-vendor.com" ]
               }
             ])"));

  if (is_affiliated()) {
    auto google_objects = context()->GetGrantedObjects(
        url::Origin::Create(GURL("https://google.com")));
    ASSERT_EQ(1u, google_objects.size());
#if BUILDFLAG(IS_ANDROID)
    // Android doesn't include the USB device list because it takes too much
    // space
    EXPECT_EQ(u"USB devices from vendor 18D1",
              context()->GetObjectDisplayName(google_objects[0]->value));
#else
    EXPECT_EQ(u"USB devices from Google Inc.",
              context()->GetObjectDisplayName(google_objects[0]->value));
#endif  // BUILDFLAG(IS_ANDROID)

    auto unknown_vendor_objects = context()->GetGrantedObjects(
        url::Origin::Create(GURL("https://unknown-vendor.com")));
    ASSERT_EQ(1u, unknown_vendor_objects.size());
    EXPECT_EQ(
        u"USB devices from vendor 18D2",
        context()->GetObjectDisplayName(unknown_vendor_objects[0]->value));

    auto unknown_product_objects = context()->GetGrantedObjects(
        url::Origin::Create(GURL("https://unknown-product.google.com")));
    ASSERT_EQ(1u, unknown_product_objects.size());
#if BUILDFLAG(IS_ANDROID)
    // Android doesn't include the USB device list because it takes too much
    // space
    EXPECT_EQ(
        u"USB device (18D1:162E)",
        context()->GetObjectDisplayName(unknown_product_objects[0]->value));
#else
    EXPECT_EQ(
        u"USB device from Google Inc. (product 162E)",
        context()->GetObjectDisplayName(unknown_product_objects[0]->value));
#endif  // BUILDFLAG(IS_ANDROID)

    auto unknown_product_and_vendor_objects =
        context()->GetGrantedObjects(url::Origin::Create(
            GURL("https://unknown-product.unknown-vendor.com")));
    ASSERT_EQ(1u, unknown_product_and_vendor_objects.size());
    EXPECT_EQ(u"USB device (18D2:162E)",
              context()->GetObjectDisplayName(
                  unknown_product_and_vendor_objects[0]->value));
  } else {
    // Policy-defined port permissions are not set for unaffiliated users.
    auto google_objects = context()->GetGrantedObjects(
        url::Origin::Create(GURL("https://google.com")));
    EXPECT_EQ(0u, google_objects.size());

    auto unknown_vendor_objects = context()->GetGrantedObjects(
        url::Origin::Create(GURL("https://unknown-vendor.com")));
    EXPECT_EQ(0u, unknown_vendor_objects.size());

    auto unknown_product_objects = context()->GetGrantedObjects(
        url::Origin::Create(GURL("https://unknown-product.google.com")));
    EXPECT_EQ(0u, unknown_product_objects.size());

    auto unknown_product_and_vendor_objects =
        context()->GetGrantedObjects(url::Origin::Create(
            GURL("https://unknown-product.unknown-vendor.com")));
    EXPECT_EQ(0u, unknown_product_and_vendor_objects.size());
  }
}

TEST_P(SerialChooserContextAffiliatedTest, PolicyAllowOverridesGuard) {
  const auto kFooOrigin = url::Origin::Create(GURL("https://foo.origin"));
  const auto kBarOrigin = url::Origin::Create(GURL("https://bar.origin"));

  auto* profile_prefs = profile()->GetTestingPrefService();
  profile_prefs->SetManagedPref(
      prefs::kManagedDefaultSerialGuardSetting,
      std::make_unique<base::Value>(CONTENT_SETTING_BLOCK));
  local_state()->SetManagedPref(prefs::kManagedSerialAllowAllPortsForUrls,
                                ParseJson(R"([ "https://foo.origin" ])"));

  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();

  EXPECT_FALSE(context()->CanRequestObjectPermission(kFooOrigin));

  if (is_affiliated()) {
    EXPECT_TRUE(context()->HasPortPermission(kFooOrigin, *port));
  } else {
    // Policy-defined port permissions are not set for unaffiliated users.
    EXPECT_FALSE(context()->HasPortPermission(kFooOrigin, *port));
  }

  EXPECT_FALSE(context()->CanRequestObjectPermission(kBarOrigin));
  EXPECT_FALSE(context()->HasPortPermission(kBarOrigin, *port));
}

TEST_P(SerialChooserContextAffiliatedTest, PolicyAllowOverridesBlocked) {
  const auto kFooOrigin = url::Origin::Create(GURL("https://foo.origin"));
  const auto kBarOrigin = url::Origin::Create(GURL("https://bar.origin"));

  auto* profile_prefs = profile()->GetTestingPrefService();
  profile_prefs->SetManagedPref(
      prefs::kManagedSerialBlockedForUrls,
      ParseJson(R"([ "https://foo.origin", "https://bar.origin" ])"));
  local_state()->SetManagedPref(prefs::kManagedSerialAllowAllPortsForUrls,
                                ParseJson(R"([ "https://foo.origin" ])"));

  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();

  EXPECT_FALSE(context()->CanRequestObjectPermission(kFooOrigin));

  if (is_affiliated()) {
    EXPECT_TRUE(context()->HasPortPermission(kFooOrigin, *port));
  } else {
    // Policy-defined port permissions are not set for unaffiliated users.
    EXPECT_FALSE(context()->HasPortPermission(kFooOrigin, *port));
  }

  EXPECT_FALSE(context()->CanRequestObjectPermission(kBarOrigin));
  EXPECT_FALSE(context()->HasPortPermission(kBarOrigin, *port));
}

TEST_F(SerialChooserContextTest, Blocklist) {
  const auto origin = url::Origin::Create(GURL("https://google.com"));

  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();
  port->has_vendor_id = true;
  port->vendor_id = 0x18D1;
  port->has_product_id = true;
  port->product_id = 0x58F0;
  context()->GrantPortPermission(origin, *port);
  EXPECT_TRUE(context()->HasPortPermission(origin, *port));

  // Adding a USB device to the blocklist overrides any previously granted
  // permissions.
  SetDynamicBlocklist("usb:18D1:58F0");
  EXPECT_FALSE(context()->HasPortPermission(origin, *port));

  // The lists of granted permissions will still include the entry because
  // permission storage does not include the USB vendor and product IDs on all
  // platforms and users should still be made aware of permissions they've
  // granted even if they are being blocked from taking effect.
  std::vector<std::unique_ptr<SerialChooserContext::Object>> objects =
      context()->GetGrantedObjects(origin);
  EXPECT_EQ(1u, objects.size());

  std::vector<std::unique_ptr<SerialChooserContext::Object>>
      all_origin_objects = context()->GetAllGrantedObjects();
  EXPECT_EQ(1u, all_origin_objects.size());
}

TEST_P(SerialChooserContextAffiliatedTest, BlocklistOverridesPolicy) {
  const auto origin = url::Origin::Create(GURL("https://google.com"));

  local_state()->SetManagedPref(prefs::kManagedSerialAllowUsbDevicesForUrls,
                                ParseJson(R"([
               {
                 "devices": [{ "vendor_id": 6353, "product_id": 22768 }],
                 "urls": [ "https://google.com" ]
               }
             ])"));

  auto port = device::mojom::SerialPortInfo::New();
  port->token = base::UnguessableToken::Create();
  port->has_vendor_id = true;
  port->vendor_id = 0x18D1;
  port->has_product_id = true;
  port->product_id = 0x58F0;

  if (is_affiliated()) {
    EXPECT_TRUE(context()->HasPortPermission(origin, *port));
  } else {
    // Policy-defined port permissions are not set for unaffiliated users.
    EXPECT_FALSE(context()->HasPortPermission(origin, *port));
  }

  // Adding a USB device to the blocklist overrides permissions granted by
  // policy.
  SetDynamicBlocklist("usb:18D1:58F0");
  EXPECT_FALSE(context()->HasPortPermission(origin, *port));
}

// Boolean parameter means if user is affiliated on the device. Affiliated
// users belong to the domain that owns the device and is only meaningful
// on ChromeOS.
//
// The SerialAllowAllPortsForUrls and SerialAllowUsbDevicesForUrls policies
// only take effect for sffiliated users.
INSTANTIATE_TEST_SUITE_P(
    SerialChooserContextAffiliatedTestInstance,
    SerialChooserContextAffiliatedTest,
#if BUILDFLAG(IS_CHROMEOS)
    testing::Values(true, false),
#else
    testing::Values(true),
#endif
    [](const testing::TestParamInfo<
        SerialChooserContextAffiliatedTest::ParamType>& info) {
      return info.param ? "affiliated" : "unaffiliated";
    });
