Skip to content

Commit

Permalink
[Cast Receiver] Add Window Controls
Browse files Browse the repository at this point in the history
This CL replaces the cast-specific CastContentWindow type with a
generic platform-specific type, with an implementation on top of
CastContentWindow.

Bug: 1357135, 1359588
Change-Id: I42a06fd9689d99978de0d154e9c08f88fa5397e0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3993678
Reviewed-by: Vigen Issahhanjan <vigeni@google.com>
Commit-Queue: Ryan Keane <rwkeane@google.com>
Cr-Commit-Position: refs/heads/main@{#1067669}
  • Loading branch information
Ryan Keane authored and Chromium LUCI CQ committed Nov 4, 2022
1 parent aa47783 commit 6802fd2
Show file tree
Hide file tree
Showing 7 changed files with 240 additions and 52 deletions.
88 changes: 49 additions & 39 deletions chromecast/cast_core/runtime/browser/runtime_application_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "chromecast/browser/cast_web_contents.h"
#include "chromecast/browser/visibility_types.h"
#include "chromecast/common/feature_constants.h"
#include "content/public/browser/web_contents.h"

namespace chromecast {
namespace {
Expand Down Expand Up @@ -232,28 +233,29 @@ void RuntimeApplicationBase::LoadPage(const GURL& url) {

// This needs to be called to get the PageState::LOADED event as it's fully
// loaded.
cast_web_contents->SetWebVisibilityAndPaint(false);
SetWebVisibilityAndPaint(false);
}

void RuntimeApplicationBase::OnPageLoaded() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DLOG(INFO) << "Page loaded: " << *this;

DCHECK(delegate_->GetCastContentWindow());
delegate_->GetCastContentWindow()->AddObserver(this);
delegate_->GetCastContentWindow()->EnableTouchInput(
touch_input_ == cast::common::TouchInput::ENABLED);
auto* window_controls = delegate_->GetContentWindowControls();
DCHECK(window_controls);
window_controls->AddVisibilityChangeObserver(*this);
if (touch_input_ == cast::common::TouchInput::ENABLED) {
window_controls->EnableTouchInput();
} else {
window_controls->DisableTouchInput();
}

// Create the window and show the web view.
if (visibility_ == cast::common::Visibility::FULL_SCREEN) {
LOG(INFO) << "Loading page in full screen: " << *this;
delegate_->GetCastContentWindow()->GrantScreenAccess();
delegate_->GetCastContentWindow()->CreateWindow(
mojom::ZOrder::APP, VisibilityPriority::STICKY_ACTIVITY);
window_controls->ShowWindow();
} else {
LOG(INFO) << "Loading page in background: " << *this;
delegate_->GetCastContentWindow()->CreateWindow(mojom::ZOrder::APP,
VisibilityPriority::HIDDEN);
window_controls->HideWindow();
}

delegate().NotifyApplicationStarted();
Expand Down Expand Up @@ -325,21 +327,18 @@ void RuntimeApplicationBase::SetVisibility(
<< cast::common::Visibility::Type_Name(visibility_) << ", "
<< *this;

if (!delegate_->GetCastContentWindow()) {
auto* window_controls = delegate_->GetContentWindowControls();
if (!window_controls) {
return;
}

switch (visibility_) {
case cast::common::Visibility::FULL_SCREEN:
delegate_->GetCastContentWindow()->RequestVisibility(
VisibilityPriority::STICKY_ACTIVITY);
delegate_->GetCastContentWindow()->GrantScreenAccess();
window_controls->ShowWindow();
break;

case cast::common::Visibility::HIDDEN:
delegate_->GetCastContentWindow()->RequestVisibility(
VisibilityPriority::HIDDEN);
delegate_->GetCastContentWindow()->RevokeScreenAccess();
window_controls->HideWindow();
break;

default:
Expand All @@ -360,12 +359,16 @@ void RuntimeApplicationBase::SetTouchInput(
<< cast::common::TouchInput::Type_Name(touch_input_) << ", "
<< *this;

if (!delegate_->GetCastContentWindow()) {
auto* window_controls = delegate_->GetContentWindowControls();
if (!window_controls) {
return;
}

delegate_->GetCastContentWindow()->EnableTouchInput(
touch_input_ == cast::common::TouchInput::ENABLED);
if (touch_input_ == cast::common::TouchInput::ENABLED) {
window_controls->EnableTouchInput();
} else {
window_controls->DisableTouchInput();
}
}

bool RuntimeApplicationBase::IsApplicationRunning() const {
Expand Down Expand Up @@ -393,8 +396,9 @@ void RuntimeApplicationBase::StopApplication(
cast_web_contents->ClosePage();

// Check if window is still available as page might have been closed before.
if (delegate_->GetCastContentWindow()) {
delegate_->GetCastContentWindow()->RemoveObserver(this);
auto* window_controls = delegate_->GetContentWindowControls();
if (window_controls) {
window_controls->RemoveVisibilityChangeObserver(*this);
}
}

Expand All @@ -405,25 +409,31 @@ void RuntimeApplicationBase::StopApplication(
<< *this;
}

void RuntimeApplicationBase::OnVisibilityChange(
VisibilityType visibility_type) {
DCHECK(delegate_->GetWebContents());
auto* cast_web_contents =
CastWebContents::FromWebContents(delegate_->GetWebContents());
DCHECK(cast_web_contents);
switch (visibility_type) {
case VisibilityType::FULL_SCREEN:
case VisibilityType::PARTIAL_OUT:
case VisibilityType::TRANSIENTLY_HIDDEN:
LOG(INFO) << "Application is visible now: " << *this;
cast_web_contents->SetWebVisibilityAndPaint(true);
break;
void RuntimeApplicationBase::SetWebVisibilityAndPaint(bool is_visible) {
auto* web_contents = delegate_->GetWebContents();
if (!web_contents) {
return;
}

default:
LOG(INFO) << "Application is hidden now: " << *this;
cast_web_contents->SetWebVisibilityAndPaint(false);
break;
if (is_visible) {
web_contents->WasShown();
} else {
web_contents->WasHidden();
}

if (web_contents->GetVisibility() != content::Visibility::VISIBLE) {
// Since we are managing the visibility, we need to ensure pages are
// unfrozen in the event this occurred while in the background.
web_contents->SetPageFrozen(false);
}
}

void RuntimeApplicationBase::OnWindowShown() {
SetWebVisibilityAndPaint(true);
}

void RuntimeApplicationBase::OnWindowHidden() {
SetWebVisibilityAndPaint(false);
}

} // namespace chromecast
22 changes: 13 additions & 9 deletions chromecast/cast_core/runtime/browser/runtime_application_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "chromecast/browser/cast_content_window.h"
#include "chromecast/browser/mojom/cast_web_service.mojom.h"
#include "components/cast_receiver/browser/public/content_window_controls.h"
#include "components/cast_receiver/browser/public/runtime_application.h"
#include "components/url_rewrite/mojom/url_request_rewrite.mojom.h"
#include "third_party/cast_core/public/src/proto/common/application_config.pb.h"
#include "third_party/cast_core/public/src/proto/common/application_state.pb.h"
#include "third_party/cast_core/public/src/proto/web/message_channel.pb.h"

namespace content {
class WebContents;
class WebUIControllerFactory;
} // namespace content

Expand All @@ -30,8 +31,9 @@ class MessagePortService;

// This class is for sharing code between Web and streaming RuntimeApplication
// implementations, including Load and Launch behavior.
class RuntimeApplicationBase : public cast_receiver::RuntimeApplication,
public CastContentWindow::Observer {
class RuntimeApplicationBase
: public cast_receiver::RuntimeApplication,
public cast_receiver::ContentWindowControls::VisibilityChangeObserver {
public:
// This class defines a wrapper around any platform-specific communication
// details required for functionality of a RuntimeApplicationBase instance.
Expand Down Expand Up @@ -67,10 +69,9 @@ class RuntimeApplicationBase : public cast_receiver::RuntimeApplication,
// Returns the WebContents this application should use.
virtual content::WebContents* GetWebContents() = 0;

// Returns the CastContentWindow associated with this application.
//
// TODO(crbug.com/1359559): Remove this function.
virtual CastContentWindow* GetCastContentWindow() = 0;
// Returns the window controls for this instance.
virtual cast_receiver::ContentWindowControls*
GetContentWindowControls() = 0;
};

~RuntimeApplicationBase() override;
Expand Down Expand Up @@ -171,8 +172,11 @@ class RuntimeApplicationBase : public cast_receiver::RuntimeApplication,
void OnPageLoaded();

private:
// CastContentWindow::Observer implementation:
void OnVisibilityChange(VisibilityType visibility_type) override;
void SetWebVisibilityAndPaint(bool is_visible);

// ContentWindowControls::VisibilityChangeObserver implementation:
void OnWindowShown() override;
void OnWindowHidden() override;

const std::string cast_session_id_;
const cast::common::ApplicationConfig app_config_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,73 @@
#include "chromecast/cast_core/runtime/browser/url_rewrite/url_request_rewrite_type_converters.h"

namespace chromecast {
namespace {

class CastContentWindowControls : public cast_receiver::ContentWindowControls,
public CastContentWindow::Observer {
public:
CastContentWindowControls(CastContentWindow& content_window)
: content_window_(content_window) {
content_window_->AddObserver(this);
}

~CastContentWindowControls() override {
content_window_->RemoveObserver(this);
}

// cast_receiver::ContentWindowControls implementation.
void ShowWindow() override {
if (!was_window_created_) {
content_window_->GrantScreenAccess();
content_window_->CreateWindow(mojom::ZOrder::APP,
VisibilityPriority::STICKY_ACTIVITY);
was_window_created_ = true;
return;
}

content_window_->RequestVisibility(VisibilityPriority::STICKY_ACTIVITY);
content_window_->GrantScreenAccess();
}

void HideWindow() override {
if (!was_window_created_) {
content_window_->CreateWindow(mojom::ZOrder::APP,
VisibilityPriority::HIDDEN);
was_window_created_ = true;
return;
}

content_window_->RequestVisibility(VisibilityPriority::HIDDEN);
content_window_->RevokeScreenAccess();
}

void EnableTouchInput() override { content_window_->EnableTouchInput(true); }

void DisableTouchInput() override {
content_window_->EnableTouchInput(false);
}

private:
// CastContentWindow::Observer implementation.
void OnVisibilityChange(VisibilityType visibility_type) override {
switch (visibility_type) {
case VisibilityType::FULL_SCREEN:
case VisibilityType::PARTIAL_OUT:
case VisibilityType::TRANSIENTLY_HIDDEN:
OnWindowShown();
break;
default:
OnWindowHidden();
break;
}
}

bool was_window_created_ = false;

base::raw_ref<CastContentWindow> content_window_;
};

} // namespace

RuntimeApplicationServiceImpl::RuntimeApplicationServiceImpl(
std::unique_ptr<RuntimeApplicationBase> runtime_application,
Expand Down Expand Up @@ -323,12 +390,18 @@ content::WebContents* RuntimeApplicationServiceImpl::GetWebContents() {
return cast_web_view_->web_contents();
}

CastContentWindow* RuntimeApplicationServiceImpl::GetCastContentWindow() {
if (!cast_web_view_) {
cast_receiver::ContentWindowControls*
RuntimeApplicationServiceImpl::GetContentWindowControls() {
if (!cast_web_view_ || !cast_web_view_->window()) {
return nullptr;
}

return cast_web_view_->window();
if (!content_window_controls_) {
content_window_controls_ =
std::make_unique<CastContentWindowControls>(*cast_web_view_->window());
}

return content_window_controls_.get();
}

void RuntimeApplicationServiceImpl::OnAllBindingsReceived(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class RuntimeApplicationServiceImpl : public RuntimeApplicationBase::Delegate {
std::unique_ptr<content::WebUIControllerFactory> CreateWebUIControllerFactory(
std::vector<std::string> hosts) override;
content::WebContents* GetWebContents() override;
CastContentWindow* GetCastContentWindow() override;
cast_receiver::ContentWindowControls* GetContentWindowControls() override;

private:
// Creates the root CastWebView for this Cast session.
Expand Down Expand Up @@ -105,6 +105,11 @@ class RuntimeApplicationServiceImpl : public RuntimeApplicationBase::Delegate {
// displayed.
CastWebView::Scoped cast_web_view_;

// Controls for window, as a wrapper around a CastContentWindow instance.
// NOTE: Must be declared after |cast_web_view_|.
std::unique_ptr<cast_receiver::ContentWindowControls>
content_window_controls_;

absl::optional<cast::utils::GrpcServer> grpc_server_;
absl::optional<cast::v2::CoreApplicationServiceStub> core_app_stub_;
absl::optional<cast::v2::CoreMessagePortApplicationServiceStub>
Expand Down
2 changes: 2 additions & 0 deletions components/cast_receiver/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ source_set("browser") {
public = [
"public/application_client.h",
"public/application_state_observer.h",
"public/content_window_controls.h",
"public/runtime_application.h",
"public/streaming_resolution_observer.h",
]
sources = [
"application_client.cc",
"content_window_controls.cc",
"runtime_application.cc",
]
friend = [ ":unit_tests" ]
Expand Down
38 changes: 38 additions & 0 deletions components/cast_receiver/browser/content_window_controls.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/cast_receiver/browser/public/content_window_controls.h"

namespace cast_receiver {

ContentWindowControls::VisibilityChangeObserver::~VisibilityChangeObserver() =
default;

ContentWindowControls::ContentWindowControls() = default;

ContentWindowControls::~ContentWindowControls() = default;

void ContentWindowControls::AddVisibilityChangeObserver(
VisibilityChangeObserver& observer) {
visibility_state_observer_list_.AddObserver(&observer);
}

void ContentWindowControls::RemoveVisibilityChangeObserver(
VisibilityChangeObserver& observer) {
visibility_state_observer_list_.RemoveObserver(&observer);
}

void ContentWindowControls::OnWindowShown() {
for (auto& observer : visibility_state_observer_list_) {
observer.OnWindowShown();
}
}

void ContentWindowControls::OnWindowHidden() {
for (auto& observer : visibility_state_observer_list_) {
observer.OnWindowHidden();
}
}

} // namespace cast_receiver

0 comments on commit 6802fd2

Please sign in to comment.