1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/media/media_web_contents_observer.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "media/base/media_content_type.h"
#include "media/mojo/mojom/media_player.mojom.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
namespace content {
namespace {
constexpr auto kContentType = media::MediaContentType::kPersistent;
class TestMediaPlayer final : public media::mojom::MediaPlayer {
public:
mojo::AssociatedReceiver<media::mojom::MediaPlayer>& receiver() {
return receiver_;
}
// media::mojom::MediaPlayer implementation.
void RequestPlay() override {}
void RequestPause(bool triggered_by_user) override {}
void RequestSeekForward(base::TimeDelta seek_time) override {}
void RequestSeekBackward(base::TimeDelta seek_time) override {}
void RequestSeekTo(base::TimeDelta seek_time) override {}
void RequestEnterPictureInPicture() override {}
void RequestMute(bool mute) override {}
void SetVolumeMultiplier(double multiplier) override {}
void SetPersistentState(bool persistent) override {}
void SetPowerExperimentState(bool enabled) override {}
void SetAudioSinkId(const std::string& sink_id) override {}
void SuspendForFrameClosed() override {}
void RequestMediaRemoting() override {}
void RequestVisibility(
RequestVisibilityCallback request_visibility_callback) override {}
void RecordAutoPictureInPictureInfo(
const media::PictureInPictureEventsInfo::AutoPipInfo&
auto_picture_in_picture_info) override {}
private:
mojo::AssociatedReceiver<media::mojom::MediaPlayer> receiver_{this};
};
using MediaWebContentsObserverTest = RenderViewHostImplTestHarness;
TEST_F(MediaWebContentsObserverTest, GetCurrentlyPlayingVideoCount) {
MediaWebContentsObserver& media_web_contents_observer =
*contents()->media_web_contents_observer();
mojo::AssociatedRemote<media::mojom::MediaPlayerHost> player_host;
media_web_contents_observer.BindMediaPlayerHost(
contents()->GetPrimaryMainFrame()->GetGlobalId(),
player_host.BindNewEndpointAndPassDedicatedReceiver());
TestMediaPlayer audio_video_player;
mojo::AssociatedRemote<media::mojom::MediaPlayerObserver>
audio_video_player_observer;
player_host->OnMediaPlayerAdded(
audio_video_player.receiver().BindNewEndpointAndPassRemote(),
audio_video_player_observer.BindNewEndpointAndPassReceiver(),
/*player_id=*/0);
TestMediaPlayer video_player;
mojo::AssociatedRemote<media::mojom::MediaPlayerObserver>
video_player_observer;
player_host->OnMediaPlayerAdded(
video_player.receiver().BindNewEndpointAndPassRemote(),
video_player_observer.BindNewEndpointAndPassReceiver(),
/*player_id=*/1);
player_host.FlushForTesting();
EXPECT_EQ(media_web_contents_observer.GetCurrentlyPlayingVideoCount(), 0);
audio_video_player_observer->OnMediaMetadataChanged(
/*has_audio=*/true, /*has_video=*/false, kContentType);
audio_video_player_observer.FlushForTesting();
EXPECT_EQ(media_web_contents_observer.GetCurrentlyPlayingVideoCount(), 0)
<< "Nothing is playing";
audio_video_player_observer->OnMediaPlaying();
audio_video_player_observer.FlushForTesting();
EXPECT_EQ(media_web_contents_observer.GetCurrentlyPlayingVideoCount(), 0)
<< "An audio-only player is playing";
video_player_observer->OnMediaMetadataChanged(
/*has_audio=*/false, /*has_video=*/true, kContentType);
video_player_observer.FlushForTesting();
EXPECT_EQ(media_web_contents_observer.GetCurrentlyPlayingVideoCount(), 0)
<< "An audio-only player is playing";
video_player_observer->OnMediaPlaying();
video_player_observer.FlushForTesting();
EXPECT_EQ(media_web_contents_observer.GetCurrentlyPlayingVideoCount(), 1);
audio_video_player_observer->OnMediaMetadataChanged(
/*has_audio=*/true, /*has_video=*/true, kContentType);
audio_video_player_observer.FlushForTesting();
EXPECT_EQ(media_web_contents_observer.GetCurrentlyPlayingVideoCount(), 2)
<< "A video track was added to an initially audio-only player";
video_player_observer->OnMediaPaused(/*stream_ended=*/false);
video_player_observer.FlushForTesting();
EXPECT_EQ(media_web_contents_observer.GetCurrentlyPlayingVideoCount(), 1);
audio_video_player_observer->OnMediaMetadataChanged(
/*has_audio=*/true, /*has_video=*/false, kContentType);
audio_video_player_observer.FlushForTesting();
EXPECT_EQ(media_web_contents_observer.GetCurrentlyPlayingVideoCount(), 0)
<< "The video track was removed again";
}
} // namespace
} // namespace content
|