blob: 28cb2dbb720fdb4610afda4b6b1df9011da3f6c5 [file] [log] [blame]
// 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 "content/browser/renderer_host/input/fling_scheduler_android.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "ui/compositor/compositor.h"
namespace content {
FlingSchedulerAndroid::FlingSchedulerAndroid(RenderWidgetHostImpl* host)
: host_(host) {
DCHECK(host);
}
FlingSchedulerAndroid::~FlingSchedulerAndroid() {
if (observed_window_)
observed_window_->RemoveObserver(this);
}
void FlingSchedulerAndroid::ScheduleFlingProgress(
base::WeakPtr<FlingController> fling_controller) {
DCHECK(fling_controller);
fling_controller_ = fling_controller;
if (!observed_window_) {
ui::WindowAndroid* window = GetRootWindow();
// If the root window does not have a Compositor (happens on Android
// WebView), we'll never receive an OnAnimate call. In this case fall back
// to BeginFrames coming from the host.
if (!window || !window->GetCompositor()) {
host_->SetNeedsBeginFrameForFlingProgress();
return;
}
window->AddObserver(this);
observed_window_ = window;
}
observed_window_->SetNeedsAnimate();
}
void FlingSchedulerAndroid::DidStopFlingingOnBrowser(
base::WeakPtr<FlingController> fling_controller) {
DCHECK(fling_controller);
if (observed_window_) {
observed_window_->RemoveObserver(this);
observed_window_ = nullptr;
}
fling_controller_ = nullptr;
host_->DidStopFlinging();
}
bool FlingSchedulerAndroid::NeedsBeginFrameForFlingProgress() {
ui::WindowAndroid* window = GetRootWindow();
// If the root window does not have a Compositor (happens on Android
// WebView), we'll never receive an OnAnimate call. In this case fall back
// to BeginFrames coming from the host.
return !window || !window->GetCompositor();
}
void FlingSchedulerAndroid::ProgressFlingOnBeginFrameIfneeded(
base::TimeTicks current_time) {
// If a WindowAndroid is being observed, there is no need for BeginFrames
// coming from the host.
if (observed_window_)
return;
if (!fling_controller_)
return;
fling_controller_->ProgressFling(current_time);
}
ui::WindowAndroid* FlingSchedulerAndroid::GetRootWindow() {
if (!host_->GetView())
return nullptr;
return host_->GetView()->GetNativeView()->GetWindowAndroid();
}
void FlingSchedulerAndroid::OnDetachCompositor() {
// Once the window's compositor has detached, we will no longer receive
// OnAnimate calls. Stop observing the window.
observed_window_->RemoveObserver(this);
observed_window_ = nullptr;
}
void FlingSchedulerAndroid::OnAnimate(base::TimeTicks frame_begin_time) {
DCHECK(observed_window_);
if (fling_controller_)
fling_controller_->ProgressFling(frame_begin_time);
}
} // namespace content