File: cast_media_source_unittest.cc

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (193 lines) | stat: -rw-r--r-- 8,307 bytes parent folder | download | duplicates (7)
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/media_router/common/providers/cast/cast_media_source.h"

#include "components/media_router/common/providers/cast/channel/cast_message_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/openscreen/src/cast/common/public/cast_streaming_app_ids.h"

using cast_channel::CastDeviceCapability;
using cast_channel::CastDeviceCapabilitySet;
using cast_channel::ReceiverAppType;

namespace media_router {

namespace {
void AssertDefaultCastMediaSource(CastMediaSource* source) {
  EXPECT_TRUE(source->client_id().empty());
  EXPECT_EQ(kDefaultLaunchTimeout, source->launch_timeout());
  EXPECT_EQ(AutoJoinPolicy::kPageScoped, source->auto_join_policy());
  EXPECT_EQ(DefaultActionPolicy::kCreateSession,
            source->default_action_policy());
  EXPECT_EQ(ReceiverAppType::kWeb, source->supported_app_types()[0]);
}
}  // namespace

TEST(CastMediaSourceTest, FromCastURLWithDefaults) {
  MediaSource::Id source_id("cast:ABCDEFAB");
  std::unique_ptr<CastMediaSource> source =
      CastMediaSource::FromMediaSourceId(source_id);
  ASSERT_TRUE(source);
  EXPECT_EQ(source_id, source->source_id());
  ASSERT_EQ(1u, source->app_infos().size());
  const CastAppInfo& app_info = source->app_infos()[0];
  EXPECT_EQ("ABCDEFAB", app_info.app_id);
  EXPECT_TRUE(app_info.required_capabilities.empty());
  EXPECT_EQ(std::nullopt, source->target_playout_delay());
  EXPECT_EQ(true, source->site_requested_audio_capture());
  EXPECT_EQ(cast_channel::VirtualConnectionType::kStrong,
            source->connection_type());
  AssertDefaultCastMediaSource(source.get());
}

TEST(CastMediaSourceTest, FromCastURL) {
  MediaSource::Id source_id(
      "cast:ABCDEFAB?capabilities=video_out,audio_out"
      "&clientId=12345"
      "&launchTimeout=30000"
      "&autoJoinPolicy=tab_and_origin_scoped"
      "&defaultActionPolicy=cast_this_tab"
      "&appParams=appParams"
      "&supportedAppTypes=ANDROID_TV,WEB"
      "&streamingTargetPlayoutDelayMillis=42"
      "&streamingCaptureAudio=0"
      "&invisibleSender=true");
  std::unique_ptr<CastMediaSource> source =
      CastMediaSource::FromMediaSourceId(source_id);
  ASSERT_TRUE(source);
  EXPECT_EQ(source_id, source->source_id());
  ASSERT_EQ(1u, source->app_infos().size());
  const CastAppInfo& app_info = source->app_infos()[0];
  EXPECT_EQ("ABCDEFAB", app_info.app_id);
  EXPECT_EQ((CastDeviceCapabilitySet{CastDeviceCapability::kVideoOut,
                                     CastDeviceCapability::kAudioOut}),
            app_info.required_capabilities);
  EXPECT_EQ("12345", source->client_id());
  EXPECT_EQ(base::Milliseconds(30000), source->launch_timeout());
  EXPECT_EQ(AutoJoinPolicy::kTabAndOriginScoped, source->auto_join_policy());
  EXPECT_EQ(DefaultActionPolicy::kCastThisTab, source->default_action_policy());
  EXPECT_EQ(ReceiverAppType::kAndroidTv, source->supported_app_types()[0]);
  EXPECT_EQ(ReceiverAppType::kWeb, source->supported_app_types()[1]);
  EXPECT_EQ("appParams", source->app_params());
  EXPECT_EQ(base::Milliseconds(42), source->target_playout_delay());
  EXPECT_EQ(false, source->site_requested_audio_capture());
  EXPECT_EQ(cast_channel::VirtualConnectionType::kInvisible,
            source->connection_type());
}

TEST(CastMediaSourceTest, FromLegacyCastURL) {
  MediaSource::Id source_id(
      "https://google.com/cast"
      "#__castAppId__=ABCDEFAB(video_out,audio_out)"
      "/__castAppId__=otherAppId"
      "/__castClientId__=12345"
      "/__castLaunchTimeout__=30000"
      "/__castAutoJoinPolicy__=origin_scoped"
      "/__castDefaultActionPolicy__=cast_this_tab");
  std::unique_ptr<CastMediaSource> source =
      CastMediaSource::FromMediaSourceId(source_id);
  ASSERT_TRUE(source);
  EXPECT_EQ(source_id, source->source_id());
  ASSERT_EQ(2u, source->app_infos().size());
  const CastAppInfo& app_info = source->app_infos()[0];
  EXPECT_EQ("ABCDEFAB", app_info.app_id);
  EXPECT_EQ((CastDeviceCapabilitySet{CastDeviceCapability::kVideoOut,
                                     CastDeviceCapability::kAudioOut}),
            app_info.required_capabilities);
  EXPECT_EQ("otherAppId", source->app_infos()[1].app_id);
  EXPECT_EQ("12345", source->client_id());
  EXPECT_EQ(base::Milliseconds(30000), source->launch_timeout());
  EXPECT_EQ(AutoJoinPolicy::kOriginScoped, source->auto_join_policy());
  EXPECT_EQ(DefaultActionPolicy::kCastThisTab, source->default_action_policy());
  EXPECT_EQ(ReceiverAppType::kWeb, source->supported_app_types()[0]);
}

TEST(CastMediaSourceTest, FromPresentationURL) {
  MediaSource::Id source_id("https://google.com");
  std::unique_ptr<CastMediaSource> source =
      CastMediaSource::FromMediaSourceId(source_id);
  ASSERT_TRUE(source);
  EXPECT_EQ(source_id, source->source_id());
  ASSERT_EQ(2u, source->app_infos().size());
  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioVideoAppId(),
            source->app_infos()[0].app_id);
  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioOnlyAppId(),
            source->app_infos()[1].app_id);
  AssertDefaultCastMediaSource(source.get());
}

TEST(CastMediaSourceTest, FromRemotePlaybackURL) {
  MediaSource::Id source_id(
      "remote-playback:media-session?tab_id=1&video_codec=vc&audio_codec=ac");
  std::unique_ptr<CastMediaSource> source =
      CastMediaSource::FromMediaSourceId(source_id);
  ASSERT_TRUE(source);
  EXPECT_EQ(source_id, source->source_id());
  ASSERT_EQ(2u, source->app_infos().size());
  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioVideoAppId(),
            source->app_infos()[0].app_id);
  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioOnlyAppId(),
            source->app_infos()[1].app_id);
}

TEST(CastMediaSourceTest, FromMirroringURN) {
  MediaSource::Id source_id("urn:x-org.chromium.media:source:tab:5");
  std::unique_ptr<CastMediaSource> source =
      CastMediaSource::FromMediaSourceId(source_id);
  ASSERT_TRUE(source);
  EXPECT_EQ(source_id, source->source_id());
  ASSERT_EQ(2u, source->app_infos().size());
  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioVideoAppId(),
            source->app_infos()[0].app_id);
  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioOnlyAppId(),
            source->app_infos()[1].app_id);
  AssertDefaultCastMediaSource(source.get());
}

TEST(CastMediaSourceTest, FromDesktopUrnWithoutAudio) {
  MediaSource::Id source_id("urn:x-org.chromium.media:source:desktop:foo");
  std::unique_ptr<CastMediaSource> source =
      CastMediaSource::FromMediaSourceId(source_id);
  ASSERT_TRUE(source);
  EXPECT_EQ(source_id, source->source_id());
  ASSERT_EQ(1u, source->app_infos().size());
  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioVideoAppId(),
            source->app_infos()[0].app_id);
  AssertDefaultCastMediaSource(source.get());
}

TEST(CastMediaSourceTest, FromDesktopUrnWithAudio) {
  MediaSource::Id source_id(
      "urn:x-org.chromium.media:source:desktop:foo?with_audio=true");
  std::unique_ptr<CastMediaSource> source =
      CastMediaSource::FromMediaSourceId(source_id);
  ASSERT_TRUE(source);
  EXPECT_EQ(source_id, source->source_id());
  ASSERT_EQ(2u, source->app_infos().size());
  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioVideoAppId(),
            source->app_infos()[0].app_id);
  EXPECT_EQ(openscreen::cast::GetCastStreamingAudioOnlyAppId(),
            source->app_infos()[1].app_id);
  AssertDefaultCastMediaSource(source.get());
}

TEST(CastMediaSourceTest, FromInvalidSource) {
  EXPECT_FALSE(CastMediaSource::FromMediaSourceId("invalid:source"));
  EXPECT_FALSE(CastMediaSource::FromMediaSourceId("file:///foo.mp4"));
  EXPECT_FALSE(CastMediaSource::FromMediaSourceId(""));
  EXPECT_FALSE(CastMediaSource::FromMediaSourceId("cast:"));

  // Missing app ID.
  EXPECT_FALSE(CastMediaSource::FromMediaSourceId("cast:?param=foo"));
  EXPECT_FALSE(CastMediaSource::FromMediaSourceId(
      "https://google.com/cast#__castAppId__=/param=foo"));
  // URL spec exceeds maximum size limit 64KB.
  int length = 64 * 1024 + 1;
  std::string invalidURL(length, 'a');
  EXPECT_FALSE(CastMediaSource::FromMediaSourceId("cast:appid?" + invalidURL));
}

}  // namespace media_router