blob: 248ad7bf66b7642558a10751ec0082f7192c6b16 [file] [log] [blame]
// Copyright 2016 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 "cc/input/browser_controls_offset_manager.h"
#include <stdint.h>
#include <algorithm>
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/numerics/ranges.h"
#include "cc/input/browser_controls_offset_manager_client.h"
#include "cc/trees/layer_tree_impl.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/transform.h"
namespace cc {
namespace {
// These constants were chosen empirically for their visually pleasant behavior.
// Contact tedchoc@chromium.org for questions about changing these values.
const int64_t kShowHideMaxDurationMs = 200;
// TODO(sinansahin): Temporary value, pending UX guidance probably.
const int64_t kHeightChangeDurationMs = 200;
}
// static
std::unique_ptr<BrowserControlsOffsetManager>
BrowserControlsOffsetManager::Create(BrowserControlsOffsetManagerClient* client,
float controls_show_threshold,
float controls_hide_threshold) {
return base::WrapUnique(new BrowserControlsOffsetManager(
client, controls_show_threshold, controls_hide_threshold));
}
BrowserControlsOffsetManager::BrowserControlsOffsetManager(
BrowserControlsOffsetManagerClient* client,
float controls_show_threshold,
float controls_hide_threshold)
: client_(client),
permitted_state_(BrowserControlsState::kBoth),
accumulated_scroll_delta_(0.f),
baseline_top_content_offset_(0.f),
baseline_bottom_content_offset_(0.f),
controls_show_threshold_(controls_hide_threshold),
controls_hide_threshold_(controls_show_threshold),
pinch_gesture_active_(false),
constraint_changed_since_commit_(false),
top_min_height_change_in_progress_(false),
bottom_min_height_change_in_progress_(false),
top_controls_min_height_offset_(0.f),
bottom_controls_min_height_offset_(0.f) {
CHECK(client_);
UpdateOldBrowserControlsParams();
}
BrowserControlsOffsetManager::~BrowserControlsOffsetManager() = default;
float BrowserControlsOffsetManager::ControlsTopOffset() const {
return ContentTopOffset() - TopControlsHeight();
}
float BrowserControlsOffsetManager::ContentTopOffset() const {
return TopControlsHeight() > 0
? TopControlsShownRatio() * TopControlsHeight() : 0.0f;
}
float BrowserControlsOffsetManager::TopControlsShownRatio() const {
return client_->CurrentTopControlsShownRatio();
}
float BrowserControlsOffsetManager::TopControlsHeight() const {
return client_->TopControlsHeight();
}
float BrowserControlsOffsetManager::TopControlsMinHeight() const {
return client_->TopControlsMinHeight();
}
float BrowserControlsOffsetManager::TopControlsMinShownRatio() const {
return TopControlsHeight() ? TopControlsMinHeight() / TopControlsHeight()
: 0.f;
}
float BrowserControlsOffsetManager::BottomControlsHeight() const {
return client_->BottomControlsHeight();
}
float BrowserControlsOffsetManager::BottomControlsMinHeight() const {
return client_->BottomControlsMinHeight();
}
float BrowserControlsOffsetManager::BottomControlsMinShownRatio() const {
return BottomControlsHeight()
? BottomControlsMinHeight() / BottomControlsHeight()
: 0.f;
}
float BrowserControlsOffsetManager::ContentBottomOffset() const {
return BottomControlsHeight() > 0
? BottomControlsShownRatio() * BottomControlsHeight() : 0.0f;
}
float BrowserControlsOffsetManager::BottomControlsShownRatio() const {
return client_->CurrentBottomControlsShownRatio();
}
float BrowserControlsOffsetManager::TopControlsMinHeightOffset() const {
return top_controls_min_height_offset_;
}
float BrowserControlsOffsetManager::BottomControlsMinHeightOffset() const {
return bottom_controls_min_height_offset_;
}
std::pair<float, float>
BrowserControlsOffsetManager::TopControlsShownRatioRange() {
if (top_controls_animation_.IsInitialized())
return std::make_pair(top_controls_animation_.min_value(),
top_controls_animation_.max_value());
return std::make_pair(0.f, 1.f);
}
std::pair<float, float>
BrowserControlsOffsetManager::BottomControlsShownRatioRange() {
if (bottom_controls_animation_.IsInitialized())
return std::make_pair(bottom_controls_animation_.min_value(),
bottom_controls_animation_.max_value());
return std::make_pair(0.f, 1.f);
}
void BrowserControlsOffsetManager::UpdateBrowserControlsState(
BrowserControlsState constraints,
BrowserControlsState current,
bool animate) {
DCHECK(!(constraints == BrowserControlsState::kShown &&
current == BrowserControlsState::kHidden));
DCHECK(!(constraints == BrowserControlsState::kHidden &&
current == BrowserControlsState::kShown));
TRACE_EVENT2("cc", "BrowserControlsOffsetManager::UpdateBrowserControlsState",
"constraints", static_cast<int>(constraints), "current",
static_cast<int>(current));
// If the constraints have changed we need to inform Blink about it since
// that'll affect main thread scrolling as well as layout.
if (permitted_state_ != constraints) {
constraint_changed_since_commit_ = true;
client_->SetNeedsCommit();
}
permitted_state_ = constraints;
// Don't do anything if it doesn't matter which state the controls are in.
if (constraints == BrowserControlsState::kBoth &&
current == BrowserControlsState::kBoth)
return;
// Don't do anything if there is no change in offset.
float final_top_shown_ratio = 1.f;
float final_bottom_shown_ratio = 1.f;
AnimationDirection direction = AnimationDirection::SHOWING_CONTROLS;
if (constraints == BrowserControlsState::kHidden ||
current == BrowserControlsState::kHidden) {
final_top_shown_ratio = TopControlsMinShownRatio();
final_bottom_shown_ratio = BottomControlsMinShownRatio();
direction = AnimationDirection::HIDING_CONTROLS;
}
if (final_top_shown_ratio == TopControlsShownRatio() &&
final_bottom_shown_ratio == BottomControlsShownRatio()) {
TRACE_EVENT_INSTANT0("cc", "Ratios Unchanged", TRACE_EVENT_SCOPE_THREAD);
ResetAnimations();
return;
}
ResetAnimations();
if (animate)
SetupAnimation(direction);
else
client_->SetCurrentBrowserControlsShownRatio(final_top_shown_ratio,
final_bottom_shown_ratio);
}
BrowserControlsState BrowserControlsOffsetManager::PullConstraintForMainThread(
bool* out_changed_since_commit) {
DCHECK(out_changed_since_commit);
*out_changed_since_commit = constraint_changed_since_commit_;
constraint_changed_since_commit_ = false;
return permitted_state_;
}
void BrowserControlsOffsetManager::OnBrowserControlsParamsChanged(
bool animate_changes) {
if (old_browser_controls_params_.top_controls_height == TopControlsHeight() &&
old_browser_controls_params_.top_controls_min_height ==
TopControlsMinHeight() &&
old_browser_controls_params_.bottom_controls_height ==
BottomControlsHeight() &&
old_browser_controls_params_.bottom_controls_min_height ==
BottomControlsMinHeight()) {
return;
}
float old_top_height = old_browser_controls_params_.top_controls_height;
float new_top_ratio =
TopControlsHeight()
? TopControlsShownRatio() * old_top_height / TopControlsHeight()
: 0.f;
float old_bottom_height = old_browser_controls_params_.bottom_controls_height;
float new_bottom_ratio = BottomControlsHeight()
? BottomControlsShownRatio() *
old_bottom_height / BottomControlsHeight()
: 0.f;
if (!animate_changes) {
// If the min-heights changed when the controls were at the min-height, the
// shown ratios need to be snapped to the new min-shown-ratio to keep the
// controls at the min height. If the controls were fully shown, we want to
// keep them fully shown even after the heights changed. For any other
// cases, we should update the shown ratio so the visible height remains the
// same.
if (TopControlsShownRatio() == OldTopControlsMinShownRatio())
new_top_ratio = TopControlsMinShownRatio();
else if (TopControlsShownRatio() == 1.f)
new_top_ratio = 1.f;
if (BottomControlsShownRatio() == OldBottomControlsMinShownRatio())
new_bottom_ratio = BottomControlsMinShownRatio();
else if (BottomControlsShownRatio() == 1.f)
new_bottom_ratio = 1.f;
}
// Browser controls height change animations
// If the browser controls heights (and/or min-heights) changed and need to be
// animated, the setup is done here. All the animations done in this class
// involve changing the shown ratios smoothly.
//
// There are several cases to handle:
// 1- The controls shown ratio was at the minimum ratio
// - If the min-height changed, we will run an animation from
// old-min-height / new-total-height to new-min-height / new-total-height
// - If the min-height didn't change, we should update the shown ratio to
// min-height / new-total-height so that the controls keep the same
// visible height and don't jump. No animation needed in this case.
// 2- The controls shown ratio was at the highest ratio (should be 1 here)
// - If the total height changed, we will run an animation from
// old-total-height / new-total-height to 1.
// - If the total height didn't change, we don't need to do anything.
// 3- The controls shown ratio is between the minimum and the maximum. This
// would be the case if there is a show/hide animation running or there is
// a scroll event and the controls are half-shown. In this case, we won't
// run an animation--but update the shown ratio so the visible height
// remains the same (See updated_{top,bottom}_ratio above).
//
// When this method is called as a result of a height change,
// TopControlsHeight(), TopControlsMinHeight(), BottomControlsHeight(), and
// BottomControlsMinHeight() will already be returning the new values.
// However, the shown ratios aren't updated.
bool top_controls_need_animation = animate_changes;
bool bottom_controls_need_animation = animate_changes;
float top_target_ratio;
// If the top controls height changed when they were fully shown.
if (TopControlsShownRatio() == 1.f && TopControlsHeight() != old_top_height) {
top_target_ratio = 1.f; // i.e. new_height / new_height
// If the top controls min-height changed when they were at the minimum
// shown ratio. For example, the min height changed from 0 to a positive
// value while the top controls were completely hidden.
} else if (TopControlsShownRatio() == OldTopControlsMinShownRatio() &&
TopControlsMinHeight() !=
old_browser_controls_params_.top_controls_min_height) {
top_target_ratio = TopControlsMinShownRatio();
} else {
top_controls_need_animation = false;
}
float bottom_target_ratio;
// If the bottom controls height changed when they were fully shown.
if (BottomControlsShownRatio() == 1.f &&
BottomControlsHeight() != old_bottom_height) {
bottom_target_ratio = 1.f; // i.e. new_height / new_height
// If the bottom controls min-height changed when they were at the minimum
// shown ratio.
} else if (BottomControlsShownRatio() == OldBottomControlsMinShownRatio() &&
BottomControlsMinHeight() !=
old_browser_controls_params_.bottom_controls_min_height) {
bottom_target_ratio = BottomControlsMinShownRatio();
} else {
bottom_controls_need_animation = false;
}
if (top_controls_need_animation) {
InitAnimationForHeightChange(&top_controls_animation_, new_top_ratio,
top_target_ratio);
if (old_browser_controls_params_.top_controls_min_height !=
TopControlsMinHeight()) {
top_controls_min_height_offset_ =
old_browser_controls_params_.top_controls_min_height;
top_min_height_change_in_progress_ = true;
}
} else {
top_controls_min_height_offset_ = TopControlsMinHeight();
}
if (bottom_controls_need_animation) {
InitAnimationForHeightChange(&bottom_controls_animation_, new_bottom_ratio,
bottom_target_ratio);
if (old_browser_controls_params_.bottom_controls_min_height !=
BottomControlsMinHeight()) {
bottom_controls_min_height_offset_ =
old_browser_controls_params_.bottom_controls_min_height;
bottom_min_height_change_in_progress_ = true;
}
} else {
bottom_controls_min_height_offset_ = BottomControlsMinHeight();
}
// We won't run any animations if the controls are in an in-between state.
// Examples: a show/hide animation is running, shown ratio is some value
// between min-shown-ratio and 1 because of a scroll event.
UpdateOldBrowserControlsParams();
client_->SetCurrentBrowserControlsShownRatio(new_top_ratio, new_bottom_ratio);
}
void BrowserControlsOffsetManager::ScrollBegin() {
if (pinch_gesture_active_)
return;
ResetAnimations();
ResetBaseline();
}
gfx::Vector2dF BrowserControlsOffsetManager::ScrollBy(
const gfx::Vector2dF& pending_delta) {
// If one or both of the top/bottom controls are showing, the shown ratio
// needs to be computed.
if (!TopControlsHeight() && !BottomControlsHeight())
return pending_delta;
if (pinch_gesture_active_)
return pending_delta;
if ((permitted_state_ == BrowserControlsState::kShown &&
pending_delta.y() > 0) ||
(permitted_state_ == BrowserControlsState::kHidden &&
pending_delta.y() < 0))
return pending_delta;
accumulated_scroll_delta_ += pending_delta.y();
// We want to base our calculations on top or bottom controls. After consuming
// the scroll delta, we will calculate a shown ratio for the controls. The
// top controls have the priority because they need to visually be in sync
// with the web contents.
bool base_on_top_controls = TopControlsHeight();
float old_top_offset = ContentTopOffset();
float baseline_content_offset = base_on_top_controls
? baseline_top_content_offset_
: baseline_bottom_content_offset_;
// The top and bottom controls ratios can be calculated independently.
// However, we want the (normalized) ratios to be equal when scrolling.
// Having normalized ratios in this context means the top and bottom controls
// reach the min and max ratios at the same time when scrolling or during
// the usual show/hide animations, but they can have different shown ratios at
// any time.
float shown_ratio =
(baseline_content_offset - accumulated_scroll_delta_) /
(base_on_top_controls ? TopControlsHeight() : BottomControlsHeight());
float min_ratio = base_on_top_controls ? TopControlsMinShownRatio()
: BottomControlsMinShownRatio();
float normalized_shown_ratio =
(base::ClampToRange(shown_ratio, min_ratio, 1.f) - min_ratio) /
(1.f - min_ratio);
// Even though the real shown ratios (shown height / total height) of the top
// and bottom controls can be different, they share the same
// relative/normalized ratio to keep them in sync.
client_->SetCurrentBrowserControlsShownRatio(
TopControlsMinShownRatio() +
normalized_shown_ratio * (1.f - TopControlsMinShownRatio()),
BottomControlsMinShownRatio() +
normalized_shown_ratio * (1.f - BottomControlsMinShownRatio()));
// If the controls are fully visible, treat the current position as the
// new baseline even if the gesture didn't end.
if (TopControlsShownRatio() == 1.f && BottomControlsShownRatio() == 1.f)
ResetBaseline();
ResetAnimations();
// applied_delta will negate any scroll on the content if the top browser
// controls are showing in favor of hiding the controls and resizing the
// content. If the top controls have no height, the content should scroll
// immediately.
gfx::Vector2dF applied_delta(0.f, old_top_offset - ContentTopOffset());
return pending_delta - applied_delta;
}
void BrowserControlsOffsetManager::ScrollEnd() {
if (pinch_gesture_active_)
return;
StartAnimationIfNecessary();
}
void BrowserControlsOffsetManager::PinchBegin() {
DCHECK(!pinch_gesture_active_);
pinch_gesture_active_ = true;
StartAnimationIfNecessary();
}
void BrowserControlsOffsetManager::PinchEnd() {
DCHECK(pinch_gesture_active_);
// Pinch{Begin,End} will always occur within the scope of Scroll{Begin,End},
// so return to a state expected by the remaining scroll sequence.
pinch_gesture_active_ = false;
ScrollBegin();
}
gfx::Vector2dF BrowserControlsOffsetManager::Animate(
base::TimeTicks monotonic_time) {
if (!HasAnimation() || !client_->HaveRootScrollNode())
return gfx::Vector2dF();
float old_top_offset = ContentTopOffset();
float old_bottom_offset = ContentBottomOffset();
base::Optional<float> new_top_ratio =
top_controls_animation_.Tick(monotonic_time);
if (!new_top_ratio.has_value())
new_top_ratio = TopControlsShownRatio();
base::Optional<float> new_bottom_ratio =
bottom_controls_animation_.Tick(monotonic_time);
if (!new_bottom_ratio.has_value())
new_bottom_ratio = BottomControlsShownRatio();
client_->SetCurrentBrowserControlsShownRatio(new_top_ratio.value(),
new_bottom_ratio.value());
float top_offset_delta = ContentTopOffset() - old_top_offset;
float bottom_offset_delta = ContentBottomOffset() - old_bottom_offset;
if (top_min_height_change_in_progress_) {
top_controls_min_height_offset_ += top_offset_delta;
// Ticking the animation might reset it if it's at the final value.
top_min_height_change_in_progress_ =
top_controls_animation_.IsInitialized();
}
if (bottom_min_height_change_in_progress_) {
// Ticking the animation might reset it if it's at the final value.
bottom_controls_min_height_offset_ += bottom_offset_delta;
bottom_min_height_change_in_progress_ =
bottom_controls_animation_.IsInitialized();
}
gfx::Vector2dF scroll_delta(0.f, top_offset_delta);
return scroll_delta;
}
bool BrowserControlsOffsetManager::HasAnimation() {
return top_controls_animation_.IsInitialized() ||
bottom_controls_animation_.IsInitialized();
}
void BrowserControlsOffsetManager::ResetAnimations() {
// If the animation doesn't need to jump to the end, Animation::Reset() will
// return |base::nullopt|.
base::Optional<float> top_ratio = top_controls_animation_.Reset();
base::Optional<float> bottom_ratio = bottom_controls_animation_.Reset();
if (top_ratio.has_value() || bottom_ratio.has_value()) {
client_->SetCurrentBrowserControlsShownRatio(
top_ratio.has_value() ? top_ratio.value() : TopControlsShownRatio(),
bottom_ratio.has_value() ? bottom_ratio.value()
: BottomControlsShownRatio());
if (top_min_height_change_in_progress_) {
DCHECK(top_ratio.has_value());
top_controls_min_height_offset_ = TopControlsMinHeight();
}
if (bottom_min_height_change_in_progress_) {
DCHECK(bottom_ratio.has_value());
bottom_controls_min_height_offset_ = BottomControlsMinHeight();
}
}
top_min_height_change_in_progress_ = false;
bottom_min_height_change_in_progress_ = false;
}
void BrowserControlsOffsetManager::SetupAnimation(
AnimationDirection direction) {
DCHECK_NE(AnimationDirection::NO_ANIMATION, direction);
DCHECK(direction != AnimationDirection::HIDING_CONTROLS ||
TopControlsShownRatio() > 0.f);
DCHECK(direction != AnimationDirection::SHOWING_CONTROLS ||
TopControlsShownRatio() < 1.f);
if (top_controls_animation_.IsInitialized() &&
top_controls_animation_.Direction() == direction &&
bottom_controls_animation_.IsInitialized() &&
bottom_controls_animation_.Direction() == direction)
return;
if (!TopControlsHeight() && !BottomControlsHeight()) {
float ratio = direction == AnimationDirection::HIDING_CONTROLS ? 0.f : 1.f;
client_->SetCurrentBrowserControlsShownRatio(ratio, ratio);
return;
}
// Providing artificially larger/smaller stop ratios to make the animation
// faster if the start ratio is closer to stop ratio.
const float max_stop_ratio =
direction == AnimationDirection::SHOWING_CONTROLS ? 1 : -1;
float top_start_ratio = TopControlsShownRatio();
float top_stop_ratio = top_start_ratio + max_stop_ratio;
top_controls_animation_.Initialize(direction, top_start_ratio, top_stop_ratio,
kShowHideMaxDurationMs,
/*jump_to_end_on_reset=*/false);
top_controls_animation_.SetBounds(TopControlsMinShownRatio(), 1.f);
float bottom_start_ratio = BottomControlsShownRatio();
float bottom_stop_ratio = bottom_start_ratio + max_stop_ratio;
bottom_controls_animation_.Initialize(
direction, bottom_start_ratio, bottom_stop_ratio, kShowHideMaxDurationMs,
/*jump_to_end_on_reset=*/false);
bottom_controls_animation_.SetBounds(BottomControlsMinShownRatio(), 1.f);
client_->DidChangeBrowserControlsPosition();
}
void BrowserControlsOffsetManager::StartAnimationIfNecessary() {
if ((TopControlsShownRatio() == TopControlsMinShownRatio() ||
TopControlsShownRatio() == 1.f) &&
(BottomControlsShownRatio() == BottomControlsMinShownRatio() ||
BottomControlsShownRatio() == 1.f))
return;
float normalized_top_ratio =
(TopControlsShownRatio() - TopControlsMinShownRatio()) /
(1.f - TopControlsMinShownRatio());
if (normalized_top_ratio >= 1.f - controls_hide_threshold_) {
// If we're showing so much that the hide threshold won't trigger, show.
SetupAnimation(AnimationDirection::SHOWING_CONTROLS);
} else if (normalized_top_ratio <= controls_show_threshold_) {
// If we're showing so little that the show threshold won't trigger, hide.
SetupAnimation(AnimationDirection::HIDING_CONTROLS);
} else {
// If we could be either showing or hiding, we determine which one to
// do based on whether or not the total scroll delta was moving up or
// down.
SetupAnimation(accumulated_scroll_delta_ <= 0.f
? AnimationDirection::SHOWING_CONTROLS
: AnimationDirection::HIDING_CONTROLS);
}
}
void BrowserControlsOffsetManager::ResetBaseline() {
accumulated_scroll_delta_ = 0.f;
baseline_top_content_offset_ = ContentTopOffset();
baseline_bottom_content_offset_ = ContentBottomOffset();
}
void BrowserControlsOffsetManager::InitAnimationForHeightChange(
Animation* animation,
float start_ratio,
float stop_ratio) {
AnimationDirection direction = start_ratio < stop_ratio
? AnimationDirection::SHOWING_CONTROLS
: AnimationDirection::HIDING_CONTROLS;
animation->Initialize(direction, start_ratio, stop_ratio,
kHeightChangeDurationMs, /*jump_to_end_on_reset=*/true);
}
float BrowserControlsOffsetManager::OldTopControlsMinShownRatio() {
return old_browser_controls_params_.top_controls_height
? old_browser_controls_params_.top_controls_min_height /
old_browser_controls_params_.top_controls_height
: 0.f;
}
float BrowserControlsOffsetManager::OldBottomControlsMinShownRatio() {
return old_browser_controls_params_.bottom_controls_height
? old_browser_controls_params_.bottom_controls_min_height /
old_browser_controls_params_.bottom_controls_height
: 0.f;
}
void BrowserControlsOffsetManager::UpdateOldBrowserControlsParams() {
// No need to update the other two bool members as they aren't useful for this
// class.
old_browser_controls_params_.top_controls_height = TopControlsHeight();
old_browser_controls_params_.top_controls_min_height = TopControlsMinHeight();
old_browser_controls_params_.bottom_controls_height = BottomControlsHeight();
old_browser_controls_params_.bottom_controls_min_height =
BottomControlsMinHeight();
}
// class Animation
BrowserControlsOffsetManager::Animation::Animation() {}
void BrowserControlsOffsetManager::Animation::Initialize(
AnimationDirection direction,
float start_value,
float stop_value,
int64_t duration,
bool jump_to_end_on_reset) {
direction_ = direction;
start_value_ = start_value;
stop_value_ = stop_value;
duration_ = base::TimeDelta::FromMilliseconds(duration);
initialized_ = true;
jump_to_end_on_reset_ = jump_to_end_on_reset;
SetBounds(std::min(start_value_, stop_value_),
std::max(start_value_, stop_value_));
}
base::Optional<float> BrowserControlsOffsetManager::Animation::Tick(
base::TimeTicks monotonic_time) {
if (!IsInitialized())
return base::nullopt;
if (!started_) {
start_time_ = monotonic_time;
stop_time_ = start_time_ + duration_;
started_ = true;
}
float value = gfx::Tween::ClampedFloatValueBetween(
monotonic_time, start_time_, start_value_, stop_time_, stop_value_);
if (IsComplete(value)) {
value = base::ClampToRange(stop_value_, min_value_, max_value_);
Reset();
}
return value;
}
void BrowserControlsOffsetManager::Animation::SetBounds(float min, float max) {
min_value_ = min;
max_value_ = max;
}
base::Optional<float> BrowserControlsOffsetManager::Animation::Reset() {
auto ret = jump_to_end_on_reset_ ? base::make_optional(base::ClampToRange(
stop_value_, min_value_, max_value_))
: base::nullopt;
started_ = false;
initialized_ = false;
start_time_ = base::TimeTicks();
start_value_ = 0.f;
stop_time_ = base::TimeTicks();
stop_value_ = 0.f;
direction_ = AnimationDirection::NO_ANIMATION;
duration_ = base::TimeDelta();
min_value_ = 0.f;
max_value_ = 1.f;
jump_to_end_on_reset_ = false;
return ret;
}
bool BrowserControlsOffsetManager::Animation::IsComplete(float value) {
return (direction_ == AnimationDirection::SHOWING_CONTROLS &&
(value >= stop_value_ || value >= max_value_)) ||
(direction_ == AnimationDirection::HIDING_CONTROLS &&
(value <= stop_value_ || value <= min_value_));
}
} // namespace cc