// Copyright 2018 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 "chrome/browser/ui/media_router/media_router_ui.h"

#include <initializer_list>
#include <memory>
#include <utility>
#include <vector>

#include "base/containers/contains.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/media/router/chrome_media_router_factory.h"
#include "chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h"
#include "chrome/browser/sessions/session_tab_helper_factory.h"
#include "chrome/browser/ui/media_router/cast_dialog_controller.h"
#include "chrome/browser/ui/media_router/media_cast_mode.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "components/media_router/browser/media_router_factory.h"
#include "components/media_router/browser/media_sinks_observer.h"
#include "components/media_router/browser/presentation/presentation_service_delegate_impl.h"
#include "components/media_router/browser/test/mock_media_router.h"
#include "components/media_router/browser/test/test_helper.h"
#include "components/media_router/common/media_source.h"
#include "components/media_router/common/route_request_result.h"
#include "components/media_router/common/test/test_helper.h"
#include "components/sessions/content/session_tab_helper.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension_builder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/display/display.h"
#include "url/origin.h"

#if BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
#include "ui/base/cocoa/permissions_utils.h"
#endif

using testing::_;
using testing::Invoke;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::WithArg;

namespace media_router {

namespace {

constexpr char kRouteId[] = "route1";
constexpr char kSinkDescription[] = "description";
constexpr char kSinkId[] = "sink1";
constexpr char kSinkName[] = "sink name";
constexpr char kSourceId[] = "source1";

ACTION_TEMPLATE(SaveArgWithMove,
                HAS_1_TEMPLATE_PARAMS(int, k),
                AND_1_VALUE_PARAMS(pointer)) {
  *pointer = std::move(::testing::get<k>(args));
}

class MockControllerObserver : public CastDialogController::Observer {
 public:
  MockControllerObserver() = default;
  explicit MockControllerObserver(CastDialogController* controller)
      : controller_(controller) {
    controller_->AddObserver(this);
  }

  ~MockControllerObserver() override {
    if (controller_)
      controller_->RemoveObserver(this);
  }

  MOCK_METHOD1(OnModelUpdated, void(const CastDialogModel& model));
  void OnControllerInvalidated() {
    controller_ = nullptr;
    OnControllerInvalidatedInternal();
  }
  MOCK_METHOD0(OnControllerInvalidatedInternal, void());

 private:
  raw_ptr<CastDialogController> controller_ = nullptr;
};

class PresentationRequestCallbacks {
 public:
  PresentationRequestCallbacks() {}

  explicit PresentationRequestCallbacks(
      const blink::mojom::PresentationError& expected_error)
      : expected_error_(expected_error) {}

  void Success(const blink::mojom::PresentationInfo&,
               mojom::RoutePresentationConnectionPtr,
               const MediaRoute&) {}

  void Error(const blink::mojom::PresentationError& error) {
    EXPECT_EQ(expected_error_.error_type, error.error_type);
    EXPECT_EQ(expected_error_.message, error.message);
  }

 private:
  blink::mojom::PresentationError expected_error_;
};

class TestWebContentsDisplayObserver : public WebContentsDisplayObserver {
 public:
  explicit TestWebContentsDisplayObserver(const display::Display& display)
      : display_(display) {}
  ~TestWebContentsDisplayObserver() override {}

  const display::Display& GetCurrentDisplay() const override {
    return display_;
  }

  void set_display(const display::Display& display) { display_ = display; }

 private:
  display::Display display_;
};

}  // namespace

class MediaRouterViewsUITest : public ChromeRenderViewHostTestHarness {
 public:
  void SetUp() override {
    ChromeRenderViewHostTestHarness::SetUp();

    SetMediaRouterFactory();
    mock_router_ = static_cast<MockMediaRouter*>(
        MediaRouterFactory::GetApiForBrowserContext(GetBrowserContext()));
    logger_ = std::make_unique<LoggerImpl>();

    // Store sink observers so that they can be notified in tests.
    ON_CALL(*mock_router_, RegisterMediaSinksObserver(_))
        .WillByDefault([this](MediaSinksObserver* observer) {
          media_sinks_observers_.push_back(observer);
          return true;
        });
    ON_CALL(*mock_router_, GetLogger()).WillByDefault(Return(logger_.get()));

    CreateSessionServiceTabHelper(web_contents());
    ui_ =
        MediaRouterUI::CreateWithDefaultMediaSourceAndMirroring(web_contents());
  }

  void TearDown() override {
#if BUILDFLAG(IS_MAC)
    clear_screen_capture_allowed_for_testing();
#endif
    ui_.reset();
    ChromeRenderViewHostTestHarness::TearDown();
  }

  virtual void SetMediaRouterFactory() {
    ChromeMediaRouterFactory::GetInstance()->SetTestingFactory(
        GetBrowserContext(), base::BindRepeating(&MockMediaRouter::Create));
  }

  void CreateMediaRouterUIForURL(const GURL& url) {
    web_contents()->GetController().LoadURL(url, content::Referrer(),
                                            ui::PAGE_TRANSITION_LINK, "");
    content::RenderFrameHostTester::CommitPendingLoad(
        &web_contents()->GetController());
    CreateSessionServiceTabHelper(web_contents());
    ui_ =
        MediaRouterUI::CreateWithDefaultMediaSourceAndMirroring(web_contents());
  }

  // These methods are used so that we don't have to friend each test case that
  // calls the private methods.
  void NotifyUiOnSinksUpdated(
      const std::vector<MediaSinkWithCastModes>& sinks) {
    ui_->OnSinksUpdated(sinks);
  }
  void NotifyUiOnRoutesUpdated(const std::vector<MediaRoute>& routes) {
    ui_->OnRoutesUpdated(routes);
  }

  void StartTabCasting(bool is_incognito) {
    MediaSource media_source = MediaSource::ForTab(
        sessions::SessionTabHelper::IdForTab(web_contents()).id());
    EXPECT_CALL(
        *mock_router_,
        CreateRouteInternal(media_source.id(), kSinkId, _, web_contents(), _,
                            base::Seconds(60), is_incognito));
    MediaSink sink{CreateCastSink(kSinkId, kSinkName)};
    for (MediaSinksObserver* sinks_observer : media_sinks_observers_)
      sinks_observer->OnSinksUpdated({sink}, std::vector<url::Origin>());
    ui_->StartCasting(kSinkId, MediaCastMode::TAB_MIRROR);
  }

  void StartCastingAndExpectTimeout(MediaCastMode cast_mode,
                                    const std::string& expected_issue_title,
                                    int timeout_seconds) {
    NiceMock<MockControllerObserver> observer(ui_.get());
    MediaSink sink{CreateCastSink(kSinkId, kSinkName)};
    ui_->OnSinksUpdated({{sink, {cast_mode}}});
    MediaRouteResponseCallback callback;
    EXPECT_CALL(*mock_router_,
                CreateRouteInternal(_, _, _, _, _,
                                    base::Seconds(timeout_seconds), false))
        .WillOnce(SaveArgWithMove<4>(&callback));
    for (MediaSinksObserver* sinks_observer : media_sinks_observers_)
      sinks_observer->OnSinksUpdated({sink}, std::vector<url::Origin>());
    ui_->StartCasting(kSinkId, cast_mode);
    Mock::VerifyAndClearExpectations(mock_router_);

    EXPECT_CALL(observer, OnModelUpdated(_))
        .WillOnce(WithArg<0>([&](const CastDialogModel& model) {
          EXPECT_EQ(model.media_sinks()[0].issue->info().title,
                    expected_issue_title);
        }));
    std::unique_ptr<RouteRequestResult> result = RouteRequestResult::FromError(
        "Timed out", mojom::RouteRequestResultCode::TIMED_OUT);
    std::move(callback).Run(nullptr, *result);
  }

  // The caller must hold on to PresentationRequestCallbacks returned so that
  // a callback can later be called on it.
  std::unique_ptr<PresentationRequestCallbacks> ExpectPresentationError(
      blink::mojom::PresentationErrorType error_type,
      const std::string& error_message) {
    blink::mojom::PresentationError expected_error(error_type, error_message);
    auto request_callbacks =
        std::make_unique<PresentationRequestCallbacks>(expected_error);
    start_presentation_context_ = std::make_unique<StartPresentationContext>(
        presentation_request_,
        base::BindOnce(&PresentationRequestCallbacks::Success,
                       base::Unretained(request_callbacks.get())),
        base::BindOnce(&PresentationRequestCallbacks::Error,
                       base::Unretained(request_callbacks.get())));
    StartPresentationContext* context_ptr = start_presentation_context_.get();
    ui_->media_route_starter()->set_start_presentation_context_for_test(
        std::move(start_presentation_context_));
    ui_->media_route_starter()->OnDefaultPresentationChanged(
        &context_ptr->presentation_request());
    return request_callbacks;
  }

 protected:
  std::vector<MediaSinksObserver*> media_sinks_observers_;
  raw_ptr<MockMediaRouter> mock_router_ = nullptr;
  std::unique_ptr<MediaRouterUI> ui_;
  std::unique_ptr<StartPresentationContext> start_presentation_context_;
  std::unique_ptr<LoggerImpl> logger_;
  content::PresentationRequest presentation_request_{
      {0, 0},
      {GURL("https://google.com/presentation")},
      url::Origin::Create(GURL("http://google.com"))};
};

TEST_F(MediaRouterViewsUITest, NotifyObserver) {
  MockControllerObserver observer;

  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>(Invoke([](const CastDialogModel& model) {
        EXPECT_TRUE(model.media_sinks().empty());
      })));
  ui_->AddObserver(&observer);

  MediaSink sink{CreateCastSink(kSinkId, kSinkName)};
  MediaSinkWithCastModes sink_with_cast_modes(sink);
  sink_with_cast_modes.cast_modes = {MediaCastMode::TAB_MIRROR};
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>(Invoke([&sink](const CastDialogModel& model) {
        EXPECT_EQ(1u, model.media_sinks().size());
        const UIMediaSink& ui_sink = model.media_sinks()[0];
        EXPECT_EQ(sink.id(), ui_sink.id);
        EXPECT_EQ(base::UTF8ToUTF16(sink.name()), ui_sink.friendly_name);
        EXPECT_EQ(UIMediaSinkState::AVAILABLE, ui_sink.state);
        EXPECT_TRUE(
            base::Contains(ui_sink.cast_modes, MediaCastMode::TAB_MIRROR));
        EXPECT_EQ(sink.icon_type(), ui_sink.icon_type);
      })));
  NotifyUiOnSinksUpdated({sink_with_cast_modes});

  MediaRoute route(kRouteId, MediaSource(kSourceId), kSinkId, "", true);
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(
          WithArg<0>(Invoke([&sink, &route](const CastDialogModel& model) {
            EXPECT_EQ(1u, model.media_sinks().size());
            const UIMediaSink& ui_sink = model.media_sinks()[0];
            EXPECT_EQ(sink.id(), ui_sink.id);
            EXPECT_EQ(UIMediaSinkState::CONNECTED, ui_sink.state);
            EXPECT_EQ(route.media_route_id(), ui_sink.route->media_route_id());
          })));
  NotifyUiOnRoutesUpdated({route});

  EXPECT_CALL(observer, OnControllerInvalidatedInternal());
  ui_.reset();
}

TEST_F(MediaRouterViewsUITest, SinkFriendlyName) {
  NiceMock<MockControllerObserver> observer(ui_.get());

  MediaSink sink{CreateCastSink(kSinkId, kSinkName)};
  sink.set_description(kSinkDescription);
  MediaSinkWithCastModes sink_with_cast_modes(sink);
  const char* separator = " \u2010 ";
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(Invoke([&](const CastDialogModel& model) {
        EXPECT_EQ(base::UTF8ToUTF16(sink.name() + separator +
                                    sink.description().value()),
                  model.media_sinks()[0].friendly_name);
      }));
  NotifyUiOnSinksUpdated({sink_with_cast_modes});
}

TEST_F(MediaRouterViewsUITest, SetDialogHeader) {
  MockControllerObserver observer;
  // Initially, the dialog header should simply say "Cast".
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce([&](const CastDialogModel& model) {
        EXPECT_EQ(
            l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_TAB_MIRROR_CAST_MODE),
            model.dialog_header());
      });
  ui_->AddObserver(&observer);

  // The observer is called multiple times when the default PresentationRequest
  // is changed; the last invocation has the correct header.
  std::u16string current_header;
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillRepeatedly([&](const CastDialogModel& model) {
        current_header = model.dialog_header();
      });

  // First test a presentation started from an https: origin.
  const GURL presentation_url("https://presentation.com");
  const auto https_origin =
      url::Origin::Create(GURL("https://requesting-page.com"));
  // An https origin is included in the dialog header without the scheme.
  content::PresentationRequest presentation_request(
      content::GlobalRenderFrameHostId(), {presentation_url}, https_origin);
  ui_->media_route_starter()->OnDefaultPresentationChanged(
      &presentation_request);
  EXPECT_EQ(l10n_util::GetStringFUTF16(IDS_MEDIA_ROUTER_PRESENTATION_CAST_MODE,
                                       base::UTF8ToUTF16(https_origin.host())),
            current_header);

  // An opaque origin is empty, which causes the dialog to fall back to the tab
  // mirroring header.
  presentation_request = content::PresentationRequest(
      content::GlobalRenderFrameHostId(), {presentation_url}, url::Origin());
  ui_->media_route_starter()->OnDefaultPresentationChanged(
      &presentation_request);
  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_TAB_MIRROR_CAST_MODE),
            current_header);

  // An extension origin is replaced by the extension name.
  const std::string extension_id = "extensionid";
  const auto extension_origin =
      url::Origin::Create(GURL("chrome-extension://" + extension_id));
  auto* registry = extensions::ExtensionRegistry::Get(GetBrowserContext());
  scoped_refptr<const extensions::Extension> extension =
      extensions::ExtensionBuilder(
          "Test Extension", extensions::ExtensionBuilder::Type::EXTENSION)
          .SetID(extension_id)
          .Build();

  ASSERT_TRUE(registry->AddEnabled(extension));

  presentation_request = content::PresentationRequest(
      content::GlobalRenderFrameHostId(), {presentation_url}, extension_origin);
  ui_->media_route_starter()->OnDefaultPresentationChanged(
      &presentation_request);
  EXPECT_EQ(l10n_util::GetStringFUTF16(IDS_MEDIA_ROUTER_PRESENTATION_CAST_MODE,
                                       std::u16string(u"Test Extension")),
            current_header);

  ui_->RemoveObserver(&observer);
}

TEST_F(MediaRouterViewsUITest, StartCasting) {
  StartTabCasting(false);
}

TEST_F(MediaRouterViewsUITest, StopCasting) {
  EXPECT_CALL(*mock_router_, TerminateRoute(kRouteId));
  ui_->StopCasting(kRouteId);
}

TEST_F(MediaRouterViewsUITest, ConnectingState) {
  NiceMock<MockControllerObserver> observer(ui_.get());

  MediaSink sink{CreateDialSink(kSinkId, kSinkName)};
  for (MediaSinksObserver* sinks_observer : media_sinks_observers_)
    sinks_observer->OnSinksUpdated({sink}, std::vector<url::Origin>());

  // When a request to Cast to a sink is made, its state should become
  // CONNECTING.
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>(Invoke([](const CastDialogModel& model) {
        ASSERT_EQ(1u, model.media_sinks().size());
        EXPECT_EQ(UIMediaSinkState::CONNECTING, model.media_sinks()[0].state);
      })));
  ui_->StartCasting(kSinkId, MediaCastMode::TAB_MIRROR);

  // Once a route is created for the sink, its state should become CONNECTED.
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>(Invoke([](const CastDialogModel& model) {
        ASSERT_EQ(1u, model.media_sinks().size());
        EXPECT_EQ(UIMediaSinkState::CONNECTED, model.media_sinks()[0].state);
      })));
  MediaRoute route(kRouteId, MediaSource(kSourceId), kSinkId, "", true);
  NotifyUiOnRoutesUpdated({route});
}

TEST_F(MediaRouterViewsUITest, DisconnectingState) {
  NiceMock<MockControllerObserver> observer(ui_.get());

  MediaSink sink{CreateDialSink(kSinkId, kSinkName)};
  MediaRoute route(kRouteId, MediaSource(kSourceId), kSinkId, "", true);
  for (MediaSinksObserver* sinks_observer : media_sinks_observers_)
    sinks_observer->OnSinksUpdated({sink}, std::vector<url::Origin>());
  NotifyUiOnRoutesUpdated({route});

  // When a request to stop casting to a sink is made, its state should become
  // DISCONNECTING.
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>(Invoke([](const CastDialogModel& model) {
        ASSERT_EQ(1u, model.media_sinks().size());
        EXPECT_EQ(UIMediaSinkState::DISCONNECTING,
                  model.media_sinks()[0].state);
      })));
  ui_->StopCasting(kRouteId);

  // Once the route is removed, the sink's state should become AVAILABLE.
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>(Invoke([](const CastDialogModel& model) {
        ASSERT_EQ(1u, model.media_sinks().size());
        EXPECT_EQ(UIMediaSinkState::AVAILABLE, model.media_sinks()[0].state);
      })));
  NotifyUiOnRoutesUpdated({});
}

TEST_F(MediaRouterViewsUITest, AddAndRemoveIssue) {
  MediaSink sink1{CreateCastSink("sink_id1", "Sink 1")};
  MediaSink sink2{CreateCastSink("sink_id2", "Sink 2")};
  NotifyUiOnSinksUpdated({{sink1, {MediaCastMode::TAB_MIRROR}},
                          {sink2, {MediaCastMode::TAB_MIRROR}}});

  NiceMock<MockControllerObserver> observer(ui_.get());
  NiceMock<MockIssuesObserver> issues_observer(mock_router_->GetIssueManager());
  issues_observer.Init();
  const std::string issue_title("Issue 1");
  IssueInfo issue(issue_title, IssueInfo::Action::DISMISS,
                  IssueInfo::Severity::WARNING);
  issue.sink_id = sink2.id();
  Issue::Id issue_id = -1;

  EXPECT_CALL(issues_observer, OnIssue)
      .WillOnce(
          Invoke([&issue_id](const Issue& issue) { issue_id = issue.id(); }));
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>(
          Invoke([&sink1, &sink2, &issue_title](const CastDialogModel& model) {
            EXPECT_EQ(2u, model.media_sinks().size());
            EXPECT_EQ(model.media_sinks()[0].id, sink1.id());
            EXPECT_FALSE(model.media_sinks()[0].issue.has_value());
            EXPECT_EQ(model.media_sinks()[1].id, sink2.id());
            EXPECT_EQ(model.media_sinks()[1].issue->info().title, issue_title);
          })));
  mock_router_->GetIssueManager()->AddIssue(issue);

  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>(Invoke([&sink2](const CastDialogModel& model) {
        EXPECT_EQ(2u, model.media_sinks().size());
        EXPECT_EQ(model.media_sinks()[1].id, sink2.id());
        EXPECT_FALSE(model.media_sinks()[1].issue.has_value());
      })));
  mock_router_->GetIssueManager()->ClearIssue(issue_id);
}

TEST_F(MediaRouterViewsUITest, RouteCreationTimeoutForTab) {
  StartCastingAndExpectTimeout(
      MediaCastMode::TAB_MIRROR,
      l10n_util::GetStringUTF8(
          IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_TAB),
      60);
}

TEST_F(MediaRouterViewsUITest, RouteCreationTimeoutForDesktop) {
#if BUILDFLAG(IS_MAC)
  if (base::mac::IsAtLeastOS10_15())
    set_screen_capture_allowed_for_testing(true);
#endif

  StartCastingAndExpectTimeout(
      MediaCastMode::DESKTOP_MIRROR,
      l10n_util::GetStringUTF8(
          IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_DESKTOP),
      120);
}

TEST_F(MediaRouterViewsUITest, RouteCreationTimeoutForPresentation) {
  content::PresentationRequest presentation_request(
      {0, 0}, {GURL("https://presentationurl.com")},
      url::Origin::Create(GURL("https://frameurl.fakeurl")));
  ui_->media_route_starter()->OnDefaultPresentationChanged(
      &presentation_request);
  StartCastingAndExpectTimeout(
      MediaCastMode::PRESENTATION,
      l10n_util::GetStringFUTF8(IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT,
                                u"frameurl.fakeurl"),
      20);
}

#if BUILDFLAG(IS_MAC)
TEST_F(MediaRouterViewsUITest, DesktopMirroringFailsWhenDisallowedOnMac) {
  // Failure due to a lack of screen capture permissions only happens on macOS
  // 10.15 or later. See crbug.com/1087236 for more info.
  if (!base::mac::IsAtLeastOS10_15())
    return;

  set_screen_capture_allowed_for_testing(false);
  MockControllerObserver observer(ui_.get());
  MediaSink sink{CreateCastSink(kSinkId, kSinkName)};
  ui_->OnSinksUpdated({{sink, {MediaCastMode::DESKTOP_MIRROR}}});
  for (MediaSinksObserver* sinks_observer : media_sinks_observers_)
    sinks_observer->OnSinksUpdated({sink}, std::vector<url::Origin>());

  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>([&](const CastDialogModel& model) {
        EXPECT_EQ(
            model.media_sinks()[0].issue->info().title,
            l10n_util::GetStringUTF8(
                IDS_MEDIA_ROUTER_ISSUE_MAC_SCREEN_CAPTURE_PERMISSION_ERROR));
      }));
  ui_->StartCasting(kSinkId, MediaCastMode::DESKTOP_MIRROR);
}
#endif

TEST_F(MediaRouterViewsUITest, SortedSinks) {
  NotifyUiOnSinksUpdated({{CreateCastSink("sink3", "B sink"), {}},
                          {CreateCastSink("sink2", "A sink"), {}},
                          {CreateCastSink("sink1", "B sink"), {}}});

  // Sort first by name, then by ID.
  const auto& sorted_sinks = ui_->GetEnabledSinks();
  EXPECT_EQ("sink2", sorted_sinks[0].sink.id());
  EXPECT_EQ("sink1", sorted_sinks[1].sink.id());
  EXPECT_EQ("sink3", sorted_sinks[2].sink.id());
}

TEST_F(MediaRouterViewsUITest, SortSinksByIconType) {
  NotifyUiOnSinksUpdated(
      {{MediaSink{"id1", "B sink", SinkIconType::CAST_AUDIO_GROUP,
                  mojom::MediaRouteProviderId::CAST},
        {}},
       {MediaSink{"id2", "sink", SinkIconType::GENERIC,
                  mojom::MediaRouteProviderId::WIRED_DISPLAY},
        {}},
       {MediaSink{"id3", "A sink", SinkIconType::CAST_AUDIO_GROUP,
                  mojom::MediaRouteProviderId::CAST},
        {}},
       {MediaSink{"id4", "sink", SinkIconType::CAST_AUDIO,
                  mojom::MediaRouteProviderId::CAST},
        {}},
       {MediaSink{"id5", "sink", SinkIconType::CAST,
                  mojom::MediaRouteProviderId::CAST},
        {}}});

  // The sorted order is CAST, CAST_AUDIO_GROUP "A", CAST_AUDIO_GROUP "B",
  // CAST_AUDIO, HANGOUT, GENERIC.
  const auto& sorted_sinks = ui_->GetEnabledSinks();
  EXPECT_EQ("id5", sorted_sinks[0].sink.id());
  EXPECT_EQ("id3", sorted_sinks[1].sink.id());
  EXPECT_EQ("id1", sorted_sinks[2].sink.id());
  EXPECT_EQ("id4", sorted_sinks[3].sink.id());
  EXPECT_EQ("id2", sorted_sinks[4].sink.id());
}

TEST_F(MediaRouterViewsUITest, NotFoundErrorOnCloseWithNoSinks) {
  auto request_callbacks = ExpectPresentationError(
      blink::mojom::PresentationErrorType::NO_AVAILABLE_SCREENS,
      "No screens found.");
  // Destroying the UI should return the expected error from above to the error
  // callback.
  ui_.reset();
}

TEST_F(MediaRouterViewsUITest, NotFoundErrorOnCloseWithNoCompatibleSinks) {
  auto request_callbacks = ExpectPresentationError(
      blink::mojom::PresentationErrorType::NO_AVAILABLE_SCREENS,
      "No screens found.");
  // Send a sink to the UI that is compatible with sources other than the
  // presentation url to cause a NotFoundError.
  std::vector<MediaSink> sinks = {CreateDialSink(kSinkId, kSinkName)};
  auto presentation_source = MediaSource::ForPresentationUrl(
      presentation_request_.presentation_urls[0]);
  for (MediaSinksObserver* sinks_observer : media_sinks_observers_) {
    if (!(sinks_observer->source() == presentation_source)) {
      sinks_observer->OnSinksUpdated(sinks, {});
    }
  }
  // Destroying the UI should return the expected error from above to the error
  // callback.
  ui_.reset();
}

TEST_F(MediaRouterViewsUITest, AbortErrorOnClose) {
  auto request_callbacks = ExpectPresentationError(
      blink::mojom::PresentationErrorType::PRESENTATION_REQUEST_CANCELLED,
      "Dialog closed.");
  // Send a sink to the UI that is compatible with the presentation url to avoid
  // a NotFoundError.
  std::vector<MediaSink> sinks = {CreateDialSink(kSinkId, kSinkName)};
  auto presentation_source = MediaSource::ForPresentationUrl(
      presentation_request_.presentation_urls[0]);
  for (MediaSinksObserver* sinks_observer : media_sinks_observers_) {
    if (sinks_observer->source() == presentation_source) {
      sinks_observer->OnSinksUpdated(sinks, {});
    }
  }
  // Destroying the UI should return the expected error from above to the error
  // callback.
  ui_.reset();
}

// A wired display sink should not be on the sinks list when the dialog is on
// that display, to prevent showing a fullscreen presentation window over the
// controlling window.
TEST_F(MediaRouterViewsUITest, UpdateSinksWhenDialogMovesToAnotherDisplay) {
  NiceMock<MockControllerObserver> observer(ui_.get());
  const display::Display display1(1000001);
  const display::Display display2(1000002);
  const std::string display_sink_id1 =
      WiredDisplayMediaRouteProvider::GetSinkIdForDisplay(display1);
  const std::string display_sink_id2 =
      WiredDisplayMediaRouteProvider::GetSinkIdForDisplay(display2);

  auto display_observer_unique =
      std::make_unique<TestWebContentsDisplayObserver>(display1);
  TestWebContentsDisplayObserver* display_observer =
      display_observer_unique.get();
  ui_->display_observer_ = std::move(display_observer_unique);

  NotifyUiOnSinksUpdated(
      {{CreateWiredDisplaySink(display_sink_id1, "sink"), {}},
       {CreateWiredDisplaySink(display_sink_id2, "sink"), {}},
       {CreateDialSink("id3", "sink"), {}}});

  // Initially |display_sink_id1| should not be on the sinks list because we are
  // on |display1|.
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>([&](const CastDialogModel& model) {
        const auto& sinks = model.media_sinks();
        EXPECT_EQ(2u, sinks.size());
        EXPECT_TRUE(std::find_if(sinks.begin(), sinks.end(),
                                 [&](const UIMediaSink& sink) {
                                   return sink.id == display_sink_id1;
                                 }) == sinks.end());
      }));
  ui_->UpdateSinks();
  Mock::VerifyAndClearExpectations(&observer);

  // Change the display to |display2|. Now |display_sink_id2| should be removed
  // from the list of sinks.
  EXPECT_CALL(observer, OnModelUpdated(_))
      .WillOnce(WithArg<0>([&](const CastDialogModel& model) {
        const auto& sinks = model.media_sinks();
        EXPECT_EQ(2u, sinks.size());
        EXPECT_TRUE(std::find_if(sinks.begin(), sinks.end(),
                                 [&](const UIMediaSink& sink) {
                                   return sink.id == display_sink_id2;
                                 }) == sinks.end());
      }));
  display_observer->set_display(display2);
  ui_->UpdateSinks();
}

class MediaRouterViewsUIIncognitoTest : public MediaRouterViewsUITest {
 protected:
  void SetMediaRouterFactory() override {
    // We must set the factory on the non-incognito browser context.
    MediaRouterFactory::GetInstance()->SetTestingFactory(
        MediaRouterViewsUITest::GetBrowserContext(),
        base::BindRepeating(&MockMediaRouter::Create));
  }

  content::BrowserContext* GetBrowserContext() override {
    return static_cast<Profile*>(MediaRouterViewsUITest::GetBrowserContext())
        ->GetPrimaryOTRProfile(/*create_if_needed=*/true);
  }
};

TEST_F(MediaRouterViewsUIIncognitoTest, RouteRequestFromIncognito) {
  StartTabCasting(true);
}

}  // namespace media_router
