blob: 1df98384bcd335532fe28e6ffaa3ae5975b35b7b [file] [log] [blame]
// Copyright 2019 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 "chromecast/browser/webview/webview_window_manager.h"
#include "chromecast/graphics/cast_window_manager.h"
#include "components/exo/shell_surface_util.h"
#include "components/exo/surface.h"
#include "ui/aura/env.h"
namespace chromecast {
// Keeps track of the creation and destruction of webview container windows, and
// adds and removes the root window rounded corner decoration accordingly.
// Rounded corners only need to be present when webviews are being displayed.
class RoundedCornersObserver : public WebviewWindowManager::Observer,
public aura::WindowObserver {
public:
explicit RoundedCornersObserver(CastWindowManager* cast_window_manager)
: cast_window_manager_(cast_window_manager) {}
~RoundedCornersObserver() override {}
// WebviewWindowManager::Observer implementation
void OnNewWebviewContainerWindow(aura::Window* window, int app_id) override {
// Observe the lifecycle of this window so we can remove rounded corners
// when it goes away.
window->AddObserver(this);
// Add rounded corners on the first created window.
if (cast_window_manager_ && !num_container_windows_) {
cast_window_manager_->SetEnableRoundedCorners(true);
}
num_container_windows_++;
}
// aura::WindowObserver implementation
void OnWindowDestroyed(aura::Window* window) override {
// Remove the rounded corners when we're out of container windows.
num_container_windows_--;
DCHECK_GE(num_container_windows_, 0);
if (cast_window_manager_ && !num_container_windows_) {
cast_window_manager_->SetEnableRoundedCorners(false);
}
}
private:
CastWindowManager* cast_window_manager_;
int num_container_windows_ = 0;
DISALLOW_COPY_AND_ASSIGN(RoundedCornersObserver);
};
WebviewWindowManager::WebviewWindowManager(
CastWindowManager* cast_window_manager)
: rounded_corners_observer_(
std::make_unique<RoundedCornersObserver>(cast_window_manager)) {
aura::Env::GetInstance()->AddObserver(this);
AddObserver(rounded_corners_observer_.get());
}
WebviewWindowManager::~WebviewWindowManager() {
aura::Env::GetInstance()->RemoveObserver(this);
}
void WebviewWindowManager::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void WebviewWindowManager::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
void WebviewWindowManager::OnWindowInitialized(aura::Window* window) {
observed_windows_.push_back(window);
window->AddObserver(this);
}
void WebviewWindowManager::OnWindowDestroying(aura::Window* window) {
window->RemoveObserver(this);
auto it =
std::find(observed_windows_.begin(), observed_windows_.end(), window);
DCHECK(it != observed_windows_.end());
observed_windows_.erase(it);
}
void WebviewWindowManager::OnWindowPropertyChanged(aura::Window* window,
const void* key,
intptr_t old) {
if (key != exo::kClientSurfaceIdKey)
return;
int app_id = window->GetProperty(exo::kClientSurfaceIdKey);
LOG(INFO) << "Found window for webview " << app_id;
for (auto& observer : observers_)
observer.OnNewWebviewContainerWindow(window, app_id);
}
} // namespace chromecast