chromium/chrome/browser/ui/views/media_router/presentation_receiver_window_view_browsertest.cc

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

#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/views/media_router/presentation_receiver_window_view.h"

#include "base/functional/callback.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/media_router/presentation_receiver_window_delegate.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/location_bar/location_icon_view.h"
#include "chrome/browser/ui/views/media_router/presentation_receiver_window_frame.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "ui/base/ui_base_types.h"
#include "ui/events/event.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/view.h"
#include "url/gurl.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/public/cpp/window_properties.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/widget/widget.h"
#endif

namespace {

WebContents;

// Provides a WebContents for the PresentationReceiverWindowView to display and
// a window-close callback for the test to cleanly close the view.
class FakeReceiverDelegate final : public PresentationReceiverWindowDelegate {};

class PresentationReceiverWindowViewBrowserTest : public InProcessBrowserTest {};

#if BUILDFLAG(IS_CHROMEOS_ASH)
IN_PROC_BROWSER_TEST_F(PresentationReceiverWindowViewBrowserTest,
                       ChromeOSHardwareFullscreenButton) {
  // Bypass ExclusiveAccessContext and default accelerator to simulate hardware
  // window state button, which sets the native aura window to a "normal" state.

  // Waits for the PresentationReceiverWindowView to enter or exit fullscreen.
  // It waits for the location bar visibility to change rather than simply using
  // RunLoop::RunUntilIdle because in Mash, the fullscreen change takes place in
  // another process.
  class FullscreenWaiter final {
   public:
    enum class AwaitType {
      kOutOfFullscreen,
      kIntoFullscreen,
    };

    FullscreenWaiter(PresentationReceiverWindowView* receiver_view,
                     AwaitType await_type,
                     base::OnceClosure fullscreen_callback)
        : receiver_view_(receiver_view),
          await_type_(await_type),
          fullscreen_callback_(std::move(fullscreen_callback)) {
      auto* location_bar_view = receiver_view_->location_bar_view();
      subscription_ =
          location_bar_view->AddVisibleChangedCallback(base::BindRepeating(
              &FullscreenWaiter::OnViewVisibilityChanged,
              base::Unretained(this), base::Unretained(location_bar_view)));
    }

    FullscreenWaiter(const FullscreenWaiter&) = delete;
    FullscreenWaiter& operator=(const FullscreenWaiter&) = delete;

    ~FullscreenWaiter() = default;

   private:
    void OnViewVisibilityChanged(views::View* observed_view) {
      bool fullscreen = !observed_view->GetVisible();
      EXPECT_EQ(fullscreen, receiver_view_->IsFullscreen());
      if (fullscreen == (await_type_ == AwaitType::kIntoFullscreen))
        std::move(fullscreen_callback_).Run();
    }

    const raw_ptr<PresentationReceiverWindowView> receiver_view_;
    base::CallbackListSubscription subscription_;
    const AwaitType await_type_;
    base::OnceClosure fullscreen_callback_;
  };

  {
    base::RunLoop fullscreen_loop;
    FullscreenWaiter waiter(receiver_view_,
                            FullscreenWaiter::AwaitType::kIntoFullscreen,
                            fullscreen_loop.QuitClosure());
    receiver_view_->ShowInactiveFullscreen();
    fullscreen_loop.Run();

    ASSERT_TRUE(receiver_view_->IsFullscreen());
    EXPECT_FALSE(receiver_view_->location_bar_view()->GetVisible());
  }

  {
    base::RunLoop fullscreen_loop;
    FullscreenWaiter waiter(receiver_view_,
                            FullscreenWaiter::AwaitType::kOutOfFullscreen,
                            fullscreen_loop.QuitClosure());
    receiver_view_->GetWidget()->SetFullscreen(false);
    fullscreen_loop.Run();
    ASSERT_FALSE(receiver_view_->IsFullscreen());
    EXPECT_TRUE(receiver_view_->location_bar_view()->GetVisible());
  }

  // Back to fullscreen with the hardware button.
  {
    base::RunLoop fullscreen_loop;
    FullscreenWaiter waiter(receiver_view_,
                            FullscreenWaiter::AwaitType::kIntoFullscreen,
                            fullscreen_loop.QuitClosure());
    receiver_view_->GetWidget()->SetFullscreen(true);
    fullscreen_loop.Run();
    ASSERT_TRUE(receiver_view_->IsFullscreen());
    EXPECT_FALSE(receiver_view_->location_bar_view()->GetVisible());
  }
}
#endif

IN_PROC_BROWSER_TEST_F(PresentationReceiverWindowViewBrowserTest,
                       LocationBarViewShown) {}

IN_PROC_BROWSER_TEST_F(PresentationReceiverWindowViewBrowserTest,
                       ShowPageInfoDialog) {}

}  // namespace