Commit 71596b87 authored by wutao's avatar wutao Committed by Commit Bot

ambient: Impl media string animation

This patch adds a transform animation to scroll the long text in the media info.
Text will stop a few seconds before scrolling.

Bug: b/167236615
Test: added new tests
Change-Id: I4c79b5e4a150dbe6d02b5d602af8b2d202e0f065
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2411545
Commit-Queue: Tao Wu <wutao@chromium.org>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#810855}
parent 88c98070
...@@ -49,6 +49,9 @@ constexpr base::TimeDelta kTokenUsageTimeBuffer = ...@@ -49,6 +49,9 @@ constexpr base::TimeDelta kTokenUsageTimeBuffer =
// Spacing between two portrait images. // Spacing between two portrait images.
constexpr int kMarginLeftOfRelatedImageDip = 8; constexpr int kMarginLeftOfRelatedImageDip = 8;
// Media string related.
constexpr int kMediaStringMaxWidthDip = 280;
} // namespace ash } // namespace ash
#endif // ASH_AMBIENT_AMBIENT_CONSTANTS_H_ #endif // ASH_AMBIENT_AMBIENT_CONSTANTS_H_
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "chromeos/dbus/power_manager/idle.pb.h" #include "chromeos/dbus/power_manager/idle.pb.h"
#include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_unittest_util.h" #include "ui/gfx/image/image_unittest_util.h"
#include "ui/views/controls/label.h"
namespace ash { namespace ash {
...@@ -197,6 +198,14 @@ void AmbientAshTestBase::SetScreenBrightnessAndWait(double percent) { ...@@ -197,6 +198,14 @@ void AmbientAshTestBase::SetScreenBrightnessAndWait(double percent) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
} }
views::View* AmbientAshTestBase::GetMediaStringViewTextContainer() {
return GetMediaStringView()->media_text_container_for_testing();
}
views::Label* AmbientAshTestBase::GetMediaStringViewTextLabel() {
return GetMediaStringView()->media_text_label_for_testing();
}
void AmbientAshTestBase::SimulateMediaMetadataChanged( void AmbientAshTestBase::SimulateMediaMetadataChanged(
media_session::MediaMetadata metadata) { media_session::MediaMetadata metadata) {
GetMediaStringView()->MediaSessionMetadataChanged(metadata); GetMediaStringView()->MediaSessionMetadataChanged(metadata);
......
...@@ -19,6 +19,10 @@ ...@@ -19,6 +19,10 @@
#include "services/media_session/public/mojom/media_session.mojom.h" #include "services/media_session/public/mojom/media_session.mojom.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
namespace views {
class Label;
} // namespace views
namespace ash { namespace ash {
class AmbientAccessTokenController; class AmbientAccessTokenController;
...@@ -62,6 +66,10 @@ class AmbientAshTestBase : public AshTestBase { ...@@ -62,6 +66,10 @@ class AmbientAshTestBase : public AshTestBase {
void SimulateSystemSuspendAndWait( void SimulateSystemSuspendAndWait(
power_manager::SuspendImminent::Reason reason); power_manager::SuspendImminent::Reason reason);
views::View* GetMediaStringViewTextContainer();
views::Label* GetMediaStringViewTextLabel();
// Simulates the system starting to resume. // Simulates the system starting to resume.
// Wait until the event has been processed. // Wait until the event has been processed.
void SimulateSystemResumeAndWait(); void SimulateSystemResumeAndWait();
......
...@@ -37,9 +37,8 @@ namespace { ...@@ -37,9 +37,8 @@ namespace {
using chromeos::assistant::features::IsAmbientAssistantEnabled; using chromeos::assistant::features::IsAmbientAssistantEnabled;
// Appearance. // Appearance.
constexpr int kHorizontalMarginDip = 16;
constexpr int kAssistantPreferredHeightDip = 128; constexpr int kAssistantPreferredHeightDip = 128;
constexpr int kMediaStringTopMarginDip = 25; constexpr int kMediaStringMarginDip = 32;
// A tolerance threshold used to ignore spurious mouse move. // A tolerance threshold used to ignore spurious mouse move.
constexpr int kMouseMoveErrorTolerancePx = 3; constexpr int kMouseMoveErrorTolerancePx = 3;
...@@ -185,12 +184,9 @@ void AmbientContainerView::LayoutMediaStringView() { ...@@ -185,12 +184,9 @@ void AmbientContainerView::LayoutMediaStringView() {
// The media string view is positioned on the right-top corner of the // The media string view is positioned on the right-top corner of the
// container. // container.
// TODO(meilinw): without a maximum width limit, media string can grow too
// long or even overflow the screen. Revisit here to polish the UI once the
// spec is available. See b/163398805.
int x = int x =
container_size.width() - kHorizontalMarginDip - preferred_size.width(); container_size.width() - kMediaStringMarginDip - preferred_size.width();
int y = kMediaStringTopMarginDip; int y = kMediaStringMarginDip;
media_string_view_->SetBoundsRect( media_string_view_->SetBoundsRect(
gfx::Rect(x, y, preferred_size.width(), preferred_size.height())); gfx::Rect(x, y, preferred_size.width(), preferred_size.height()));
} }
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#include "ash/ambient/ui/media_string_view.h" #include "ash/ambient/ui/media_string_view.h"
#include <memory> #include <memory>
#include <string>
#include "ash/ambient/ambient_constants.h"
#include "ash/ambient/util/ambient_util.h" #include "ash/ambient/util/ambient_util.h"
#include "ash/assistant/ui/assistant_view_ids.h" #include "ash/assistant/ui/assistant_view_ids.h"
#include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/ash_pref_names.h"
...@@ -15,23 +15,29 @@ ...@@ -15,23 +15,29 @@
#include "ash/shell_delegate.h" #include "ash/shell_delegate.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "services/media_session/public/mojom/media_session.mojom.h" #include "services/media_session/public/mojom/media_session.mojom.h"
#include "services/media_session/public/mojom/media_session_service.mojom.h" #include "services/media_session/public/mojom/media_session_service.mojom.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/shadow_value.h"
#include "ui/gfx/text_constants.h"
#include "ui/gfx/transform.h"
#include "ui/views/border.h"
#include "ui/views/controls/label.h" #include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/layout/flex_layout_types.h"
namespace ash { namespace ash {
namespace { namespace {
// Typography. // Typography.
constexpr SkColor kTextColor = SK_ColorWHITE;
constexpr char kMiddleDotSeparator[] = " \u00B7 "; constexpr char kMiddleDotSeparator[] = " \u00B7 ";
constexpr char kPreceedingEighthNoteSymbol[] = "\u266A "; constexpr char kPreceedingEighthNoteSymbol[] = "\u266A ";
constexpr int kDefaultFontSizeDip = 64;
constexpr int kMediaStringFontSizeDip = 16;
// Returns true if we should show media string for ambient mode on lock-screen // Returns true if we should show media string for ambient mode on lock-screen
// based on user pref. We should keep the same user policy here as the // based on user pref. We should keep the same user policy here as the
...@@ -58,6 +64,10 @@ const char* MediaStringView::GetClassName() const { ...@@ -58,6 +64,10 @@ const char* MediaStringView::GetClassName() const {
return "MediaStringView"; return "MediaStringView";
} }
void MediaStringView::VisibilityChanged(View* starting_from, bool is_visible) {
media_text_->layer()->GetAnimator()->StopAnimating();
}
void MediaStringView::MediaSessionInfoChanged( void MediaStringView::MediaSessionInfoChanged(
media_session::mojom::MediaSessionInfoPtr session_info) { media_session::mojom::MediaSessionInfoPtr session_info) {
if (ambient::util::IsShowing(LockScreen::ScreenType::kLock) && if (ambient::util::IsShowing(LockScreen::ScreenType::kLock) &&
...@@ -85,18 +95,38 @@ void MediaStringView::MediaSessionMetadataChanged( ...@@ -85,18 +95,38 @@ void MediaStringView::MediaSessionMetadataChanged(
metadata.value_or(media_session::MediaMetadata()); metadata.value_or(media_session::MediaMetadata());
base::string16 media_string; base::string16 media_string;
base::string16 middle_dot = base::UTF8ToUTF16(kMiddleDotSeparator);
if (!session_metadata.title.empty() && !session_metadata.artist.empty()) { if (!session_metadata.title.empty() && !session_metadata.artist.empty()) {
media_string = session_metadata.title + media_string =
base::UTF8ToUTF16(kMiddleDotSeparator) + session_metadata.title + middle_dot + session_metadata.artist;
session_metadata.artist;
} else if (!session_metadata.title.empty()) { } else if (!session_metadata.title.empty()) {
media_string = session_metadata.title; media_string = session_metadata.title;
} else { } else {
media_string = session_metadata.artist; media_string = session_metadata.artist;
} }
// Formats the media string with a preceding music eighth note. // Reset text and stop any ongoing animation.
SetText(base::UTF8ToUTF16(kPreceedingEighthNoteSymbol) + media_string); media_text_->SetText(base::string16());
media_text_->layer()->GetAnimator()->StopAnimating();
media_text_->SetText(media_string);
media_text_->layer()->SetTransform(gfx::Transform());
const auto& text_size = media_text_->GetPreferredSize();
const int text_width = text_size.width();
media_text_container_->SetPreferredSize(gfx::Size(
std::min(kMediaStringMaxWidthDip, text_width), text_size.height()));
if (NeedToAnimate()) {
media_text_->SetText(media_string + middle_dot + media_string + middle_dot);
ScheduleScrolling(/*is_initial=*/true);
}
}
void MediaStringView::OnImplicitAnimationsCompleted() {
if (!NeedToAnimate())
return;
ScheduleScrolling(/*is_initial=*/false);
} }
void MediaStringView::InitLayout() { void MediaStringView::InitLayout() {
...@@ -105,12 +135,44 @@ void MediaStringView::InitLayout() { ...@@ -105,12 +135,44 @@ void MediaStringView::InitLayout() {
SetPaintToLayer(); SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false); layer()->SetFillsBoundsOpaquely(false);
auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal));
layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart);
layout->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kCenter);
icon_ = AddChildView(std::make_unique<views::Label>(
base::UTF8ToUTF16(kPreceedingEighthNoteSymbol)));
media_text_container_ = AddChildView(std::make_unique<views::View>());
media_text_container_->SetPaintToLayer();
media_text_container_->layer()->SetFillsBoundsOpaquely(false);
media_text_container_->layer()->SetMasksToBounds(true);
auto* text_layout = media_text_container_->SetLayoutManager(
std::make_unique<views::FlexLayout>());
text_layout->SetOrientation(views::LayoutOrientation::kHorizontal);
text_layout->SetMainAxisAlignment(views::LayoutAlignment::kStart);
text_layout->SetCrossAxisAlignment(views::LayoutAlignment::kCenter);
media_text_ =
media_text_container_->AddChildView(std::make_unique<views::Label>());
media_text_->SetPaintToLayer();
media_text_->layer()->SetFillsBoundsOpaquely(false);
// Defines the appearance. // Defines the appearance.
SetAutoColorReadabilityEnabled(false); constexpr SkColor kTextColor = SK_ColorWHITE;
SetEnabledColor(kTextColor); constexpr int kDefaultFontSizeDip = 64;
SetFontList(ambient::util::GetDefaultFontlist().DeriveWithSizeDelta( constexpr int kMediaStringFontSizeDip = 18;
for (auto* view : {icon_, media_text_}) {
view->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_TO_HEAD);
view->SetVerticalAlignment(gfx::VerticalAlignment::ALIGN_BOTTOM);
view->SetAutoColorReadabilityEnabled(false);
view->SetEnabledColor(kTextColor);
view->SetFontList(ambient::util::GetDefaultFontlist().DeriveWithSizeDelta(
kMediaStringFontSizeDip - kDefaultFontSizeDip)); kMediaStringFontSizeDip - kDefaultFontSizeDip));
SetShadows(ambient::util::GetTextShadowValues()); view->SetShadows(ambient::util::GetTextShadowValues());
view->SetElideBehavior(gfx::ElideBehavior::NO_ELIDE);
}
BindMediaControllerObserver(); BindMediaControllerObserver();
} }
...@@ -136,4 +198,56 @@ void MediaStringView::BindMediaControllerObserver() { ...@@ -136,4 +198,56 @@ void MediaStringView::BindMediaControllerObserver() {
observer_receiver_.BindNewPipeAndPassRemote()); observer_receiver_.BindNewPipeAndPassRemote());
} }
bool MediaStringView::NeedToAnimate() const {
return media_text_->GetPreferredSize().width() >
media_text_container_->GetPreferredSize().width();
}
gfx::Transform MediaStringView::GetMediaTextTransform(bool is_initial) {
gfx::Transform transform;
if (is_initial) {
// Start animation half way of |media_text_container_|.
transform.Translate(kMediaStringMaxWidthDip / 2, 0);
}
return transform;
}
void MediaStringView::ScheduleScrolling(bool is_initial) {
if (!GetVisible())
return;
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&MediaStringView::StartScrolling,
weak_factory_.GetWeakPtr(), is_initial));
}
void MediaStringView::StartScrolling(bool is_initial) {
ui::Layer* text_layer = media_text_->layer();
text_layer->SetTransform(GetMediaTextTransform(is_initial));
{
// Desired speed is 10 seconds for kMediaStringMaxWidthDip.
const int text_width = media_text_->GetPreferredSize().width();
const int shadow_width =
gfx::ShadowValue::GetMargin(ambient::util::GetTextShadowValues())
.width();
const int start_x = text_layer->GetTargetTransform().To2dTranslation().x();
const int end_x = -(text_width + shadow_width) / 2;
const int transform_distance = start_x - end_x;
const base::TimeDelta kScrollingDuration =
base::TimeDelta::FromSeconds(10) * transform_distance /
kMediaStringMaxWidthDip;
ui::ScopedLayerAnimationSettings animation(text_layer->GetAnimator());
animation.SetTransitionDuration(kScrollingDuration);
animation.SetTweenType(gfx::Tween::LINEAR);
animation.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
animation.AddObserver(this);
gfx::Transform transform;
transform.Translate(end_x, 0);
text_layer->SetTransform(transform);
}
}
} // namespace ash } // namespace ash
...@@ -5,22 +5,24 @@ ...@@ -5,22 +5,24 @@
#ifndef ASH_AMBIENT_UI_MEDIA_STRING_VIEW_H_ #ifndef ASH_AMBIENT_UI_MEDIA_STRING_VIEW_H_
#define ASH_AMBIENT_UI_MEDIA_STRING_VIEW_H_ #define ASH_AMBIENT_UI_MEDIA_STRING_VIEW_H_
#include <string>
#include "ash/app_menu/notification_item_view.h"
#include "ash/public/cpp/ambient/ambient_ui_model.h"
#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/remote.h"
#include "services/media_session/public/mojom/media_controller.mojom.h" #include "services/media_session/public/mojom/media_controller.mojom.h"
#include "ui/views/controls/image_view.h" #include "ui/compositor/layer_animation_observer.h"
#include "ui/views/controls/label.h" #include "ui/views/view.h"
namespace views {
class Label;
} // namespace views
namespace ash { namespace ash {
// Container for displaying ongoing media information, including the name of the // Container for displaying ongoing media information, including the name of the
// media and the artist, formatted with a proceding music note symbol and a // media and the artist, formatted with a proceding music note symbol and a
// middle dot separator. // middle dot separator.
class MediaStringView : public views::Label, class MediaStringView : public views::View,
public media_session::mojom::MediaControllerObserver { public media_session::mojom::MediaControllerObserver,
public ui::ImplicitAnimationObserver {
public: public:
MediaStringView(); MediaStringView();
MediaStringView(const MediaStringView&) = delete; MediaStringView(const MediaStringView&) = delete;
...@@ -29,6 +31,7 @@ class MediaStringView : public views::Label, ...@@ -29,6 +31,7 @@ class MediaStringView : public views::Label,
// views::Label: // views::Label:
const char* GetClassName() const override; const char* GetClassName() const override;
void VisibilityChanged(View* starting_from, bool is_visible) override;
// media_session::mojom::MediaControllerObserver: // media_session::mojom::MediaControllerObserver:
void MediaSessionInfoChanged( void MediaSessionInfoChanged(
...@@ -43,15 +46,44 @@ class MediaStringView : public views::Label, ...@@ -43,15 +46,44 @@ class MediaStringView : public views::Label,
void MediaSessionPositionChanged( void MediaSessionPositionChanged(
const base::Optional<media_session::MediaPosition>& position) override {} const base::Optional<media_session::MediaPosition>& position) override {}
// ui::ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override;
private: private:
friend class AmbientAshTestBase;
void InitLayout(); void InitLayout();
void BindMediaControllerObserver(); void BindMediaControllerObserver();
bool NeedToAnimate() const;
// Get the transform of |media_text_| for scrolling animation.
gfx::Transform GetMediaTextTransform(bool is_initial);
void ScheduleScrolling(bool is_initial);
void StartScrolling(bool is_initial);
views::View* media_text_container_for_testing() {
return media_text_container_;
}
views::Label* media_text_label_for_testing() { return media_text_; }
// Music eighth note.
views::Label* icon_ = nullptr;
// Container of media info text.
views::View* media_text_container_ = nullptr;
// With an extra copy of media info text for scrolling animation.
views::Label* media_text_ = nullptr;
// Used to receive updates to the active media controller. // Used to receive updates to the active media controller.
mojo::Remote<media_session::mojom::MediaController> media_controller_remote_; mojo::Remote<media_session::mojom::MediaController> media_controller_remote_;
mojo::Receiver<media_session::mojom::MediaControllerObserver> mojo::Receiver<media_session::mojom::MediaControllerObserver>
observer_receiver_{this}; observer_receiver_{this};
base::WeakPtrFactory<MediaStringView> weak_factory_{this};
}; };
} // namespace ash } // namespace ash
......
...@@ -4,12 +4,15 @@ ...@@ -4,12 +4,15 @@
#include "ash/ambient/ui/media_string_view.h" #include "ash/ambient/ui/media_string_view.h"
#include "ash/ambient/ambient_constants.h"
#include "ash/ambient/test/ambient_ash_test_base.h" #include "ash/ambient/test/ambient_ash_test_base.h"
#include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/ash_pref_names.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "services/media_session/public/mojom/media_session.mojom.h" #include "services/media_session/public/mojom/media_session.mojom.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/views/controls/label.h"
namespace ash { namespace ash {
...@@ -23,6 +26,10 @@ class MediaStringViewTest : public AmbientAshTestBase { ...@@ -23,6 +26,10 @@ class MediaStringViewTest : public AmbientAshTestBase {
AmbientAshTestBase::SetUp(); AmbientAshTestBase::SetUp();
GetSessionControllerClient()->set_show_lock_screen_views(true); GetSessionControllerClient()->set_show_lock_screen_views(true);
} }
const base::string16& GetText() {
return GetMediaStringViewTextLabel()->GetText();
}
}; };
TEST_F(MediaStringViewTest, ShowMediaTitleAndArtist) { TEST_F(MediaStringViewTest, ShowMediaTitleAndArtist) {
...@@ -35,9 +42,213 @@ TEST_F(MediaStringViewTest, ShowMediaTitleAndArtist) { ...@@ -35,9 +42,213 @@ TEST_F(MediaStringViewTest, ShowMediaTitleAndArtist) {
SimulateMediaMetadataChanged(metadata); SimulateMediaMetadataChanged(metadata);
const base::string16 expected_text = const base::string16 expected_text = base::UTF8ToUTF16("title \u00B7 artist");
base::UTF8ToUTF16("\u266A title \u00B7 artist"); EXPECT_EQ(GetMediaStringViewTextLabel()->GetText(), expected_text);
EXPECT_EQ(GetMediaStringView()->GetText(), expected_text); }
TEST_F(MediaStringViewTest, TextContainerFitsWidthOfShortText) {
ShowAmbientScreen();
// Sets metadata for current session.
media_session::MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("title");
metadata.artist = base::ASCIIToUTF16("artist");
SimulateMediaMetadataChanged(metadata);
EXPECT_LT(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
kMediaStringMaxWidthDip);
EXPECT_EQ(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
GetMediaStringViewTextContainer()->GetPreferredSize().width());
}
TEST_F(MediaStringViewTest, TextContainerHasMaxWidthWithLongText) {
ShowAmbientScreen();
// Sets metadata for current session.
media_session::MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("A super duper long title");
metadata.artist = base::ASCIIToUTF16("A super duper long artist name");
SimulateMediaMetadataChanged(metadata);
EXPECT_GT(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
kMediaStringMaxWidthDip);
EXPECT_EQ(kMediaStringMaxWidthDip,
GetMediaStringViewTextContainer()->GetPreferredSize().width());
}
TEST_F(MediaStringViewTest, HasNoAnimationWithShortText) {
ui::ScopedAnimationDurationScaleMode test_duration_mode(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
ShowAmbientScreen();
// Sets metadata for current session.
media_session::MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("title");
metadata.artist = base::ASCIIToUTF16("name");
SimulateMediaPlaybackStateChanged(
media_session::mojom::MediaPlaybackState::kPlaying);
SimulateMediaMetadataChanged(metadata);
EXPECT_LT(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
kMediaStringMaxWidthDip);
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(100));
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
}
TEST_F(MediaStringViewTest, HasAnimationWithLongText) {
ui::ScopedAnimationDurationScaleMode test_duration_mode(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
ShowAmbientScreen();
// Sets metadata for current session.
media_session::MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("A super duper long title");
metadata.artist = base::ASCIIToUTF16("A super duper long artist name");
SimulateMediaPlaybackStateChanged(
media_session::mojom::MediaPlaybackState::kPlaying);
SimulateMediaMetadataChanged(metadata);
EXPECT_GT(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
kMediaStringMaxWidthDip);
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(100));
EXPECT_TRUE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
}
TEST_F(MediaStringViewTest, ShouldStopAndStartAnimationWhenTextChanges) {
ui::ScopedAnimationDurationScaleMode test_duration_mode(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
ShowAmbientScreen();
// Sets metadata for current session.
media_session::MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("A super duper long title");
metadata.artist = base::ASCIIToUTF16("A super duper long artist name");
SimulateMediaPlaybackStateChanged(
media_session::mojom::MediaPlaybackState::kPlaying);
SimulateMediaMetadataChanged(metadata);
EXPECT_GT(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
kMediaStringMaxWidthDip);
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(100));
EXPECT_TRUE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
// Change to another long text.
metadata.title = base::ASCIIToUTF16("Another super duper long title");
metadata.artist = base::ASCIIToUTF16("Another super duper long artist name");
SimulateMediaMetadataChanged(metadata);
EXPECT_GT(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
kMediaStringMaxWidthDip);
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(100));
EXPECT_TRUE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
}
TEST_F(MediaStringViewTest, ShouldStartAndStopAnimationWhenTextChanges) {
ui::ScopedAnimationDurationScaleMode test_duration_mode(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
ShowAmbientScreen();
// Sets metadata for current session.
media_session::MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("title");
metadata.artist = base::ASCIIToUTF16("name");
SimulateMediaPlaybackStateChanged(
media_session::mojom::MediaPlaybackState::kPlaying);
SimulateMediaMetadataChanged(metadata);
EXPECT_LT(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
kMediaStringMaxWidthDip);
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(100));
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
// Change to long text.
metadata.title = base::ASCIIToUTF16("A super duper long title");
metadata.artist = base::ASCIIToUTF16("A super duper long artist name");
SimulateMediaMetadataChanged(metadata);
EXPECT_GT(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
kMediaStringMaxWidthDip);
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(100));
EXPECT_TRUE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
// Change to short text.
metadata.title = base::ASCIIToUTF16("title");
metadata.artist = base::ASCIIToUTF16("name");
SimulateMediaMetadataChanged(metadata);
EXPECT_LT(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
kMediaStringMaxWidthDip);
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(100));
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
}
TEST_F(MediaStringViewTest, PauseMediaWillStopAnimationWithLongText) {
ui::ScopedAnimationDurationScaleMode test_duration_mode(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
ShowAmbientScreen();
// Sets metadata for current session.
media_session::MediaMetadata metadata;
metadata.title = base::ASCIIToUTF16("A super duper long title");
metadata.artist = base::ASCIIToUTF16("A super duper long artist name");
SimulateMediaPlaybackStateChanged(
media_session::mojom::MediaPlaybackState::kPlaying);
SimulateMediaMetadataChanged(metadata);
EXPECT_GT(GetMediaStringViewTextLabel()->GetPreferredSize().width(),
kMediaStringMaxWidthDip);
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(100));
EXPECT_TRUE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
SimulateMediaPlaybackStateChanged(
media_session::mojom::MediaPlaybackState::kPaused);
EXPECT_FALSE(GetMediaStringView()->GetVisible());
EXPECT_FALSE(
GetMediaStringViewTextLabel()->layer()->GetAnimator()->is_animating());
} }
TEST_F(MediaStringViewTest, ShowWhenMediaIsPlaying) { TEST_F(MediaStringViewTest, ShowWhenMediaIsPlaying) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment