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 =
// Spacing between two portrait images.
constexpr int kMarginLeftOfRelatedImageDip = 8;
// Media string related.
constexpr int kMediaStringMaxWidthDip = 280;
} // namespace ash
#endif // ASH_AMBIENT_AMBIENT_CONSTANTS_H_
......@@ -32,6 +32,7 @@
#include "chromeos/dbus/power_manager/idle.pb.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/views/controls/label.h"
namespace ash {
......@@ -197,6 +198,14 @@ void AmbientAshTestBase::SetScreenBrightnessAndWait(double percent) {
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(
media_session::MediaMetadata metadata) {
GetMediaStringView()->MediaSessionMetadataChanged(metadata);
......
......@@ -19,6 +19,10 @@
#include "services/media_session/public/mojom/media_session.mojom.h"
#include "ui/views/widget/widget.h"
namespace views {
class Label;
} // namespace views
namespace ash {
class AmbientAccessTokenController;
......@@ -62,6 +66,10 @@ class AmbientAshTestBase : public AshTestBase {
void SimulateSystemSuspendAndWait(
power_manager::SuspendImminent::Reason reason);
views::View* GetMediaStringViewTextContainer();
views::Label* GetMediaStringViewTextLabel();
// Simulates the system starting to resume.
// Wait until the event has been processed.
void SimulateSystemResumeAndWait();
......
......@@ -37,9 +37,8 @@ namespace {
using chromeos::assistant::features::IsAmbientAssistantEnabled;
// Appearance.
constexpr int kHorizontalMarginDip = 16;
constexpr int kAssistantPreferredHeightDip = 128;
constexpr int kMediaStringTopMarginDip = 25;
constexpr int kMediaStringMarginDip = 32;
// A tolerance threshold used to ignore spurious mouse move.
constexpr int kMouseMoveErrorTolerancePx = 3;
......@@ -185,12 +184,9 @@ void AmbientContainerView::LayoutMediaStringView() {
// The media string view is positioned on the right-top corner of the
// 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 =
container_size.width() - kHorizontalMarginDip - preferred_size.width();
int y = kMediaStringTopMarginDip;
container_size.width() - kMediaStringMarginDip - preferred_size.width();
int y = kMediaStringMarginDip;
media_string_view_->SetBoundsRect(
gfx::Rect(x, y, preferred_size.width(), preferred_size.height()));
}
......
......@@ -5,8 +5,8 @@
#include "ash/ambient/ui/media_string_view.h"
#include <memory>
#include <string>
#include "ash/ambient/ambient_constants.h"
#include "ash/ambient/util/ambient_util.h"
#include "ash/assistant/ui/assistant_view_ids.h"
#include "ash/public/cpp/ash_pref_names.h"
......@@ -15,23 +15,29 @@
#include "ash/shell_delegate.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.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_service.mojom.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/layout/box_layout.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/layout/flex_layout_types.h"
namespace ash {
namespace {
// Typography.
constexpr SkColor kTextColor = SK_ColorWHITE;
constexpr char kMiddleDotSeparator[] = " \u00B7 ";
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
// based on user pref. We should keep the same user policy here as the
......@@ -58,6 +64,10 @@ const char* MediaStringView::GetClassName() const {
return "MediaStringView";
}
void MediaStringView::VisibilityChanged(View* starting_from, bool is_visible) {
media_text_->layer()->GetAnimator()->StopAnimating();
}
void MediaStringView::MediaSessionInfoChanged(
media_session::mojom::MediaSessionInfoPtr session_info) {
if (ambient::util::IsShowing(LockScreen::ScreenType::kLock) &&
......@@ -85,18 +95,38 @@ void MediaStringView::MediaSessionMetadataChanged(
metadata.value_or(media_session::MediaMetadata());
base::string16 media_string;
base::string16 middle_dot = base::UTF8ToUTF16(kMiddleDotSeparator);
if (!session_metadata.title.empty() && !session_metadata.artist.empty()) {
media_string = session_metadata.title +
base::UTF8ToUTF16(kMiddleDotSeparator) +
session_metadata.artist;
media_string =
session_metadata.title + middle_dot + session_metadata.artist;
} else if (!session_metadata.title.empty()) {
media_string = session_metadata.title;
} else {
media_string = session_metadata.artist;
}
// Formats the media string with a preceding music eighth note.
SetText(base::UTF8ToUTF16(kPreceedingEighthNoteSymbol) + media_string);
// Reset text and stop any ongoing animation.
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() {
......@@ -105,12 +135,44 @@ void MediaStringView::InitLayout() {
SetPaintToLayer();
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.
SetAutoColorReadabilityEnabled(false);
SetEnabledColor(kTextColor);
SetFontList(ambient::util::GetDefaultFontlist().DeriveWithSizeDelta(
kMediaStringFontSizeDip - kDefaultFontSizeDip));
SetShadows(ambient::util::GetTextShadowValues());
constexpr SkColor kTextColor = SK_ColorWHITE;
constexpr int kDefaultFontSizeDip = 64;
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));
view->SetShadows(ambient::util::GetTextShadowValues());
view->SetElideBehavior(gfx::ElideBehavior::NO_ELIDE);
}
BindMediaControllerObserver();
}
......@@ -136,4 +198,56 @@ void MediaStringView::BindMediaControllerObserver() {
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
......@@ -5,22 +5,24 @@
#ifndef 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/remote.h"
#include "services/media_session/public/mojom/media_controller.mojom.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/views/view.h"
namespace views {
class Label;
} // namespace views
namespace ash {
// Container for displaying ongoing media information, including the name of the
// media and the artist, formatted with a proceding music note symbol and a
// middle dot separator.
class MediaStringView : public views::Label,
public media_session::mojom::MediaControllerObserver {
class MediaStringView : public views::View,
public media_session::mojom::MediaControllerObserver,
public ui::ImplicitAnimationObserver {
public:
MediaStringView();
MediaStringView(const MediaStringView&) = delete;
......@@ -29,6 +31,7 @@ class MediaStringView : public views::Label,
// views::Label:
const char* GetClassName() const override;
void VisibilityChanged(View* starting_from, bool is_visible) override;
// media_session::mojom::MediaControllerObserver:
void MediaSessionInfoChanged(
......@@ -43,15 +46,44 @@ class MediaStringView : public views::Label,
void MediaSessionPositionChanged(
const base::Optional<media_session::MediaPosition>& position) override {}
// ui::ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override;
private:
friend class AmbientAshTestBase;
void InitLayout();
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.
mojo::Remote<media_session::mojom::MediaController> media_controller_remote_;
mojo::Receiver<media_session::mojom::MediaControllerObserver>
observer_receiver_{this};
base::WeakPtrFactory<MediaStringView> weak_factory_{this};
};
} // namespace ash
......
......@@ -4,12 +4,15 @@
#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/public/cpp/ash_pref_names.h"
#include "ash/shell.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.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 {
......@@ -23,6 +26,10 @@ class MediaStringViewTest : public AmbientAshTestBase {
AmbientAshTestBase::SetUp();
GetSessionControllerClient()->set_show_lock_screen_views(true);
}
const base::string16& GetText() {
return GetMediaStringViewTextLabel()->GetText();
}
};
TEST_F(MediaStringViewTest, ShowMediaTitleAndArtist) {
......@@ -35,9 +42,213 @@ TEST_F(MediaStringViewTest, ShowMediaTitleAndArtist) {
SimulateMediaMetadataChanged(metadata);
const base::string16 expected_text =
base::UTF8ToUTF16("\u266A title \u00B7 artist");
EXPECT_EQ(GetMediaStringView()->GetText(), expected_text);
const base::string16 expected_text = base::UTF8ToUTF16("title \u00B7 artist");
EXPECT_EQ(GetMediaStringViewTextLabel()->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) {
......
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